pccard.c (147711) | pccard.c (147963) |
---|---|
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> | 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 147711 2005-07-01 03:40:28Z imp $"); | 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); | 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->fcn = pf; | 263 ivar->pf = pf; |
264 pf->dev = child; 265 /* | 264 pf->dev = child; 265 /* |
266 * XXX We might want to move the next two lines into | 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"); | 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->fcn->number, 882 devi->fcn->cfe->number); | 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, | 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) | 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); | 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 *func = devi->fcn; | 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", | 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, func->number); | 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); | 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 *func = devi->fcn; | 984 struct pccard_function *pf = devi->pf; |
985 | 985 |
986 snprintf(buf, buflen, "function=%d", func->number); | 986 snprintf(buf, buflen, "function=%d", pf->number); |
987 return (0); 988} 989 | 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 |
|
990static int 991pccard_child_pnpinfo_str(device_t bus, device_t child, char *buf, 992 size_t buflen) 993{ 994 struct pccard_ivar *devi = PCCARD_IVAR(child); | 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); |
995 struct pccard_function *func = devi->fcn; | 1015 struct pccard_function *pf = devi->pf; |
996 struct pccard_softc *sc = PCCARD_SOFTC(bus); | 1016 struct pccard_softc *sc = PCCARD_SOFTC(bus); |
1017 char cis0[128], cis1[128]; |
|
997 | 1018 |
998 /* XXX need to make sure that we've quoted the " in strings! */ | 1019 pccard_safe_quote(cis0, sc->card.cis1_info[0], sizeof(cis0)); 1020 pccard_safe_quote(cis1, sc->card.cis1_info[1], sizeof(cis1)); |
999 snprintf(buf, buflen, "manufacturer=0x%04x product=0x%04x " 1000 "cisvendor=\"%s\" cisproduct=\"%s\" function_type=%d", | 1021 snprintf(buf, buflen, "manufacturer=0x%04x product=0x%04x " 1022 "cisvendor=\"%s\" cisproduct=\"%s\" function_type=%d", |
1001 sc->card.manufacturer, sc->card.product, sc->card.cis1_info[0], 1002 sc->card.cis1_info[1], func->function); | 1023 sc->card.manufacturer, sc->card.product, cis0, cis1, pf->function); |
1003 return (0); 1004} 1005 1006static int 1007pccard_read_ivar(device_t bus, device_t child, int which, u_char *result) 1008{ 1009 struct pccard_ivar *devi = PCCARD_IVAR(child); | 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); |
1010 struct pccard_function *func = devi->fcn; | 1031 struct pccard_function *pf = devi->pf; |
1011 struct pccard_softc *sc = PCCARD_SOFTC(bus); 1012 | 1032 struct pccard_softc *sc = PCCARD_SOFTC(bus); 1033 |
1034 if (!pf) 1035 panic("No pccard function pointer"); |
|
1013 switch (which) { 1014 default: | 1036 switch (which) { 1037 default: |
1038 return (EINVAL); |
|
1015 case PCCARD_IVAR_ETHADDR: | 1039 case PCCARD_IVAR_ETHADDR: |
1016 bcopy(func->pf_funce_lan_nid, result, ETHER_ADDR_LEN); | 1040 bcopy(pf->pf_funce_lan_nid, result, ETHER_ADDR_LEN); |
1017 break; 1018 case PCCARD_IVAR_VENDOR: | 1041 break; 1042 case PCCARD_IVAR_VENDOR: |
1019 *(uint32_t *) result = sc->card.manufacturer; | 1043 *(uint32_t *)result = sc->card.manufacturer; |
1020 break; 1021 case PCCARD_IVAR_PRODUCT: | 1044 break; 1045 case PCCARD_IVAR_PRODUCT: |
1022 *(uint32_t *) result = sc->card.product; | 1046 *(uint32_t *)result = sc->card.product; |
1023 break; 1024 case PCCARD_IVAR_PRODEXT: | 1047 break; 1048 case PCCARD_IVAR_PRODEXT: |
1025 *(uint16_t *) result = sc->card.prodext; | 1049 *(uint16_t *)result = sc->card.prodext; |
1026 break; 1027 case PCCARD_IVAR_FUNCTION: | 1050 break; 1051 case PCCARD_IVAR_FUNCTION: |
1028 *(uint32_t *) result = func->function; | 1052 *(uint32_t *)result = pf->function; |
1029 break; 1030 case PCCARD_IVAR_FUNCTION_NUMBER: | 1053 break; 1054 case PCCARD_IVAR_FUNCTION_NUMBER: |
1031 if (!func) { 1032 device_printf(bus, "No function number, bug!\n"); 1033 return (ENOENT); 1034 } 1035 *(uint32_t *) result = func->number; | 1055 *(uint32_t *)result = pf->number; |
1036 break; 1037 case PCCARD_IVAR_VENDOR_STR: | 1056 break; 1057 case PCCARD_IVAR_VENDOR_STR: |
1038 *(char **) result = sc->card.cis1_info[0]; | 1058 *(const char **)result = sc->card.cis1_info[0]; |
1039 break; 1040 case PCCARD_IVAR_PRODUCT_STR: | 1059 break; 1060 case PCCARD_IVAR_PRODUCT_STR: |
1041 *(char **) result = sc->card.cis1_info[1]; | 1061 *(const char **)result = sc->card.cis1_info[1]; |
1042 break; 1043 case PCCARD_IVAR_CIS3_STR: | 1062 break; 1063 case PCCARD_IVAR_CIS3_STR: |
1044 *(char **) result = sc->card.cis1_info[2]; | 1064 *(const char **)result = sc->card.cis1_info[2]; |
1045 break; 1046 case PCCARD_IVAR_CIS4_STR: | 1065 break; 1066 case PCCARD_IVAR_CIS4_STR: |
1047 *(char **) result = sc->card.cis1_info[3]; | 1067 *(const char **)result = sc->card.cis1_info[3]; |
1048 break; 1049 } 1050 return (0); 1051} 1052 1053static void 1054pccard_driver_added(device_t dev, driver_t *driver) 1055{ --- 108 unchanged lines hidden (view full) --- 1164 rman_set_device(rle->res, dev); 1165 return (0); 1166} 1167 1168static void 1169pccard_child_detached(device_t parent, device_t dev) 1170{ 1171 struct pccard_ivar *ivar = PCCARD_IVAR(dev); | 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); |
1172 struct pccard_function *pf = ivar->fcn; | 1192 struct pccard_function *pf = ivar->pf; |
1173 1174 pccard_function_disable(pf); 1175} 1176 1177static void 1178pccard_intr(void *arg) 1179{ 1180 struct pccard_function *pf = (struct pccard_function*) arg; --- 29 unchanged lines hidden (view full) --- 1210} 1211 1212static int 1213pccard_setup_intr(device_t dev, device_t child, struct resource *irq, 1214 int flags, driver_intr_t *intr, void *arg, void **cookiep) 1215{ 1216 struct pccard_softc *sc = PCCARD_SOFTC(dev); 1217 struct pccard_ivar *ivar = PCCARD_IVAR(child); | 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); |
1218 struct pccard_function *func = ivar->fcn; | 1238 struct pccard_function *pf = ivar->pf; |
1219 int err; 1220 | 1239 int err; 1240 |
1221 if (func->intr_handler != NULL) | 1241 if (pf->intr_handler != NULL) |
1222 panic("Only one interrupt handler per function allowed"); 1223 err = bus_generic_setup_intr(dev, child, irq, flags, pccard_intr, | 1242 panic("Only one interrupt handler per function allowed"); 1243 err = bus_generic_setup_intr(dev, child, irq, flags, pccard_intr, |
1224 func, cookiep); | 1244 pf, cookiep); |
1225 if (err != 0) 1226 return (err); | 1245 if (err != 0) 1246 return (err); |
1227 func->intr_handler = intr; 1228 func->intr_handler_arg = arg; 1229 func->intr_handler_cookie = *cookiep; | 1247 pf->intr_handler = intr; 1248 pf->intr_handler_arg = arg; 1249 pf->intr_handler_cookie = *cookiep; |
1230 if (pccard_mfc(sc)) { | 1250 if (pccard_mfc(sc)) { |
1231 pccard_ccr_write(func, PCCARD_CCR_OPTION, 1232 pccard_ccr_read(func, PCCARD_CCR_OPTION) | | 1251 pccard_ccr_write(pf, PCCARD_CCR_OPTION, 1252 pccard_ccr_read(pf, PCCARD_CCR_OPTION) | |
1233 PCCARD_CCR_OPTION_IREQ_ENABLE); 1234 } 1235 return (0); 1236} 1237 1238static int 1239pccard_teardown_intr(device_t dev, device_t child, struct resource *r, 1240 void *cookie) 1241{ 1242 struct pccard_softc *sc = PCCARD_SOFTC(dev); 1243 struct pccard_ivar *ivar = PCCARD_IVAR(child); | 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); |
1244 struct pccard_function *func = ivar->fcn; | 1264 struct pccard_function *pf = ivar->pf; |
1245 int ret; 1246 1247 if (pccard_mfc(sc)) { | 1265 int ret; 1266 1267 if (pccard_mfc(sc)) { |
1248 pccard_ccr_write(func, PCCARD_CCR_OPTION, 1249 pccard_ccr_read(func, PCCARD_CCR_OPTION) & | 1268 pccard_ccr_write(pf, PCCARD_CCR_OPTION, 1269 pccard_ccr_read(pf, PCCARD_CCR_OPTION) & |
1250 ~PCCARD_CCR_OPTION_IREQ_ENABLE); 1251 } 1252 ret = bus_generic_teardown_intr(dev, child, r, cookie); 1253 if (ret == 0) { | 1270 ~PCCARD_CCR_OPTION_IREQ_ENABLE); 1271 } 1272 ret = bus_generic_teardown_intr(dev, child, r, cookie); 1273 if (ret == 0) { |
1254 func->intr_handler = NULL; 1255 func->intr_handler_arg = NULL; 1256 func->intr_handler_cookie = NULL; | 1274 pf->intr_handler = NULL; 1275 pf->intr_handler_arg = NULL; 1276 pf->intr_handler_cookie = NULL; |
1257 } 1258 1259 return (ret); 1260} 1261 1262static int 1263pccard_activate_resource(device_t brdev, device_t child, int type, int rid, 1264 struct resource *r) 1265{ 1266 struct pccard_ivar *ivar = PCCARD_IVAR(child); | 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); |
1267 struct pccard_function *pf = ivar->fcn; | 1287 struct pccard_function *pf = ivar->pf; |
1268 1269 switch(type) { 1270 case SYS_RES_IOPORT: 1271 /* 1272 * We need to adjust IOBASE[01] and IOSIZE if we're an MFC 1273 * card. 1274 */ 1275 if (pccard_mfc(pf->sc)) --- 69 unchanged lines hidden --- | 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 --- |