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