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