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 if (len != 6) { 269 printf("*** ERROR *** BAR length not 6 (%d)\n", len); 270 return (EINVAL); 271 } else { 272 struct cardbus_devinfo *dinfo = device_get_ivars(child); 273 int type; 274 int reg; 275 u_int32_t bar; 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, " 302 "len=%04x%s%s\n", 303 (type==SYS_RES_MEMORY)?"MEM":"IO", bar, len, 304 (type==SYS_RES_MEMORY&&dinfo->mprefetchable&BARBIT(bar))? 305 " (Prefetchable)":"", 306 type==SYS_RES_MEMORY? 307 ((dinfo->mbelow1mb&BARBIT(bar))?" (Below 1Mb)":"") 308 :(dinfo->ibelow1mb&BARBIT(bar))?" (Below 1Mb)":"" 309 )); 310 311 resource_list_add(&dinfo->pci.resources, type, bar, 0UL, ~0UL, len); 312 } 313 return (0); 314 } 315 316 DECODE_PROTOTYPE(unhandled) 317 { 318 printf("TUPLE: %s [%d] is unhandled! Bailing...", info->name, len); 319 return (-1); 320 } 321 322 DECODE_PROTOTYPE(end) 323 { 324 printf("CIS reading done\n"); 325 return (0); 326 } 327 328 /* 329 * Functions to read the a tuple from the card 330 */ 331 332 static int 333 cardbus_read_tuple_conf(device_t cbdev, device_t child, u_int32_t start, 334 u_int32_t *off, int *tupleid, int *len, u_int8_t *tupledata) 335 { 336 int i, j; 337 u_int32_t e; 338 u_int32_t loc; 339 340 loc = start + *off; 341 342 e = pci_read_config(child, loc - loc % 4, 4); 343 for (j = loc % 4; j > 0; j--) 344 e >>= 8; 345 *len = 0; 346 for (i = loc, j = -2; j < *len; j++, i++) { 347 if (i % 4 == 0) 348 e = pci_read_config(child, i, 4); 349 if (j == -2) 350 *tupleid = 0xff & e; 351 else if (j == -1) 352 *len = 0xff & e; 353 else 354 tupledata[j] = 0xff & e; 355 e >>= 8; 356 } 357 *off += *len + 2; 358 return (0); 359 } 360 361 static int 362 cardbus_read_tuple_mem(device_t cbdev, struct resource *res, u_int32_t start, 363 u_int32_t *off, int *tupleid, int *len, u_int8_t *tupledata) 364 { 365 bus_space_tag_t bt; 366 bus_space_handle_t bh; 367 int ret; 368 369 bt = rman_get_bustag(res); 370 bh = rman_get_bushandle(res); 371 372 *tupleid = bus_space_read_1(bt, bh, start + *off); 373 *len = bus_space_read_1(bt, bh, start + *off + 1); 374 bus_space_read_region_1(bt, bh, *off + start + 2, tupledata, *len); 375 ret = 0; 376 *off += *len + 2; 377 return (ret); 378 } 379 380 static int 381 cardbus_read_tuple(device_t cbdev, device_t child, struct resource *res, 382 u_int32_t start, u_int32_t *off, int *tupleid, int *len, 383 u_int8_t *tupledata) 384 { 385 if (res == (struct resource*)~0UL) { 386 return (cardbus_read_tuple_conf(cbdev, child, start, off, 387 tupleid, len, tupledata)); 388 } else { 389 return (cardbus_read_tuple_mem(cbdev, res, start, off, 390 tupleid, len, tupledata)); 391 } 392 } 393 394 static void 395 cardbus_read_tuple_finish(device_t cbdev, device_t child, int rid, 396 struct resource *res) 397 { 398 if (res != (struct resource*)~0UL) { 399 bus_release_resource(cbdev, SYS_RES_MEMORY, rid, res); 400 pci_write_config(child, rid, 0, 4); 401 PCI_DISABLE_IO(cbdev, child, SYS_RES_MEMORY); 402 } 403 } 404 405 static struct resource * 406 cardbus_read_tuple_init(device_t cbdev, device_t child, u_int32_t *start, 407 int *rid) 408 { 409 u_int32_t testval; 410 u_int32_t size; 411 struct resource *res; 412 413 switch (CARDBUS_CIS_SPACE(*start)) { 414 case CARDBUS_CIS_ASI_TUPLE: 415 /* CIS in tuple space need no initialization */ 416 return ((struct resource*)~0UL); 417 case CARDBUS_CIS_ASI_BAR0: 418 case CARDBUS_CIS_ASI_BAR1: 419 case CARDBUS_CIS_ASI_BAR2: 420 case CARDBUS_CIS_ASI_BAR3: 421 case CARDBUS_CIS_ASI_BAR4: 422 case CARDBUS_CIS_ASI_BAR5: 423 *rid = CARDBUS_BASE0_REG + (CARDBUS_CIS_SPACE(*start) - 1) * 4; 424 pci_write_config(child, *rid, ~0UL, 4); 425 break; 426 case CARDBUS_CIS_ASI_ROM: 427 *rid = CARDBUS_ROM_REG; 428 pci_write_config(child, *rid, CARDBUS_ROM_ADDRMASK, 4); 429 break; 430 default: 431 device_printf(cbdev, "Unable to read CIS: Unknown space: %d\n", 432 CARDBUS_CIS_SPACE(*start)); 433 return (NULL); 434 } 435 436 /* figure out how much space we need */ 437 testval = pci_read_config(child, *rid, 4); 438 if (testval & 1) { 439 device_printf(cbdev, "CIS Space is IO, expecting memory.\n"); 440 return (NULL); 441 } 442 size = CARDBUS_MAPREG_MEM_SIZE(testval); 443 if (size < 4096) 444 size = 4096; 445 /* allocate the memory space to read CIS */ 446 res = bus_alloc_resource(cbdev, SYS_RES_MEMORY, rid, 0, ~0, size, 447 rman_make_alignment_flags(size) | RF_ACTIVE); 448 if (res == NULL) { 449 device_printf(cbdev, "Unable to allocate resource " 450 "to read CIS.\n"); 451 return (NULL); 452 } 453 pci_write_config(child, *rid, 454 rman_get_start(res) | ((*rid == CARDBUS_ROM_REG)? 455 CARDBUS_ROM_ENABLE : 0), 456 4); 457 PCI_ENABLE_IO(cbdev, child, SYS_RES_MEMORY); 458 459 /* Flip to the right ROM image if CIS is in ROM */ 460 if (CARDBUS_CIS_SPACE(*start) == CARDBUS_CIS_ASI_ROM) { 461 bus_space_tag_t bt; 462 bus_space_handle_t bh; 463 int imagenum; 464 u_int32_t imagesize; 465 int mystart = 0; 466 int romnum = 0; 467 int dataptr; 468 469 bt = rman_get_bustag(res); 470 bh = rman_get_bushandle(res); 471 472 imagenum = CARDBUS_CIS_ASI_ROM_IMAGE(*start); 473 for (romnum = 0;; romnum++) { 474 if (bus_space_read_2(bt, bh, 475 mystart+CARDBUS_EXROM_SIGNATURE) != 0xaa55) { 476 device_printf(cbdev, "Bad header in rom %d: " 477 "[%x] %04x\n", romnum, mystart + 478 CARDBUS_EXROM_SIGNATURE, 479 bus_space_read_2(bt, bh, 480 mystart+CARDBUS_EXROM_SIGNATURE)); 481 bus_release_resource(cbdev, SYS_RES_MEMORY, 482 *rid, res); 483 *rid = 0; 484 return (NULL); 485 } 486 dataptr = mystart + bus_space_read_2(bt, bh, 487 mystart + CARDBUS_EXROM_DATA_PTR); 488 imagesize = bus_space_read_2(bt, bh, 489 dataptr + CARDBUS_EXROM_DATA_IMAGE_LENGTH); 490 491 if (imagesize == 0) { 492 /* 493 * XXX some ROMs seem to have this as zero, 494 * can we assume this means 1 block? 495 */ 496 imagesize = 1; 497 } 498 imagesize <<= 9; 499 500 if (romnum == imagenum) 501 break; 502 if ((bus_space_read_1(bt, bh, mystart + 503 CARDBUS_EXROM_DATA_INDICATOR) & 0x80) == 0) { 504 device_printf(cbdev, "Cannot read CIS: " 505 "Not enough images of rom\n"); 506 return (NULL); 507 } 508 mystart += imagesize; 509 } 510 *start = mystart + CARDBUS_CIS_ADDR(*start); 511 } else { 512 *start = CARDBUS_CIS_SPACE(*start); 513 } 514 return (res); 515 } 516 517 /* 518 * Dispatch the right handler function per tuple 519 */ 520 521 static int 522 decode_tuple(device_t cbdev, device_t child, int tupleid, int len, 523 u_int8_t *tupledata, u_int32_t start, u_int32_t *off, 524 struct tuple_callbacks *callbacks) 525 { 526 int i; 527 for (i = 0; callbacks[i].id != CISTPL_GENERIC; i++) { 528 if (tupleid == callbacks[i].id) 529 return (callbacks[i].func(cbdev, child, tupleid, len, 530 tupledata, start, off, &callbacks[i])); 531 } 532 533 if (tupleid < CISTPL_CUSTOMSTART) { 534 device_printf(cbdev, "Undefined tuple encountered, " 535 "CIS parsing terminated\n"); 536 return (EINVAL); 537 } 538 return (callbacks[i].func(cbdev, child, tupleid, len, 539 tupledata, start, off, NULL)); 540 } 541 542 static int 543 cardbus_parse_cis(device_t cbdev, device_t child, 544 struct tuple_callbacks *callbacks) 545 { 546 u_int8_t tupledata[MAXTUPLESIZE]; 547 int tupleid; 548 int len; 549 int expect_linktarget; 550 u_int32_t start, off; 551 struct resource *res; 552 int rid; 553 554 bzero(tupledata, MAXTUPLESIZE); 555 expect_linktarget = TRUE; 556 start = pci_read_config(child, CARDBUS_CIS_REG, 4); 557 off = 0; 558 res = cardbus_read_tuple_init(cbdev, child, &start, &rid); 559 if (res == NULL) 560 return (ENXIO); 561 do { 562 if (0 != cardbus_read_tuple(cbdev, child, res, start, &off, 563 &tupleid, &len, tupledata)) { 564 device_printf(cbdev, "Failed to read CIS.\n"); 565 cardbus_read_tuple_finish(cbdev, child, rid, res); 566 return (ENXIO); 567 } 568 569 if (expect_linktarget && tupleid != CISTPL_LINKTARGET) { 570 device_printf(cbdev, "Expecting link target, got 0x%x\n", 571 tupleid); 572 cardbus_read_tuple_finish(cbdev, child, rid, res); 573 return (EINVAL); 574 } 575 expect_linktarget = decode_tuple(cbdev, child, tupleid, len, 576 tupledata, start, &off, callbacks); 577 if (expect_linktarget != 0) { 578 cardbus_read_tuple_finish(cbdev, child, rid, res); 579 return (expect_linktarget); 580 } 581 } while (tupleid != CISTPL_END); 582 cardbus_read_tuple_finish(cbdev, child, rid, res); 583 return (0); 584 } 585 586 static int 587 barsort(const void *a, const void *b) 588 { 589 return ((*(const struct resource_list_entry * const *)b)->count - 590 (*(const struct resource_list_entry * const *)a)->count); 591 } 592 593 static int 594 cardbus_alloc_resources(device_t cbdev, device_t child) 595 { 596 struct cardbus_devinfo *dinfo = device_get_ivars(child); 597 int count; 598 struct resource_list_entry *rle; 599 struct resource_list_entry **barlist; 600 int tmp; 601 u_int32_t mem_psize = 0, mem_nsize = 0, io_size = 0; 602 struct resource *res; 603 u_int32_t start,end; 604 int rid, flags; 605 606 count = 0; 607 SLIST_FOREACH(rle, &dinfo->pci.resources, link) { 608 count++; 609 } 610 if (count == 0) 611 return (0); 612 barlist = malloc(sizeof(struct resource_list_entry*) * count, M_DEVBUF, 613 M_WAITOK); 614 count = 0; 615 SLIST_FOREACH(rle, &dinfo->pci.resources, link) { 616 barlist[count] = rle; 617 if (rle->type == SYS_RES_IOPORT) { 618 io_size += rle->count; 619 } else if (rle->type == SYS_RES_MEMORY) { 620 if (dinfo->mprefetchable & BARBIT(rle->rid)) 621 mem_psize += rle->count; 622 else 623 mem_nsize += rle->count; 624 } 625 count++; 626 } 627 628 /* 629 * We want to allocate the largest resource first, so that our 630 * allocated memory is packed. 631 */ 632 qsort(barlist, count, sizeof(struct resource_list_entry*), barsort); 633 634 /* Allocate prefetchable memory */ 635 flags = 0; 636 for (tmp = 0; tmp < count; tmp++) { 637 if (barlist[tmp]->res == NULL && 638 barlist[tmp]->type == SYS_RES_MEMORY && 639 dinfo->mprefetchable & BARBIT(barlist[tmp]->rid)) { 640 flags = rman_make_alignment_flags(barlist[tmp]->count); 641 break; 642 } 643 } 644 if (flags > 0) { /* If any prefetchable memory is requested... */ 645 /* 646 * First we allocate one big space for all resources of this 647 * type. We do this because our parent, pccbb, needs to open 648 * a window to forward all addresses within the window, and 649 * it would be best if nobody else has resources allocated 650 * within the window. 651 * (XXX: Perhaps there might be a better way to do this?) 652 */ 653 rid = 0; 654 res = bus_alloc_resource(cbdev, SYS_RES_MEMORY, &rid, 0, 655 (dinfo->mprefetchable & dinfo->mbelow1mb)?0xFFFFF:~0UL, 656 mem_psize, flags); 657 start = rman_get_start(res); 658 end = rman_get_end(res); 659 DEVPRINTF((cbdev, "Prefetchable memory at %x-%x\n", start, end)); 660 /* 661 * Now that we know the region is free, release it and hand it 662 * out piece by piece. 663 */ 664 bus_release_resource(cbdev, SYS_RES_MEMORY, rid, res); 665 for (tmp = 0; tmp < count; tmp++) { 666 if (barlist[tmp]->res == NULL && 667 barlist[tmp]->type == SYS_RES_MEMORY && 668 dinfo->mprefetchable & BARBIT(barlist[tmp]->rid)) { 669 barlist[tmp]->res = bus_alloc_resource(cbdev, 670 barlist[tmp]->type, 671 &barlist[tmp]->rid, start, end, 672 barlist[tmp]->count, 673 rman_make_alignment_flags( 674 barlist[tmp]->count)); 675 if (barlist[tmp]->res == NULL) { 676 mem_nsize += barlist[tmp]->count; 677 dinfo->mprefetchable &= 678 ~BARBIT(barlist[tmp]->rid); 679 DEVPRINTF((cbdev, "Cannot pre-allocate " 680 "prefetchable memory, will try as " 681 "non-prefetchable.\n")); 682 } else { 683 barlist[tmp]->start = 684 rman_get_start(barlist[tmp]->res); 685 barlist[tmp]->end = 686 rman_get_end(barlist[tmp]->res); 687 pci_write_config(child, 688 barlist[tmp]->rid, 689 barlist[tmp]->start, 4); 690 DEVPRINTF((cbdev, "Prefetchable memory " 691 "rid=%x at %lx-%lx\n", 692 barlist[tmp]->rid, 693 barlist[tmp]->start, 694 barlist[tmp]->end)); 695 } 696 } 697 } 698 } 699 700 /* Allocate non-prefetchable memory */ 701 flags = 0; 702 for (tmp = 0; tmp < count; tmp++) { 703 if (barlist[tmp]->res == NULL && 704 barlist[tmp]->type == SYS_RES_MEMORY) { 705 flags = rman_make_alignment_flags(barlist[tmp]->count); 706 break; 707 } 708 } 709 if (flags > 0) { /* If any non-prefetchable memory is requested... */ 710 /* 711 * First we allocate one big space for all resources of this 712 * type. We do this because our parent, pccbb, needs to open 713 * a window to forward all addresses within the window, and 714 * it would be best if nobody else has resources allocated 715 * within the window. 716 * (XXX: Perhaps there might be a better way to do this?) 717 */ 718 rid = 0; 719 res = bus_alloc_resource(cbdev, SYS_RES_MEMORY, &rid, 0, 720 ((~dinfo->mprefetchable) & dinfo->mbelow1mb)?0xFFFFF:~0UL, 721 mem_nsize, flags); 722 start = rman_get_start(res); 723 end = rman_get_end(res); 724 DEVPRINTF((cbdev, "Non-prefetchable memory at %x-%x\n", 725 start, end)); 726 /* 727 * Now that we know the region is free, release it and hand it 728 * out piece by piece. 729 */ 730 bus_release_resource(cbdev, SYS_RES_MEMORY, rid, res); 731 for (tmp = 0; tmp < count; tmp++) { 732 if (barlist[tmp]->res == NULL && 733 barlist[tmp]->type == SYS_RES_MEMORY) { 734 barlist[tmp]->res = bus_alloc_resource(cbdev, 735 barlist[tmp]->type, &barlist[tmp]->rid, 736 start, end, barlist[tmp]->count, 737 rman_make_alignment_flags( 738 barlist[tmp]->count)); 739 if (barlist[tmp]->res == NULL) { 740 DEVPRINTF((cbdev, "Cannot pre-allocate " 741 "memory for cardbus device\n")); 742 return (ENOMEM); 743 } 744 barlist[tmp]->start = 745 rman_get_start(barlist[tmp]->res); 746 barlist[tmp]->end = rman_get_end( 747 barlist[tmp]->res); 748 pci_write_config(child, barlist[tmp]->rid, 749 barlist[tmp]->start, 4); 750 DEVPRINTF((cbdev, "Non-prefetchable memory " 751 "rid=%x at %lx-%lx (%lx)\n", 752 barlist[tmp]->rid, barlist[tmp]->start, 753 barlist[tmp]->end, barlist[tmp]->count)); 754 } 755 } 756 } 757 758 /* Allocate IO ports */ 759 flags = 0; 760 for (tmp = 0; tmp < count; tmp++) { 761 if (barlist[tmp]->res == NULL && 762 barlist[tmp]->type == SYS_RES_IOPORT) { 763 flags = rman_make_alignment_flags(barlist[tmp]->count); 764 break; 765 } 766 } 767 if (flags > 0) { /* If any IO port is requested... */ 768 /* 769 * First we allocate one big space for all resources of this 770 * type. We do this because our parent, pccbb, needs to open 771 * a window to forward all addresses within the window, and 772 * it would be best if nobody else has resources allocated 773 * within the window. 774 * (XXX: Perhaps there might be a better way to do this?) 775 */ 776 rid = 0; 777 res = bus_alloc_resource(cbdev, SYS_RES_IOPORT, &rid, 0, 778 (dinfo->ibelow1mb)?0xFFFFF:~0UL, io_size, flags); 779 start = rman_get_start(res); 780 end = rman_get_end(res); 781 DEVPRINTF((cbdev, "IO port at %x-%x\n", start, end)); 782 /* 783 * Now that we know the region is free, release it and hand it 784 * out piece by piece. 785 */ 786 bus_release_resource(cbdev, SYS_RES_IOPORT, rid, res); 787 for (tmp = 0; tmp < count; tmp++) { 788 if (barlist[tmp]->res == NULL && 789 barlist[tmp]->type == SYS_RES_IOPORT) { 790 barlist[tmp]->res = bus_alloc_resource(cbdev, 791 barlist[tmp]->type, &barlist[tmp]->rid, 792 start, end, barlist[tmp]->count, 793 rman_make_alignment_flags( 794 barlist[tmp]->count)); 795 if (barlist[tmp]->res == NULL) { 796 DEVPRINTF((cbdev, "Cannot pre-allocate " 797 "IO port for cardbus device\n")); 798 return (ENOMEM); 799 } 800 barlist[tmp]->start = 801 rman_get_start(barlist[tmp]->res); 802 barlist[tmp]->end = 803 rman_get_end(barlist[tmp]->res); 804 pci_write_config(child, barlist[tmp]->rid, 805 barlist[tmp]->start, 4); 806 DEVPRINTF((cbdev, "IO port rid=%x at %lx-%lx\n", 807 barlist[tmp]->rid, barlist[tmp]->start, 808 barlist[tmp]->end)); 809 } 810 } 811 } 812 813 /* Allocate IRQ */ 814 /* XXX: Search CIS for IRQ description */ 815 rid = 0; 816 res = bus_alloc_resource(cbdev, SYS_RES_IRQ, &rid, 0, ~0UL, 1, 817 RF_SHAREABLE); 818 resource_list_add(&dinfo->pci.resources, SYS_RES_IRQ, rid, 819 rman_get_start(res), rman_get_end(res), 1); 820 rle = resource_list_find(&dinfo->pci.resources, SYS_RES_IRQ, rid); 821 rle->res = res; 822 dinfo->pci.cfg.intline = rman_get_start(res); 823 pci_write_config(child, PCIR_INTLINE, rman_get_start(res), 1); 824 825 return (0); 826 } 827 828 /* 829 * Adding a memory/io resource (sans CIS) 830 */ 831 832 static void 833 cardbus_add_map(device_t cbdev, device_t child, int reg) 834 { 835 struct cardbus_devinfo *dinfo = device_get_ivars(child); 836 struct resource_list_entry *rle; 837 u_int32_t size; 838 u_int32_t testval; 839 int type; 840 841 SLIST_FOREACH(rle, &dinfo->pci.resources, link) { 842 if (rle->rid == reg) 843 return; 844 } 845 846 if (reg == CARDBUS_ROM_REG) 847 testval = CARDBUS_ROM_ADDRMASK; 848 else 849 testval = ~0; 850 851 pci_write_config(child, reg, testval, 4); 852 testval = pci_read_config(child, reg, 4); 853 854 if (testval == ~0 || testval == 0) 855 return; 856 857 if ((testval & 1) == 0) 858 type = SYS_RES_MEMORY; 859 else 860 type = SYS_RES_IOPORT; 861 862 size = CARDBUS_MAPREG_MEM_SIZE(testval); 863 device_printf(cbdev, "Resource not specified in CIS: id=%x, size=%x\n", 864 reg, size); 865 resource_list_add(&dinfo->pci.resources, type, reg, 0UL, ~0UL, size); 866 } 867 868 static void 869 cardbus_pickup_maps(device_t cbdev, device_t child) 870 { 871 struct cardbus_devinfo *dinfo = device_get_ivars(child); 872 struct cardbus_quirk *q; 873 int reg; 874 875 /* 876 * Try to pick up any resources that was not specified in CIS. 877 * Some devices (eg, 3c656) does not list all resources required by 878 * the driver in its CIS. 879 * XXX: should we do this or use quirks? 880 */ 881 for (reg = 0; reg < dinfo->pci.cfg.nummaps; reg++) { 882 cardbus_add_map(cbdev, child, PCIR_MAPS + reg * 4); 883 } 884 885 for (q = &cardbus_quirks[0]; q->devid; q++) { 886 if (q->devid == ((dinfo->pci.cfg.device << 16) | dinfo->pci.cfg.vendor) 887 && q->type == CARDBUS_QUIRK_MAP_REG) { 888 cardbus_add_map(cbdev, child, q->arg1); 889 } 890 } 891 } 892 893 int 894 cardbus_cis_read(device_t cbdev, device_t child, u_int8_t id, 895 struct cis_tupleinfo **buff, int *nret) 896 { 897 struct tuple_callbacks cisread_callbacks[] = { 898 MAKETUPLE(NULL, nothing), 899 /* first entry will be overwritten */ 900 MAKETUPLE(NULL, nothing), 901 MAKETUPLE(DEVICE, nothing), 902 MAKETUPLE(LONG_LINK_CB, unhandled), 903 MAKETUPLE(INDIRECT, unhandled), 904 MAKETUPLE(CONFIG_CB, nothing), 905 MAKETUPLE(CFTABLE_ENTRY_CB, nothing), 906 MAKETUPLE(LONGLINK_MFC, unhandled), 907 MAKETUPLE(BAR, nothing), 908 MAKETUPLE(PWR_MGMNT, nothing), 909 MAKETUPLE(EXTDEVICE, nothing), 910 MAKETUPLE(CHECKSUM, nothing), 911 MAKETUPLE(LONGLINK_A, unhandled), 912 MAKETUPLE(LONGLINK_C, unhandled), 913 MAKETUPLE(LINKTARGET, nothing), 914 MAKETUPLE(NO_LINK, nothing), 915 MAKETUPLE(VERS_1, nothing), 916 MAKETUPLE(ALTSTR, nothing), 917 MAKETUPLE(DEVICE_A, nothing), 918 MAKETUPLE(JEDEC_C, nothing), 919 MAKETUPLE(JEDEC_A, nothing), 920 MAKETUPLE(CONFIG, nothing), 921 MAKETUPLE(CFTABLE_ENTRY, nothing), 922 MAKETUPLE(DEVICE_OC, nothing), 923 MAKETUPLE(DEVICE_OA, nothing), 924 MAKETUPLE(DEVICE_GEO, nothing), 925 MAKETUPLE(DEVICE_GEO_A, nothing), 926 MAKETUPLE(MANFID, nothing), 927 MAKETUPLE(FUNCID, nothing), 928 MAKETUPLE(FUNCE, nothing), 929 MAKETUPLE(SWIL, nothing), 930 MAKETUPLE(VERS_2, nothing), 931 MAKETUPLE(FORMAT, nothing), 932 MAKETUPLE(GEOMETRY, nothing), 933 MAKETUPLE(BYTEORDER, nothing), 934 MAKETUPLE(DATE, nothing), 935 MAKETUPLE(BATTERY, nothing), 936 MAKETUPLE(ORG, nothing), 937 MAKETUPLE(END, end), 938 MAKETUPLE(GENERIC, nothing), 939 }; 940 int ret; 941 942 cisread_callbacks[0].id = id; 943 cisread_callbacks[0].name = "COPY"; 944 cisread_callbacks[0].func = decode_tuple_copy; 945 ncisread_buf = 0; 946 cisread_buf = NULL; 947 ret = cardbus_parse_cis(cbdev, child, cisread_callbacks); 948 949 *buff = cisread_buf; 950 *nret = ncisread_buf; 951 return (ret); 952 } 953 954 void 955 cardbus_cis_free(device_t cbdev, struct cis_tupleinfo *buff, int *nret) 956 { 957 int i; 958 for (i = 0; i < *nret; i++) 959 free(buff[i].data, M_DEVBUF); 960 if (*nret > 0) 961 free(buff, M_DEVBUF); 962 } 963 964 int 965 cardbus_do_cis(device_t cbdev, device_t child) 966 { 967 int ret; 968 struct tuple_callbacks init_callbacks[] = { 969 MAKETUPLE(NULL, generic), 970 MAKETUPLE(DEVICE, generic), 971 MAKETUPLE(LONG_LINK_CB, unhandled), 972 MAKETUPLE(INDIRECT, unhandled), 973 MAKETUPLE(CONFIG_CB, generic), 974 MAKETUPLE(CFTABLE_ENTRY_CB, generic), 975 MAKETUPLE(LONGLINK_MFC, unhandled), 976 MAKETUPLE(BAR, bar), 977 MAKETUPLE(PWR_MGMNT, generic), 978 MAKETUPLE(EXTDEVICE, generic), 979 MAKETUPLE(CHECKSUM, generic), 980 MAKETUPLE(LONGLINK_A, unhandled), 981 MAKETUPLE(LONGLINK_C, unhandled), 982 MAKETUPLE(LINKTARGET, linktarget), 983 MAKETUPLE(NO_LINK, generic), 984 MAKETUPLE(VERS_1, vers_1), 985 MAKETUPLE(ALTSTR, generic), 986 MAKETUPLE(DEVICE_A, generic), 987 MAKETUPLE(JEDEC_C, generic), 988 MAKETUPLE(JEDEC_A, generic), 989 MAKETUPLE(CONFIG, generic), 990 MAKETUPLE(CFTABLE_ENTRY, generic), 991 MAKETUPLE(DEVICE_OC, generic), 992 MAKETUPLE(DEVICE_OA, generic), 993 MAKETUPLE(DEVICE_GEO, generic), 994 MAKETUPLE(DEVICE_GEO_A, generic), 995 MAKETUPLE(MANFID, manfid), 996 MAKETUPLE(FUNCID, funcid), 997 MAKETUPLE(FUNCE, funce), 998 MAKETUPLE(SWIL, generic), 999 MAKETUPLE(VERS_2, generic), 1000 MAKETUPLE(FORMAT, generic), 1001 MAKETUPLE(GEOMETRY, generic), 1002 MAKETUPLE(BYTEORDER, generic), 1003 MAKETUPLE(DATE, generic), 1004 MAKETUPLE(BATTERY, generic), 1005 MAKETUPLE(ORG, generic), 1006 MAKETUPLE(END, end), 1007 MAKETUPLE(GENERIC, generic), 1008 }; 1009 1010 ret = cardbus_parse_cis(cbdev, child, init_callbacks); 1011 if (ret < 0) 1012 return (ret); 1013 cardbus_pickup_maps(cbdev, child); 1014 return (cardbus_alloc_resources(cbdev, child)); 1015 } 1016