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