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