pccard.c (121521) | pccard.c (121905) |
---|---|
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 121521 2003-10-26 00:51:40Z imp $"); | 33__FBSDID("$FreeBSD: head/sys/dev/pccard/pccard.c 121905 2003-11-02 20:18:19Z 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> --- 216 unchanged lines hidden (view full) --- 258 */ 259 pccard_function_init(pf); 260 if (sc->sc_enabled_count == 0) 261 POWER_ENABLE_SOCKET(device_get_parent(dev), dev); 262 if (pccard_function_enable(pf) == 0 && 263 pccard_set_default_descr(child) == 0 && 264 device_probe_and_attach(child) == 0) { 265 DEVPRINTF((sc->dev, "function %d CCR at %d " | 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> --- 216 unchanged lines hidden (view full) --- 258 */ 259 pccard_function_init(pf); 260 if (sc->sc_enabled_count == 0) 261 POWER_ENABLE_SOCKET(device_get_parent(dev), dev); 262 if (pccard_function_enable(pf) == 0 && 263 pccard_set_default_descr(child) == 0 && 264 device_probe_and_attach(child) == 0) { 265 DEVPRINTF((sc->dev, "function %d CCR at %d " |
266 "offset %x: %x %x %x %x, %x %x %x %x, %x\n", | 266 "offset %x mask %x: " 267 "%x %x %x %x, %x %x %x %x, %x\n", |
267 pf->number, pf->pf_ccr_window, pf->pf_ccr_offset, | 268 pf->number, pf->pf_ccr_window, pf->pf_ccr_offset, |
268 pccard_ccr_read(pf, 0x00), | 269 pf->ccr_mask, pccard_ccr_read(pf, 0x00), |
269 pccard_ccr_read(pf, 0x02), pccard_ccr_read(pf, 0x04), 270 pccard_ccr_read(pf, 0x06), pccard_ccr_read(pf, 0x0A), 271 pccard_ccr_read(pf, 0x0C), pccard_ccr_read(pf, 0x0E), 272 pccard_ccr_read(pf, 0x10), pccard_ccr_read(pf, 0x12))); 273 } else { 274 if (pf->cfe != NULL) 275 pccard_function_disable(pf); 276 } --- 246 unchanged lines hidden (view full) --- 523 BUS_RELEASE_RESOURCE(device_get_parent(pf->sc->dev), 524 pf->sc->dev, rle->type, rle->rid, rle->res); 525 rle->res = NULL; 526 } 527 } 528 resource_list_free(&devi->resources); 529} 530 | 270 pccard_ccr_read(pf, 0x02), pccard_ccr_read(pf, 0x04), 271 pccard_ccr_read(pf, 0x06), pccard_ccr_read(pf, 0x0A), 272 pccard_ccr_read(pf, 0x0C), pccard_ccr_read(pf, 0x0E), 273 pccard_ccr_read(pf, 0x10), pccard_ccr_read(pf, 0x12))); 274 } else { 275 if (pf->cfe != NULL) 276 pccard_function_disable(pf); 277 } --- 246 unchanged lines hidden (view full) --- 524 BUS_RELEASE_RESOURCE(device_get_parent(pf->sc->dev), 525 pf->sc->dev, rle->type, rle->rid, rle->res); 526 rle->res = NULL; 527 } 528 } 529 resource_list_free(&devi->resources); 530} 531 |
532static void 533pccard_mfc_adjust_iobase(struct pccard_function *pf, bus_addr_t addr, 534 bus_addr_t offset, bus_size_t size) 535{ 536 bus_addr_t iosize; 537 bus_size_t tmp; 538 539 if (addr != 0) { 540 if (pf->pf_mfc_iomax == 0) { 541 pf->pf_mfc_iobase = addr + offset; 542 pf->pf_mfc_iomax = pf->pf_mfc_iobase + size; 543 } else { 544 /* this makes the assumption that nothing overlaps */ 545 if (pf->pf_mfc_iobase > addr + offset) 546 pf->pf_mfc_iobase = addr + offset; 547 if (pf->pf_mfc_iomax < addr + offset + size) 548 pf->pf_mfc_iomax = addr + offset + size; 549 } 550 } 551 552 tmp = pf->pf_mfc_iomax - pf->pf_mfc_iobase; 553 /* round up to nearest (2^n)-1 */ 554 for (iosize = 1; iosize < tmp; iosize <<= 1) 555 ; 556 iosize--; 557 558 DEVPRINTF((pf->dev, "MFC: I/O base 0x%x IOSIZE %lld\n", 559 pf->pf_mfc_iobase, (uint64_t) iosize)); 560 pccard_ccr_write(pf, PCCARD_CCR_IOBASE0, 561 pf->pf_mfc_iobase & 0xff); 562 pccard_ccr_write(pf, PCCARD_CCR_IOBASE1, 563 (pf->pf_mfc_iobase >> 8) & 0xff); 564 pccard_ccr_write(pf, PCCARD_CCR_IOBASE2, 0); 565 pccard_ccr_write(pf, PCCARD_CCR_IOBASE3, 0); 566 pccard_ccr_write(pf, PCCARD_CCR_IOSIZE, iosize); 567} 568 |
|
531/* Enable a PCCARD function */ 532static int 533pccard_function_enable(struct pccard_function *pf) 534{ 535 struct pccard_function *tmp; 536 int reg; 537 device_t dev = pf->sc->dev; 538 --- 71 unchanged lines hidden (view full) --- 610 if ((pf->cfe->flags & PCCARD_CFE_IO16) == 0) 611 reg |= PCCARD_CCR_STATUS_IOIS8; 612 if (pf->cfe->flags & PCCARD_CFE_AUDIO) 613 reg |= PCCARD_CCR_STATUS_AUDIO; 614 pccard_ccr_write(pf, PCCARD_CCR_STATUS, reg); 615 616 pccard_ccr_write(pf, PCCARD_CCR_SOCKETCOPY, 0); 617 | 569/* Enable a PCCARD function */ 570static int 571pccard_function_enable(struct pccard_function *pf) 572{ 573 struct pccard_function *tmp; 574 int reg; 575 device_t dev = pf->sc->dev; 576 --- 71 unchanged lines hidden (view full) --- 648 if ((pf->cfe->flags & PCCARD_CFE_IO16) == 0) 649 reg |= PCCARD_CCR_STATUS_IOIS8; 650 if (pf->cfe->flags & PCCARD_CFE_AUDIO) 651 reg |= PCCARD_CCR_STATUS_AUDIO; 652 pccard_ccr_write(pf, PCCARD_CCR_STATUS, reg); 653 654 pccard_ccr_write(pf, PCCARD_CCR_SOCKETCOPY, 0); 655 |
618 if (pccard_mfc(pf->sc)) { 619 long tmp, iosize; | 656 if (pccard_mfc(pf->sc)) 657 pccard_mfc_adjust_iobase(pf, 0, 0, 0); |
620 | 658 |
621 tmp = pf->pf_mfc_iomax - pf->pf_mfc_iobase; 622 /* round up to nearest (2^n)-1 */ 623 for (iosize = 1; iosize < tmp; iosize <<= 1) 624 ; 625 iosize--; 626 627 pccard_ccr_write(pf, PCCARD_CCR_IOBASE0, 628 pf->pf_mfc_iobase & 0xff); 629 pccard_ccr_write(pf, PCCARD_CCR_IOBASE1, 630 (pf->pf_mfc_iobase >> 8) & 0xff); 631 pccard_ccr_write(pf, PCCARD_CCR_IOBASE2, 0); 632 pccard_ccr_write(pf, PCCARD_CCR_IOBASE3, 0); 633 634 pccard_ccr_write(pf, PCCARD_CCR_IOSIZE, iosize); 635 } 636 | |
637#ifdef PCCARDDEBUG 638 if (pccard_debug) { 639 STAILQ_FOREACH(tmp, &pf->sc->card.pf_head, pf_list) { 640 device_printf(tmp->sc->dev, 641 "function %d CCR at %d offset %x: " 642 "%x %x %x %x, %x %x %x %x, %x\n", 643 tmp->number, tmp->pf_ccr_window, 644 tmp->pf_ccr_offset, --- 402 unchanged lines hidden (view full) --- 1047 1048static struct resource * 1049pccard_alloc_resource(device_t dev, device_t child, int type, int *rid, 1050 u_long start, u_long end, u_long count, u_int flags) 1051{ 1052 struct pccard_ivar *dinfo; 1053 struct resource_list_entry *rle = 0; 1054 int passthrough = (device_get_parent(child) != dev); | 659#ifdef PCCARDDEBUG 660 if (pccard_debug) { 661 STAILQ_FOREACH(tmp, &pf->sc->card.pf_head, pf_list) { 662 device_printf(tmp->sc->dev, 663 "function %d CCR at %d offset %x: " 664 "%x %x %x %x, %x %x %x %x, %x\n", 665 tmp->number, tmp->pf_ccr_window, 666 tmp->pf_ccr_offset, --- 402 unchanged lines hidden (view full) --- 1069 1070static struct resource * 1071pccard_alloc_resource(device_t dev, device_t child, int type, int *rid, 1072 u_long start, u_long end, u_long count, u_int flags) 1073{ 1074 struct pccard_ivar *dinfo; 1075 struct resource_list_entry *rle = 0; 1076 int passthrough = (device_get_parent(child) != dev); |
1077 int isdefault = (start == 0 && end == ~0UL && count == 1); |
|
1055 struct resource *r = NULL; 1056 | 1078 struct resource *r = NULL; 1079 |
1080 /* XXX I'm no longer sure this is right */ |
|
1057 if (passthrough) { 1058 return (BUS_ALLOC_RESOURCE(device_get_parent(dev), child, 1059 type, rid, start, end, count, flags)); 1060 } 1061 1062 dinfo = device_get_ivars(child); 1063 rle = resource_list_find(&dinfo->resources, type, *rid); 1064 | 1081 if (passthrough) { 1082 return (BUS_ALLOC_RESOURCE(device_get_parent(dev), child, 1083 type, rid, start, end, count, flags)); 1084 } 1085 1086 dinfo = device_get_ivars(child); 1087 rle = resource_list_find(&dinfo->resources, type, *rid); 1088 |
1065 if (rle == NULL) 1066 return (NULL); /* no resource of that type/rid */ 1067 1068 if (rle->res == NULL) { 1069 switch(type) { 1070 case SYS_RES_IOPORT: 1071 r = bus_alloc_resource(dev, type, rid, start, end, 1072 count, rman_make_alignment_flags(count)); 1073 if (r == NULL) 1074 goto bad; 1075 resource_list_add(&dinfo->resources, type, *rid, 1076 rman_get_start(r), rman_get_end(r), count); 1077 rle = resource_list_find(&dinfo->resources, type, *rid); 1078 if (!rle) 1079 goto bad; 1080 rle->res = r; 1081 break; 1082 case SYS_RES_MEMORY: 1083 break; 1084 case SYS_RES_IRQ: 1085 break; 1086 } 1087 return (rle->res); | 1089 if (rle == NULL && isdefault) 1090 return (NULL); /* no resource of that type/rid */ 1091 if (rle == NULL || rle->res == NULL) { 1092 /* Do we want this device to own it? */ 1093 /* XXX I think so, but that might be lame XXX */ 1094 r = bus_alloc_resource(dev, type, rid, start, end, 1095 count, flags /* XXX aligment? */); 1096 if (r == NULL) 1097 goto bad; 1098 resource_list_add(&dinfo->resources, type, *rid, 1099 rman_get_start(r), rman_get_end(r), count); 1100 rle = resource_list_find(&dinfo->resources, type, *rid); 1101 if (!rle) 1102 goto bad; 1103 rle->res = r; |
1088 } | 1104 } |
1105 /* 1106 * XXX the following looks wrong, in theory, but likely it is 1107 * XXX needed because of how the CIS code allocates resources 1108 * XXX for this device. 1109 */ |
|
1089 if (rman_get_device(rle->res) != dev) 1090 return (NULL); 1091 bus_release_resource(dev, type, *rid, rle->res); 1092 rle->res = NULL; 1093 switch(type) { 1094 case SYS_RES_IOPORT: 1095 case SYS_RES_MEMORY: 1096 if (!(flags & RF_ALIGNMENT_MASK)) --- 150 unchanged lines hidden (view full) --- 1247 func->intr_handler = NULL; 1248 func->intr_handler_arg = NULL; 1249 func->intr_handler_cookie = NULL; 1250 } 1251 1252 return (ret); 1253} 1254 | 1110 if (rman_get_device(rle->res) != dev) 1111 return (NULL); 1112 bus_release_resource(dev, type, *rid, rle->res); 1113 rle->res = NULL; 1114 switch(type) { 1115 case SYS_RES_IOPORT: 1116 case SYS_RES_MEMORY: 1117 if (!(flags & RF_ALIGNMENT_MASK)) --- 150 unchanged lines hidden (view full) --- 1268 func->intr_handler = NULL; 1269 func->intr_handler_arg = NULL; 1270 func->intr_handler_cookie = NULL; 1271 } 1272 1273 return (ret); 1274} 1275 |
1276static int 1277pccard_activate_resource(device_t brdev, device_t child, int type, int rid, 1278 struct resource *r) 1279{ 1280 struct pccard_ivar *ivar = PCCARD_IVAR(child); 1281 struct pccard_function *pf = ivar->fcn; 1282 1283 switch(type) { 1284 case SYS_RES_IOPORT: 1285 /* 1286 * We need to adjust IOBASE[01] and IOSIZE if we're an MFC 1287 * card. 1288 */ 1289 if (pccard_mfc(pf->sc)) 1290 pccard_mfc_adjust_iobase(pf, rman_get_start(r), 0, 1291 rman_get_size(r)); 1292 break; 1293 default: 1294 break; 1295 } 1296 return (bus_generic_activate_resource(brdev, child, type, rid, r)); 1297} 1298 1299static int 1300pccard_deactivate_resource(device_t brdev, device_t child, int type, 1301 int rid, struct resource *r) 1302{ 1303 /* XXX undo pccard_activate_resource? XXX */ 1304 return (bus_generic_deactivate_resource(brdev, child, type, rid, r)); 1305} 1306 |
|
1255static device_method_t pccard_methods[] = { 1256 /* Device interface */ 1257 DEVMETHOD(device_probe, pccard_probe), 1258 DEVMETHOD(device_attach, pccard_attach), 1259 DEVMETHOD(device_detach, pccard_detach), 1260 DEVMETHOD(device_shutdown, bus_generic_shutdown), 1261 DEVMETHOD(device_suspend, pccard_suspend), 1262 DEVMETHOD(device_resume, pccard_resume), 1263 1264 /* Bus interface */ 1265 DEVMETHOD(bus_print_child, pccard_print_child), 1266 DEVMETHOD(bus_driver_added, pccard_driver_added), 1267 DEVMETHOD(bus_child_detached, pccard_child_detached), 1268 DEVMETHOD(bus_alloc_resource, pccard_alloc_resource), 1269 DEVMETHOD(bus_release_resource, pccard_release_resource), | 1307static device_method_t pccard_methods[] = { 1308 /* Device interface */ 1309 DEVMETHOD(device_probe, pccard_probe), 1310 DEVMETHOD(device_attach, pccard_attach), 1311 DEVMETHOD(device_detach, pccard_detach), 1312 DEVMETHOD(device_shutdown, bus_generic_shutdown), 1313 DEVMETHOD(device_suspend, pccard_suspend), 1314 DEVMETHOD(device_resume, pccard_resume), 1315 1316 /* Bus interface */ 1317 DEVMETHOD(bus_print_child, pccard_print_child), 1318 DEVMETHOD(bus_driver_added, pccard_driver_added), 1319 DEVMETHOD(bus_child_detached, pccard_child_detached), 1320 DEVMETHOD(bus_alloc_resource, pccard_alloc_resource), 1321 DEVMETHOD(bus_release_resource, pccard_release_resource), |
1270 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), 1271 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), | 1322 DEVMETHOD(bus_activate_resource, pccard_activate_resource), 1323 DEVMETHOD(bus_deactivate_resource, pccard_deactivate_resource), |
1272 DEVMETHOD(bus_setup_intr, pccard_setup_intr), 1273 DEVMETHOD(bus_teardown_intr, pccard_teardown_intr), 1274 DEVMETHOD(bus_set_resource, pccard_set_resource), 1275 DEVMETHOD(bus_get_resource, pccard_get_resource), 1276 DEVMETHOD(bus_delete_resource, pccard_delete_resource), 1277 DEVMETHOD(bus_probe_nomatch, pccard_probe_nomatch), 1278 DEVMETHOD(bus_read_ivar, pccard_read_ivar), 1279 DEVMETHOD(bus_child_pnpinfo_str, pccard_child_pnpinfo_str), --- 26 unchanged lines hidden --- | 1324 DEVMETHOD(bus_setup_intr, pccard_setup_intr), 1325 DEVMETHOD(bus_teardown_intr, pccard_teardown_intr), 1326 DEVMETHOD(bus_set_resource, pccard_set_resource), 1327 DEVMETHOD(bus_get_resource, pccard_get_resource), 1328 DEVMETHOD(bus_delete_resource, pccard_delete_resource), 1329 DEVMETHOD(bus_probe_nomatch, pccard_probe_nomatch), 1330 DEVMETHOD(bus_read_ivar, pccard_read_ivar), 1331 DEVMETHOD(bus_child_pnpinfo_str, pccard_child_pnpinfo_str), --- 26 unchanged lines hidden --- |