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