Deleted Added
full compact
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 ---