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