1 /* 2 * Copyright (c) 2000,2001 Jonathan Chen. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions, and the following disclaimer, 10 * without modification, immediately at the beginning of the file. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in 13 * the documentation and/or other materials provided with the 14 * distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 * 28 * $FreeBSD$ 29 */ 30 31 /* 32 * Cardbus Bus Driver 33 * 34 * much of the bus code was stolen directly from sys/pci/pci.c 35 * (Copyright (c) 1997, Stefan Esser <se@freebsd.org>) 36 * 37 * Written by Jonathan Chen <jon@freebsd.org> 38 */ 39 40 #define CARDBUS_DEBUG 41 42 #include <sys/param.h> 43 #include <sys/systm.h> 44 #include <sys/malloc.h> 45 #include <sys/kernel.h> 46 47 #include <sys/bus.h> 48 #include <machine/bus.h> 49 #include <sys/rman.h> 50 #include <machine/resource.h> 51 52 #include <dev/pci/pcivar.h> 53 #include <dev/pci/pcireg.h> 54 #include <sys/pciio.h> 55 56 #include <dev/cardbus/cardbusreg.h> 57 #include <dev/cardbus/cardbusvar.h> 58 #include <dev/cardbus/cardbus_cis.h> 59 60 #include "power_if.h" 61 #include "card_if.h" 62 #include "pcib_if.h" 63 64 #if defined CARDBUS_DEBUG 65 #define DPRINTF(a) printf a 66 #define DEVPRINTF(x) device_printf x 67 #else 68 #define DPRINTF(a) 69 #define DEVPRINTF(x) 70 #endif 71 72 #if !defined(lint) 73 static const char rcsid[] = 74 "$FreeBSD$"; 75 #endif 76 77 static int cardbus_probe(device_t cbdev); 78 static int cardbus_attach(device_t cbdev); 79 static int cardbus_detach(device_t cbdev); 80 static void device_setup_regs(device_t brdev, int b, int s, int f, 81 pcicfgregs *cfg); 82 static int cardbus_attach_card(device_t cbdev); 83 static int cardbus_detach_card(device_t cbdev, int flags); 84 static void cardbus_driver_added(device_t cbdev, driver_t *driver); 85 static void cardbus_read_extcap(device_t cbdev, pcicfgregs *cfg); 86 static void cardbus_hdrtypedata(device_t brdev, int b, int s, int f, 87 pcicfgregs *cfg); 88 static struct cardbus_devinfo *cardbus_read_device(device_t brdev, int b, 89 int s, int f); 90 static int cardbus_freecfg(struct cardbus_devinfo *dinfo); 91 static void cardbus_print_verbose(struct cardbus_devinfo *dinfo); 92 static int cardbus_set_resource(device_t cbdev, device_t child, int type, 93 int rid, u_long start, u_long count, struct resource *res); 94 static int cardbus_get_resource(device_t cbdev, device_t child, int type, 95 int rid, u_long *startp, u_long *countp); 96 static void cardbus_delete_resource(device_t cbdev, device_t child, 97 int type, int rid); 98 static int cardbus_set_resource_method(device_t cbdev, device_t child, 99 int type, int rid, u_long start, u_long count); 100 static int cardbus_get_resource_method(device_t cbdev, device_t child, 101 int type, int rid, u_long *startp, u_long *countp); 102 static void cardbus_delete_resource_method(device_t cbdev, device_t child, 103 int type, int rid); 104 static void cardbus_release_all_resources(device_t cbdev, 105 struct cardbus_devinfo *dinfo); 106 static struct resource *cardbus_alloc_resource(device_t cbdev, device_t child, 107 int type, int *rid, u_long start, u_long end, u_long count, 108 u_int flags); 109 static int cardbus_release_resource(device_t cbdev, device_t child, 110 int type, int rid, struct resource *r); 111 static int cardbus_setup_intr(device_t cbdev, device_t child, 112 struct resource *irq, int flags, driver_intr_t *intr, 113 void *arg, void **cookiep); 114 static int cardbus_teardown_intr(device_t cbdev, device_t child, 115 struct resource *irq, void *cookie); 116 static int cardbus_print_resources(struct resource_list *rl, 117 const char *name, int type, const char *format); 118 static int cardbus_print_child(device_t cbdev, device_t child); 119 static void cardbus_probe_nomatch(device_t cbdev, device_t child); 120 static int cardbus_read_ivar(device_t cbdev, device_t child, int which, 121 u_long *result); 122 static int cardbus_write_ivar(device_t cbdev, device_t child, int which, 123 uintptr_t value); 124 static int cardbus_set_powerstate_method(device_t cbdev, device_t child, 125 int state); 126 static int cardbus_get_powerstate_method(device_t cbdev, device_t child); 127 static u_int32_t cardbus_read_config_method(device_t cbdev, 128 device_t child, int reg, int width); 129 static void cardbus_write_config_method(device_t cbdev, device_t child, 130 int reg, u_int32_t val, int width); 131 static __inline void cardbus_set_command_bit(device_t cbdev, device_t child, 132 u_int16_t bit); 133 static __inline void cardbus_clear_command_bit(device_t cbdev, device_t child, 134 u_int16_t bit); 135 static void cardbus_enable_busmaster_method(device_t cbdev, device_t child); 136 static void cardbus_disable_busmaster_method(device_t cbdev, device_t child); 137 static void cardbus_enable_io_method(device_t cbdev, device_t child, 138 int space); 139 static void cardbus_disable_io_method(device_t cbdev, device_t child, 140 int space); 141 142 /************************************************************************/ 143 /* Probe/Attach */ 144 /************************************************************************/ 145 146 static int 147 cardbus_probe(device_t cbdev) 148 { 149 device_set_desc(cbdev, "CardBus bus"); 150 return 0; 151 } 152 153 static int 154 cardbus_attach(device_t cbdev) 155 { 156 return 0; 157 } 158 159 static int 160 cardbus_detach(device_t cbdev) 161 { 162 cardbus_detach_card(cbdev, DETACH_FORCE); 163 return 0; 164 } 165 166 static int 167 cardbus_suspend(device_t self) 168 { 169 cardbus_detach_card(self, DETACH_FORCE); 170 return (0); 171 } 172 173 static int 174 cardbus_resume(device_t self) 175 { 176 return (0); 177 } 178 179 /************************************************************************/ 180 /* Attach/Detach card */ 181 /************************************************************************/ 182 183 static void 184 device_setup_regs(device_t brdev, int b, int s, int f, pcicfgregs *cfg) 185 { 186 PCIB_WRITE_CONFIG(brdev, b, s, f, PCIR_INTLINE, 187 pci_get_irq(device_get_parent(brdev)), 1); 188 cfg->intline = PCIB_READ_CONFIG(brdev, b, s, f, PCIR_INTLINE, 1); 189 190 PCIB_WRITE_CONFIG(brdev, b, s, f, PCIR_CACHELNSZ, 0x08, 1); 191 cfg->cachelnsz = PCIB_READ_CONFIG(brdev, b, s, f, PCIR_CACHELNSZ, 1); 192 193 PCIB_WRITE_CONFIG(brdev, b, s, f, PCIR_LATTIMER, 0xa8, 1); 194 cfg->lattimer = PCIB_READ_CONFIG(brdev, b, s, f, PCIR_LATTIMER, 1); 195 196 PCIB_WRITE_CONFIG(brdev, b, s, f, PCIR_MINGNT, 0x14, 1); 197 cfg->mingnt = PCIB_READ_CONFIG(brdev, b, s, f, PCIR_MINGNT, 1); 198 199 PCIB_WRITE_CONFIG(brdev, b, s, f, PCIR_MAXLAT, 0x14, 1); 200 cfg->maxlat = PCIB_READ_CONFIG(brdev, b, s, f, PCIR_MAXLAT, 1); 201 } 202 203 static int 204 cardbus_attach_card(device_t cbdev) 205 { 206 device_t brdev = device_get_parent(cbdev); 207 int cardattached = 0; 208 static int curr_bus_number = 2; /* XXX EVILE BAD (see below) */ 209 int bus, slot, func; 210 211 cardbus_detach_card(cbdev, 0); /* detach existing cards */ 212 213 POWER_ENABLE_SOCKET(brdev, cbdev); 214 bus = pcib_get_bus(cbdev); 215 if (bus == 0) { 216 /* 217 * XXX EVILE BAD XXX 218 * Not all BIOSes initialize the secondary bus number properly, 219 * so if the default is bad, we just put one in and hope it 220 * works. 221 */ 222 bus = curr_bus_number; 223 pci_write_config(brdev, PCIR_SECBUS_2, curr_bus_number, 1); 224 pci_write_config(brdev, PCIR_SUBBUS_2, curr_bus_number + 2, 1); 225 curr_bus_number += 3; 226 } 227 /* For each function, set it up and try to attach a driver to it */ 228 for (slot = 0; slot <= CARDBUS_SLOTMAX; slot++) { 229 int cardbusfunchigh = 0; 230 for (func = 0; func <= cardbusfunchigh; func++) { 231 struct cardbus_devinfo *dinfo = 232 cardbus_read_device(brdev, bus, slot, func); 233 234 if (dinfo == NULL) 235 continue; 236 if (dinfo->cfg.mfdev) 237 cardbusfunchigh = CARDBUS_FUNCMAX; 238 device_setup_regs(brdev, bus, slot, func, &dinfo->cfg); 239 cardbus_print_verbose(dinfo); 240 dinfo->cfg.dev = device_add_child(cbdev, NULL, -1); 241 if (!dinfo->cfg.dev) { 242 DEVPRINTF((cbdev, "Cannot add child!\n")); 243 cardbus_freecfg(dinfo); 244 continue; 245 } 246 resource_list_init(&dinfo->resources); 247 SLIST_INIT(&dinfo->intrlist); 248 device_set_ivars(dinfo->cfg.dev, dinfo); 249 cardbus_do_cis(cbdev, dinfo->cfg.dev); 250 if (device_probe_and_attach(dinfo->cfg.dev) != 0) { 251 /* when fail, release all resources */ 252 cardbus_release_all_resources(cbdev, dinfo); 253 } else 254 cardattached++; 255 } 256 } 257 258 if (cardattached > 0) 259 return 0; 260 POWER_DISABLE_SOCKET(brdev, cbdev); 261 return ENOENT; 262 } 263 264 static int 265 cardbus_detach_card(device_t cbdev, int flags) 266 { 267 int numdevs; 268 device_t *devlist; 269 int tmp; 270 int err = 0; 271 272 device_get_children(cbdev, &devlist, &numdevs); 273 274 if (numdevs == 0) { 275 if (bootverbose) 276 DEVPRINTF((cbdev, "detach_card: no card to detach!\n")); 277 POWER_DISABLE_SOCKET(device_get_parent(cbdev), cbdev); 278 free(devlist, M_TEMP); 279 return ENOENT; 280 } 281 282 for (tmp = 0; tmp < numdevs; tmp++) { 283 struct cardbus_devinfo *dinfo = device_get_ivars(devlist[tmp]); 284 int status = device_get_state(devlist[tmp]); 285 286 if (status == DS_ATTACHED || status == DS_BUSY) { 287 if (device_detach(dinfo->cfg.dev) == 0 || 288 flags & DETACH_FORCE) { 289 cardbus_release_all_resources(cbdev, dinfo); 290 device_delete_child(cbdev, devlist[tmp]); 291 } else { 292 err++; 293 } 294 cardbus_freecfg(dinfo); 295 } else { 296 cardbus_release_all_resources(cbdev, dinfo); 297 device_delete_child(cbdev, devlist[tmp]); 298 cardbus_freecfg(dinfo); 299 } 300 } 301 if (err == 0) 302 POWER_DISABLE_SOCKET(device_get_parent(cbdev), cbdev); 303 free(devlist, M_TEMP); 304 return err; 305 } 306 307 static void 308 cardbus_driver_added(device_t cbdev, driver_t *driver) 309 { 310 /* XXX check if 16-bit or cardbus! */ 311 int numdevs; 312 device_t *devlist; 313 int tmp, cardattached; 314 315 device_get_children(cbdev, &devlist, &numdevs); 316 317 cardattached = 0; 318 for (tmp = 0; tmp < numdevs; tmp++) { 319 if (device_get_state(devlist[tmp]) != DS_NOTPRESENT) 320 cardattached++; 321 } 322 323 if (cardattached == 0) { 324 free(devlist, M_TEMP); 325 CARD_REPROBE_CARD(device_get_parent(cbdev), cbdev); 326 return; 327 } 328 329 DEVICE_IDENTIFY(driver, cbdev); 330 for (tmp = 0; tmp < numdevs; tmp++) { 331 if (device_get_state(devlist[tmp]) == DS_NOTPRESENT) { 332 struct cardbus_devinfo *dinfo; 333 dinfo = device_get_ivars(devlist[tmp]); 334 cardbus_release_all_resources(cbdev, dinfo); 335 resource_list_init(&dinfo->resources); 336 cardbus_do_cis(cbdev, dinfo->cfg.dev); 337 if (device_probe_and_attach(dinfo->cfg.dev) != 0) { 338 cardbus_release_all_resources(cbdev, dinfo); 339 } else 340 cardattached++; 341 } 342 } 343 344 free(devlist, M_TEMP); 345 } 346 347 /************************************************************************/ 348 /* PCI-Like config reading (copied from pci.c */ 349 /************************************************************************/ 350 351 /* read configuration header into pcicfgrect structure */ 352 353 static void 354 cardbus_read_extcap(device_t cbdev, pcicfgregs *cfg) 355 { 356 #define REG(n, w) PCIB_READ_CONFIG(cbdev, cfg->bus, cfg->slot, cfg->func, n, w) 357 int ptr, nextptr, ptrptr; 358 359 switch (cfg->hdrtype) { 360 case 0: 361 ptrptr = 0x34; 362 break; 363 case 2: 364 ptrptr = 0x14; 365 break; 366 default: 367 return; /* no extended capabilities support */ 368 } 369 nextptr = REG(ptrptr, 1); /* sanity check? */ 370 371 /* 372 * Read capability entries. 373 */ 374 while (nextptr != 0) { 375 /* Sanity check */ 376 if (nextptr > 255) { 377 printf("illegal PCI extended capability offset %d\n", 378 nextptr); 379 return; 380 } 381 /* Find the next entry */ 382 ptr = nextptr; 383 nextptr = REG(ptr + 1, 1); 384 385 /* Process this entry */ 386 switch (REG(ptr, 1)) { 387 case 0x01: /* PCI power management */ 388 if (cfg->pp_cap == 0) { 389 cfg->pp_cap = REG(ptr + PCIR_POWER_CAP, 2); 390 cfg->pp_status = ptr + PCIR_POWER_STATUS; 391 cfg->pp_pmcsr = ptr + PCIR_POWER_PMCSR; 392 if ((nextptr - ptr) > PCIR_POWER_DATA) 393 cfg->pp_data = ptr + PCIR_POWER_DATA; 394 } 395 break; 396 default: 397 break; 398 } 399 } 400 #undef REG 401 } 402 403 /* extract header type specific config data */ 404 405 static void 406 cardbus_hdrtypedata(device_t brdev, int b, int s, int f, pcicfgregs *cfg) 407 { 408 #define REG(n, w) PCIB_READ_CONFIG(brdev, b, s, f, n, w) 409 switch (cfg->hdrtype) { 410 case 0: 411 cfg->subvendor = REG(PCIR_SUBVEND_0, 2); 412 cfg->subdevice = REG(PCIR_SUBDEV_0, 2); 413 cfg->nummaps = PCI_MAXMAPS_0; 414 break; 415 case 1: 416 cfg->subvendor = REG(PCIR_SUBVEND_1, 2); 417 cfg->subdevice = REG(PCIR_SUBDEV_1, 2); 418 cfg->nummaps = PCI_MAXMAPS_1; 419 break; 420 case 2: 421 cfg->subvendor = REG(PCIR_SUBVEND_2, 2); 422 cfg->subdevice = REG(PCIR_SUBDEV_2, 2); 423 cfg->nummaps = PCI_MAXMAPS_2; 424 break; 425 } 426 #undef REG 427 } 428 429 static struct cardbus_devinfo * 430 cardbus_read_device(device_t brdev, int b, int s, int f) 431 { 432 #define REG(n, w) PCIB_READ_CONFIG(brdev, b, s, f, n, w) 433 pcicfgregs *cfg = NULL; 434 struct cardbus_devinfo *devlist_entry = NULL; 435 436 if (REG(PCIR_DEVVENDOR, 4) != -1) { 437 devlist_entry = malloc(sizeof(struct cardbus_devinfo), 438 M_DEVBUF, M_WAITOK | M_ZERO); 439 if (devlist_entry == NULL) 440 return (NULL); 441 442 cfg = &devlist_entry->cfg; 443 444 cfg->bus = b; 445 cfg->slot = s; 446 cfg->func = f; 447 cfg->vendor = REG(PCIR_VENDOR, 2); 448 cfg->device = REG(PCIR_DEVICE, 2); 449 cfg->cmdreg = REG(PCIR_COMMAND, 2); 450 cfg->statreg = REG(PCIR_STATUS, 2); 451 cfg->baseclass = REG(PCIR_CLASS, 1); 452 cfg->subclass = REG(PCIR_SUBCLASS, 1); 453 cfg->progif = REG(PCIR_PROGIF, 1); 454 cfg->revid = REG(PCIR_REVID, 1); 455 cfg->hdrtype = REG(PCIR_HEADERTYPE, 1); 456 cfg->cachelnsz = REG(PCIR_CACHELNSZ, 1); 457 cfg->lattimer = REG(PCIR_LATTIMER, 1); 458 cfg->intpin = REG(PCIR_INTPIN, 1); 459 cfg->intline = REG(PCIR_INTLINE, 1); 460 461 cfg->mingnt = REG(PCIR_MINGNT, 1); 462 cfg->maxlat = REG(PCIR_MAXLAT, 1); 463 464 cfg->mfdev = (cfg->hdrtype & PCIM_MFDEV) != 0; 465 cfg->hdrtype &= ~PCIM_MFDEV; 466 467 cardbus_hdrtypedata(brdev, b, s, f, cfg); 468 469 if (REG(PCIR_STATUS, 2) & PCIM_STATUS_CAPPRESENT) 470 cardbus_read_extcap(brdev, cfg); 471 472 devlist_entry->conf.pc_sel.pc_bus = cfg->bus; 473 devlist_entry->conf.pc_sel.pc_dev = cfg->slot; 474 devlist_entry->conf.pc_sel.pc_func = cfg->func; 475 devlist_entry->conf.pc_hdr = cfg->hdrtype; 476 477 devlist_entry->conf.pc_subvendor = cfg->subvendor; 478 devlist_entry->conf.pc_subdevice = cfg->subdevice; 479 devlist_entry->conf.pc_vendor = cfg->vendor; 480 devlist_entry->conf.pc_device = cfg->device; 481 482 devlist_entry->conf.pc_class = cfg->baseclass; 483 devlist_entry->conf.pc_subclass = cfg->subclass; 484 devlist_entry->conf.pc_progif = cfg->progif; 485 devlist_entry->conf.pc_revid = cfg->revid; 486 } 487 return (devlist_entry); 488 #undef REG 489 } 490 491 /* free pcicfgregs structure and all depending data structures */ 492 493 static int 494 cardbus_freecfg(struct cardbus_devinfo *dinfo) 495 { 496 free(dinfo, M_DEVBUF); 497 498 return (0); 499 } 500 501 static void 502 cardbus_print_verbose(struct cardbus_devinfo *dinfo) 503 { 504 #ifndef CARDBUS_DEBUG 505 if (bootverbose) 506 #endif /* CARDBUS_DEBUG */ 507 { 508 pcicfgregs *cfg = &dinfo->cfg; 509 510 printf("found->\tvendor=0x%04x, dev=0x%04x, revid=0x%02x\n", 511 cfg->vendor, cfg->device, cfg->revid); 512 printf("\tclass=%02x-%02x-%02x, hdrtype=0x%02x, mfdev=%d\n", 513 cfg->baseclass, cfg->subclass, cfg->progif, 514 cfg->hdrtype, cfg->mfdev); 515 #ifdef CARDBUS_DEBUG 516 printf("\tcmdreg=0x%04x, statreg=0x%04x, " 517 "cachelnsz=%d (dwords)\n", 518 cfg->cmdreg, cfg->statreg, cfg->cachelnsz); 519 printf("\tlattimer=0x%02x (%d ns), mingnt=0x%02x (%d ns), " 520 "maxlat=0x%02x (%d ns)\n", 521 cfg->lattimer, cfg->lattimer * 30, 522 cfg->mingnt, cfg->mingnt * 250, cfg->maxlat, 523 cfg->maxlat * 250); 524 #endif /* CARDBUS_DEBUG */ 525 if (cfg->intpin > 0) 526 printf("\tintpin=%c, irq=%d\n", 527 cfg->intpin + 'a' - 1, cfg->intline); 528 } 529 } 530 531 /************************************************************************/ 532 /* Resources */ 533 /************************************************************************/ 534 535 static int 536 cardbus_set_resource(device_t cbdev, device_t child, int type, int rid, 537 u_long start, u_long count, struct resource *res) 538 { 539 struct cardbus_devinfo *dinfo; 540 struct resource_list *rl; 541 struct resource_list_entry *rle; 542 543 if (device_get_parent(child) != cbdev) 544 return ENOENT; 545 546 dinfo = device_get_ivars(child); 547 rl = &dinfo->resources; 548 rle = resource_list_find(rl, type, rid); 549 if (rle == NULL) { 550 resource_list_add(rl, type, rid, start, start + count - 1, 551 count); 552 if (res != NULL) { 553 rle = resource_list_find(rl, type, rid); 554 rle->res = res; 555 } 556 } else { 557 if (rle->res == NULL) { 558 } else if (rle->res->r_dev == cbdev && 559 (!(rman_get_flags(rle->res) & RF_ACTIVE))) { 560 int f; 561 f = rman_get_flags(rle->res); 562 bus_release_resource(cbdev, type, rid, res); 563 rle->res = bus_alloc_resource(cbdev, type, &rid, 564 start, start + count - 1, 565 count, f); 566 } else { 567 device_printf(cbdev, "set_resource: resource busy\n"); 568 return EBUSY; 569 } 570 rle->start = start; 571 rle->end = start + count - 1; 572 rle->count = count; 573 if (res != NULL) 574 rle->res = res; 575 } 576 if (device_get_parent(child) == cbdev) 577 pci_write_config(child, rid, start, 4); 578 return 0; 579 } 580 581 static int 582 cardbus_get_resource(device_t cbdev, device_t child, int type, int rid, 583 u_long *startp, u_long *countp) 584 { 585 struct cardbus_devinfo *dinfo; 586 struct resource_list *rl; 587 struct resource_list_entry *rle; 588 589 if (device_get_parent(child) != cbdev) 590 return ENOENT; 591 592 dinfo = device_get_ivars(child); 593 rl = &dinfo->resources; 594 rle = resource_list_find(rl, type, rid); 595 if (!rle) 596 return ENOENT; 597 if (startp) 598 *startp = rle->start; 599 if (countp) 600 *countp = rle->count; 601 return 0; 602 } 603 604 static void 605 cardbus_delete_resource(device_t cbdev, device_t child, int type, int rid) 606 { 607 struct cardbus_devinfo *dinfo; 608 struct resource_list *rl; 609 struct resource_list_entry *rle; 610 611 if (device_get_parent(child) != cbdev) 612 return; 613 614 dinfo = device_get_ivars(child); 615 rl = &dinfo->resources; 616 rle = resource_list_find(rl, type, rid); 617 if (rle) { 618 if (rle->res) { 619 if (rle->res->r_dev != cbdev || 620 rman_get_flags(rle->res) & RF_ACTIVE) { 621 device_printf(cbdev, "delete_resource: " 622 "Resource still owned by child, oops. " 623 "(type=%d, rid=%d, addr=%lx)\n", 624 rle->type, rle->rid, 625 rman_get_start(rle->res)); 626 return; 627 } 628 bus_release_resource(cbdev, type, rid, rle->res); 629 } 630 resource_list_delete(rl, type, rid); 631 } 632 if (device_get_parent(child) == cbdev) 633 pci_write_config(child, rid, 0, 4); 634 } 635 636 static int 637 cardbus_set_resource_method(device_t cbdev, device_t child, int type, int rid, 638 u_long start, u_long count) 639 { 640 int ret; 641 ret = cardbus_set_resource(cbdev, child, type, rid, start, count, NULL); 642 if (ret != 0) 643 return ret; 644 return BUS_SET_RESOURCE(device_get_parent(cbdev), child, type, rid, 645 start, count); 646 } 647 648 static int 649 cardbus_get_resource_method(device_t cbdev, device_t child, int type, int rid, 650 u_long *startp, u_long *countp) 651 { 652 int ret; 653 ret = cardbus_get_resource(cbdev, child, type, rid, startp, countp); 654 if (ret != 0) 655 return ret; 656 return BUS_GET_RESOURCE(device_get_parent(cbdev), child, type, rid, 657 startp, countp); 658 } 659 660 static void 661 cardbus_delete_resource_method(device_t cbdev, device_t child, 662 int type, int rid) 663 { 664 cardbus_delete_resource(cbdev, child, type, rid); 665 BUS_DELETE_RESOURCE(device_get_parent(cbdev), child, type, rid); 666 } 667 668 static void 669 cardbus_release_all_resources(device_t cbdev, struct cardbus_devinfo *dinfo) 670 { 671 struct resource_list_entry *rle; 672 struct cardbus_intrlist *ile; 673 674 /* Remove any interrupt handlers */ 675 while (NULL != (ile = SLIST_FIRST(&dinfo->intrlist))) { 676 device_printf(cbdev, "release_all_resource: " 677 "intr handler still active, removing.\n"); 678 bus_teardown_intr(ile->dev, ile->irq, ile->cookie); 679 SLIST_REMOVE_HEAD(&dinfo->intrlist, link); 680 free(ile, M_DEVBUF); 681 } 682 683 /* Free all allocated resources */ 684 SLIST_FOREACH(rle, &dinfo->resources, link) { 685 if (rle->res) { 686 if (rle->res->r_dev != cbdev) 687 device_printf(cbdev, "release_all_resource: " 688 "Resource still owned by child, oops. " 689 "(type=%d, rid=%d, addr=%lx)\n", 690 rle->type, rle->rid, 691 rman_get_start(rle->res)); 692 BUS_RELEASE_RESOURCE(device_get_parent(cbdev), 693 rle->res->r_dev, 694 rle->type, rle->rid, 695 rle->res); 696 rle->res = NULL; 697 /* 698 * zero out config so the card won't acknowledge 699 * access to the space anymore 700 */ 701 pci_write_config(dinfo->cfg.dev, rle->rid, 0, 4); 702 } 703 } 704 resource_list_free(&dinfo->resources); 705 } 706 707 static struct resource * 708 cardbus_alloc_resource(device_t cbdev, device_t child, int type, 709 int *rid, u_long start, u_long end, u_long count, u_int flags) 710 { 711 struct cardbus_devinfo *dinfo; 712 struct resource_list_entry *rle = 0; 713 int passthrough = (device_get_parent(child) != cbdev); 714 715 if (passthrough) { 716 return (BUS_ALLOC_RESOURCE(device_get_parent(cbdev), child, 717 type, rid, start, end, count, flags)); 718 } 719 720 dinfo = device_get_ivars(child); 721 rle = resource_list_find(&dinfo->resources, type, *rid); 722 723 if (!rle) 724 return NULL; /* no resource of that type/rid */ 725 726 if (!rle->res) { 727 device_printf(cbdev, "WARNING: Resource not reserved by bus\n"); 728 return NULL; 729 } else { 730 /* Release the cardbus hold on the resource */ 731 if (rle->res->r_dev != cbdev) 732 return NULL; 733 bus_release_resource(cbdev, type, *rid, rle->res); 734 rle->res = NULL; 735 switch (type) { 736 case SYS_RES_IOPORT: 737 case SYS_RES_MEMORY: 738 if (!(flags & RF_ALIGNMENT_MASK)) 739 flags |= rman_make_alignment_flags(rle->count); 740 break; 741 case SYS_RES_IRQ: 742 flags |= RF_SHAREABLE; 743 break; 744 } 745 /* Allocate the resource to the child */ 746 return resource_list_alloc(&dinfo->resources, cbdev, child, 747 type, rid, rle->start, rle->end, rle->count, flags); 748 } 749 } 750 751 static int 752 cardbus_release_resource(device_t cbdev, device_t child, int type, int rid, 753 struct resource *r) 754 { 755 struct cardbus_devinfo *dinfo; 756 int passthrough = (device_get_parent(child) != cbdev); 757 struct resource_list_entry *rle = 0; 758 int flags; 759 int ret; 760 761 if (passthrough) { 762 return BUS_RELEASE_RESOURCE(device_get_parent(cbdev), child, 763 type, rid, r); 764 } 765 766 dinfo = device_get_ivars(child); 767 /* 768 * According to the PCI 2.2 spec, devices may share an address 769 * decoder between memory mapped ROM access and memory 770 * mapped register access. To be safe, disable ROM access 771 * whenever it is released. 772 */ 773 if (rid == CARDBUS_ROM_REG) { 774 uint32_t rom_reg; 775 776 rom_reg = pci_read_config(child, rid, 4); 777 rom_reg &= ~CARDBUS_ROM_ENABLE; 778 pci_write_config(child, rid, rom_reg, 4); 779 } 780 781 rle = resource_list_find(&dinfo->resources, type, rid); 782 783 if (!rle) { 784 device_printf(cbdev, "Allocated resource not found\n"); 785 return ENOENT; 786 } 787 if (!rle->res) { 788 device_printf(cbdev, "Allocated resource not recorded\n"); 789 return ENOENT; 790 } 791 792 ret = BUS_RELEASE_RESOURCE(device_get_parent(cbdev), child, 793 type, rid, r); 794 switch (type) { 795 case SYS_RES_IOPORT: 796 case SYS_RES_MEMORY: 797 flags = rman_make_alignment_flags(rle->count); 798 break; 799 case SYS_RES_IRQ: 800 flags = RF_SHAREABLE; 801 break; 802 default: 803 flags = 0; 804 } 805 /* Restore cardbus hold on the resource */ 806 rle->res = bus_alloc_resource(cbdev, type, &rid, 807 rle->start, rle->end, rle->count, flags); 808 if (rle->res == NULL) 809 device_printf(cbdev, "release_resource: " 810 "unable to reacquire resource\n"); 811 return ret; 812 } 813 814 static int 815 cardbus_setup_intr(device_t cbdev, device_t child, struct resource *irq, 816 int flags, driver_intr_t *intr, void *arg, void **cookiep) 817 { 818 int ret; 819 struct cardbus_intrlist *ile; 820 device_t cdev; 821 struct cardbus_devinfo *dinfo; 822 823 ret = bus_generic_setup_intr(cbdev, child, irq, flags, intr, arg, 824 cookiep); 825 if (ret != 0) 826 return ret; 827 828 for (cdev = child; cbdev != device_get_parent(cdev); 829 cdev = device_get_parent(cdev)) 830 /* NOTHING */; 831 dinfo = device_get_ivars(cdev); 832 833 /* record interrupt handler */ 834 ile = malloc(sizeof(struct cardbus_intrlist), M_DEVBUF, M_NOWAIT); 835 ile->dev = child; 836 ile->irq = irq; 837 ile->cookie = *cookiep; 838 839 SLIST_INSERT_HEAD(&dinfo->intrlist, ile, link); 840 return 0; 841 } 842 843 static int 844 cardbus_teardown_intr(device_t cbdev, device_t child, struct resource *irq, 845 void *cookie) 846 { 847 int ret; 848 struct cardbus_intrlist *ile; 849 device_t cdev; 850 struct cardbus_devinfo *dinfo; 851 852 ret = bus_generic_teardown_intr(cbdev, child, irq, cookie); 853 if (ret != 0) 854 return ret; 855 856 for (cdev = child; cbdev != device_get_parent(cdev); 857 cdev = device_get_parent(cdev)) 858 /* NOTHING */; 859 dinfo = device_get_ivars(cdev); 860 861 /* remove interrupt handler from record */ 862 SLIST_FOREACH(ile, &dinfo->intrlist, link) { 863 if (ile->irq == irq && ile->cookie == cookie) { 864 SLIST_REMOVE(&dinfo->intrlist, ile, cardbus_intrlist, 865 link); 866 free(ile, M_DEVBUF); 867 return 0; 868 } 869 } 870 device_printf(cbdev, "teardown_intr: intr handler not recorded.\n"); 871 return ENOENT; 872 } 873 874 875 /************************************************************************/ 876 /* Other Bus Methods */ 877 /************************************************************************/ 878 879 static int 880 cardbus_print_resources(struct resource_list *rl, const char *name, 881 int type, const char *format) 882 { 883 struct resource_list_entry *rle; 884 int printed, retval; 885 886 printed = 0; 887 retval = 0; 888 /* Yes, this is kinda cheating */ 889 SLIST_FOREACH(rle, rl, link) { 890 if (rle->type == type) { 891 if (printed == 0) 892 retval += printf(" %s ", name); 893 else if (printed > 0) 894 retval += printf(","); 895 printed++; 896 retval += printf(format, rle->start); 897 if (rle->count > 1) { 898 retval += printf("-"); 899 retval += printf(format, rle->start + 900 rle->count - 1); 901 } 902 } 903 } 904 return retval; 905 } 906 907 static int 908 cardbus_print_child(device_t cbdev, device_t child) 909 { 910 struct cardbus_devinfo *dinfo; 911 struct resource_list *rl; 912 pcicfgregs *cfg; 913 int retval = 0; 914 915 dinfo = device_get_ivars(child); 916 cfg = &dinfo->cfg; 917 rl = &dinfo->resources; 918 919 retval += bus_print_child_header(cbdev, child); 920 921 retval += cardbus_print_resources(rl, "port", SYS_RES_IOPORT, "%#lx"); 922 retval += cardbus_print_resources(rl, "mem", SYS_RES_MEMORY, "%#lx"); 923 retval += cardbus_print_resources(rl, "irq", SYS_RES_IRQ, "%ld"); 924 if (device_get_flags(cbdev)) 925 retval += printf(" flags %#x", device_get_flags(cbdev)); 926 927 retval += printf(" at device %d.%d", pci_get_slot(child), 928 pci_get_function(child)); 929 930 retval += bus_print_child_footer(cbdev, child); 931 932 return (retval); 933 } 934 935 static void 936 cardbus_probe_nomatch(device_t cbdev, device_t child) 937 { 938 struct cardbus_devinfo *dinfo; 939 pcicfgregs *cfg; 940 941 dinfo = device_get_ivars(child); 942 cfg = &dinfo->cfg; 943 device_printf(cbdev, "<unknown card>"); 944 printf(" (vendor=0x%04x, dev=0x%04x)", cfg->vendor, cfg->device); 945 printf(" at %d.%d", pci_get_slot(child), pci_get_function(child)); 946 if (cfg->intpin > 0 && cfg->intline != 255) { 947 printf(" irq %d", cfg->intline); 948 } 949 printf("\n"); 950 951 return; 952 } 953 954 static int 955 cardbus_read_ivar(device_t cbdev, device_t child, int which, u_long *result) 956 { 957 struct cardbus_devinfo *dinfo; 958 pcicfgregs *cfg; 959 960 dinfo = device_get_ivars(child); 961 cfg = &dinfo->cfg; 962 963 switch (which) { 964 case PCI_IVAR_SUBVENDOR: 965 *result = cfg->subvendor; 966 break; 967 case PCI_IVAR_SUBDEVICE: 968 *result = cfg->subdevice; 969 break; 970 case PCI_IVAR_VENDOR: 971 *result = cfg->vendor; 972 break; 973 case PCI_IVAR_DEVICE: 974 *result = cfg->device; 975 break; 976 case PCI_IVAR_DEVID: 977 *result = (cfg->device << 16) | cfg->vendor; 978 break; 979 case PCI_IVAR_CLASS: 980 *result = cfg->baseclass; 981 break; 982 case PCI_IVAR_SUBCLASS: 983 *result = cfg->subclass; 984 break; 985 case PCI_IVAR_PROGIF: 986 *result = cfg->progif; 987 break; 988 case PCI_IVAR_REVID: 989 *result = cfg->revid; 990 break; 991 case PCI_IVAR_INTPIN: 992 *result = cfg->intpin; 993 break; 994 case PCI_IVAR_IRQ: 995 *result = cfg->intline; 996 break; 997 case PCI_IVAR_BUS: 998 *result = cfg->bus; 999 break; 1000 case PCI_IVAR_SLOT: 1001 *result = cfg->slot; 1002 break; 1003 case PCI_IVAR_FUNCTION: 1004 *result = cfg->func; 1005 break; 1006 default: 1007 return ENOENT; 1008 } 1009 return 0; 1010 } 1011 1012 static int 1013 cardbus_write_ivar(device_t cbdev, device_t child, int which, uintptr_t value) 1014 { 1015 struct cardbus_devinfo *dinfo; 1016 pcicfgregs *cfg; 1017 1018 dinfo = device_get_ivars(child); 1019 cfg = &dinfo->cfg; 1020 1021 switch (which) { 1022 case PCI_IVAR_SUBVENDOR: 1023 case PCI_IVAR_SUBDEVICE: 1024 case PCI_IVAR_VENDOR: 1025 case PCI_IVAR_DEVICE: 1026 case PCI_IVAR_DEVID: 1027 case PCI_IVAR_CLASS: 1028 case PCI_IVAR_SUBCLASS: 1029 case PCI_IVAR_PROGIF: 1030 case PCI_IVAR_REVID: 1031 case PCI_IVAR_INTPIN: 1032 case PCI_IVAR_IRQ: 1033 case PCI_IVAR_BUS: 1034 case PCI_IVAR_SLOT: 1035 case PCI_IVAR_FUNCTION: 1036 return EINVAL; /* disallow for now */ 1037 default: 1038 return ENOENT; 1039 } 1040 return 0; 1041 } 1042 1043 /************************************************************************/ 1044 /* Compatibility with PCI bus (XXX: Do we need this?) */ 1045 /************************************************************************/ 1046 1047 /* 1048 * PCI power manangement 1049 */ 1050 static int 1051 cardbus_set_powerstate_method(device_t cbdev, device_t child, int state) 1052 { 1053 struct cardbus_devinfo *dinfo = device_get_ivars(child); 1054 pcicfgregs *cfg = &dinfo->cfg; 1055 u_int16_t status; 1056 int result; 1057 1058 if (cfg->pp_cap != 0) { 1059 status = PCI_READ_CONFIG(cbdev, child, cfg->pp_status, 2) 1060 & ~PCIM_PSTAT_DMASK; 1061 result = 0; 1062 switch (state) { 1063 case PCI_POWERSTATE_D0: 1064 status |= PCIM_PSTAT_D0; 1065 break; 1066 case PCI_POWERSTATE_D1: 1067 if (cfg->pp_cap & PCIM_PCAP_D1SUPP) { 1068 status |= PCIM_PSTAT_D1; 1069 } else { 1070 result = EOPNOTSUPP; 1071 } 1072 break; 1073 case PCI_POWERSTATE_D2: 1074 if (cfg->pp_cap & PCIM_PCAP_D2SUPP) { 1075 status |= PCIM_PSTAT_D2; 1076 } else { 1077 result = EOPNOTSUPP; 1078 } 1079 break; 1080 case PCI_POWERSTATE_D3: 1081 status |= PCIM_PSTAT_D3; 1082 break; 1083 default: 1084 result = EINVAL; 1085 } 1086 if (result == 0) 1087 PCI_WRITE_CONFIG(cbdev, child, cfg->pp_status, 1088 status, 2); 1089 } else { 1090 result = ENXIO; 1091 } 1092 return (result); 1093 } 1094 1095 static int 1096 cardbus_get_powerstate_method(device_t cbdev, device_t child) 1097 { 1098 struct cardbus_devinfo *dinfo = device_get_ivars(child); 1099 pcicfgregs *cfg = &dinfo->cfg; 1100 u_int16_t status; 1101 int result; 1102 1103 if (cfg->pp_cap != 0) { 1104 status = PCI_READ_CONFIG(cbdev, child, cfg->pp_status, 2); 1105 switch (status & PCIM_PSTAT_DMASK) { 1106 case PCIM_PSTAT_D0: 1107 result = PCI_POWERSTATE_D0; 1108 break; 1109 case PCIM_PSTAT_D1: 1110 result = PCI_POWERSTATE_D1; 1111 break; 1112 case PCIM_PSTAT_D2: 1113 result = PCI_POWERSTATE_D2; 1114 break; 1115 case PCIM_PSTAT_D3: 1116 result = PCI_POWERSTATE_D3; 1117 break; 1118 default: 1119 result = PCI_POWERSTATE_UNKNOWN; 1120 break; 1121 } 1122 } else { 1123 /* No support, device is always at D0 */ 1124 result = PCI_POWERSTATE_D0; 1125 } 1126 return (result); 1127 } 1128 1129 static u_int32_t 1130 cardbus_read_config_method(device_t cbdev, device_t child, int reg, int width) 1131 { 1132 struct cardbus_devinfo *dinfo = device_get_ivars(child); 1133 pcicfgregs *cfg = &dinfo->cfg; 1134 1135 return PCIB_READ_CONFIG(device_get_parent(cbdev), 1136 cfg->bus, cfg->slot, cfg->func, reg, width); 1137 } 1138 1139 static void 1140 cardbus_write_config_method(device_t cbdev, device_t child, int reg, 1141 u_int32_t val, int width) 1142 { 1143 struct cardbus_devinfo *dinfo = device_get_ivars(child); 1144 pcicfgregs *cfg = &dinfo->cfg; 1145 1146 PCIB_WRITE_CONFIG(device_get_parent(cbdev), 1147 cfg->bus, cfg->slot, cfg->func, reg, val, width); 1148 } 1149 1150 static __inline void 1151 cardbus_set_command_bit(device_t cbdev, device_t child, u_int16_t bit) 1152 { 1153 u_int16_t command; 1154 1155 command = PCI_READ_CONFIG(cbdev, child, PCIR_COMMAND, 2); 1156 command |= bit; 1157 PCI_WRITE_CONFIG(cbdev, child, PCIR_COMMAND, command, 2); 1158 } 1159 1160 static __inline void 1161 cardbus_clear_command_bit(device_t cbdev, device_t child, u_int16_t bit) 1162 { 1163 u_int16_t command; 1164 1165 command = PCI_READ_CONFIG(cbdev, child, PCIR_COMMAND, 2); 1166 command &= ~bit; 1167 PCI_WRITE_CONFIG(cbdev, child, PCIR_COMMAND, command, 2); 1168 } 1169 1170 static void 1171 cardbus_enable_busmaster_method(device_t cbdev, device_t child) 1172 { 1173 cardbus_set_command_bit(cbdev, child, PCIM_CMD_BUSMASTEREN); 1174 } 1175 1176 static void 1177 cardbus_disable_busmaster_method(device_t cbdev, device_t child) 1178 { 1179 cardbus_clear_command_bit(cbdev, child, PCIM_CMD_BUSMASTEREN); 1180 } 1181 1182 static void 1183 cardbus_enable_io_method(device_t cbdev, device_t child, int space) 1184 { 1185 switch (space) { 1186 case SYS_RES_IOPORT: 1187 cardbus_set_command_bit(cbdev, child, PCIM_CMD_PORTEN); 1188 break; 1189 case SYS_RES_MEMORY: 1190 cardbus_set_command_bit(cbdev, child, PCIM_CMD_MEMEN); 1191 break; 1192 } 1193 } 1194 1195 static void 1196 cardbus_disable_io_method(device_t cbdev, device_t child, int space) 1197 { 1198 switch (space) { 1199 case SYS_RES_IOPORT: 1200 cardbus_clear_command_bit(cbdev, child, PCIM_CMD_PORTEN); 1201 break; 1202 case SYS_RES_MEMORY: 1203 cardbus_clear_command_bit(cbdev, child, PCIM_CMD_MEMEN); 1204 break; 1205 } 1206 } 1207 1208 static device_method_t cardbus_methods[] = { 1209 /* Device interface */ 1210 DEVMETHOD(device_probe, cardbus_probe), 1211 DEVMETHOD(device_attach, cardbus_attach), 1212 DEVMETHOD(device_detach, cardbus_detach), 1213 DEVMETHOD(device_shutdown, bus_generic_shutdown), 1214 DEVMETHOD(device_suspend, cardbus_suspend), 1215 DEVMETHOD(device_resume, cardbus_resume), 1216 1217 /* Bus interface */ 1218 DEVMETHOD(bus_print_child, cardbus_print_child), 1219 DEVMETHOD(bus_probe_nomatch, cardbus_probe_nomatch), 1220 DEVMETHOD(bus_read_ivar, cardbus_read_ivar), 1221 DEVMETHOD(bus_write_ivar, cardbus_write_ivar), 1222 DEVMETHOD(bus_driver_added, cardbus_driver_added), 1223 DEVMETHOD(bus_alloc_resource, cardbus_alloc_resource), 1224 DEVMETHOD(bus_release_resource, cardbus_release_resource), 1225 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), 1226 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 1227 DEVMETHOD(bus_setup_intr, cardbus_setup_intr), 1228 DEVMETHOD(bus_teardown_intr, cardbus_teardown_intr), 1229 1230 DEVMETHOD(bus_set_resource, cardbus_set_resource_method), 1231 DEVMETHOD(bus_get_resource, cardbus_get_resource_method), 1232 DEVMETHOD(bus_delete_resource, cardbus_delete_resource_method), 1233 1234 /* Card Interface */ 1235 DEVMETHOD(card_attach_card, cardbus_attach_card), 1236 DEVMETHOD(card_detach_card, cardbus_detach_card), 1237 DEVMETHOD(card_cis_read, cardbus_cis_read), 1238 DEVMETHOD(card_cis_free, cardbus_cis_free), 1239 1240 /* Cardbus/PCI interface */ 1241 DEVMETHOD(pci_read_config, cardbus_read_config_method), 1242 DEVMETHOD(pci_write_config, cardbus_write_config_method), 1243 DEVMETHOD(pci_enable_busmaster, cardbus_enable_busmaster_method), 1244 DEVMETHOD(pci_disable_busmaster, cardbus_disable_busmaster_method), 1245 DEVMETHOD(pci_enable_io, cardbus_enable_io_method), 1246 DEVMETHOD(pci_disable_io, cardbus_disable_io_method), 1247 DEVMETHOD(pci_get_powerstate, cardbus_get_powerstate_method), 1248 DEVMETHOD(pci_set_powerstate, cardbus_set_powerstate_method), 1249 1250 {0,0} 1251 }; 1252 1253 static driver_t cardbus_driver = { 1254 "cardbus", 1255 cardbus_methods, 1256 0 /* no softc */ 1257 }; 1258 1259 static devclass_t cardbus_devclass; 1260 1261 DRIVER_MODULE(cardbus, pccbb, cardbus_driver, cardbus_devclass, 0, 0); 1262 /* 1263 MODULE_DEPEND(cardbus, pccbb, 1, 1, 1); 1264 */ 1265