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