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 <pci/pcivar.h> 53 #include <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 STATIC 66 #define DPRINTF(a) printf a 67 #define DEVPRINTF(x) device_printf x 68 #else 69 #define STATIC static 70 #define DPRINTF(a) 71 #define DEVPRINTF(x) 72 #endif 73 74 #if !defined(lint) 75 static const char rcsid[] = 76 "$FreeBSD$"; 77 #endif 78 79 struct cardbus_quirk { 80 u_int32_t devid; /* Vendor/device of the card */ 81 int type; 82 #define CARDBUS_QUIRK_MAP_REG 1 /* PCI map register in weird place */ 83 int arg1; 84 int arg2; 85 }; 86 87 struct cardbus_quirk cardbus_quirks[] = { 88 { 0 } 89 }; 90 91 static int cardbus_probe(device_t dev); 92 static int cardbus_attach(device_t dev); 93 static void device_setup_regs(device_t cbdev, int b, int s, int f, 94 pcicfgregs *cfg); 95 static int cardbus_attach_card(device_t dev); 96 static int cardbus_detach_card(device_t dev, int flags); 97 static struct cardbus_devinfo *cardbus_read_device(device_t pcib, 98 int b, int s, int f); 99 static void cardbus_hdrtypedata(device_t pcib, int b, int s, int f, 100 pcicfgregs *cfg); 101 static int cardbus_freecfg(struct cardbus_devinfo *dinfo); 102 static void cardbus_print_verbose(struct cardbus_devinfo *dinfo); 103 static int cardbus_set_resource(device_t dev, device_t child, int type, 104 int rid, u_long start, u_long count); 105 static int cardbus_get_resource(device_t dev, device_t child, int type, 106 int rid, u_long *startp, u_long *countp); 107 static void cardbus_delete_resource(device_t dev, device_t child, int type, 108 int rid); 109 static int cardbus_set_resource_method(device_t dev, device_t child, int type, 110 int rid, u_long start, u_long count); 111 static int cardbus_get_resource_method(device_t dev, device_t child, int type, 112 int rid, u_long *startp, u_long *countp); 113 static int cardbus_add_map(device_t bdev, device_t dev, pcicfgregs *cfg, 114 int reg); 115 static void cardbus_add_resources(device_t dev, pcicfgregs* cfg); 116 static void cardbus_release_all_resources(device_t dev, 117 struct resource_list *rl); 118 static struct resource* cardbus_alloc_resource(device_t self, device_t child, 119 int type, int* rid,u_long start, 120 u_long end, u_long count, 121 u_int flags); 122 static int cardbus_release_resource(device_t dev, device_t child, int type, 123 int rid, struct resource *r); 124 static int cardbus_print_resources(struct resource_list *rl, const char *name, 125 int type, const char *format); 126 static int cardbus_print_child(device_t dev, device_t child); 127 static void cardbus_probe_nomatch(device_t dev, device_t child); 128 static int cardbus_read_ivar(device_t dev, device_t child, int which, 129 u_long *result); 130 static int cardbus_write_ivar(device_t dev, device_t child, int which, 131 uintptr_t value); 132 static u_int32_t cardbus_read_config_method(device_t dev, device_t child, 133 int reg, int width); 134 static void cardbus_write_config_method(device_t dev, device_t child, int reg, 135 u_int32_t val, int width); 136 137 /************************************************************************/ 138 /* Probe/Attach */ 139 /************************************************************************/ 140 141 static int 142 cardbus_probe(device_t dev) 143 { 144 device_set_desc(dev, "Cardbus bus (newcard)"); 145 return 0; 146 } 147 148 static int 149 cardbus_attach(device_t dev) 150 { 151 return 0; 152 } 153 154 static int 155 cardbus_detach(device_t dev) 156 { 157 cardbus_detach_card(dev, DETACH_FORCE); 158 return 0; 159 } 160 161 /************************************************************************/ 162 /* Attach/Detach card */ 163 /************************************************************************/ 164 165 static void 166 device_setup_regs(device_t bdev, int b, int s, int f, pcicfgregs *cfg) 167 { 168 PCIB_WRITE_CONFIG(bdev, b, s, f, PCIR_INTLINE, 169 pci_get_irq(device_get_parent(bdev)), 1); 170 cfg->intline = PCIB_READ_CONFIG(bdev, b, s, f, PCIR_INTLINE, 1); 171 172 PCIB_WRITE_CONFIG(bdev, b, s, f, PCIR_CACHELNSZ, 0x08, 1); 173 cfg->cachelnsz = PCIB_READ_CONFIG(bdev, b, s, f, PCIR_CACHELNSZ, 1); 174 175 PCIB_WRITE_CONFIG(bdev, b, s, f, PCIR_LATTIMER, 0xa8, 1); 176 cfg->lattimer = PCIB_READ_CONFIG(bdev, b, s, f, PCIR_LATTIMER, 1); 177 178 PCIB_WRITE_CONFIG(bdev, b, s, f, PCIR_MINGNT, 0x14, 1); 179 cfg->mingnt = PCIB_READ_CONFIG(bdev, b, s, f, PCIR_MINGNT, 1); 180 181 PCIB_WRITE_CONFIG(bdev, b, s, f, PCIR_MAXLAT, 0x14, 1); 182 cfg->maxlat = PCIB_READ_CONFIG(bdev, b, s, f, PCIR_MAXLAT, 1); 183 } 184 185 static int 186 cardbus_attach_card(device_t dev) 187 { 188 device_t bdev = device_get_parent(dev); 189 int cardattached = 0; 190 static int curr_bus_number = 2; /* XXX EVILE BAD (see below) */ 191 int bus, slot, func; 192 193 cardbus_detach_card(dev, DETACH_NOWARN); /* detach existing cards */ 194 195 POWER_ENABLE_SOCKET(bdev, dev); 196 bus = pcib_get_bus(dev); 197 if (bus == 0) { 198 /* 199 * XXX EVILE BAD XXX 200 * Not all BIOSes initialize the secondary bus number properly, 201 * so if the default is bad, we just put one in and hope it 202 * works. 203 */ 204 bus = curr_bus_number; 205 pci_write_config (bdev, PCIR_SECBUS_2, curr_bus_number, 1); 206 pci_write_config (bdev, PCIR_SUBBUS_2, curr_bus_number+2, 1); 207 curr_bus_number += 3; 208 } 209 for (slot = 0; slot <= CARDBUS_SLOTMAX; slot++) { 210 int cardbusfunchigh = 0; 211 for (func = 0; func <= cardbusfunchigh; func++) { 212 struct cardbus_devinfo *dinfo = 213 cardbus_read_device(bdev, bus, slot, func); 214 215 if (dinfo == NULL) continue; 216 if (dinfo->cfg.mfdev) 217 cardbusfunchigh = CARDBUS_FUNCMAX; 218 device_setup_regs(bdev, bus, slot, func, &dinfo->cfg); 219 cardbus_print_verbose(dinfo); 220 dinfo->cfg.dev = device_add_child(dev, NULL, -1); 221 if (!dinfo->cfg.dev) { 222 DEVPRINTF((dev, "Cannot add child!\n")); 223 cardbus_freecfg(dinfo); 224 continue; 225 } 226 resource_list_init(&dinfo->resources); 227 device_set_ivars(dinfo->cfg.dev, dinfo); 228 cardbus_add_resources(dinfo->cfg.dev, &dinfo->cfg); 229 cardbus_do_cis(dev, dinfo->cfg.dev); 230 if (device_probe_and_attach(dinfo->cfg.dev) != 0) { 231 cardbus_release_all_resources(dinfo->cfg.dev, 232 &dinfo->resources); 233 } else 234 cardattached++; 235 } 236 } 237 238 if (cardattached > 0) return 0; 239 POWER_DISABLE_SOCKET(bdev, dev); 240 return ENOENT; 241 } 242 243 static int 244 cardbus_detach_card(device_t dev, int flags) 245 { 246 int numdevs; 247 device_t *devlist; 248 int tmp; 249 int err=0; 250 251 device_get_children(dev, &devlist, &numdevs); 252 253 if (numdevs == 0) { 254 if (!(flags & DETACH_NOWARN)) { 255 DEVPRINTF((dev, "Detaching card: no cards to detach!\n")); 256 POWER_DISABLE_SOCKET(device_get_parent(dev), dev); 257 } 258 free(devlist, M_TEMP); 259 return ENOENT; 260 } 261 262 for (tmp = 0; tmp < numdevs; tmp++) { 263 struct cardbus_devinfo *dinfo = device_get_ivars(devlist[tmp]); 264 int status = device_get_state(devlist[tmp]); 265 266 if (status == DS_ATTACHED || status == DS_BUSY) { 267 if (device_detach(dinfo->cfg.dev) == 0 || 268 flags & DETACH_FORCE){ 269 cardbus_release_all_resources(dinfo->cfg.dev, 270 &dinfo->resources); 271 device_delete_child(dev, devlist[tmp]); 272 } else { 273 err++; 274 } 275 cardbus_freecfg(dinfo); 276 } else { 277 device_delete_child(dev, devlist[tmp]); 278 } 279 } 280 if (err == 0) 281 POWER_DISABLE_SOCKET(device_get_parent(dev), dev); 282 free(devlist, M_TEMP); 283 return err; 284 } 285 286 static void 287 cardbus_driver_added(device_t dev, driver_t *driver) 288 { 289 int numdevs; 290 device_t *devlist; 291 device_t bdev = device_get_parent(dev); 292 int tmp, cardattached; 293 294 device_get_children(dev, &devlist, &numdevs); 295 296 cardattached = 0; 297 for (tmp = 0; tmp < numdevs; tmp++) { 298 if (device_get_state(devlist[tmp]) != DS_NOTPRESENT) 299 cardattached++; 300 } 301 302 if (cardattached == 0) 303 POWER_ENABLE_SOCKET(bdev, dev); 304 DEVICE_IDENTIFY(driver, dev); 305 for (tmp = 0; tmp < numdevs; tmp++) { 306 if (device_get_state(devlist[tmp]) == DS_NOTPRESENT){ 307 struct cardbus_devinfo *dinfo; 308 dinfo = device_get_ivars(devlist[tmp]); 309 resource_list_init(&dinfo->resources); 310 cardbus_add_resources(dinfo->cfg.dev, &dinfo->cfg); 311 cardbus_do_cis(dev, dinfo->cfg.dev); 312 if (device_probe_and_attach(dinfo->cfg.dev) != 0) { 313 cardbus_release_all_resources(dinfo->cfg.dev, 314 &dinfo->resources); 315 } else 316 cardattached++; 317 } 318 } 319 320 if (cardattached == 0) 321 POWER_DISABLE_SOCKET(bdev, dev); 322 free(devlist, M_TEMP); 323 } 324 325 /************************************************************************/ 326 /* PCI-Like config reading (copied from pci.c */ 327 /************************************************************************/ 328 329 /* read configuration header into pcicfgrect structure */ 330 331 static struct cardbus_devinfo * 332 cardbus_read_device(device_t pcib, int b, int s, int f) 333 { 334 #define REG(n, w) PCIB_READ_CONFIG(pcib, b, s, f, n, w) 335 pcicfgregs *cfg = NULL; 336 struct cardbus_devinfo *devlist_entry = NULL; 337 338 if (PCIB_READ_CONFIG(pcib, b, s, f, PCIR_DEVVENDOR, 4) != -1) { 339 devlist_entry = malloc(sizeof(struct cardbus_devinfo), 340 M_DEVBUF, M_WAITOK | M_ZERO); 341 if (devlist_entry == NULL) 342 return (NULL); 343 344 cfg = &devlist_entry->cfg; 345 346 cfg->bus = b; 347 cfg->slot = s; 348 cfg->func = f; 349 cfg->vendor = REG(PCIR_VENDOR, 2); 350 cfg->device = REG(PCIR_DEVICE, 2); 351 cfg->cmdreg = REG(PCIR_COMMAND, 2); 352 cfg->statreg = REG(PCIR_STATUS, 2); 353 cfg->baseclass = REG(PCIR_CLASS, 1); 354 cfg->subclass = REG(PCIR_SUBCLASS, 1); 355 cfg->progif = REG(PCIR_PROGIF, 1); 356 cfg->revid = REG(PCIR_REVID, 1); 357 cfg->hdrtype = REG(PCIR_HEADERTYPE, 1); 358 cfg->cachelnsz = REG(PCIR_CACHELNSZ, 1); 359 cfg->lattimer = REG(PCIR_LATTIMER, 1); 360 cfg->intpin = REG(PCIR_INTPIN, 1); 361 cfg->intline = REG(PCIR_INTLINE, 1); 362 #ifdef __alpha__ 363 alpha_platform_assign_pciintr(cfg); 364 #endif 365 366 #ifdef APIC_IO 367 if (cfg->intpin != 0) { 368 int airq; 369 370 airq = pci_apic_irq(cfg->bus, cfg->slot, cfg->intpin); 371 if (airq >= 0) { 372 /* PCI specific entry found in MP table */ 373 if (airq != cfg->intline) { 374 undirect_pci_irq(cfg->intline); 375 cfg->intline = airq; 376 } 377 } else { 378 /* 379 * PCI interrupts might be redirected to the 380 * ISA bus according to some MP tables. Use the 381 * same methods as used by the ISA devices 382 * devices to find the proper IOAPIC int pin. 383 */ 384 airq = isa_apic_irq(cfg->intline); 385 if ((airq >= 0) && (airq != cfg->intline)) { 386 /* XXX: undirect_pci_irq() ? */ 387 undirect_isa_irq(cfg->intline); 388 cfg->intline = airq; 389 } 390 } 391 } 392 #endif /* APIC_IO */ 393 394 cfg->mingnt = REG(PCIR_MINGNT, 1); 395 cfg->maxlat = REG(PCIR_MAXLAT, 1); 396 397 cfg->mfdev = (cfg->hdrtype & PCIM_MFDEV) != 0; 398 cfg->hdrtype &= ~PCIM_MFDEV; 399 400 cardbus_hdrtypedata(pcib, b, s, f, cfg); 401 402 devlist_entry->conf.pc_sel.pc_bus = cfg->bus; 403 devlist_entry->conf.pc_sel.pc_dev = cfg->slot; 404 devlist_entry->conf.pc_sel.pc_func = cfg->func; 405 devlist_entry->conf.pc_hdr = cfg->hdrtype; 406 407 devlist_entry->conf.pc_subvendor = cfg->subvendor; 408 devlist_entry->conf.pc_subdevice = cfg->subdevice; 409 devlist_entry->conf.pc_vendor = cfg->vendor; 410 devlist_entry->conf.pc_device = cfg->device; 411 412 devlist_entry->conf.pc_class = cfg->baseclass; 413 devlist_entry->conf.pc_subclass = cfg->subclass; 414 devlist_entry->conf.pc_progif = cfg->progif; 415 devlist_entry->conf.pc_revid = cfg->revid; 416 } 417 return (devlist_entry); 418 #undef REG 419 } 420 421 /* extract header type specific config data */ 422 423 static void 424 cardbus_hdrtypedata(device_t pcib, int b, int s, int f, pcicfgregs *cfg) 425 { 426 #define REG(n, w) PCIB_READ_CONFIG(pcib, b, s, f, n, w) 427 switch (cfg->hdrtype) { 428 case 0: 429 cfg->subvendor = REG(PCIR_SUBVEND_0, 2); 430 cfg->subdevice = REG(PCIR_SUBDEV_0, 2); 431 cfg->nummaps = PCI_MAXMAPS_0; 432 break; 433 case 1: 434 cfg->subvendor = REG(PCIR_SUBVEND_1, 2); 435 cfg->subdevice = REG(PCIR_SUBDEV_1, 2); 436 cfg->nummaps = PCI_MAXMAPS_1; 437 break; 438 case 2: 439 cfg->subvendor = REG(PCIR_SUBVEND_2, 2); 440 cfg->subdevice = REG(PCIR_SUBDEV_2, 2); 441 cfg->nummaps = PCI_MAXMAPS_2; 442 break; 443 } 444 #undef REG 445 } 446 447 /* free pcicfgregs structure and all depending data structures */ 448 449 static int 450 cardbus_freecfg(struct cardbus_devinfo *dinfo) 451 { 452 free(dinfo, M_DEVBUF); 453 454 return (0); 455 } 456 457 static void 458 cardbus_print_verbose(struct cardbus_devinfo *dinfo) 459 { 460 if (bootverbose) { 461 pcicfgregs *cfg = &dinfo->cfg; 462 463 printf("found->\tvendor=0x%04x, dev=0x%04x, revid=0x%02x\n", 464 cfg->vendor, cfg->device, cfg->revid); 465 printf("\tclass=%02x-%02x-%02x, hdrtype=0x%02x, mfdev=%d\n", 466 cfg->baseclass, cfg->subclass, cfg->progif, 467 cfg->hdrtype, cfg->mfdev); 468 #ifdef CARDBUS_DEBUG 469 printf("\tcmdreg=0x%04x, statreg=0x%04x, cachelnsz=%d (dwords)\n", 470 cfg->cmdreg, cfg->statreg, cfg->cachelnsz); 471 printf("\tlattimer=0x%02x (%d ns), mingnt=0x%02x (%d ns), maxlat=0x%02x (%d ns)\n", 472 cfg->lattimer, cfg->lattimer * 30, 473 cfg->mingnt, cfg->mingnt * 250, cfg->maxlat, cfg->maxlat * 250); 474 #endif /* CARDBUS_DEBUG */ 475 if (cfg->intpin > 0) 476 printf("\tintpin=%c, irq=%d\n", cfg->intpin +'a' -1, cfg->intline); 477 } 478 } 479 480 /************************************************************************/ 481 /* Resources */ 482 /************************************************************************/ 483 484 static int 485 cardbus_set_resource(device_t dev, device_t child, int type, int rid, 486 u_long start, u_long count) 487 { 488 struct cardbus_devinfo *dinfo = device_get_ivars(child); 489 struct resource_list *rl = &dinfo->resources; 490 resource_list_add(rl, type, rid, start, start + count - 1, count); 491 if (device_get_parent(child) == dev) 492 pci_write_config(child, rid, start, 4); 493 return 0; 494 } 495 496 static int 497 cardbus_get_resource(device_t dev, device_t child, int type, int rid, 498 u_long *startp, u_long *countp) 499 { 500 struct cardbus_devinfo *dinfo = device_get_ivars(child); 501 struct resource_list *rl = &dinfo->resources; 502 struct resource_list_entry *rle; 503 rle = resource_list_find(rl, type, rid); 504 if (!rle) 505 return ENOENT; 506 if (startp) 507 *startp = rle->start; 508 if (countp) 509 *countp = rle->count; 510 return 0; 511 } 512 513 static void 514 cardbus_delete_resource(device_t dev, device_t child, int type, int rid) 515 { 516 struct cardbus_devinfo *dinfo = device_get_ivars(child); 517 struct resource_list *rl = &dinfo->resources; 518 struct resource_list_entry *rle; 519 rle = resource_list_find(rl, type, rid); 520 if (rle) { 521 if (rle->res) 522 bus_generic_release_resource(dev, child, type, rid, 523 rle->res); 524 resource_list_delete(rl, type, rid); 525 } 526 if (device_get_parent(child) == dev) 527 pci_write_config(child, rid, 0, 4); 528 } 529 530 static int 531 cardbus_set_resource_method(device_t dev, device_t child, int type, int rid, 532 u_long start, u_long count) 533 { 534 int ret; 535 ret = cardbus_set_resource(dev, child, type, rid, start, count); 536 if (ret != 0) return ret; 537 return BUS_SET_RESOURCE(device_get_parent(dev), child, type, rid, 538 start, count); 539 } 540 541 static int 542 cardbus_get_resource_method(device_t dev, device_t child, int type, int rid, 543 u_long *startp, u_long *countp) 544 { 545 int ret; 546 ret = cardbus_get_resource(dev, child, type, rid, startp, countp); 547 if (ret != 0) return ret; 548 return BUS_GET_RESOURCE(device_get_parent(dev), child, type, rid, 549 startp, countp); 550 } 551 552 static void 553 cardbus_delete_resource_method(device_t dev, device_t child, 554 int type, int rid) 555 { 556 cardbus_delete_resource(dev, child, type, rid); 557 BUS_DELETE_RESOURCE(device_get_parent(dev), child, type, rid); 558 } 559 560 static int 561 cardbus_add_map(device_t cbdev, device_t dev, pcicfgregs *cfg, int reg) 562 { 563 struct cardbus_devinfo *dinfo = device_get_ivars(dev); 564 struct resource_list *rl = &dinfo->resources; 565 struct resource_list_entry *rle; 566 struct resource *res; 567 device_t bdev = device_get_parent(cbdev); 568 u_int32_t size; 569 u_int32_t testval; 570 int type; 571 572 if (reg == CARDBUS_ROM_REG) 573 testval = CARDBUS_ROM_ADDRMASK; 574 else 575 testval = ~0; 576 577 PCIB_WRITE_CONFIG(bdev, cfg->bus, cfg->slot, cfg->func, 578 reg, testval, 4); 579 580 testval = PCIB_READ_CONFIG(bdev, cfg->bus, cfg->slot, cfg->func, 581 reg, 4); 582 if (testval == ~0 || testval == 0) 583 return 0; 584 585 if ((testval&1) == 0) 586 type = SYS_RES_MEMORY; 587 else 588 type = SYS_RES_IOPORT; 589 590 size = CARDBUS_MAPREG_MEM_SIZE(testval); 591 res = bus_generic_alloc_resource(cbdev, dev, type, ®, 0, ~0, size, 592 rman_make_alignment_flags(size)); 593 if (res) { 594 u_int32_t start = rman_get_start(res); 595 u_int32_t end = rman_get_end(res); 596 cardbus_set_resource(cbdev, dev, type, reg, start,end-start+1); 597 rle = resource_list_find(rl, type, reg); 598 rle->res = res; 599 } else { 600 device_printf(dev, "Unable to add map %02x\n", reg); 601 type = 0; 602 } 603 return type; 604 } 605 606 static void 607 cardbus_add_resources(device_t dev, pcicfgregs* cfg) 608 { 609 device_t cbdev = device_get_parent(dev); 610 device_t bdev = device_get_parent(cbdev); 611 struct cardbus_devinfo *dinfo = device_get_ivars(dev); 612 struct resource_list *rl = &dinfo->resources; 613 struct cardbus_quirk *q; 614 struct resource_list_entry *rle; 615 struct resource *res; 616 int rid; 617 u_int command; 618 int type; 619 int types; 620 int i; 621 622 types = 0; 623 for (i = 0; i < cfg->nummaps; i++) { 624 type = cardbus_add_map(cbdev, dev, cfg, PCIR_MAPS + i*4); 625 types |= 0x1 << type; 626 } 627 type = cardbus_add_map(cbdev, dev, cfg, CARDBUS_ROM_REG); 628 types |= 0x1 << type; 629 630 for (q = &cardbus_quirks[0]; q->devid; q++) { 631 if (q->devid == ((cfg->device << 16) | cfg->vendor) 632 && q->type == CARDBUS_QUIRK_MAP_REG) { 633 type = cardbus_add_map(cbdev, dev, cfg, q->arg1); 634 types |= 0x1 << type; 635 } 636 } 637 638 command = PCIB_READ_CONFIG(bdev, cfg->bus, cfg->slot, 639 cfg->func, PCIR_COMMAND, 2); 640 if ((types & (0x1 << SYS_RES_MEMORY)) != 0) 641 command |= PCIM_CMD_MEMEN; 642 if ((types & (0x1 << SYS_RES_IOPORT)) != 0) 643 command |= PCIM_CMD_PORTEN; 644 command |= PCIM_CMD_BUSMASTEREN; 645 PCIB_WRITE_CONFIG(bdev, cfg->bus, cfg->slot, cfg->func, 646 PCIR_COMMAND, command, 2); 647 648 rid = 0; 649 res = bus_generic_alloc_resource(cbdev, dev, SYS_RES_IRQ, 650 &rid, 0, ~0, 1, RF_SHAREABLE); 651 652 if (res == NULL) 653 panic("Cannot allocate IRQ for card\n"); 654 655 resource_list_add(rl, SYS_RES_IRQ, rid, 656 rman_get_start(res), rman_get_start(res), 1); 657 rle = resource_list_find(rl, SYS_RES_IRQ, rid); 658 rle->res = res; 659 } 660 661 static void 662 cardbus_release_all_resources(device_t dev, struct resource_list *rl) 663 { 664 struct resource_list_entry *rle; 665 666 SLIST_FOREACH(rle, rl, link) { 667 if (rle->res) { 668 bus_generic_release_resource(device_get_parent(dev), 669 dev, rle->type, rle->rid, 670 rle->res); 671 } 672 } 673 } 674 675 static struct resource* 676 cardbus_alloc_resource(device_t self, device_t child, int type, 677 int* rid, u_long start, u_long end, 678 u_long count, u_int flags) 679 { 680 struct cardbus_devinfo *dinfo = device_get_ivars(child); 681 struct resource_list *rl = &dinfo->resources; 682 struct resource_list_entry *rle = NULL; 683 struct resource *res; 684 685 if (device_get_parent(child) == self || child == self) 686 rle = resource_list_find(rl, type, *rid); 687 if (rle) { 688 if (flags & RF_ACTIVE) { 689 if (bus_activate_resource(child, rle->type, *rid, 690 rle->res)) { 691 return NULL; 692 } 693 if (*rid == CARDBUS_ROM_REG) { 694 uint32_t rom_reg; 695 696 rom_reg = pci_read_config(child, *rid, 4); 697 rom_reg |= CARDBUS_ROM_ENABLE; 698 pci_write_config(child, *rid, rom_reg, 4); 699 } 700 } 701 return rle->res; /* XXX: check if range within start/end */ 702 } else { 703 res = bus_generic_alloc_resource(self, child, type, rid, 704 start, end, count, flags); 705 if (res) { 706 start = rman_get_start(res); 707 end = rman_get_end(res); 708 cardbus_set_resource(self, child, type, *rid, start, 709 end-start+1); 710 rle = resource_list_find(rl, type, *rid); 711 rle->res = res; 712 return res; 713 } else { 714 device_printf(self, "Resource Allocation Failed!\n"); 715 return NULL; 716 } 717 } 718 } 719 720 static int 721 cardbus_release_resource(device_t dev, device_t child, int type, int rid, 722 struct resource *r) 723 { 724 /* 725 * According to the PCI 2.2 spec, devices may share an address 726 * decoder between memory mapped ROM access and memory 727 * mapped register access. To be safe, disable ROM access 728 * whenever it is released. 729 */ 730 if (rid == CARDBUS_ROM_REG) { 731 uint32_t rom_reg; 732 733 rom_reg = pci_read_config(child, rid, 4); 734 rom_reg &= ~CARDBUS_ROM_ENABLE; 735 pci_write_config(child, rid, rom_reg, 4); 736 } 737 738 return bus_deactivate_resource(child, type, rid, r); 739 } 740 741 /************************************************************************/ 742 /* Other Bus Methods */ 743 /************************************************************************/ 744 745 static int 746 cardbus_print_resources(struct resource_list *rl, const char *name, 747 int type, const char *format) 748 { 749 struct resource_list_entry *rle; 750 int printed, retval; 751 752 printed = 0; 753 retval = 0; 754 /* Yes, this is kinda cheating */ 755 SLIST_FOREACH(rle, rl, link) { 756 if (rle->type == type) { 757 if (printed == 0) 758 retval += printf(" %s ", name); 759 else if (printed > 0) 760 retval += printf(","); 761 printed++; 762 retval += printf(format, rle->start); 763 if (rle->count > 1) { 764 retval += printf("-"); 765 retval += printf(format, rle->start + 766 rle->count - 1); 767 } 768 } 769 } 770 return retval; 771 } 772 773 static int 774 cardbus_print_child(device_t dev, device_t child) 775 { 776 struct cardbus_devinfo *dinfo; 777 struct resource_list *rl; 778 pcicfgregs *cfg; 779 int retval = 0; 780 781 dinfo = device_get_ivars(child); 782 cfg = &dinfo->cfg; 783 rl = &dinfo->resources; 784 785 retval += bus_print_child_header(dev, child); 786 787 retval += cardbus_print_resources(rl, "port", SYS_RES_IOPORT, "%#lx"); 788 retval += cardbus_print_resources(rl, "mem", SYS_RES_MEMORY, "%#lx"); 789 retval += cardbus_print_resources(rl, "irq", SYS_RES_IRQ, "%ld"); 790 if (device_get_flags(dev)) 791 retval += printf(" flags %#x", device_get_flags(dev)); 792 793 retval += printf(" at device %d.%d", pci_get_slot(child), 794 pci_get_function(child)); 795 796 retval += bus_print_child_footer(dev, child); 797 798 return (retval); 799 } 800 801 static void cardbus_probe_nomatch(device_t dev, device_t child) { 802 struct cardbus_devinfo *dinfo; 803 pcicfgregs *cfg; 804 805 dinfo = device_get_ivars(child); 806 cfg = &dinfo->cfg; 807 device_printf(dev, "<unknown card>"); 808 printf(" (vendor=0x%04x, dev=0x%04x)", cfg->vendor, cfg->device); 809 printf(" at %d.%d", pci_get_slot(child), pci_get_function(child)); 810 if (cfg->intpin > 0 && cfg->intline != 255) { 811 printf(" irq %d", cfg->intline); 812 } 813 printf("\n"); 814 815 return; 816 } 817 818 static int 819 cardbus_read_ivar(device_t dev, device_t child, int which, u_long *result) 820 { 821 struct cardbus_devinfo *dinfo; 822 pcicfgregs *cfg; 823 824 dinfo = device_get_ivars(child); 825 cfg = &dinfo->cfg; 826 827 switch (which) { 828 case PCI_IVAR_SUBVENDOR: 829 *result = cfg->subvendor; 830 break; 831 case PCI_IVAR_SUBDEVICE: 832 *result = cfg->subdevice; 833 break; 834 case PCI_IVAR_VENDOR: 835 *result = cfg->vendor; 836 break; 837 case PCI_IVAR_DEVICE: 838 *result = cfg->device; 839 break; 840 case PCI_IVAR_DEVID: 841 *result = (cfg->device << 16) | cfg->vendor; 842 break; 843 case PCI_IVAR_CLASS: 844 *result = cfg->baseclass; 845 break; 846 case PCI_IVAR_SUBCLASS: 847 *result = cfg->subclass; 848 break; 849 case PCI_IVAR_PROGIF: 850 *result = cfg->progif; 851 break; 852 case PCI_IVAR_REVID: 853 *result = cfg->revid; 854 break; 855 case PCI_IVAR_INTPIN: 856 *result = cfg->intpin; 857 break; 858 case PCI_IVAR_IRQ: 859 *result = cfg->intline; 860 break; 861 case PCI_IVAR_BUS: 862 *result = cfg->bus; 863 break; 864 case PCI_IVAR_SLOT: 865 *result = cfg->slot; 866 break; 867 case PCI_IVAR_FUNCTION: 868 *result = cfg->func; 869 break; 870 default: 871 return ENOENT; 872 } 873 return 0; 874 } 875 876 static int 877 cardbus_write_ivar(device_t dev, device_t child, int which, uintptr_t value) 878 { 879 struct cardbus_devinfo *dinfo; 880 pcicfgregs *cfg; 881 882 dinfo = device_get_ivars(child); 883 cfg = &dinfo->cfg; 884 885 switch (which) { 886 case PCI_IVAR_SUBVENDOR: 887 case PCI_IVAR_SUBDEVICE: 888 case PCI_IVAR_VENDOR: 889 case PCI_IVAR_DEVICE: 890 case PCI_IVAR_DEVID: 891 case PCI_IVAR_CLASS: 892 case PCI_IVAR_SUBCLASS: 893 case PCI_IVAR_PROGIF: 894 case PCI_IVAR_REVID: 895 case PCI_IVAR_INTPIN: 896 case PCI_IVAR_IRQ: 897 case PCI_IVAR_BUS: 898 case PCI_IVAR_SLOT: 899 case PCI_IVAR_FUNCTION: 900 return EINVAL; /* disallow for now */ 901 default: 902 return ENOENT; 903 } 904 return 0; 905 } 906 907 /************************************************************************/ 908 /* Compatibility with PCI bus (XXX: Do we need this?) */ 909 /************************************************************************/ 910 911 static u_int32_t 912 cardbus_read_config_method(device_t dev, device_t child, int reg, int width) 913 { 914 struct cardbus_devinfo *dinfo = device_get_ivars(child); 915 pcicfgregs *cfg = &dinfo->cfg; 916 917 return PCIB_READ_CONFIG(device_get_parent(dev), 918 cfg->bus, cfg->slot, cfg->func, 919 reg, width); 920 } 921 922 static void 923 cardbus_write_config_method(device_t dev, device_t child, int reg, 924 u_int32_t val, int width) 925 { 926 struct cardbus_devinfo *dinfo = device_get_ivars(child); 927 pcicfgregs *cfg = &dinfo->cfg; 928 929 PCIB_WRITE_CONFIG(device_get_parent(dev), 930 cfg->bus, cfg->slot, cfg->func, 931 reg, val, width); 932 } 933 934 static device_method_t cardbus_methods[] = { 935 /* Device interface */ 936 DEVMETHOD(device_probe, cardbus_probe), 937 DEVMETHOD(device_attach, cardbus_attach), 938 DEVMETHOD(device_detach, cardbus_detach), 939 DEVMETHOD(device_shutdown, bus_generic_shutdown), 940 DEVMETHOD(device_suspend, bus_generic_suspend), 941 DEVMETHOD(device_resume, bus_generic_resume), 942 943 /* Bus interface */ 944 DEVMETHOD(bus_print_child, cardbus_print_child), 945 DEVMETHOD(bus_probe_nomatch, cardbus_probe_nomatch), 946 DEVMETHOD(bus_read_ivar, cardbus_read_ivar), 947 DEVMETHOD(bus_write_ivar, cardbus_write_ivar), 948 DEVMETHOD(bus_driver_added, cardbus_driver_added), 949 DEVMETHOD(bus_alloc_resource, cardbus_alloc_resource), 950 DEVMETHOD(bus_release_resource, cardbus_release_resource), 951 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), 952 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 953 DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), 954 DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), 955 DEVMETHOD(bus_driver_added, bus_generic_driver_added), 956 957 DEVMETHOD(bus_set_resource, cardbus_set_resource_method), 958 DEVMETHOD(bus_get_resource, cardbus_get_resource_method), 959 DEVMETHOD(bus_delete_resource, cardbus_delete_resource_method), 960 961 /* Card Interface */ 962 DEVMETHOD(card_attach_card, cardbus_attach_card), 963 DEVMETHOD(card_detach_card, cardbus_detach_card), 964 DEVMETHOD(card_cis_read, cardbus_cis_read), 965 DEVMETHOD(card_cis_free, cardbus_cis_free), 966 967 /* Cardbus/PCI interface */ 968 DEVMETHOD(pci_read_config, cardbus_read_config_method), 969 DEVMETHOD(pci_write_config, cardbus_write_config_method), 970 971 {0,0} 972 }; 973 974 static driver_t cardbus_driver = { 975 "cardbus", 976 cardbus_methods, 977 0 /* no softc */ 978 }; 979 980 static devclass_t cardbus_devclass; 981 982 DRIVER_MODULE(cardbus, pccbb, cardbus_driver, cardbus_devclass, 0, 0); 983 /* 984 MODULE_DEPEND(cardbus, pccbb, 1, 1, 1); 985 */ 986