Deleted Added
sdiff udiff text old ( 147711 ) new ( 147963 )
full compact
1/* $NetBSD: pcmcia.c,v 1.23 2000/07/28 19:17:02 drochner Exp $ */
2
3/*-
4 * Copyright (c) 1997 Marc Horowitz. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 16 unchanged lines hidden (view full) ---

25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#include <sys/cdefs.h>
33__FBSDID("$FreeBSD: head/sys/dev/pccard/pccard.c 147963 2005-07-13 15:00:59Z imp $");
34
35#include <sys/param.h>
36#include <sys/systm.h>
37#include <sys/malloc.h>
38#include <sys/module.h>
39#include <sys/kernel.h>
40#include <sys/queue.h>
41#include <sys/sysctl.h>

--- 213 unchanged lines hidden (view full) ---

255 * are combination cards, but only one of these units
256 * can be on at a time.
257 */
258 ivar = malloc(sizeof(struct pccard_ivar), M_DEVBUF,
259 M_WAITOK | M_ZERO);
260 resource_list_init(&ivar->resources);
261 child = device_add_child(dev, NULL, -1);
262 device_set_ivars(child, ivar);
263 ivar->pf = pf;
264 pf->dev = child;
265 /*
266 * XXX We might want to move the next three lines into
267 * XXX the pccard interface layer. For the moment, this
268 * XXX is OK, but some drivers want to pick the config
269 * XXX entry to use as well as some address tweaks (mostly
270 * XXX due to bugs in decode logic that makes some
271 * XXX addresses illegal or broken).
272 */
273 pccard_function_init(pf);
274 if (sc->sc_enabled_count == 0)

--- 598 unchanged lines hidden (view full) ---

873 pccard_print_resources(rl, "port", SYS_RES_IOPORT,
874 PCCARD_NPORT, "%#lx");
875 pccard_print_resources(rl, "iomem", SYS_RES_MEMORY,
876 PCCARD_NMEM, "%#lx");
877 pccard_print_resources(rl, "irq", SYS_RES_IRQ, PCCARD_NIRQ,
878 "%ld");
879 pccard_print_resources(rl, "drq", SYS_RES_DRQ, PCCARD_NDRQ,
880 "%ld");
881 retval += printf(" function %d config %d", devi->pf->number,
882 devi->pf->cfe->number);
883 }
884
885 retval += bus_print_child_footer(dev, child);
886
887 return (retval);
888}
889
890static int
891pccard_set_resource(device_t dev, device_t child, int type, int rid,
892 u_long start, u_long count)
893{
894 struct pccard_ivar *devi = PCCARD_IVAR(child);
895 struct resource_list *rl = &devi->resources;
896
897 if (type != SYS_RES_IOPORT && type != SYS_RES_MEMORY
898 && type != SYS_RES_IRQ && type != SYS_RES_DRQ)
899 return (EINVAL);
900 if (rid < 0)

--- 59 unchanged lines hidden (view full) ---

960 return (CARD_SET_MEMORY_OFFSET(device_get_parent(dev), child, rid,
961 offset, deltap));
962}
963
964static void
965pccard_probe_nomatch(device_t bus, device_t child)
966{
967 struct pccard_ivar *devi = PCCARD_IVAR(child);
968 struct pccard_function *pf = devi->pf;
969 struct pccard_softc *sc = PCCARD_SOFTC(bus);
970
971 device_printf(bus, "<unknown card>");
972 printf(" (manufacturer=0x%04x, product=0x%04x) at function %d\n",
973 sc->card.manufacturer, sc->card.product, pf->number);
974 device_printf(bus, " CIS info: %s, %s, %s\n", sc->card.cis1_info[0],
975 sc->card.cis1_info[1], sc->card.cis1_info[2]);
976 return;
977}
978
979static int
980pccard_child_location_str(device_t bus, device_t child, char *buf,
981 size_t buflen)
982{
983 struct pccard_ivar *devi = PCCARD_IVAR(child);
984 struct pccard_function *pf = devi->pf;
985
986 snprintf(buf, buflen, "function=%d", pf->number);
987 return (0);
988}
989
990/* XXX Maybe this should be in subr_bus? */
991static void
992pccard_safe_quote(char *dst, const char *src, size_t len)
993{
994 char *walker = dst, *ep = dst + len - 1;
995
996 if (len == 0)
997 return;
998 while (walker < ep)
999 {
1000 if (*src == '"') {
1001 if (ep - walker < 2)
1002 break;
1003 *walker++ = '\\';
1004 }
1005 *walker++ = *src++;
1006 }
1007 *walker = '\0';
1008}
1009
1010static int
1011pccard_child_pnpinfo_str(device_t bus, device_t child, char *buf,
1012 size_t buflen)
1013{
1014 struct pccard_ivar *devi = PCCARD_IVAR(child);
1015 struct pccard_function *pf = devi->pf;
1016 struct pccard_softc *sc = PCCARD_SOFTC(bus);
1017 char cis0[128], cis1[128];
1018
1019 pccard_safe_quote(cis0, sc->card.cis1_info[0], sizeof(cis0));
1020 pccard_safe_quote(cis1, sc->card.cis1_info[1], sizeof(cis1));
1021 snprintf(buf, buflen, "manufacturer=0x%04x product=0x%04x "
1022 "cisvendor=\"%s\" cisproduct=\"%s\" function_type=%d",
1023 sc->card.manufacturer, sc->card.product, cis0, cis1, pf->function);
1024 return (0);
1025}
1026
1027static int
1028pccard_read_ivar(device_t bus, device_t child, int which, u_char *result)
1029{
1030 struct pccard_ivar *devi = PCCARD_IVAR(child);
1031 struct pccard_function *pf = devi->pf;
1032 struct pccard_softc *sc = PCCARD_SOFTC(bus);
1033
1034 if (!pf)
1035 panic("No pccard function pointer");
1036 switch (which) {
1037 default:
1038 return (EINVAL);
1039 case PCCARD_IVAR_ETHADDR:
1040 bcopy(pf->pf_funce_lan_nid, result, ETHER_ADDR_LEN);
1041 break;
1042 case PCCARD_IVAR_VENDOR:
1043 *(uint32_t *)result = sc->card.manufacturer;
1044 break;
1045 case PCCARD_IVAR_PRODUCT:
1046 *(uint32_t *)result = sc->card.product;
1047 break;
1048 case PCCARD_IVAR_PRODEXT:
1049 *(uint16_t *)result = sc->card.prodext;
1050 break;
1051 case PCCARD_IVAR_FUNCTION:
1052 *(uint32_t *)result = pf->function;
1053 break;
1054 case PCCARD_IVAR_FUNCTION_NUMBER:
1055 *(uint32_t *)result = pf->number;
1056 break;
1057 case PCCARD_IVAR_VENDOR_STR:
1058 *(const char **)result = sc->card.cis1_info[0];
1059 break;
1060 case PCCARD_IVAR_PRODUCT_STR:
1061 *(const char **)result = sc->card.cis1_info[1];
1062 break;
1063 case PCCARD_IVAR_CIS3_STR:
1064 *(const char **)result = sc->card.cis1_info[2];
1065 break;
1066 case PCCARD_IVAR_CIS4_STR:
1067 *(const char **)result = sc->card.cis1_info[3];
1068 break;
1069 }
1070 return (0);
1071}
1072
1073static void
1074pccard_driver_added(device_t dev, driver_t *driver)
1075{

--- 108 unchanged lines hidden (view full) ---

1184 rman_set_device(rle->res, dev);
1185 return (0);
1186}
1187
1188static void
1189pccard_child_detached(device_t parent, device_t dev)
1190{
1191 struct pccard_ivar *ivar = PCCARD_IVAR(dev);
1192 struct pccard_function *pf = ivar->pf;
1193
1194 pccard_function_disable(pf);
1195}
1196
1197static void
1198pccard_intr(void *arg)
1199{
1200 struct pccard_function *pf = (struct pccard_function*) arg;

--- 29 unchanged lines hidden (view full) ---

1230}
1231
1232static int
1233pccard_setup_intr(device_t dev, device_t child, struct resource *irq,
1234 int flags, driver_intr_t *intr, void *arg, void **cookiep)
1235{
1236 struct pccard_softc *sc = PCCARD_SOFTC(dev);
1237 struct pccard_ivar *ivar = PCCARD_IVAR(child);
1238 struct pccard_function *pf = ivar->pf;
1239 int err;
1240
1241 if (pf->intr_handler != NULL)
1242 panic("Only one interrupt handler per function allowed");
1243 err = bus_generic_setup_intr(dev, child, irq, flags, pccard_intr,
1244 pf, cookiep);
1245 if (err != 0)
1246 return (err);
1247 pf->intr_handler = intr;
1248 pf->intr_handler_arg = arg;
1249 pf->intr_handler_cookie = *cookiep;
1250 if (pccard_mfc(sc)) {
1251 pccard_ccr_write(pf, PCCARD_CCR_OPTION,
1252 pccard_ccr_read(pf, PCCARD_CCR_OPTION) |
1253 PCCARD_CCR_OPTION_IREQ_ENABLE);
1254 }
1255 return (0);
1256}
1257
1258static int
1259pccard_teardown_intr(device_t dev, device_t child, struct resource *r,
1260 void *cookie)
1261{
1262 struct pccard_softc *sc = PCCARD_SOFTC(dev);
1263 struct pccard_ivar *ivar = PCCARD_IVAR(child);
1264 struct pccard_function *pf = ivar->pf;
1265 int ret;
1266
1267 if (pccard_mfc(sc)) {
1268 pccard_ccr_write(pf, PCCARD_CCR_OPTION,
1269 pccard_ccr_read(pf, PCCARD_CCR_OPTION) &
1270 ~PCCARD_CCR_OPTION_IREQ_ENABLE);
1271 }
1272 ret = bus_generic_teardown_intr(dev, child, r, cookie);
1273 if (ret == 0) {
1274 pf->intr_handler = NULL;
1275 pf->intr_handler_arg = NULL;
1276 pf->intr_handler_cookie = NULL;
1277 }
1278
1279 return (ret);
1280}
1281
1282static int
1283pccard_activate_resource(device_t brdev, device_t child, int type, int rid,
1284 struct resource *r)
1285{
1286 struct pccard_ivar *ivar = PCCARD_IVAR(child);
1287 struct pccard_function *pf = ivar->pf;
1288
1289 switch(type) {
1290 case SYS_RES_IOPORT:
1291 /*
1292 * We need to adjust IOBASE[01] and IOSIZE if we're an MFC
1293 * card.
1294 */
1295 if (pccard_mfc(pf->sc))

--- 69 unchanged lines hidden ---