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 free(barlist, M_DEVBUF); 743 return (ENOMEM); 744 } 745 barlist[tmp]->start = 746 rman_get_start(barlist[tmp]->res); 747 barlist[tmp]->end = rman_get_end( 748 barlist[tmp]->res); 749 pci_write_config(child, barlist[tmp]->rid, 750 barlist[tmp]->start, 4); 751 DEVPRINTF((cbdev, "Non-prefetchable memory " 752 "rid=%x at %lx-%lx (%lx)\n", 753 barlist[tmp]->rid, barlist[tmp]->start, 754 barlist[tmp]->end, barlist[tmp]->count)); 755 } 756 } 757 } 758 759 /* Allocate IO ports */ 760 flags = 0; 761 for (tmp = 0; tmp < count; tmp++) { 762 if (barlist[tmp]->res == NULL && 763 barlist[tmp]->type == SYS_RES_IOPORT) { 764 flags = rman_make_alignment_flags(barlist[tmp]->count); 765 break; 766 } 767 } 768 if (flags > 0) { /* If any IO port is requested... */ 769 /* 770 * First we allocate one big space for all resources of this 771 * type. We do this because our parent, pccbb, needs to open 772 * a window to forward all addresses within the window, and 773 * it would be best if nobody else has resources allocated 774 * within the window. 775 * (XXX: Perhaps there might be a better way to do this?) 776 */ 777 rid = 0; 778 res = bus_alloc_resource(cbdev, SYS_RES_IOPORT, &rid, 0, 779 (dinfo->ibelow1mb)?0xFFFFF:~0UL, io_size, flags); 780 start = rman_get_start(res); 781 end = rman_get_end(res); 782 DEVPRINTF((cbdev, "IO port at %x-%x\n", start, end)); 783 /* 784 * Now that we know the region is free, release it and hand it 785 * out piece by piece. 786 */ 787 bus_release_resource(cbdev, SYS_RES_IOPORT, rid, res); 788 for (tmp = 0; tmp < count; tmp++) { 789 if (barlist[tmp]->res == NULL && 790 barlist[tmp]->type == SYS_RES_IOPORT) { 791 barlist[tmp]->res = bus_alloc_resource(cbdev, 792 barlist[tmp]->type, &barlist[tmp]->rid, 793 start, end, barlist[tmp]->count, 794 rman_make_alignment_flags( 795 barlist[tmp]->count)); 796 if (barlist[tmp]->res == NULL) { 797 DEVPRINTF((cbdev, "Cannot pre-allocate " 798 "IO port for cardbus device\n")); 799 free(barlist, M_DEVBUF); 800 return (ENOMEM); 801 } 802 barlist[tmp]->start = 803 rman_get_start(barlist[tmp]->res); 804 barlist[tmp]->end = 805 rman_get_end(barlist[tmp]->res); 806 pci_write_config(child, barlist[tmp]->rid, 807 barlist[tmp]->start, 4); 808 DEVPRINTF((cbdev, "IO port rid=%x at %lx-%lx\n", 809 barlist[tmp]->rid, barlist[tmp]->start, 810 barlist[tmp]->end)); 811 } 812 } 813 } 814 815 /* Allocate IRQ */ 816 rid = 0; 817 res = bus_alloc_resource(cbdev, SYS_RES_IRQ, &rid, 0, ~0UL, 1, 818 RF_SHAREABLE); 819 resource_list_add(&dinfo->pci.resources, SYS_RES_IRQ, rid, 820 rman_get_start(res), rman_get_end(res), 1); 821 rle = resource_list_find(&dinfo->pci.resources, SYS_RES_IRQ, rid); 822 rle->res = res; 823 dinfo->pci.cfg.intline = rman_get_start(res); 824 pci_write_config(child, PCIR_INTLINE, rman_get_start(res), 1); 825 826 free(barlist, M_DEVBUF); 827 return (0); 828 } 829 830 /* 831 * Adding a memory/io resource (sans CIS) 832 */ 833 834 static void 835 cardbus_add_map(device_t cbdev, device_t child, int reg) 836 { 837 struct cardbus_devinfo *dinfo = device_get_ivars(child); 838 struct resource_list_entry *rle; 839 u_int32_t size; 840 u_int32_t testval; 841 int type; 842 843 SLIST_FOREACH(rle, &dinfo->pci.resources, link) { 844 if (rle->rid == reg) 845 return; 846 } 847 848 if (reg == CARDBUS_ROM_REG) 849 testval = CARDBUS_ROM_ADDRMASK; 850 else 851 testval = ~0; 852 853 pci_write_config(child, reg, testval, 4); 854 testval = pci_read_config(child, reg, 4); 855 856 if (testval == ~0 || testval == 0) 857 return; 858 859 if ((testval & 1) == 0) 860 type = SYS_RES_MEMORY; 861 else 862 type = SYS_RES_IOPORT; 863 864 size = CARDBUS_MAPREG_MEM_SIZE(testval); 865 device_printf(cbdev, "Resource not specified in CIS: id=%x, size=%x\n", 866 reg, size); 867 resource_list_add(&dinfo->pci.resources, type, reg, 0UL, ~0UL, size); 868 } 869 870 static void 871 cardbus_pickup_maps(device_t cbdev, device_t child) 872 { 873 struct cardbus_devinfo *dinfo = device_get_ivars(child); 874 struct cardbus_quirk *q; 875 int reg; 876 877 /* 878 * Try to pick up any resources that was not specified in CIS. 879 * Some devices (eg, 3c656) does not list all resources required by 880 * the driver in its CIS. 881 * XXX: should we do this or use quirks? 882 */ 883 for (reg = 0; reg < dinfo->pci.cfg.nummaps; reg++) { 884 cardbus_add_map(cbdev, child, PCIR_MAPS + reg * 4); 885 } 886 887 for (q = &cardbus_quirks[0]; q->devid; q++) { 888 if (q->devid == ((dinfo->pci.cfg.device << 16) | dinfo->pci.cfg.vendor) 889 && q->type == CARDBUS_QUIRK_MAP_REG) { 890 cardbus_add_map(cbdev, child, q->arg1); 891 } 892 } 893 } 894 895 int 896 cardbus_cis_read(device_t cbdev, device_t child, u_int8_t id, 897 struct cis_tupleinfo **buff, int *nret) 898 { 899 struct tuple_callbacks cisread_callbacks[] = { 900 MAKETUPLE(NULL, nothing), 901 /* first entry will be overwritten */ 902 MAKETUPLE(NULL, nothing), 903 MAKETUPLE(DEVICE, nothing), 904 MAKETUPLE(LONG_LINK_CB, unhandled), 905 MAKETUPLE(INDIRECT, unhandled), 906 MAKETUPLE(CONFIG_CB, nothing), 907 MAKETUPLE(CFTABLE_ENTRY_CB, nothing), 908 MAKETUPLE(LONGLINK_MFC, unhandled), 909 MAKETUPLE(BAR, nothing), 910 MAKETUPLE(PWR_MGMNT, nothing), 911 MAKETUPLE(EXTDEVICE, nothing), 912 MAKETUPLE(CHECKSUM, nothing), 913 MAKETUPLE(LONGLINK_A, unhandled), 914 MAKETUPLE(LONGLINK_C, unhandled), 915 MAKETUPLE(LINKTARGET, nothing), 916 MAKETUPLE(NO_LINK, nothing), 917 MAKETUPLE(VERS_1, nothing), 918 MAKETUPLE(ALTSTR, nothing), 919 MAKETUPLE(DEVICE_A, nothing), 920 MAKETUPLE(JEDEC_C, nothing), 921 MAKETUPLE(JEDEC_A, nothing), 922 MAKETUPLE(CONFIG, nothing), 923 MAKETUPLE(CFTABLE_ENTRY, nothing), 924 MAKETUPLE(DEVICE_OC, nothing), 925 MAKETUPLE(DEVICE_OA, nothing), 926 MAKETUPLE(DEVICE_GEO, nothing), 927 MAKETUPLE(DEVICE_GEO_A, nothing), 928 MAKETUPLE(MANFID, nothing), 929 MAKETUPLE(FUNCID, nothing), 930 MAKETUPLE(FUNCE, nothing), 931 MAKETUPLE(SWIL, nothing), 932 MAKETUPLE(VERS_2, nothing), 933 MAKETUPLE(FORMAT, nothing), 934 MAKETUPLE(GEOMETRY, nothing), 935 MAKETUPLE(BYTEORDER, nothing), 936 MAKETUPLE(DATE, nothing), 937 MAKETUPLE(BATTERY, nothing), 938 MAKETUPLE(ORG, nothing), 939 MAKETUPLE(END, end), 940 MAKETUPLE(GENERIC, nothing), 941 }; 942 int ret; 943 944 cisread_callbacks[0].id = id; 945 cisread_callbacks[0].name = "COPY"; 946 cisread_callbacks[0].func = decode_tuple_copy; 947 ncisread_buf = 0; 948 cisread_buf = NULL; 949 ret = cardbus_parse_cis(cbdev, child, cisread_callbacks); 950 951 *buff = cisread_buf; 952 *nret = ncisread_buf; 953 return (ret); 954 } 955 956 void 957 cardbus_cis_free(device_t cbdev, struct cis_tupleinfo *buff, int *nret) 958 { 959 int i; 960 for (i = 0; i < *nret; i++) 961 free(buff[i].data, M_DEVBUF); 962 if (*nret > 0) 963 free(buff, M_DEVBUF); 964 } 965 966 int 967 cardbus_do_cis(device_t cbdev, device_t child) 968 { 969 int ret; 970 struct tuple_callbacks init_callbacks[] = { 971 MAKETUPLE(NULL, generic), 972 MAKETUPLE(DEVICE, generic), 973 MAKETUPLE(LONG_LINK_CB, unhandled), 974 MAKETUPLE(INDIRECT, unhandled), 975 MAKETUPLE(CONFIG_CB, generic), 976 MAKETUPLE(CFTABLE_ENTRY_CB, generic), 977 MAKETUPLE(LONGLINK_MFC, unhandled), 978 MAKETUPLE(BAR, bar), 979 MAKETUPLE(PWR_MGMNT, generic), 980 MAKETUPLE(EXTDEVICE, generic), 981 MAKETUPLE(CHECKSUM, generic), 982 MAKETUPLE(LONGLINK_A, unhandled), 983 MAKETUPLE(LONGLINK_C, unhandled), 984 MAKETUPLE(LINKTARGET, linktarget), 985 MAKETUPLE(NO_LINK, generic), 986 MAKETUPLE(VERS_1, vers_1), 987 MAKETUPLE(ALTSTR, generic), 988 MAKETUPLE(DEVICE_A, generic), 989 MAKETUPLE(JEDEC_C, generic), 990 MAKETUPLE(JEDEC_A, generic), 991 MAKETUPLE(CONFIG, generic), 992 MAKETUPLE(CFTABLE_ENTRY, generic), 993 MAKETUPLE(DEVICE_OC, generic), 994 MAKETUPLE(DEVICE_OA, generic), 995 MAKETUPLE(DEVICE_GEO, generic), 996 MAKETUPLE(DEVICE_GEO_A, generic), 997 MAKETUPLE(MANFID, manfid), 998 MAKETUPLE(FUNCID, funcid), 999 MAKETUPLE(FUNCE, funce), 1000 MAKETUPLE(SWIL, generic), 1001 MAKETUPLE(VERS_2, generic), 1002 MAKETUPLE(FORMAT, generic), 1003 MAKETUPLE(GEOMETRY, generic), 1004 MAKETUPLE(BYTEORDER, generic), 1005 MAKETUPLE(DATE, generic), 1006 MAKETUPLE(BATTERY, generic), 1007 MAKETUPLE(ORG, generic), 1008 MAKETUPLE(END, end), 1009 MAKETUPLE(GENERIC, generic), 1010 }; 1011 1012 ret = cardbus_parse_cis(cbdev, child, init_callbacks); 1013 if (ret < 0) 1014 return (ret); 1015 cardbus_pickup_maps(cbdev, child); 1016 return (cardbus_alloc_resources(cbdev, child)); 1017 } 1018