1 /* $NetBSD: pcmcia_cis.c,v 1.28 2001/11/15 09:48:12 lukem Exp $ */ 2 3 /* 4 * Copyright (c) 1997 Marc Horowitz. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed by Marc Horowitz. 17 * 4. The name of the author may not be used to endorse or promote products 18 * derived from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #include <sys/cdefs.h> 33 __KERNEL_RCSID(0, "$NetBSD: pcmcia_cis.c,v 1.28 2001/11/15 09:48:12 lukem Exp $"); 34 35 #include <sys/param.h> 36 #include <sys/systm.h> 37 #include <sys/device.h> 38 #include <sys/malloc.h> 39 40 #include <dev/pcmcia/pcmciareg.h> 41 #include <dev/pcmcia/pcmciachip.h> 42 #include <dev/pcmcia/pcmciavar.h> 43 44 #ifdef PCMCIACISDEBUG 45 int pcmciacis_debug = 0; 46 #define DPRINTF(arg) if (pcmciacis_debug) printf arg 47 #else 48 #define DPRINTF(arg) 49 #endif 50 51 #define PCMCIA_CIS_SIZE 1024 52 53 struct cis_state { 54 int count; 55 int gotmfc; 56 struct pcmcia_config_entry temp_cfe; 57 struct pcmcia_config_entry *default_cfe; 58 struct pcmcia_card *card; 59 struct pcmcia_function *pf; 60 }; 61 62 int pcmcia_parse_cis_tuple __P((struct pcmcia_tuple *, void *)); 63 static int decode_funce __P((struct pcmcia_tuple *, struct pcmcia_function *)); 64 65 66 void 67 pcmcia_read_cis(sc) 68 struct pcmcia_softc *sc; 69 { 70 struct cis_state state; 71 72 memset(&state, 0, sizeof state); 73 74 state.card = &sc->card; 75 76 state.card->error = 0; 77 state.card->cis1_major = -1; 78 state.card->cis1_minor = -1; 79 state.card->cis1_info[0] = NULL; 80 state.card->cis1_info[1] = NULL; 81 state.card->cis1_info[2] = NULL; 82 state.card->cis1_info[3] = NULL; 83 state.card->manufacturer = PCMCIA_VENDOR_INVALID; 84 state.card->product = PCMCIA_PRODUCT_INVALID; 85 SIMPLEQ_INIT(&state.card->pf_head); 86 87 state.pf = NULL; 88 89 if (pcmcia_scan_cis((struct device *)sc, pcmcia_parse_cis_tuple, 90 &state) == -1) 91 state.card->error++; 92 } 93 94 int 95 pcmcia_scan_cis(dev, fct, arg) 96 struct device *dev; 97 int (*fct) __P((struct pcmcia_tuple *, void *)); 98 void *arg; 99 { 100 struct pcmcia_softc *sc = (struct pcmcia_softc *) dev; 101 pcmcia_chipset_tag_t pct; 102 pcmcia_chipset_handle_t pch; 103 int window; 104 struct pcmcia_mem_handle pcmh; 105 struct pcmcia_tuple tuple; 106 int longlink_present; 107 int longlink_common; 108 u_long longlink_addr; 109 int mfc_count; 110 int mfc_index; 111 struct { 112 int common; 113 u_long addr; 114 } mfc[256 / 5]; 115 int ret; 116 117 ret = 0; 118 119 pct = sc->pct; 120 pch = sc->pch; 121 122 /* allocate some memory */ 123 124 if (pcmcia_chip_mem_alloc(pct, pch, PCMCIA_CIS_SIZE, &pcmh)) { 125 #ifdef DIAGNOSTIC 126 printf("%s: can't alloc memory to read attributes\n", 127 sc->dev.dv_xname); 128 #endif 129 return -1; 130 } 131 /* initialize state for the primary tuple chain */ 132 if (pcmcia_chip_mem_map(pct, pch, PCMCIA_MEM_ATTR, 0, 133 PCMCIA_CIS_SIZE, &pcmh, &tuple.ptr, &window)) { 134 pcmcia_chip_mem_free(pct, pch, &pcmh); 135 #ifdef DIAGNOSTIC 136 printf("%s: can't map memory to read attributes\n", 137 sc->dev.dv_xname); 138 #endif 139 return -1; 140 } 141 tuple.memt = pcmh.memt; 142 tuple.memh = pcmh.memh; 143 144 DPRINTF(("cis mem map %x\n", (unsigned int) tuple.memh)); 145 146 tuple.mult = 2; 147 148 longlink_present = 1; 149 longlink_common = 1; 150 longlink_addr = 0; 151 152 mfc_count = 0; 153 mfc_index = 0; 154 155 DPRINTF(("%s: CIS tuple chain:\n", sc->dev.dv_xname)); 156 157 while (1) { 158 while (1) { 159 /* 160 * Perform boundary check for insane cards. 161 * If CIS is too long, simulate CIS end. 162 * (This check may not be sufficient for 163 * malicious cards.) 164 */ 165 if (tuple.mult * tuple.ptr >= PCMCIA_CIS_SIZE - 1 166 - 32 /* ad hoc value */ ) { 167 DPRINTF(("CISTPL_END (too long CIS)\n")); 168 tuple.code = PCMCIA_CISTPL_END; 169 goto cis_end; 170 } 171 172 /* get the tuple code */ 173 174 DELAY(1000); 175 tuple.code = pcmcia_cis_read_1(&tuple, tuple.ptr); 176 177 /* two special-case tuples */ 178 179 if (tuple.code == PCMCIA_CISTPL_NULL) { 180 DPRINTF(("CISTPL_NONE\n 00\n")); 181 tuple.ptr++; 182 continue; 183 } else if (tuple.code == PCMCIA_CISTPL_END) { 184 DPRINTF(("CISTPL_END\n ff\n")); 185 cis_end: 186 /* Call the function for the END tuple, since 187 the CIS semantics depend on it */ 188 if ((*fct) (&tuple, arg)) { 189 pcmcia_chip_mem_unmap(pct, pch, 190 window); 191 ret = 1; 192 goto done; 193 } 194 tuple.ptr++; 195 break; 196 } 197 /* now all the normal tuples */ 198 199 DELAY(1250); 200 tuple.length = pcmcia_cis_read_1(&tuple, tuple.ptr + 1); 201 switch (tuple.code) { 202 case PCMCIA_CISTPL_LONGLINK_A: 203 case PCMCIA_CISTPL_LONGLINK_C: 204 if (tuple.length < 4) { 205 DPRINTF(("CISTPL_LONGLINK_%s too " 206 "short %d\n", 207 longlink_common ? "C" : "A", 208 tuple.length)); 209 break; 210 } 211 longlink_present = 1; 212 longlink_common = (tuple.code == 213 PCMCIA_CISTPL_LONGLINK_C) ? 1 : 0; 214 longlink_addr = pcmcia_tuple_read_4(&tuple, 0); 215 DPRINTF(("CISTPL_LONGLINK_%s %lx\n", 216 longlink_common ? "C" : "A", 217 longlink_addr)); 218 break; 219 case PCMCIA_CISTPL_NO_LINK: 220 longlink_present = 0; 221 DPRINTF(("CISTPL_NO_LINK\n")); 222 break; 223 case PCMCIA_CISTPL_CHECKSUM: 224 if (tuple.length < 5) { 225 DPRINTF(("CISTPL_CHECKSUM too " 226 "short %d\n", tuple.length)); 227 break; 228 } { 229 int16_t offset; 230 u_long addr, length; 231 u_int cksum, sum; 232 int i; 233 234 *((u_int16_t *) & offset) = 235 pcmcia_tuple_read_2(&tuple, 0); 236 DELAY(500); 237 length = pcmcia_tuple_read_2(&tuple, 2); 238 DELAY(500); 239 cksum = pcmcia_tuple_read_1(&tuple, 4); 240 241 addr = tuple.ptr + offset; 242 243 DPRINTF(("CISTPL_CHECKSUM addr=%lx " 244 "len=%lx cksum=%x", 245 addr, length, cksum)); 246 247 /* 248 * XXX do more work to deal with 249 * distant regions 250 */ 251 if ((addr >= PCMCIA_CIS_SIZE) || 252 ((addr + length) < 0) || 253 ((addr + length) >= 254 PCMCIA_CIS_SIZE)) { 255 DPRINTF((" skipped, " 256 "too distant\n")); 257 break; 258 } 259 sum = 0; 260 for (i = 0; i < length; i++) 261 sum += 262 bus_space_read_1(tuple.memt, 263 tuple.memh, 264 addr + tuple.mult * i); 265 if (cksum != (sum & 0xff)) { 266 DPRINTF((" failed sum=%x\n", 267 sum)); 268 printf("%s: CIS checksum " 269 "failed\n", 270 sc->dev.dv_xname); 271 #if 0 272 /* 273 * XXX Some working cards have 274 * XXX bad checksums!! 275 */ 276 ret = -1; 277 #endif 278 } else { 279 DPRINTF((" ok\n")); 280 } 281 } 282 break; 283 case PCMCIA_CISTPL_LONGLINK_MFC: 284 if (tuple.length < 1) { 285 DPRINTF(("CISTPL_LONGLINK_MFC too " 286 "short %d\n", tuple.length)); 287 break; 288 } 289 if (((tuple.length - 1) % 5) != 0) { 290 DPRINTF(("CISTPL_LONGLINK_MFC bogus " 291 "length %d\n", tuple.length)); 292 break; 293 } 294 /* 295 * this is kind of ad hoc, as I don't have 296 * any real documentation 297 */ 298 { 299 int i, tmp_count; 300 301 /* 302 * put count into tmp var so that 303 * if we have to bail (because it's 304 * a bogus count) it won't be 305 * remembered for later use. 306 */ 307 tmp_count = 308 pcmcia_tuple_read_1(&tuple, 0); 309 DPRINTF(("CISTPL_LONGLINK_MFC %d", 310 tmp_count)); 311 312 /* 313 * make _sure_ it's the right size; 314 * if too short, it may be a weird 315 * (unknown/undefined) format 316 */ 317 if (tuple.length != (tmp_count*5 + 1)) { 318 DPRINTF((" bogus length %d\n", 319 tuple.length)); 320 break; 321 } 322 323 #ifdef PCMCIACISDEBUG /* maybe enable all the time? */ 324 /* 325 * sanity check for a programming 326 * error which is difficult to find 327 * when debugging. 328 */ 329 if (tmp_count > 330 howmany(sizeof mfc, sizeof mfc[0])) 331 panic("CISTPL_LONGLINK_MFC mfc " 332 "count would blow stack"); 333 #endif 334 335 mfc_count = tmp_count; 336 for (i = 0; i < mfc_count; i++) { 337 mfc[i].common = 338 (pcmcia_tuple_read_1(&tuple, 339 1 + 5 * i) == 340 PCMCIA_MFC_MEM_COMMON) ? 341 1 : 0; 342 mfc[i].addr = 343 pcmcia_tuple_read_4(&tuple, 344 1 + 5 * i + 1); 345 DPRINTF((" %s:%lx", 346 mfc[i].common ? "common" : 347 "attr", mfc[i].addr)); 348 } 349 DPRINTF(("\n")); 350 } 351 /* 352 * for LONGLINK_MFC, fall through to the 353 * function. This tuple has structural and 354 * semantic content. 355 */ 356 default: 357 { 358 if ((*fct) (&tuple, arg)) { 359 pcmcia_chip_mem_unmap(pct, 360 pch, window); 361 ret = 1; 362 goto done; 363 } 364 } 365 break; 366 } /* switch */ 367 #ifdef PCMCIACISDEBUG 368 /* print the tuple */ 369 { 370 int i; 371 372 DPRINTF((" %02x %02x", tuple.code, 373 tuple.length)); 374 375 for (i = 0; i < tuple.length; i++) { 376 DPRINTF((" %02x", 377 pcmcia_tuple_read_1(&tuple, i))); 378 if ((i % 16) == 13) 379 DPRINTF(("\n")); 380 } 381 if ((i % 16) != 14) 382 DPRINTF(("\n")); 383 } 384 #endif 385 /* skip to the next tuple */ 386 tuple.ptr += 2 + tuple.length; 387 } 388 389 /* 390 * the chain is done. Clean up and move onto the next one, 391 * if any. The loop is here in the case that there is an MFC 392 * card with no longlink (which defaults to existing, == 0). 393 * In general, this means that if one pointer fails, it will 394 * try the next one, instead of just bailing. 395 */ 396 397 while (1) { 398 pcmcia_chip_mem_unmap(pct, pch, window); 399 400 if (longlink_present) { 401 /* 402 * if the longlink is to attribute memory, 403 * then it is unindexed. That is, if the 404 * link value is 0x100, then the actual 405 * memory address is 0x200. This means that 406 * we need to multiply by 2 before calling 407 * mem_map, and then divide the resulting ptr 408 * by 2 after. 409 */ 410 411 if (!longlink_common) 412 longlink_addr *= 2; 413 414 pcmcia_chip_mem_map(pct, pch, longlink_common ? 415 (PCMCIA_WIDTH_MEM8 | PCMCIA_MEM_COMMON) : 416 PCMCIA_MEM_ATTR, 417 longlink_addr, PCMCIA_CIS_SIZE, 418 &pcmh, &tuple.ptr, &window); 419 420 if (!longlink_common) 421 tuple.ptr /= 2; 422 423 DPRINTF(("cis mem map %x\n", 424 (unsigned int) tuple.memh)); 425 426 tuple.mult = longlink_common ? 1 : 2; 427 longlink_present = 0; 428 longlink_common = 1; 429 longlink_addr = 0; 430 } else if (mfc_count && (mfc_index < mfc_count)) { 431 if (!mfc[mfc_index].common) 432 mfc[mfc_index].addr *= 2; 433 434 pcmcia_chip_mem_map(pct, pch, 435 mfc[mfc_index].common ? 436 (PCMCIA_WIDTH_MEM8 | PCMCIA_MEM_COMMON) : 437 PCMCIA_MEM_ATTR, 438 mfc[mfc_index].addr, PCMCIA_CIS_SIZE, 439 &pcmh, &tuple.ptr, &window); 440 441 if (!mfc[mfc_index].common) 442 tuple.ptr /= 2; 443 444 DPRINTF(("cis mem map %x\n", 445 (unsigned int) tuple.memh)); 446 447 /* set parse state, and point at the next one */ 448 449 tuple.mult = mfc[mfc_index].common ? 1 : 2; 450 451 mfc_index++; 452 } else { 453 goto done; 454 } 455 456 /* make sure that the link is valid */ 457 tuple.code = pcmcia_cis_read_1(&tuple, tuple.ptr); 458 if (tuple.code != PCMCIA_CISTPL_LINKTARGET) { 459 DPRINTF(("CISTPL_LINKTARGET expected, " 460 "code %02x observed\n", tuple.code)); 461 continue; 462 } 463 tuple.length = pcmcia_cis_read_1(&tuple, tuple.ptr + 1); 464 if (tuple.length < 3) { 465 DPRINTF(("CISTPL_LINKTARGET too short %d\n", 466 tuple.length)); 467 continue; 468 } 469 if ((pcmcia_tuple_read_1(&tuple, 0) != 'C') || 470 (pcmcia_tuple_read_1(&tuple, 1) != 'I') || 471 (pcmcia_tuple_read_1(&tuple, 2) != 'S')) { 472 DPRINTF(("CISTPL_LINKTARGET magic " 473 "%02x%02x%02x incorrect\n", 474 pcmcia_tuple_read_1(&tuple, 0), 475 pcmcia_tuple_read_1(&tuple, 1), 476 pcmcia_tuple_read_1(&tuple, 2))); 477 continue; 478 } 479 tuple.ptr += 2 + tuple.length; 480 481 break; 482 } 483 } 484 485 pcmcia_chip_mem_unmap(pct, pch, window); 486 487 done: 488 /* Last, free the allocated memory block */ 489 pcmcia_chip_mem_free(pct, pch, &pcmh); 490 491 return (ret); 492 } 493 494 /* XXX this is incredibly verbose. Not sure what trt is */ 495 496 void 497 pcmcia_print_cis(sc) 498 struct pcmcia_softc *sc; 499 { 500 struct pcmcia_card *card = &sc->card; 501 struct pcmcia_function *pf; 502 struct pcmcia_config_entry *cfe; 503 int i; 504 505 printf("%s: CIS version ", sc->dev.dv_xname); 506 if (card->cis1_major == 4) { 507 if (card->cis1_minor == 0) 508 printf("PCMCIA 1.0\n"); 509 else if (card->cis1_minor == 1) 510 printf("PCMCIA 2.0 or 2.1\n"); 511 } else if (card->cis1_major >= 5) 512 printf("PC Card Standard %d.%d\n", card->cis1_major, card->cis1_minor); 513 else 514 printf("unknown (major=%d, minor=%d)\n", 515 card->cis1_major, card->cis1_minor); 516 517 printf("%s: CIS info: ", sc->dev.dv_xname); 518 for (i = 0; i < 4; i++) { 519 if (card->cis1_info[i] == NULL) 520 break; 521 if (i) 522 printf(", "); 523 printf("%s", card->cis1_info[i]); 524 } 525 printf("\n"); 526 527 printf("%s: Manufacturer code 0x%x, product 0x%x\n", 528 sc->dev.dv_xname, card->manufacturer, card->product); 529 530 for (pf = card->pf_head.sqh_first; pf != NULL; 531 pf = pf->pf_list.sqe_next) { 532 printf("%s: function %d: ", sc->dev.dv_xname, pf->number); 533 534 switch (pf->function) { 535 case PCMCIA_FUNCTION_UNSPEC: 536 printf("unspecified"); 537 break; 538 case PCMCIA_FUNCTION_MULTIFUNCTION: 539 printf("multi-function"); 540 break; 541 case PCMCIA_FUNCTION_MEMORY: 542 printf("memory"); 543 break; 544 case PCMCIA_FUNCTION_SERIAL: 545 printf("serial port"); 546 break; 547 case PCMCIA_FUNCTION_PARALLEL: 548 printf("parallel port"); 549 break; 550 case PCMCIA_FUNCTION_DISK: 551 printf("fixed disk"); 552 switch (pf->pf_funce_disk_interface) { 553 case PCMCIA_TPLFE_DDI_PCCARD_ATA: 554 printf("(ata)"); 555 break; 556 default: 557 break; 558 } 559 break; 560 case PCMCIA_FUNCTION_VIDEO: 561 printf("video adapter"); 562 break; 563 case PCMCIA_FUNCTION_NETWORK: 564 printf("network adapter"); 565 break; 566 case PCMCIA_FUNCTION_AIMS: 567 printf("auto incrementing mass storage"); 568 break; 569 case PCMCIA_FUNCTION_SCSI: 570 printf("SCSI bridge"); 571 break; 572 case PCMCIA_FUNCTION_SECURITY: 573 printf("Security services"); 574 break; 575 case PCMCIA_FUNCTION_INSTRUMENT: 576 printf("Instrument"); 577 break; 578 default: 579 printf("unknown (%d)", pf->function); 580 break; 581 } 582 583 printf(", ccr addr %lx mask %lx\n", pf->ccr_base, pf->ccr_mask); 584 585 for (cfe = pf->cfe_head.sqh_first; cfe != NULL; 586 cfe = cfe->cfe_list.sqe_next) { 587 printf("%s: function %d, config table entry %d: ", 588 sc->dev.dv_xname, pf->number, cfe->number); 589 590 switch (cfe->iftype) { 591 case PCMCIA_IFTYPE_MEMORY: 592 printf("memory card"); 593 break; 594 case PCMCIA_IFTYPE_IO: 595 printf("I/O card"); 596 break; 597 default: 598 printf("card type unknown"); 599 break; 600 } 601 602 printf("; irq mask %x", cfe->irqmask); 603 604 if (cfe->num_iospace) { 605 printf("; iomask %lx, iospace", cfe->iomask); 606 607 for (i = 0; i < cfe->num_iospace; i++) { 608 printf(" %lx", cfe->iospace[i].start); 609 if (cfe->iospace[i].length) 610 printf("-%lx", 611 cfe->iospace[i].start + 612 cfe->iospace[i].length - 1); 613 } 614 } 615 if (cfe->num_memspace) { 616 printf("; memspace"); 617 618 for (i = 0; i < cfe->num_memspace; i++) { 619 printf(" %lx", 620 cfe->memspace[i].cardaddr); 621 if (cfe->memspace[i].length) 622 printf("-%lx", 623 cfe->memspace[i].cardaddr + 624 cfe->memspace[i].length - 1); 625 if (cfe->memspace[i].hostaddr) 626 printf("@%lx", 627 cfe->memspace[i].hostaddr); 628 } 629 } 630 if (cfe->maxtwins) 631 printf("; maxtwins %d", cfe->maxtwins); 632 633 printf(";"); 634 635 if (cfe->flags & PCMCIA_CFE_MWAIT_REQUIRED) 636 printf(" mwait_required"); 637 if (cfe->flags & PCMCIA_CFE_RDYBSY_ACTIVE) 638 printf(" rdybsy_active"); 639 if (cfe->flags & PCMCIA_CFE_WP_ACTIVE) 640 printf(" wp_active"); 641 if (cfe->flags & PCMCIA_CFE_BVD_ACTIVE) 642 printf(" bvd_active"); 643 if (cfe->flags & PCMCIA_CFE_IO8) 644 printf(" io8"); 645 if (cfe->flags & PCMCIA_CFE_IO16) 646 printf(" io16"); 647 if (cfe->flags & PCMCIA_CFE_IRQSHARE) 648 printf(" irqshare"); 649 if (cfe->flags & PCMCIA_CFE_IRQPULSE) 650 printf(" irqpulse"); 651 if (cfe->flags & PCMCIA_CFE_IRQLEVEL) 652 printf(" irqlevel"); 653 if (cfe->flags & PCMCIA_CFE_POWERDOWN) 654 printf(" powerdown"); 655 if (cfe->flags & PCMCIA_CFE_READONLY) 656 printf(" readonly"); 657 if (cfe->flags & PCMCIA_CFE_AUDIO) 658 printf(" audio"); 659 660 printf("\n"); 661 } 662 } 663 664 if (card->error) 665 printf("%s: %d errors found while parsing CIS\n", 666 sc->dev.dv_xname, card->error); 667 } 668 669 int 670 pcmcia_parse_cis_tuple(tuple, arg) 671 struct pcmcia_tuple *tuple; 672 void *arg; 673 { 674 /* most of these are educated guesses */ 675 static struct pcmcia_config_entry init_cfe = { 676 -1, PCMCIA_CFE_RDYBSY_ACTIVE | PCMCIA_CFE_WP_ACTIVE | 677 PCMCIA_CFE_BVD_ACTIVE, PCMCIA_IFTYPE_MEMORY, 678 }; 679 680 struct cis_state *state = arg; 681 682 switch (tuple->code) { 683 case PCMCIA_CISTPL_END: 684 /* if we've seen a LONGLINK_MFC, and this is the first 685 * END after it, reset the function list. 686 * 687 * XXX This might also be the right place to start a 688 * new function, but that assumes that a function 689 * definition never crosses any longlink, and I'm not 690 * sure about that. This is probably safe for MFC 691 * cards, but what we have now isn't broken, so I'd 692 * rather not change it. 693 */ 694 if (state->gotmfc == 1) { 695 struct pcmcia_function *pf, *pfnext; 696 697 for (pf = state->card->pf_head.sqh_first; pf != NULL; 698 pf = pfnext) { 699 pfnext = pf->pf_list.sqe_next; 700 free(pf, M_DEVBUF); 701 } 702 703 SIMPLEQ_INIT(&state->card->pf_head); 704 705 state->count = 0; 706 state->gotmfc = 2; 707 state->pf = NULL; 708 } 709 break; 710 case PCMCIA_CISTPL_LONGLINK_MFC: 711 /* 712 * this tuple's structure was dealt with in scan_cis. here, 713 * record the fact that the MFC tuple was seen, so that 714 * functions declared before the MFC link can be cleaned 715 * up. 716 */ 717 state->gotmfc = 1; 718 break; 719 #ifdef PCMCIACISDEBUG 720 case PCMCIA_CISTPL_DEVICE: 721 case PCMCIA_CISTPL_DEVICE_A: 722 { 723 u_int reg, dtype, dspeed; 724 725 reg = pcmcia_tuple_read_1(tuple, 0); 726 dtype = reg & PCMCIA_DTYPE_MASK; 727 dspeed = reg & PCMCIA_DSPEED_MASK; 728 729 DPRINTF(("CISTPL_DEVICE%s type=", 730 (tuple->code == PCMCIA_CISTPL_DEVICE) ? "" : "_A")); 731 switch (dtype) { 732 case PCMCIA_DTYPE_NULL: 733 DPRINTF(("null")); 734 break; 735 case PCMCIA_DTYPE_ROM: 736 DPRINTF(("rom")); 737 break; 738 case PCMCIA_DTYPE_OTPROM: 739 DPRINTF(("otprom")); 740 break; 741 case PCMCIA_DTYPE_EPROM: 742 DPRINTF(("eprom")); 743 break; 744 case PCMCIA_DTYPE_EEPROM: 745 DPRINTF(("eeprom")); 746 break; 747 case PCMCIA_DTYPE_FLASH: 748 DPRINTF(("flash")); 749 break; 750 case PCMCIA_DTYPE_SRAM: 751 DPRINTF(("sram")); 752 break; 753 case PCMCIA_DTYPE_DRAM: 754 DPRINTF(("dram")); 755 break; 756 case PCMCIA_DTYPE_FUNCSPEC: 757 DPRINTF(("funcspec")); 758 break; 759 case PCMCIA_DTYPE_EXTEND: 760 DPRINTF(("extend")); 761 break; 762 default: 763 DPRINTF(("reserved")); 764 break; 765 } 766 DPRINTF((" speed=")); 767 switch (dspeed) { 768 case PCMCIA_DSPEED_NULL: 769 DPRINTF(("null")); 770 break; 771 case PCMCIA_DSPEED_250NS: 772 DPRINTF(("250ns")); 773 break; 774 case PCMCIA_DSPEED_200NS: 775 DPRINTF(("200ns")); 776 break; 777 case PCMCIA_DSPEED_150NS: 778 DPRINTF(("150ns")); 779 break; 780 case PCMCIA_DSPEED_100NS: 781 DPRINTF(("100ns")); 782 break; 783 case PCMCIA_DSPEED_EXT: 784 DPRINTF(("ext")); 785 break; 786 default: 787 DPRINTF(("reserved")); 788 break; 789 } 790 } 791 DPRINTF(("\n")); 792 break; 793 #endif 794 case PCMCIA_CISTPL_VERS_1: 795 if (tuple->length < 6) { 796 DPRINTF(("CISTPL_VERS_1 too short %d\n", 797 tuple->length)); 798 break; 799 } { 800 int start, i, ch, count; 801 802 state->card->cis1_major = pcmcia_tuple_read_1(tuple, 0); 803 state->card->cis1_minor = pcmcia_tuple_read_1(tuple, 1); 804 805 for (count = 0, start = 0, i = 0; 806 (count < 4) && ((i + 4) < 256); i++) { 807 ch = pcmcia_tuple_read_1(tuple, 2 + i); 808 if (ch == 0xff) { 809 if (i > start) { 810 state->card->cis1_info_buf[i] = 0; 811 state->card->cis1_info[count] = 812 state->card->cis1_info_buf + start; 813 } 814 break; 815 } 816 state->card->cis1_info_buf[i] = ch; 817 if (ch == 0) { 818 state->card->cis1_info[count] = 819 state->card->cis1_info_buf + start; 820 start = i + 1; 821 count++; 822 } 823 } 824 DPRINTF(("CISTPL_VERS_1\n")); 825 } 826 break; 827 case PCMCIA_CISTPL_MANFID: 828 if (tuple->length < 4) { 829 DPRINTF(("CISTPL_MANFID too short %d\n", 830 tuple->length)); 831 break; 832 } 833 state->card->manufacturer = pcmcia_tuple_read_2(tuple, 0); 834 state->card->product = pcmcia_tuple_read_2(tuple, 2); 835 DPRINTF(("CISTPL_MANFID\n")); 836 break; 837 case PCMCIA_CISTPL_FUNCID: 838 if (tuple->length < 1) { 839 DPRINTF(("CISTPL_FUNCID too short %d\n", 840 tuple->length)); 841 break; 842 } 843 if (state->pf) { 844 if (state->pf->function == PCMCIA_FUNCTION_UNSPEC) { 845 /* 846 * This looks like a opportunistic function 847 * created by a CONFIG tuple. Just keep it. 848 */ 849 } else { 850 /* 851 * A function is being defined, end it. 852 */ 853 state->pf = NULL; 854 } 855 } 856 if (state->pf == NULL) { 857 state->pf = malloc(sizeof(*state->pf), M_DEVBUF, 858 M_NOWAIT); 859 memset(state->pf, 0, sizeof(*state->pf)); 860 state->pf->number = state->count++; 861 state->pf->last_config_index = -1; 862 SIMPLEQ_INIT(&state->pf->cfe_head); 863 864 SIMPLEQ_INSERT_TAIL(&state->card->pf_head, state->pf, 865 pf_list); 866 } 867 state->pf->function = pcmcia_tuple_read_1(tuple, 0); 868 869 DPRINTF(("CISTPL_FUNCID\n")); 870 break; 871 case PCMCIA_CISTPL_FUNCE: 872 if (state->pf == NULL || state->pf->function <= 0) { 873 DPRINTF(("CISTPL_FUNCE is not followed by " 874 "valid CISTPL_FUNCID\n")); 875 break; 876 } 877 if (tuple->length >= 2) { 878 decode_funce(tuple, state->pf); 879 } 880 break; 881 case PCMCIA_CISTPL_CONFIG: 882 if (tuple->length < 3) { 883 DPRINTF(("CISTPL_CONFIG too short %d\n", 884 tuple->length)); 885 break; 886 } { 887 u_int reg, rasz, rmsz, rfsz; 888 int i; 889 890 reg = pcmcia_tuple_read_1(tuple, 0); 891 rasz = 1 + ((reg & PCMCIA_TPCC_RASZ_MASK) >> 892 PCMCIA_TPCC_RASZ_SHIFT); 893 rmsz = 1 + ((reg & PCMCIA_TPCC_RMSZ_MASK) >> 894 PCMCIA_TPCC_RMSZ_SHIFT); 895 rfsz = ((reg & PCMCIA_TPCC_RFSZ_MASK) >> 896 PCMCIA_TPCC_RFSZ_SHIFT); 897 898 if (tuple->length < (rasz + rmsz + rfsz)) { 899 DPRINTF(("CISTPL_CONFIG (%d,%d,%d) too " 900 "short %d\n", rasz, rmsz, rfsz, 901 tuple->length)); 902 break; 903 } 904 if (state->pf == NULL) { 905 state->pf = malloc(sizeof(*state->pf), 906 M_DEVBUF, M_NOWAIT); 907 memset(state->pf, 0, sizeof(*state->pf)); 908 state->pf->number = state->count++; 909 state->pf->last_config_index = -1; 910 SIMPLEQ_INIT(&state->pf->cfe_head); 911 912 SIMPLEQ_INSERT_TAIL(&state->card->pf_head, 913 state->pf, pf_list); 914 915 state->pf->function = PCMCIA_FUNCTION_UNSPEC; 916 } 917 state->pf->last_config_index = 918 pcmcia_tuple_read_1(tuple, 1); 919 920 state->pf->ccr_base = 0; 921 for (i = 0; i < rasz; i++) 922 state->pf->ccr_base |= 923 ((pcmcia_tuple_read_1(tuple, 2 + i)) << 924 (i * 8)); 925 926 state->pf->ccr_mask = 0; 927 for (i = 0; i < rmsz; i++) 928 state->pf->ccr_mask |= 929 ((pcmcia_tuple_read_1(tuple, 930 2 + rasz + i)) << (i * 8)); 931 932 /* skip the reserved area and subtuples */ 933 934 /* reset the default cfe for each cfe list */ 935 state->temp_cfe = init_cfe; 936 state->default_cfe = &state->temp_cfe; 937 } 938 DPRINTF(("CISTPL_CONFIG\n")); 939 break; 940 case PCMCIA_CISTPL_CFTABLE_ENTRY: 941 { 942 int idx, i, j; 943 u_int reg, reg2; 944 u_int intface, def, num; 945 u_int power, timing, iospace, irq, memspace, misc; 946 struct pcmcia_config_entry *cfe; 947 948 idx = 0; 949 950 reg = pcmcia_tuple_read_1(tuple, idx); 951 idx++; 952 intface = reg & PCMCIA_TPCE_INDX_INTFACE; 953 def = reg & PCMCIA_TPCE_INDX_DEFAULT; 954 num = reg & PCMCIA_TPCE_INDX_NUM_MASK; 955 956 /* 957 * this is a little messy. Some cards have only a 958 * cfentry with the default bit set. So, as we go 959 * through the list, we add new indexes to the queue, 960 * and keep a pointer to the last one with the 961 * default bit set. if we see a record with the same 962 * index, as the default, we stash the default and 963 * replace the queue entry. otherwise, we just add 964 * new entries to the queue, pointing the default ptr 965 * at them if the default bit is set. if we get to 966 * the end with the default pointer pointing at a 967 * record which hasn't had a matching index, that's 968 * ok; it just becomes a cfentry like any other. 969 */ 970 971 /* 972 * if the index in the cis differs from the default 973 * cis, create new entry in the queue and start it 974 * with the current default 975 */ 976 if (state->default_cfe == NULL) { 977 DPRINTF(("CISTPL_CFTABLE_ENTRY with no " 978 "default\n")); 979 break; 980 } 981 if (num != state->default_cfe->number) { 982 cfe = (struct pcmcia_config_entry *) 983 malloc(sizeof(*cfe), M_DEVBUF, M_NOWAIT); 984 985 *cfe = *state->default_cfe; 986 987 SIMPLEQ_INSERT_TAIL(&state->pf->cfe_head, 988 cfe, cfe_list); 989 990 cfe->number = num; 991 992 /* 993 * if the default bit is set in the cis, then 994 * point the new default at whatever is being 995 * filled in 996 */ 997 if (def) 998 state->default_cfe = cfe; 999 } else { 1000 /* 1001 * the cis index matches the default index, 1002 * fill in the default cfentry. It is 1003 * assumed that the cfdefault index is in the 1004 * queue. For it to be otherwise, the cis 1005 * index would have to be -1 (initial 1006 * condition) which is not possible, or there 1007 * would have to be a preceding cis entry 1008 * which had the same cis index and had the 1009 * default bit unset. Neither condition 1010 * should happen. If it does, this cfentry 1011 * is lost (written into temp space), which 1012 * is an acceptable failure mode. 1013 */ 1014 1015 cfe = state->default_cfe; 1016 1017 /* 1018 * if the cis entry does not have the default 1019 * bit set, copy the default out of the way 1020 * first. 1021 */ 1022 if (!def) { 1023 state->temp_cfe = *state->default_cfe; 1024 state->default_cfe = &state->temp_cfe; 1025 } 1026 } 1027 1028 if (intface) { 1029 reg = pcmcia_tuple_read_1(tuple, idx); 1030 idx++; 1031 cfe->flags &= ~(PCMCIA_CFE_MWAIT_REQUIRED 1032 | PCMCIA_CFE_RDYBSY_ACTIVE 1033 | PCMCIA_CFE_WP_ACTIVE 1034 | PCMCIA_CFE_BVD_ACTIVE); 1035 if (reg & PCMCIA_TPCE_IF_MWAIT) 1036 cfe->flags |= PCMCIA_CFE_MWAIT_REQUIRED; 1037 if (reg & PCMCIA_TPCE_IF_RDYBSY) 1038 cfe->flags |= PCMCIA_CFE_RDYBSY_ACTIVE; 1039 if (reg & PCMCIA_TPCE_IF_WP) 1040 cfe->flags |= PCMCIA_CFE_WP_ACTIVE; 1041 if (reg & PCMCIA_TPCE_IF_BVD) 1042 cfe->flags |= PCMCIA_CFE_BVD_ACTIVE; 1043 cfe->iftype = reg & PCMCIA_TPCE_IF_IFTYPE; 1044 } 1045 reg = pcmcia_tuple_read_1(tuple, idx); 1046 idx++; 1047 1048 power = reg & PCMCIA_TPCE_FS_POWER_MASK; 1049 timing = reg & PCMCIA_TPCE_FS_TIMING; 1050 iospace = reg & PCMCIA_TPCE_FS_IOSPACE; 1051 irq = reg & PCMCIA_TPCE_FS_IRQ; 1052 memspace = reg & PCMCIA_TPCE_FS_MEMSPACE_MASK; 1053 misc = reg & PCMCIA_TPCE_FS_MISC; 1054 1055 if (power) { 1056 /* skip over power, don't save */ 1057 /* for each parameter selection byte */ 1058 for (i = 0; i < power; i++) { 1059 reg = pcmcia_tuple_read_1(tuple, idx); 1060 idx++; 1061 /* for each bit */ 1062 for (j = 0; j < 7; j++) { 1063 /* if the bit is set */ 1064 if ((reg >> j) & 0x01) { 1065 /* skip over bytes */ 1066 do { 1067 reg2 = pcmcia_tuple_read_1(tuple, idx); 1068 idx++; 1069 /* 1070 * until 1071 * non-extensi 1072 * on byte 1073 */ 1074 } while (reg2 & 0x80); 1075 } 1076 } 1077 } 1078 } 1079 if (timing) { 1080 /* skip over timing, don't save */ 1081 reg = pcmcia_tuple_read_1(tuple, idx); 1082 idx++; 1083 1084 if ((reg & PCMCIA_TPCE_TD_RESERVED_MASK) != 1085 PCMCIA_TPCE_TD_RESERVED_MASK) 1086 idx++; 1087 if ((reg & PCMCIA_TPCE_TD_RDYBSY_MASK) != 1088 PCMCIA_TPCE_TD_RDYBSY_MASK) 1089 idx++; 1090 if ((reg & PCMCIA_TPCE_TD_WAIT_MASK) != 1091 PCMCIA_TPCE_TD_WAIT_MASK) 1092 idx++; 1093 } 1094 if (iospace) { 1095 if (tuple->length <= idx) { 1096 DPRINTF(("ran out of space before TCPE_IO\n")); 1097 goto abort_cfe; 1098 } 1099 1100 reg = pcmcia_tuple_read_1(tuple, idx); 1101 idx++; 1102 1103 cfe->flags &= 1104 ~(PCMCIA_CFE_IO8 | PCMCIA_CFE_IO16); 1105 if (reg & PCMCIA_TPCE_IO_BUSWIDTH_8BIT) 1106 cfe->flags |= PCMCIA_CFE_IO8; 1107 if (reg & PCMCIA_TPCE_IO_BUSWIDTH_16BIT) 1108 cfe->flags |= PCMCIA_CFE_IO16; 1109 cfe->iomask = 1110 reg & PCMCIA_TPCE_IO_IOADDRLINES_MASK; 1111 1112 if (reg & PCMCIA_TPCE_IO_HASRANGE) { 1113 reg = pcmcia_tuple_read_1(tuple, idx); 1114 idx++; 1115 1116 cfe->num_iospace = 1 + (reg & 1117 PCMCIA_TPCE_IO_RANGE_COUNT); 1118 1119 if (cfe->num_iospace > 1120 (sizeof(cfe->iospace) / 1121 sizeof(cfe->iospace[0]))) { 1122 DPRINTF(("too many io " 1123 "spaces %d", 1124 cfe->num_iospace)); 1125 state->card->error++; 1126 break; 1127 } 1128 for (i = 0; i < cfe->num_iospace; i++) { 1129 switch (reg & PCMCIA_TPCE_IO_RANGE_ADDRSIZE_MASK) { 1130 case PCMCIA_TPCE_IO_RANGE_ADDRSIZE_ONE: 1131 cfe->iospace[i].start = 1132 pcmcia_tuple_read_1(tuple, idx); 1133 idx++; 1134 break; 1135 case PCMCIA_TPCE_IO_RANGE_ADDRSIZE_TWO: 1136 cfe->iospace[i].start = 1137 pcmcia_tuple_read_2(tuple, idx); 1138 idx += 2; 1139 break; 1140 case PCMCIA_TPCE_IO_RANGE_ADDRSIZE_FOUR: 1141 cfe->iospace[i].start = 1142 pcmcia_tuple_read_4(tuple, idx); 1143 idx += 4; 1144 break; 1145 } 1146 switch (reg & 1147 PCMCIA_TPCE_IO_RANGE_LENGTHSIZE_MASK) { 1148 case PCMCIA_TPCE_IO_RANGE_LENGTHSIZE_ONE: 1149 cfe->iospace[i].length = 1150 pcmcia_tuple_read_1(tuple, idx); 1151 idx++; 1152 break; 1153 case PCMCIA_TPCE_IO_RANGE_LENGTHSIZE_TWO: 1154 cfe->iospace[i].length = 1155 pcmcia_tuple_read_2(tuple, idx); 1156 idx += 2; 1157 break; 1158 case PCMCIA_TPCE_IO_RANGE_LENGTHSIZE_FOUR: 1159 cfe->iospace[i].length = 1160 pcmcia_tuple_read_4(tuple, idx); 1161 idx += 4; 1162 break; 1163 } 1164 cfe->iospace[i].length++; 1165 } 1166 } else { 1167 cfe->num_iospace = 1; 1168 cfe->iospace[0].start = 0; 1169 cfe->iospace[0].length = 1170 (1 << cfe->iomask); 1171 } 1172 } 1173 if (irq) { 1174 if (tuple->length <= idx) { 1175 DPRINTF(("ran out of space before TCPE_IR\n")); 1176 goto abort_cfe; 1177 } 1178 1179 reg = pcmcia_tuple_read_1(tuple, idx); 1180 idx++; 1181 1182 cfe->flags &= ~(PCMCIA_CFE_IRQSHARE 1183 | PCMCIA_CFE_IRQPULSE 1184 | PCMCIA_CFE_IRQLEVEL); 1185 if (reg & PCMCIA_TPCE_IR_SHARE) 1186 cfe->flags |= PCMCIA_CFE_IRQSHARE; 1187 if (reg & PCMCIA_TPCE_IR_PULSE) 1188 cfe->flags |= PCMCIA_CFE_IRQPULSE; 1189 if (reg & PCMCIA_TPCE_IR_LEVEL) 1190 cfe->flags |= PCMCIA_CFE_IRQLEVEL; 1191 1192 if (reg & PCMCIA_TPCE_IR_HASMASK) { 1193 /* 1194 * it's legal to ignore the 1195 * special-interrupt bits, so I will 1196 */ 1197 1198 cfe->irqmask = 1199 pcmcia_tuple_read_2(tuple, idx); 1200 idx += 2; 1201 } else { 1202 cfe->irqmask = 1203 (1 << (reg & PCMCIA_TPCE_IR_IRQ)); 1204 } 1205 } 1206 if (memspace) { 1207 if (tuple->length <= idx) { 1208 DPRINTF(("ran out of space before TCPE_MS\n")); 1209 goto abort_cfe; 1210 } 1211 1212 if (memspace == PCMCIA_TPCE_FS_MEMSPACE_NONE) { 1213 cfe->num_memspace = 0; 1214 } else if (memspace == PCMCIA_TPCE_FS_MEMSPACE_LENGTH) { 1215 cfe->num_memspace = 1; 1216 cfe->memspace[0].length = 256 * 1217 pcmcia_tuple_read_2(tuple, idx); 1218 idx += 2; 1219 cfe->memspace[0].cardaddr = 0; 1220 cfe->memspace[0].hostaddr = 0; 1221 } else if (memspace == 1222 PCMCIA_TPCE_FS_MEMSPACE_LENGTHADDR) { 1223 cfe->num_memspace = 1; 1224 cfe->memspace[0].length = 256 * 1225 pcmcia_tuple_read_2(tuple, idx); 1226 idx += 2; 1227 cfe->memspace[0].cardaddr = 256 * 1228 pcmcia_tuple_read_2(tuple, idx); 1229 idx += 2; 1230 cfe->memspace[0].hostaddr = cfe->memspace[0].cardaddr; 1231 } else { 1232 int lengthsize; 1233 int cardaddrsize; 1234 int hostaddrsize; 1235 1236 reg = pcmcia_tuple_read_1(tuple, idx); 1237 idx++; 1238 1239 cfe->num_memspace = (reg & 1240 PCMCIA_TPCE_MS_COUNT) + 1; 1241 1242 if (cfe->num_memspace > 1243 (sizeof(cfe->memspace) / 1244 sizeof(cfe->memspace[0]))) { 1245 DPRINTF(("too many mem " 1246 "spaces %d", 1247 cfe->num_memspace)); 1248 state->card->error++; 1249 break; 1250 } 1251 lengthsize = 1252 ((reg & PCMCIA_TPCE_MS_LENGTH_SIZE_MASK) >> 1253 PCMCIA_TPCE_MS_LENGTH_SIZE_SHIFT); 1254 cardaddrsize = 1255 ((reg & PCMCIA_TPCE_MS_CARDADDR_SIZE_MASK) >> 1256 PCMCIA_TPCE_MS_CARDADDR_SIZE_SHIFT); 1257 hostaddrsize = 1258 (reg & PCMCIA_TPCE_MS_HOSTADDR) ? cardaddrsize : 0; 1259 1260 if (lengthsize == 0) { 1261 DPRINTF(("cfe memspace " 1262 "lengthsize == 0")); 1263 state->card->error++; 1264 } 1265 for (i = 0; i < cfe->num_memspace; i++) { 1266 if (lengthsize) { 1267 cfe->memspace[i].length = 1268 256 * pcmcia_tuple_read_n(tuple, lengthsize, 1269 idx); 1270 idx += lengthsize; 1271 } else { 1272 cfe->memspace[i].length = 0; 1273 } 1274 if (cfe->memspace[i].length == 0) { 1275 DPRINTF(("cfe->memspace[%d].length == 0", 1276 i)); 1277 state->card->error++; 1278 } 1279 if (cardaddrsize) { 1280 cfe->memspace[i].cardaddr = 1281 256 * pcmcia_tuple_read_n(tuple, cardaddrsize, 1282 idx); 1283 idx += cardaddrsize; 1284 } else { 1285 cfe->memspace[i].cardaddr = 0; 1286 } 1287 if (hostaddrsize) { 1288 cfe->memspace[i].hostaddr = 1289 256 * pcmcia_tuple_read_n(tuple, hostaddrsize, 1290 idx); 1291 idx += hostaddrsize; 1292 } else { 1293 cfe->memspace[i].hostaddr = 0; 1294 } 1295 } 1296 } 1297 } 1298 if (misc) { 1299 if (tuple->length <= idx) { 1300 DPRINTF(("ran out of space before TCPE_MI\n")); 1301 goto abort_cfe; 1302 } 1303 1304 reg = pcmcia_tuple_read_1(tuple, idx); 1305 idx++; 1306 1307 cfe->flags &= ~(PCMCIA_CFE_POWERDOWN 1308 | PCMCIA_CFE_READONLY 1309 | PCMCIA_CFE_AUDIO); 1310 if (reg & PCMCIA_TPCE_MI_PWRDOWN) 1311 cfe->flags |= PCMCIA_CFE_POWERDOWN; 1312 if (reg & PCMCIA_TPCE_MI_READONLY) 1313 cfe->flags |= PCMCIA_CFE_READONLY; 1314 if (reg & PCMCIA_TPCE_MI_AUDIO) 1315 cfe->flags |= PCMCIA_CFE_AUDIO; 1316 cfe->maxtwins = reg & PCMCIA_TPCE_MI_MAXTWINS; 1317 1318 while (reg & PCMCIA_TPCE_MI_EXT) { 1319 reg = pcmcia_tuple_read_1(tuple, idx); 1320 idx++; 1321 } 1322 } 1323 /* skip all the subtuples */ 1324 } 1325 1326 abort_cfe: 1327 DPRINTF(("CISTPL_CFTABLE_ENTRY\n")); 1328 break; 1329 default: 1330 DPRINTF(("unhandled CISTPL %x\n", tuple->code)); 1331 break; 1332 } 1333 1334 return (0); 1335 } 1336 1337 1338 1339 static int 1340 decode_funce(tuple, pf) 1341 struct pcmcia_tuple *tuple; 1342 struct pcmcia_function *pf; 1343 { 1344 int type = pcmcia_tuple_read_1(tuple, 0); 1345 1346 switch (pf->function) { 1347 case PCMCIA_FUNCTION_DISK: 1348 if (type == PCMCIA_TPLFE_TYPE_DISK_DEVICE_INTERFACE) { 1349 pf->pf_funce_disk_interface 1350 = pcmcia_tuple_read_1(tuple, 1); 1351 } 1352 break; 1353 case PCMCIA_FUNCTION_NETWORK: 1354 if (type == PCMCIA_TPLFE_TYPE_LAN_NID) { 1355 int i; 1356 int len = pcmcia_tuple_read_1(tuple, 1); 1357 if (tuple->length < 2 + len || len > 8) { 1358 /* tuple length not enough or nid too long */ 1359 break; 1360 } 1361 for (i = 0; i < len; ++i) { 1362 pf->pf_funce_lan_nid[i] 1363 = pcmcia_tuple_read_1(tuple, 2 + i); 1364 } 1365 pf->pf_funce_lan_nidlen = len; 1366 } 1367 break; 1368 default: 1369 break; 1370 } 1371 1372 return 0; 1373 } 1374