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 */ 29 30 #include <sys/cdefs.h> 31 __FBSDID("$FreeBSD$"); 32 33 /* 34 * CIS Handling for the Cardbus Bus 35 */ 36 37 #include <sys/param.h> 38 #include <sys/systm.h> 39 #include <sys/kernel.h> 40 #include <sys/malloc.h> 41 42 #include <sys/bus.h> 43 #include <machine/bus.h> 44 #include <machine/resource.h> 45 #include <sys/rman.h> 46 #include <sys/endian.h> 47 48 #include <sys/pciio.h> 49 #include <dev/pci/pcivar.h> 50 #include <dev/pci/pcireg.h> 51 52 #include <dev/pccard/pccardvar.h> 53 #include <dev/pccard/pccard_cis.h> 54 55 #include <dev/cardbus/cardbusreg.h> 56 #include <dev/cardbus/cardbusvar.h> 57 #include <dev/cardbus/cardbus_cis.h> 58 59 extern int cardbus_cis_debug; 60 61 #define DPRINTF(a) if (cardbus_cis_debug) printf a 62 #define DEVPRINTF(x) if (cardbus_cis_debug) device_printf x 63 64 struct tuple_callbacks; 65 66 typedef int (tuple_cb) (device_t cbdev, device_t child, int id, int len, 67 uint8_t *tupledata, uint32_t start, uint32_t *off, 68 struct tuple_callbacks *info); 69 70 struct tuple_callbacks { 71 int id; 72 char *name; 73 tuple_cb *func; 74 }; 75 76 static int decode_tuple_generic(device_t cbdev, device_t child, int id, 77 int len, uint8_t *tupledata, uint32_t start, uint32_t *off, 78 struct tuple_callbacks *info); 79 static int decode_tuple_linktarget(device_t cbdev, device_t child, int id, 80 int len, uint8_t *tupledata, uint32_t start, uint32_t *off, 81 struct tuple_callbacks *info); 82 static int decode_tuple_vers_1(device_t cbdev, device_t child, int id, 83 int len, uint8_t *tupledata, uint32_t start, uint32_t *off, 84 struct tuple_callbacks *info); 85 static int decode_tuple_funcid(device_t cbdev, device_t child, int id, 86 int len, uint8_t *tupledata, uint32_t start, uint32_t *off, 87 struct tuple_callbacks *info); 88 static int decode_tuple_manfid(device_t cbdev, device_t child, int id, 89 int len, uint8_t *tupledata, uint32_t start, uint32_t *off, 90 struct tuple_callbacks *info); 91 static int decode_tuple_funce(device_t cbdev, device_t child, int id, 92 int len, uint8_t *tupledata, uint32_t start, uint32_t *off, 93 struct tuple_callbacks *info); 94 static int decode_tuple_bar(device_t cbdev, device_t child, int id, 95 int len, uint8_t *tupledata, uint32_t start, uint32_t *off, 96 struct tuple_callbacks *info); 97 static int decode_tuple_unhandled(device_t cbdev, device_t child, int id, 98 int len, uint8_t *tupledata, uint32_t start, uint32_t *off, 99 struct tuple_callbacks *info); 100 static int decode_tuple_end(device_t cbdev, device_t child, int id, 101 int len, uint8_t *tupledata, uint32_t start, uint32_t *off, 102 struct tuple_callbacks *info); 103 104 static int cardbus_read_tuple_conf(device_t cbdev, device_t child, 105 uint32_t start, uint32_t *off, int *tupleid, int *len, 106 uint8_t *tupledata); 107 static int cardbus_read_tuple_mem(device_t cbdev, struct resource *res, 108 uint32_t start, uint32_t *off, int *tupleid, int *len, 109 uint8_t *tupledata); 110 static int cardbus_read_tuple(device_t cbdev, device_t child, 111 struct resource *res, uint32_t start, uint32_t *off, 112 int *tupleid, int *len, uint8_t *tupledata); 113 static void cardbus_read_tuple_finish(device_t cbdev, device_t child, 114 int rid, struct resource *res); 115 static struct resource *cardbus_read_tuple_init(device_t cbdev, device_t child, 116 uint32_t *start, int *rid); 117 static int decode_tuple(device_t cbdev, device_t child, int tupleid, 118 int len, uint8_t *tupledata, uint32_t start, 119 uint32_t *off, struct tuple_callbacks *callbacks); 120 static int cardbus_parse_cis(device_t cbdev, device_t child, 121 struct tuple_callbacks *callbacks); 122 static int barsort(const void *a, const void *b); 123 static int cardbus_alloc_resources(device_t cbdev, device_t child); 124 static void cardbus_add_map(device_t cbdev, device_t child, int reg); 125 static void cardbus_pickup_maps(device_t cbdev, device_t child); 126 127 128 #define MAKETUPLE(NAME,FUNC) { CISTPL_ ## NAME, #NAME, decode_tuple_ ## FUNC } 129 130 static char *funcnames[] = { 131 "Multi-Functioned", 132 "Memory", 133 "Serial Port", 134 "Parallel Port", 135 "Fixed Disk", 136 "Video Adaptor", 137 "Network Adaptor", 138 "AIMS", 139 "SCSI", 140 "Security" 141 }; 142 143 /* 144 * Handler functions for various CIS tuples 145 */ 146 147 static int 148 decode_tuple_generic(device_t cbdev, device_t child, int id, 149 int len, uint8_t *tupledata, uint32_t start, uint32_t *off, 150 struct tuple_callbacks *info) 151 { 152 int i; 153 154 if (cardbus_cis_debug) { 155 if (info) 156 printf("TUPLE: %s [%d]:", info->name, len); 157 else 158 printf("TUPLE: Unknown(0x%02x) [%d]:", id, len); 159 160 for (i = 0; i < len; i++) { 161 if (i % 0x10 == 0 && len > 0x10) 162 printf("\n 0x%02x:", i); 163 printf(" %02x", tupledata[i]); 164 } 165 printf("\n"); 166 } 167 return (0); 168 } 169 170 static int 171 decode_tuple_linktarget(device_t cbdev, device_t child, int id, 172 int len, uint8_t *tupledata, uint32_t start, uint32_t *off, 173 struct tuple_callbacks *info) 174 { 175 int i; 176 177 if (cardbus_cis_debug) { 178 printf("TUPLE: %s [%d]:", info->name, len); 179 180 for (i = 0; i < len; i++) { 181 if (i % 0x10 == 0 && len > 0x10) 182 printf("\n 0x%02x:", i); 183 printf(" %02x", tupledata[i]); 184 } 185 printf("\n"); 186 } 187 if (len != 3 || tupledata[0] != 'C' || tupledata[1] != 'I' || 188 tupledata[2] != 'S') { 189 printf("Invalid data for CIS Link Target!\n"); 190 decode_tuple_generic(cbdev, child, id, len, tupledata, 191 start, off, info); 192 return (EINVAL); 193 } 194 return (0); 195 } 196 197 static int 198 decode_tuple_vers_1(device_t cbdev, device_t child, int id, 199 int len, uint8_t *tupledata, uint32_t start, uint32_t *off, 200 struct tuple_callbacks *info) 201 { 202 int i; 203 204 if (cardbus_cis_debug) { 205 printf("Product version: %d.%d\n", tupledata[0], tupledata[1]); 206 printf("Product name: "); 207 for (i = 2; i < len; i++) { 208 if (tupledata[i] == '\0') 209 printf(" | "); 210 else if (tupledata[i] == 0xff) 211 break; 212 else 213 printf("%c", tupledata[i]); 214 } 215 printf("\n"); 216 } 217 return (0); 218 } 219 220 static int 221 decode_tuple_funcid(device_t cbdev, device_t child, int id, 222 int len, uint8_t *tupledata, uint32_t start, uint32_t *off, 223 struct tuple_callbacks *info) 224 { 225 struct cardbus_devinfo *dinfo = device_get_ivars(child); 226 int numnames = sizeof(funcnames) / sizeof(funcnames[0]); 227 int i; 228 229 if (cardbus_cis_debug) { 230 printf("Functions: "); 231 for (i = 0; i < len; i++) { 232 if (tupledata[i] < numnames) 233 printf("%s", funcnames[tupledata[i]]); 234 else 235 printf("Unknown(%d)", tupledata[i]); 236 if (i < len-1) 237 printf(", "); 238 } 239 printf("\n"); 240 } 241 if (len > 0) 242 dinfo->funcid = tupledata[0]; /* use first in list */ 243 return (0); 244 } 245 246 static int 247 decode_tuple_manfid(device_t cbdev, device_t child, int id, 248 int len, uint8_t *tupledata, uint32_t start, uint32_t *off, 249 struct tuple_callbacks *info) 250 { 251 struct cardbus_devinfo *dinfo = device_get_ivars(child); 252 int i; 253 254 if (cardbus_cis_debug) { 255 printf("Manufacturer ID: "); 256 for (i = 0; i < len; i++) 257 printf("%02x", tupledata[i]); 258 printf("\n"); 259 } 260 261 if (len == 5) { 262 dinfo->mfrid = tupledata[1] | (tupledata[2] << 8); 263 dinfo->prodid = tupledata[3] | (tupledata[4] << 8); 264 } 265 return (0); 266 } 267 268 static int 269 decode_tuple_funce(device_t cbdev, device_t child, int id, 270 int len, uint8_t *tupledata, uint32_t start, uint32_t *off, 271 struct tuple_callbacks *info) 272 { 273 struct cardbus_devinfo *dinfo = device_get_ivars(child); 274 int type, i; 275 276 if (cardbus_cis_debug) { 277 printf("Function Extension: "); 278 for (i = 0; i < len; i++) 279 printf("%02x", tupledata[i]); 280 printf("\n"); 281 } 282 if (len < 2) /* too short */ 283 return (0); 284 type = tupledata[0]; /* XXX <32 always? */ 285 switch (dinfo->funcid) { 286 case TPL_FUNC_SERIAL: 287 if (type == TPL_FUNCE_SER_UART) { /* NB: len known > 1 */ 288 dinfo->funce.sio.type = tupledata[1] & 0x1f; 289 } 290 dinfo->fepresent |= 1<<type; 291 break; 292 case TPL_FUNC_LAN: 293 switch (type) { 294 case TPL_FUNCE_LAN_TECH: 295 dinfo->funce.lan.tech = tupledata[1]; /* XXX mask? */ 296 break; 297 #if 0 298 case TPL_FUNCE_LAN_SPEED: 299 for (i = 0; i < 3; i++) { 300 if (dinfo->funce.lan.speed[i] == 0) { 301 if (len > 4) { 302 dinfo->funce.lan.speed[i] = 303 ...; 304 } 305 break; 306 } 307 } 308 break; 309 #endif 310 case TPL_FUNCE_LAN_MEDIA: 311 for (i = 0; i < 4 && dinfo->funce.lan.media[i]; i++) { 312 if (dinfo->funce.lan.media[i] == 0) { 313 /* NB: len known > 1 */ 314 dinfo->funce.lan.media[i] = 315 tupledata[1]; /*XXX? mask */ 316 break; 317 } 318 } 319 break; 320 case TPL_FUNCE_LAN_NID: 321 if (tupledata[1] > sizeof(dinfo->funce.lan.nid)) { 322 /* ignore, warning? */ 323 return (0); 324 } 325 bcopy(tupledata + 2, dinfo->funce.lan.nid, 326 tupledata[1]); 327 break; 328 case TPL_FUNCE_LAN_CONN: 329 dinfo->funce.lan.contype = tupledata[1];/*XXX mask? */ 330 break; 331 } 332 dinfo->fepresent |= 1<<type; 333 break; 334 } 335 return (0); 336 } 337 338 static int 339 decode_tuple_bar(device_t cbdev, device_t child, int id, 340 int len, uint8_t *tupledata, uint32_t start, uint32_t *off, 341 struct tuple_callbacks *info) 342 { 343 struct cardbus_devinfo *dinfo = device_get_ivars(child); 344 int type; 345 uint8_t reg; 346 uint32_t bar, pci_bar; 347 348 if (len != 6) { 349 device_printf(cbdev, "CIS BAR length not 6 (%d)\n", len); 350 return (EINVAL); 351 } 352 353 reg = *tupledata; 354 len = le32toh(*(uint32_t*)(tupledata + 2)); 355 if (reg & TPL_BAR_REG_AS) { 356 type = SYS_RES_IOPORT; 357 } else { 358 type = SYS_RES_MEMORY; 359 } 360 361 bar = reg & TPL_BAR_REG_ASI_MASK; 362 if (bar == 0) { 363 device_printf(cbdev, "Invalid BAR type 0 in CIS\n"); 364 return (EINVAL); /* XXX Return an error? */ 365 } else if (bar == 7) { 366 /* XXX Should we try to map in Option ROMs? */ 367 return (0); 368 } 369 370 /* Convert from BAR type to BAR offset */ 371 bar = CARDBUS_BASE0_REG + (bar - 1) * 4; 372 373 if (type == SYS_RES_MEMORY) { 374 if (reg & TPL_BAR_REG_PREFETCHABLE) 375 dinfo->mprefetchable |= BARBIT(bar); 376 #if 0 377 /* 378 * XXX: It appears from a careful reading of the spec 379 * that we're not supposed to honor this when the bridge 380 * is not on the main system bus. PCI spec doesn't appear 381 * to allow for memory ranges not listed in the bridge's 382 * decode range to be decoded. The PC Card spec seems to 383 * indicate that this should only be done on x86 based 384 * machines, which seems to imply that on non-x86 machines 385 * the adddresses can be anywhere. This further implies that 386 * since the hardware can do it on non-x86 machines, it should 387 * be able to do it on x86 machines. Therefore, we can and 388 * should ignore this hint. Furthermore, the PC Card spec 389 * recommends always allocating memory above 1MB, contradicting 390 * the other part of the PC Card spec. 391 * 392 * NetBSD ignores this bit, but it also ignores the 393 * prefetchable bit too, so that's not an indication of 394 * correctness. 395 */ 396 if (reg & TPL_BAR_REG_BELOW1MB) 397 dinfo->mbelow1mb |= BARBIT(bar); 398 #endif 399 } 400 401 /* 402 * Sanity check the BAR length reported in the CIS with the length 403 * encoded in the PCI BAR. The latter seems to be more reliable. 404 * XXX - This probably belongs elsewhere. 405 */ 406 pci_write_config(child, bar, 0xffffffff, 4); 407 pci_bar = pci_read_config(child, bar, 4); 408 if ((pci_bar != 0x0) && (pci_bar != 0xffffffff)) { 409 if (type == SYS_RES_MEMORY) { 410 pci_bar &= ~0xf; 411 } else { 412 pci_bar &= ~0x3; 413 } 414 len = 1 << (ffs(pci_bar) - 1); 415 } 416 417 DEVPRINTF((cbdev, "Opening BAR: type=%s, bar=%02x, len=%04x%s%s\n", 418 (type == SYS_RES_MEMORY) ? "MEM" : "IO", bar, len, 419 (type == SYS_RES_MEMORY && dinfo->mprefetchable & BARBIT(bar)) ? 420 " (Prefetchable)" : "", type == SYS_RES_MEMORY ? 421 ((dinfo->mbelow1mb & BARBIT(bar)) ? " (Below 1Mb)" : "") : "")); 422 423 resource_list_add(&dinfo->pci.resources, type, bar, 0UL, ~0UL, len); 424 425 /* 426 * Mark the appropriate bit in the PCI command register so that 427 * device drivers will know which type of BARs can be used. 428 */ 429 pci_enable_io(child, type); 430 return (0); 431 } 432 433 static int 434 decode_tuple_unhandled(device_t cbdev, device_t child, int id, 435 int len, uint8_t *tupledata, uint32_t start, uint32_t *off, 436 struct tuple_callbacks *info) 437 { 438 /* Make this message suck less XXX */ 439 printf("TUPLE: %s [%d] is unhandled! Bailing...", info->name, len); 440 return (-1); 441 } 442 443 static int 444 decode_tuple_end(device_t cbdev, device_t child, int id, 445 int len, uint8_t *tupledata, uint32_t start, uint32_t *off, 446 struct tuple_callbacks *info) 447 { 448 if (cardbus_cis_debug) { 449 printf("CIS reading done\n"); 450 } 451 return (0); 452 } 453 454 /* 455 * Functions to read the a tuple from the card 456 */ 457 458 static int 459 cardbus_read_tuple_conf(device_t cbdev, device_t child, uint32_t start, 460 uint32_t *off, int *tupleid, int *len, uint8_t *tupledata) 461 { 462 int i, j; 463 uint32_t e; 464 uint32_t loc; 465 466 loc = start + *off; 467 468 e = pci_read_config(child, loc - loc % 4, 4); 469 for (j = loc % 4; j > 0; j--) 470 e >>= 8; 471 *len = 0; 472 for (i = loc, j = -2; j < *len; j++, i++) { 473 if (i % 4 == 0) 474 e = pci_read_config(child, i, 4); 475 if (j == -2) 476 *tupleid = 0xff & e; 477 else if (j == -1) 478 *len = 0xff & e; 479 else 480 tupledata[j] = 0xff & e; 481 e >>= 8; 482 } 483 *off += *len + 2; 484 return (0); 485 } 486 487 static int 488 cardbus_read_tuple_mem(device_t cbdev, struct resource *res, uint32_t start, 489 uint32_t *off, int *tupleid, int *len, uint8_t *tupledata) 490 { 491 bus_space_tag_t bt; 492 bus_space_handle_t bh; 493 int ret; 494 495 bt = rman_get_bustag(res); 496 bh = rman_get_bushandle(res); 497 498 *tupleid = bus_space_read_1(bt, bh, start + *off); 499 *len = bus_space_read_1(bt, bh, start + *off + 1); 500 bus_space_read_region_1(bt, bh, *off + start + 2, tupledata, *len); 501 ret = 0; 502 *off += *len + 2; 503 return (ret); 504 } 505 506 static int 507 cardbus_read_tuple(device_t cbdev, device_t child, struct resource *res, 508 uint32_t start, uint32_t *off, int *tupleid, int *len, 509 uint8_t *tupledata) 510 { 511 if (res == (struct resource*)~0UL) { 512 return (cardbus_read_tuple_conf(cbdev, child, start, off, 513 tupleid, len, tupledata)); 514 } else { 515 return (cardbus_read_tuple_mem(cbdev, res, start, off, 516 tupleid, len, tupledata)); 517 } 518 } 519 520 static void 521 cardbus_read_tuple_finish(device_t cbdev, device_t child, int rid, 522 struct resource *res) 523 { 524 if (res != (struct resource*)~0UL) { 525 bus_release_resource(cbdev, SYS_RES_MEMORY, rid, res); 526 pci_write_config(child, rid, 0, 4); 527 PCI_DISABLE_IO(cbdev, child, SYS_RES_MEMORY); 528 } 529 } 530 531 static struct resource * 532 cardbus_read_tuple_init(device_t cbdev, device_t child, uint32_t *start, 533 int *rid) 534 { 535 uint32_t testval; 536 uint32_t size; 537 struct resource *res; 538 539 switch (CARDBUS_CIS_SPACE(*start)) { 540 case CARDBUS_CIS_ASI_TUPLE: 541 /* CIS in PCI config space need no initialization */ 542 return ((struct resource*)~0UL); 543 case CARDBUS_CIS_ASI_BAR0: 544 case CARDBUS_CIS_ASI_BAR1: 545 case CARDBUS_CIS_ASI_BAR2: 546 case CARDBUS_CIS_ASI_BAR3: 547 case CARDBUS_CIS_ASI_BAR4: 548 case CARDBUS_CIS_ASI_BAR5: 549 *rid = CARDBUS_BASE0_REG + (CARDBUS_CIS_SPACE(*start) - 1) * 4; 550 break; 551 case CARDBUS_CIS_ASI_ROM: 552 *rid = CARDBUS_ROM_REG; 553 #if 0 554 /* 555 * This mask doesn't contain the bit that actually enables 556 * the Option ROM. 557 */ 558 pci_write_config(child, *rid, CARDBUS_ROM_ADDRMASK, 4); 559 #endif 560 break; 561 default: 562 device_printf(cbdev, "Unable to read CIS: Unknown space: %d\n", 563 CARDBUS_CIS_SPACE(*start)); 564 return (NULL); 565 } 566 567 /* figure out how much space we need */ 568 pci_write_config(child, *rid, 0xffffffff, 4); 569 testval = pci_read_config(child, *rid, 4); 570 571 /* 572 * This bit has a different meaning depending if we are dealing 573 * with a normal BAR or an Option ROM BAR. 574 */ 575 if (((testval & 0x1) == 0x1) && (*rid != CARDBUS_ROM_REG)) { 576 device_printf(cbdev, "CIS Space is IO, expecting memory.\n"); 577 return (NULL); 578 } 579 580 size = CARDBUS_MAPREG_MEM_SIZE(testval); 581 /* XXX Is this some kind of hack? */ 582 if (size < 4096) 583 size = 4096; 584 /* allocate the memory space to read CIS */ 585 res = bus_alloc_resource(cbdev, SYS_RES_MEMORY, rid, 0, ~0, size, 586 rman_make_alignment_flags(size) | RF_ACTIVE); 587 if (res == NULL) { 588 device_printf(cbdev, "Unable to allocate resource " 589 "to read CIS.\n"); 590 return (NULL); 591 } 592 pci_write_config(child, *rid, 593 rman_get_start(res) | ((*rid == CARDBUS_ROM_REG)? 594 CARDBUS_ROM_ENABLE : 0), 595 4); 596 PCI_ENABLE_IO(cbdev, child, SYS_RES_MEMORY); 597 598 /* Flip to the right ROM image if CIS is in ROM */ 599 if (CARDBUS_CIS_SPACE(*start) == CARDBUS_CIS_ASI_ROM) { 600 bus_space_tag_t bt; 601 bus_space_handle_t bh; 602 uint32_t imagesize; 603 uint32_t imagebase = 0; 604 uint32_t pcidata; 605 uint16_t romsig; 606 int romnum = 0; 607 int imagenum; 608 609 bt = rman_get_bustag(res); 610 bh = rman_get_bushandle(res); 611 612 imagenum = CARDBUS_CIS_ASI_ROM_IMAGE(*start); 613 for (romnum = 0;; romnum++) { 614 romsig = bus_space_read_2(bt, bh, 615 imagebase + CARDBUS_EXROM_SIGNATURE); 616 if (romsig != 0xaa55) { 617 device_printf(cbdev, "Bad header in rom %d: " 618 "[%x] %04x\n", romnum, imagebase + 619 CARDBUS_EXROM_SIGNATURE, romsig); 620 bus_release_resource(cbdev, SYS_RES_MEMORY, 621 *rid, res); 622 *rid = 0; 623 return (NULL); 624 } 625 626 /* 627 * If this was the Option ROM image that we were 628 * looking for, then we are done. 629 */ 630 if (romnum == imagenum) 631 break; 632 633 /* Find out where the next Option ROM image is */ 634 pcidata = imagebase + bus_space_read_2(bt, bh, 635 imagebase + CARDBUS_EXROM_DATA_PTR); 636 imagesize = bus_space_read_2(bt, bh, 637 pcidata + CARDBUS_EXROM_DATA_IMAGE_LENGTH); 638 639 if (imagesize == 0) { 640 /* 641 * XXX some ROMs seem to have this as zero, 642 * can we assume this means 1 block? 643 */ 644 device_printf(cbdev, "Warning, size of Option " 645 "ROM image %d is 0 bytes, assuming 512 " 646 "bytes.\n", romnum); 647 imagesize = 1; 648 } 649 650 /* Image size is in 512 byte units */ 651 imagesize <<= 9; 652 653 if ((bus_space_read_1(bt, bh, pcidata + 654 CARDBUS_EXROM_DATA_INDICATOR) & 0x80) != 0) { 655 device_printf(cbdev, "Cannot find CIS in " 656 "Option ROM\n"); 657 bus_release_resource(cbdev, SYS_RES_MEMORY, 658 *rid, res); 659 *rid = 0; 660 return (NULL); 661 } 662 imagebase += imagesize; 663 } 664 *start = imagebase + CARDBUS_CIS_ADDR(*start); 665 } else { 666 *start = CARDBUS_CIS_ADDR(*start); 667 } 668 669 return (res); 670 } 671 672 /* 673 * Dispatch the right handler function per tuple 674 */ 675 676 static int 677 decode_tuple(device_t cbdev, device_t child, int tupleid, int len, 678 uint8_t *tupledata, uint32_t start, uint32_t *off, 679 struct tuple_callbacks *callbacks) 680 { 681 int i; 682 for (i = 0; callbacks[i].id != CISTPL_GENERIC; i++) { 683 if (tupleid == callbacks[i].id) 684 return (callbacks[i].func(cbdev, child, tupleid, len, 685 tupledata, start, off, &callbacks[i])); 686 } 687 return (callbacks[i].func(cbdev, child, tupleid, len, 688 tupledata, start, off, NULL)); 689 } 690 691 static int 692 cardbus_parse_cis(device_t cbdev, device_t child, 693 struct tuple_callbacks *callbacks) 694 { 695 uint8_t tupledata[MAXTUPLESIZE]; 696 int tupleid; 697 int len; 698 int expect_linktarget; 699 uint32_t start, off; 700 struct resource *res; 701 int rid; 702 703 bzero(tupledata, MAXTUPLESIZE); 704 expect_linktarget = TRUE; 705 if ((start = pci_read_config(child, CARDBUS_CIS_REG, 4)) == 0) 706 return (ENXIO); 707 off = 0; 708 res = cardbus_read_tuple_init(cbdev, child, &start, &rid); 709 if (res == NULL) 710 return (ENXIO); 711 712 do { 713 if (0 != cardbus_read_tuple(cbdev, child, res, start, &off, 714 &tupleid, &len, tupledata)) { 715 device_printf(cbdev, "Failed to read CIS.\n"); 716 cardbus_read_tuple_finish(cbdev, child, rid, res); 717 return (ENXIO); 718 } 719 720 if (expect_linktarget && tupleid != CISTPL_LINKTARGET) { 721 device_printf(cbdev, "Expecting link target, got 0x%x\n", 722 tupleid); 723 cardbus_read_tuple_finish(cbdev, child, rid, res); 724 return (EINVAL); 725 } 726 expect_linktarget = decode_tuple(cbdev, child, tupleid, len, 727 tupledata, start, &off, callbacks); 728 if (expect_linktarget != 0) { 729 cardbus_read_tuple_finish(cbdev, child, rid, res); 730 return (expect_linktarget); 731 } 732 } while (tupleid != CISTPL_END); 733 cardbus_read_tuple_finish(cbdev, child, rid, res); 734 return (0); 735 } 736 737 static void 738 cardbus_do_res(struct resource_list_entry *rle, device_t child, uint32_t start) 739 { 740 rle->start = start; 741 rle->end = start + rle->count - 1; 742 pci_write_config(child, rle->rid, rle->start, 4); 743 } 744 745 static int 746 barsort(const void *a, const void *b) 747 { 748 return ((*(const struct resource_list_entry * const *)b)->count - 749 (*(const struct resource_list_entry * const *)a)->count); 750 } 751 752 static int 753 cardbus_alloc_resources(device_t cbdev, device_t child) 754 { 755 struct cardbus_devinfo *dinfo = device_get_ivars(child); 756 int count; 757 struct resource_list_entry *rle; 758 struct resource_list_entry **barlist; 759 int tmp; 760 uint32_t mem_psize = 0, mem_nsize = 0, io_size = 0; 761 struct resource *res; 762 uint32_t start,end; 763 int rid, flags; 764 765 count = 0; 766 SLIST_FOREACH(rle, &dinfo->pci.resources, link) { 767 count++; 768 } 769 if (count == 0) 770 return (0); 771 barlist = malloc(sizeof(struct resource_list_entry*) * count, M_DEVBUF, 772 M_WAITOK); 773 count = 0; 774 SLIST_FOREACH(rle, &dinfo->pci.resources, link) { 775 barlist[count] = rle; 776 if (rle->type == SYS_RES_IOPORT) { 777 io_size += rle->count; 778 } else if (rle->type == SYS_RES_MEMORY) { 779 if (dinfo->mprefetchable & BARBIT(rle->rid)) 780 mem_psize += rle->count; 781 else 782 mem_nsize += rle->count; 783 } 784 count++; 785 } 786 787 /* 788 * We want to allocate the largest resource first, so that our 789 * allocated memory is packed. 790 */ 791 qsort(barlist, count, sizeof(struct resource_list_entry*), barsort); 792 793 /* Allocate prefetchable memory */ 794 flags = 0; 795 for (tmp = 0; tmp < count; tmp++) { 796 rle = barlist[tmp]; 797 if (rle->res == NULL && 798 rle->type == SYS_RES_MEMORY && 799 dinfo->mprefetchable & BARBIT(rle->rid)) { 800 flags = rman_make_alignment_flags(rle->count); 801 break; 802 } 803 } 804 if (flags > 0) { /* If any prefetchable memory is requested... */ 805 /* 806 * First we allocate one big space for all resources of this 807 * type. We do this because our parent, pccbb, needs to open 808 * a window to forward all addresses within the window, and 809 * it would be best if nobody else has resources allocated 810 * within the window. 811 * (XXX: Perhaps there might be a better way to do this?) 812 */ 813 rid = 0; 814 res = bus_alloc_resource(cbdev, SYS_RES_MEMORY, &rid, 0, 815 (dinfo->mprefetchable & dinfo->mbelow1mb)?0xFFFFF:~0UL, 816 mem_psize, flags); 817 if (res == NULL) { 818 device_printf(cbdev, 819 "Can't get memory for prefetch mem\n"); 820 free(barlist, M_DEVBUF); 821 return (EIO); 822 } 823 start = rman_get_start(res); 824 end = rman_get_end(res); 825 DEVPRINTF((cbdev, "Prefetchable memory at %x-%x\n", start, end)); 826 /* 827 * Now that we know the region is free, release it and hand it 828 * out piece by piece. 829 */ 830 bus_release_resource(cbdev, SYS_RES_MEMORY, rid, res); 831 for (tmp = 0; tmp < count; tmp++) { 832 rle = barlist[tmp]; 833 if (rle->type == SYS_RES_MEMORY && 834 dinfo->mprefetchable & BARBIT(rle->rid)) { 835 cardbus_do_res(rle, child, start); 836 start += rle->count; 837 } 838 } 839 } 840 841 /* Allocate non-prefetchable memory */ 842 flags = 0; 843 for (tmp = 0; tmp < count; tmp++) { 844 rle = barlist[tmp]; 845 if (rle->type == SYS_RES_MEMORY && 846 (dinfo->mprefetchable & BARBIT(rle->rid)) == 0) { 847 flags = rman_make_alignment_flags(rle->count); 848 break; 849 } 850 } 851 if (flags > 0) { /* If any non-prefetchable memory is requested... */ 852 /* 853 * First we allocate one big space for all resources of this 854 * type. We do this because our parent, pccbb, needs to open 855 * a window to forward all addresses within the window, and 856 * it would be best if nobody else has resources allocated 857 * within the window. 858 * (XXX: Perhaps there might be a better way to do this?) 859 */ 860 rid = 0; 861 res = bus_alloc_resource(cbdev, SYS_RES_MEMORY, &rid, 0, 862 ((~dinfo->mprefetchable) & dinfo->mbelow1mb)?0xFFFFF:~0UL, 863 mem_nsize, flags); 864 if (res == NULL) { 865 device_printf(cbdev, 866 "Can't get memory for non-prefetch mem\n"); 867 free(barlist, M_DEVBUF); 868 return (EIO); 869 } 870 start = rman_get_start(res); 871 end = rman_get_end(res); 872 DEVPRINTF((cbdev, "Non-prefetchable memory at %x-%x\n", 873 start, end)); 874 /* 875 * Now that we know the region is free, release it and hand it 876 * out piece by piece. 877 */ 878 bus_release_resource(cbdev, SYS_RES_MEMORY, rid, res); 879 for (tmp = 0; tmp < count; tmp++) { 880 rle = barlist[tmp]; 881 if (rle->type == SYS_RES_MEMORY && 882 (dinfo->mprefetchable & BARBIT(rle->rid)) == 0) { 883 cardbus_do_res(rle, child, start); 884 start += rle->count; 885 } 886 } 887 } 888 889 /* Allocate IO ports */ 890 flags = 0; 891 for (tmp = 0; tmp < count; tmp++) { 892 rle = barlist[tmp]; 893 if (rle->type == SYS_RES_IOPORT) { 894 flags = rman_make_alignment_flags(rle->count); 895 break; 896 } 897 } 898 if (flags > 0) { /* If any IO port is requested... */ 899 /* 900 * First we allocate one big space for all resources of this 901 * type. We do this because our parent, pccbb, needs to open 902 * a window to forward all addresses within the window, and 903 * it would be best if nobody else has resources allocated 904 * within the window. 905 * (XXX: Perhaps there might be a better way to do this?) 906 */ 907 rid = 0; 908 res = bus_alloc_resource(cbdev, SYS_RES_IOPORT, &rid, 0, 909 (dinfo->ibelow1mb)?0xFFFFF:~0UL, io_size, flags); 910 if (res == NULL) { 911 device_printf(cbdev, 912 "Can't get memory for IO ports\n"); 913 free(barlist, M_DEVBUF); 914 return (EIO); 915 } 916 start = rman_get_start(res); 917 end = rman_get_end(res); 918 DEVPRINTF((cbdev, "IO port at %x-%x\n", start, end)); 919 /* 920 * Now that we know the region is free, release it and hand it 921 * out piece by piece. 922 */ 923 bus_release_resource(cbdev, SYS_RES_IOPORT, rid, res); 924 for (tmp = 0; tmp < count; tmp++) { 925 rle = barlist[tmp]; 926 if (rle->type == SYS_RES_IOPORT) { 927 cardbus_do_res(rle, child, start); 928 start += rle->count; 929 } 930 } 931 } 932 933 /* Allocate IRQ */ 934 rid = 0; 935 res = bus_alloc_resource_any(cbdev, SYS_RES_IRQ, &rid, RF_SHAREABLE); 936 if (res == NULL) { 937 device_printf(cbdev, "Can't get memory for irq\n"); 938 free(barlist, M_DEVBUF); 939 return (EIO); 940 } 941 start = rman_get_start(res); 942 end = rman_get_end(res); 943 bus_release_resource(cbdev, SYS_RES_IRQ, rid, res); 944 resource_list_add(&dinfo->pci.resources, SYS_RES_IRQ, rid, start, end, 945 1); 946 dinfo->pci.cfg.intline = rman_get_start(res); 947 pci_write_config(child, PCIR_INTLINE, rman_get_start(res), 1); 948 949 free(barlist, M_DEVBUF); 950 return (0); 951 } 952 953 /* 954 * Adding a memory/io resource (sans CIS) 955 */ 956 957 static void 958 cardbus_add_map(device_t cbdev, device_t child, int reg) 959 { 960 struct cardbus_devinfo *dinfo = device_get_ivars(child); 961 struct resource_list_entry *rle; 962 uint32_t size; 963 uint32_t testval; 964 int type; 965 966 SLIST_FOREACH(rle, &dinfo->pci.resources, link) { 967 if (rle->rid == reg) 968 return; 969 } 970 971 if (reg == CARDBUS_ROM_REG) 972 testval = CARDBUS_ROM_ADDRMASK; 973 else 974 testval = ~0; 975 976 pci_write_config(child, reg, testval, 4); 977 testval = pci_read_config(child, reg, 4); 978 979 if (testval == ~0 || testval == 0) 980 return; 981 982 if ((testval & 1) == 0) 983 type = SYS_RES_MEMORY; 984 else 985 type = SYS_RES_IOPORT; 986 987 size = CARDBUS_MAPREG_MEM_SIZE(testval); 988 device_printf(cbdev, "Resource not specified in CIS: id=%x, size=%x\n", 989 reg, size); 990 resource_list_add(&dinfo->pci.resources, type, reg, 0UL, ~0UL, size); 991 } 992 993 static void 994 cardbus_pickup_maps(device_t cbdev, device_t child) 995 { 996 struct cardbus_devinfo *dinfo = device_get_ivars(child); 997 int reg; 998 999 /* 1000 * Try to pick up any resources that was not specified in CIS. 1001 * Maybe this isn't any longer necessary now that we have fixed 1002 * CIS parsing and we should filter things here? XXX 1003 */ 1004 for (reg = 0; reg < dinfo->pci.cfg.nummaps; reg++) 1005 cardbus_add_map(cbdev, child, PCIR_BAR(reg)); 1006 } 1007 1008 int 1009 cardbus_do_cis(device_t cbdev, device_t child) 1010 { 1011 int ret; 1012 struct tuple_callbacks init_callbacks[] = { 1013 MAKETUPLE(LONGLINK_CB, unhandled), 1014 MAKETUPLE(INDIRECT, unhandled), 1015 MAKETUPLE(LONGLINK_MFC, unhandled), 1016 MAKETUPLE(BAR, bar), 1017 MAKETUPLE(LONGLINK_A, unhandled), 1018 MAKETUPLE(LONGLINK_C, unhandled), 1019 MAKETUPLE(LINKTARGET, linktarget), 1020 MAKETUPLE(VERS_1, vers_1), 1021 MAKETUPLE(MANFID, manfid), 1022 MAKETUPLE(FUNCID, funcid), 1023 MAKETUPLE(FUNCE, funce), 1024 MAKETUPLE(END, end), 1025 MAKETUPLE(GENERIC, generic), 1026 }; 1027 1028 ret = cardbus_parse_cis(cbdev, child, init_callbacks); 1029 if (ret < 0) 1030 return (ret); 1031 cardbus_pickup_maps(cbdev, child); 1032 return (cardbus_alloc_resources(cbdev, child)); 1033 } 1034