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/pccardvarp.h> 49#include <dev/pccard/pccard_cis.h> 50 51#include "card_if.h" 52 53extern int pccard_cis_debug; 54 55#define PCCARDCISDEBUG 56#ifdef PCCARDCISDEBUG 57#define DPRINTF(arg) do { if (pccard_cis_debug) printf arg; } while (0) 58#define DEVPRINTF(arg) do { if (pccard_cis_debug) device_printf arg; } while (0) 59#else 60#define DPRINTF(arg) 61#define DEVPRINTF(arg) 62#endif 63 64#define PCCARD_CIS_SIZE 4096 65 66struct cis_state { 67 int count; 68 int gotmfc; 69 struct pccard_config_entry temp_cfe; 70 struct pccard_config_entry *default_cfe; 71 struct pccard_card *card; 72 struct pccard_function *pf; 73}; 74 75static int pccard_parse_cis_tuple(const struct pccard_tuple *, void *); 76static int decode_funce(const struct pccard_tuple *, struct pccard_function *); 77 78void 79pccard_read_cis(struct pccard_softc *sc) 80{ 81 struct cis_state state; 82 83 bzero(&state, sizeof state); 84 state.card = &sc->card; 85 state.card->error = 0; 86 state.card->cis1_major = -1; 87 state.card->cis1_minor = -1; 88 state.card->cis1_info[0] = NULL; 89 state.card->cis1_info[1] = NULL; 90 state.card->cis1_info[2] = NULL; 91 state.card->cis1_info[3] = NULL; 92 state.card->manufacturer = PCMCIA_VENDOR_INVALID; 93 state.card->product = PCMCIA_PRODUCT_INVALID; 94 STAILQ_INIT(&state.card->pf_head); 95 state.pf = NULL; 96 97 /* 98 * XXX The following shouldn't be needed, but some slow cards 99 * XXX seem to need it still. Need to investigate if there's 100 * XXX a way to tell if the card is 'ready' or not rather than 101 * XXX sleeping like this. We're called just after the power 102 * XXX up of the socket. The standard timing diagrams don't 103 * XXX seem to indicate that a delay is required. The old 104 * XXX delay was 1s. This delay is .1s. 105 */ 106 pause("pccard", hz / 10); 107 if (pccard_scan_cis(device_get_parent(sc->dev), sc->dev, 108 pccard_parse_cis_tuple, &state) == -1) 109 state.card->error++; 110} 111 112int 113pccard_scan_cis(device_t bus, device_t dev, pccard_scan_t fct, void *arg) 114{ 115 struct resource *res; 116 int rid; 117 struct pccard_tuple tuple; 118 int longlink_present; 119 int longlink_common; 120 u_long longlink_addr; /* Type suspect */ 121 int mfc_count; 122 int mfc_index; 123#ifdef PCCARDCISDEBUG 124 int cis_none_cnt = 10; /* Only report 10 CIS_NONEs */ 125#endif 126 struct { 127 int common; 128 u_long addr; 129 } mfc[256 / 5]; 130 int ret; 131 132 ret = 0; 133 134 /* allocate some memory */ 135 136 /* 137 * Some reports from the field suggest that a 64k memory boundary 138 * helps card CIS being able to be read. Try it here and see what 139 * the results actually are. I'm not sure I understand why this 140 * would make cards work better, but it is easy enough to test. 141 */ 142 rid = 0; 143 res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, 0, ~0, 144 PCCARD_CIS_SIZE, RF_ACTIVE | rman_make_alignment_flags(64*1024)); 145 if (res == NULL) { 146 device_printf(dev, "can't alloc memory to read attributes\n"); 147 return -1; 148 } 149 CARD_SET_RES_FLAGS(bus, dev, SYS_RES_MEMORY, rid, PCCARD_A_MEM_ATTR); 150 tuple.memt = rman_get_bustag(res); 151 tuple.memh = rman_get_bushandle(res); 152 tuple.ptr = 0; 153 154 DPRINTF(("cis mem map 0x%x (resource: 0x%lx)\n", 155 (unsigned int) tuple.memh, rman_get_start(res))); 156 157 tuple.mult = 2; 158 159 longlink_present = 1; 160 longlink_common = 1; 161 longlink_addr = 0; 162 163 mfc_count = 0; 164 mfc_index = 0; 165 166 DEVPRINTF((dev, "CIS tuple chain:\n")); 167 168 while (1) { 169 while (1) { 170 /* 171 * Perform boundary check for insane cards. 172 * If CIS is too long, simulate CIS end. 173 * (This check may not be sufficient for 174 * malicious cards.) 175 */ 176 if (tuple.mult * tuple.ptr >= PCCARD_CIS_SIZE - 1 177 - 32 /* ad hoc value */ ) { 178 printf("CIS is too long -- truncating\n"); 179 tuple.code = CISTPL_END; 180 } else { 181 /* get the tuple code */ 182 tuple.code = pccard_cis_read_1(&tuple, tuple.ptr); 183 } 184 185 /* two special-case tuples */ 186 187 if (tuple.code == CISTPL_NULL) { 188#ifdef PCCARDCISDEBUG 189 if (cis_none_cnt > 0) 190 DPRINTF(("CISTPL_NONE\n 00\n")); 191 else if (cis_none_cnt == 0) 192 DPRINTF(("TOO MANY CIS_NONE\n")); 193 cis_none_cnt--; 194#endif 195 if ((*fct)(&tuple, arg)) { 196 ret = 1; 197 goto done; 198 } 199 tuple.ptr++; 200 continue; 201 } else if (tuple.code == CISTPL_END) { 202 DPRINTF(("CISTPL_END\n ff\n")); 203 /* Call the function for the END tuple, since 204 the CIS semantics depend on it */ 205 if ((*fct)(&tuple, arg)) { 206 ret = 1; 207 goto done; 208 } 209 tuple.ptr++; 210 break; 211 } 212 /* now all the normal tuples */ 213 214 tuple.length = pccard_cis_read_1(&tuple, tuple.ptr + 1); 215 switch (tuple.code) { 216 case CISTPL_LONGLINK_A: 217 case CISTPL_LONGLINK_C: 218 if ((*fct)(&tuple, arg)) { 219 ret = 1; 220 goto done; 221 } 222 if (tuple.length < 4) { 223 DPRINTF(("CISTPL_LONGLINK_%s too " 224 "short %d\n", 225 longlink_common ? "C" : "A", 226 tuple.length)); 227 break; 228 } 229 longlink_present = 1; 230 longlink_common = (tuple.code == 231 CISTPL_LONGLINK_C) ? 1 : 0; 232 longlink_addr = pccard_tuple_read_4(&tuple, 0); 233 DPRINTF(("CISTPL_LONGLINK_%s %lx\n", 234 longlink_common ? "C" : "A", 235 longlink_addr)); 236 break; 237 case CISTPL_NO_LINK: 238 if ((*fct)(&tuple, arg)) { 239 ret = 1; 240 goto done; 241 } 242 longlink_present = 0; 243 DPRINTF(("CISTPL_NO_LINK\n")); 244 break; 245 case CISTPL_CHECKSUM: 246 if ((*fct)(&tuple, arg)) { 247 ret = 1; 248 goto done; 249 } 250 if (tuple.length < 5) { 251 DPRINTF(("CISTPL_CHECKSUM too " 252 "short %d\n", tuple.length)); 253 break; 254 } { 255 int16_t offset; 256 u_long addr, length; 257 u_int cksum, sum; 258 int i; 259 260 offset = (uint16_t) 261 pccard_tuple_read_2(&tuple, 0); 262 length = pccard_tuple_read_2(&tuple, 2); 263 cksum = pccard_tuple_read_1(&tuple, 4); 264 265 addr = tuple.ptr + offset; 266 267 DPRINTF(("CISTPL_CHECKSUM addr=%lx " 268 "len=%lx cksum=%x", 269 addr, length, cksum)); 270 271 /* 272 * XXX do more work to deal with 273 * distant regions 274 */ 275 if ((addr >= PCCARD_CIS_SIZE) || 276 ((addr + length) >= 277 PCCARD_CIS_SIZE)) { 278 DPRINTF((" skipped, " 279 "too distant\n")); 280 break; 281 } 282 sum = 0; 283 for (i = 0; i < length; i++) 284 sum += 285 bus_space_read_1(tuple.memt, 286 tuple.memh, 287 addr + tuple.mult * i); 288 if (cksum != (sum & 0xff)) { 289 DPRINTF((" failed sum=%x\n", 290 sum)); 291 device_printf(dev, 292 "CIS checksum failed\n"); 293#if 0 294 /* 295 * XXX Some working cards have 296 * XXX bad checksums!! 297 */ 298 ret = -1; 299#endif 300 } else { 301 DPRINTF((" ok\n")); 302 } 303 } 304 break; 305 case CISTPL_LONGLINK_MFC: 306 if (tuple.length < 1) { 307 DPRINTF(("CISTPL_LONGLINK_MFC too " 308 "short %d\n", tuple.length)); 309 break; 310 } 311 if (((tuple.length - 1) % 5) != 0) { 312 DPRINTF(("CISTPL_LONGLINK_MFC bogus " 313 "length %d\n", tuple.length)); 314 break; 315 } 316 /* 317 * this is kind of ad hoc, as I don't have 318 * any real documentation 319 */ 320 { 321 int i, tmp_count; 322 323 /* 324 * put count into tmp var so that 325 * if we have to bail (because it's 326 * a bogus count) it won't be 327 * remembered for later use. 328 */ 329 tmp_count = 330 pccard_tuple_read_1(&tuple, 0); 331 332 DPRINTF(("CISTPL_LONGLINK_MFC %d", 333 tmp_count)); 334 335 /* 336 * make _sure_ it's the right size; 337 * if too short, it may be a weird 338 * (unknown/undefined) format 339 */ 340 if (tuple.length != (tmp_count*5 + 1)) { 341 DPRINTF((" bogus length %d\n", 342 tuple.length)); 343 break; 344 } 345 /* 346 * sanity check for a programming 347 * error which is difficult to find 348 * when debugging. 349 */ 350 if (tmp_count > 351 howmany(sizeof mfc, sizeof mfc[0])) 352 panic("CISTPL_LONGLINK_MFC mfc " 353 "count would blow stack"); 354 mfc_count = tmp_count; 355 for (i = 0; i < mfc_count; i++) { 356 mfc[i].common = 357 (pccard_tuple_read_1(&tuple, 358 1 + 5 * i) == 359 PCCARD_MFC_MEM_COMMON) ? 360 1 : 0; 361 mfc[i].addr = 362 pccard_tuple_read_4(&tuple, 363 1 + 5 * i + 1); 364 DPRINTF((" %s:%lx", 365 mfc[i].common ? "common" : 366 "attr", mfc[i].addr)); 367 } 368 DPRINTF(("\n")); 369 } 370 /* 371 * for LONGLINK_MFC, fall through to the 372 * function. This tuple has structural and 373 * semantic content. 374 */ 375 default: 376 { 377 if ((*fct)(&tuple, arg)) { 378 ret = 1; 379 goto done; 380 } 381 } 382 break; 383 } /* switch */ 384#ifdef PCCARDCISDEBUG 385 /* print the tuple */ 386 { 387 int i; 388 389 DPRINTF((" %02x %02x", tuple.code, 390 tuple.length)); 391 392 for (i = 0; i < tuple.length; i++) { 393 DPRINTF((" %02x", 394 pccard_tuple_read_1(&tuple, i))); 395 if ((i % 16) == 13) 396 DPRINTF(("\n")); 397 } 398 399 if ((i % 16) != 14) 400 DPRINTF(("\n")); 401 } 402#endif 403 /* skip to the next tuple */ 404 tuple.ptr += 2 + tuple.length; 405 } 406 407 /* 408 * the chain is done. Clean up and move onto the next one, 409 * if any. The loop is here in the case that there is an MFC 410 * card with no longlink (which defaults to existing, == 0). 411 * In general, this means that if one pointer fails, it will 412 * try the next one, instead of just bailing. 413 */ 414 while (1) { 415 if (longlink_present) { 416 CARD_SET_RES_FLAGS(bus, dev, SYS_RES_MEMORY, 417 rid, longlink_common ? 418 PCCARD_A_MEM_COM : PCCARD_A_MEM_ATTR); 419 DPRINTF(("cis mem map %x\n", 420 (unsigned int) tuple.memh)); 421 tuple.mult = longlink_common ? 1 : 2; 422 tuple.ptr = longlink_addr; 423 longlink_present = 0; 424 longlink_common = 1; 425 longlink_addr = 0; 426 } else if (mfc_count && (mfc_index < mfc_count)) { 427 CARD_SET_RES_FLAGS(bus, dev, SYS_RES_MEMORY, 428 rid, mfc[mfc_index].common ? 429 PCCARD_A_MEM_COM : PCCARD_A_MEM_ATTR); 430 DPRINTF(("cis mem map %x\n", 431 (unsigned int) tuple.memh)); 432 /* set parse state, and point at the next one */ 433 tuple.mult = mfc[mfc_index].common ? 1 : 2; 434 tuple.ptr = mfc[mfc_index].addr; 435 mfc_index++; 436 } else { 437 goto done; 438 } 439 440 /* make sure that the link is valid */ 441 tuple.code = pccard_cis_read_1(&tuple, tuple.ptr); 442 if (tuple.code != CISTPL_LINKTARGET) { 443 DPRINTF(("CISTPL_LINKTARGET expected, " 444 "code %02x observed\n", tuple.code)); 445 continue; 446 } 447 tuple.length = pccard_cis_read_1(&tuple, tuple.ptr + 1); 448 if (tuple.length < 3) { 449 DPRINTF(("CISTPL_LINKTARGET too short %d\n", 450 tuple.length)); 451 continue; 452 } 453 if ((pccard_tuple_read_1(&tuple, 0) != 'C') || 454 (pccard_tuple_read_1(&tuple, 1) != 'I') || 455 (pccard_tuple_read_1(&tuple, 2) != 'S')) { 456 DPRINTF(("CISTPL_LINKTARGET magic " 457 "%02x%02x%02x incorrect\n", 458 pccard_tuple_read_1(&tuple, 0), 459 pccard_tuple_read_1(&tuple, 1), 460 pccard_tuple_read_1(&tuple, 2))); 461 continue; 462 } 463 tuple.ptr += 2 + tuple.length; 464 break; 465 } 466 } 467 468done: 469 bus_release_resource(dev, SYS_RES_MEMORY, rid, res); 470 471 return (ret); 472} 473 474/* XXX this is incredibly verbose. Not sure what trt is */ 475 476void 477pccard_print_cis(device_t dev) 478{ 479 struct pccard_softc *sc = PCCARD_SOFTC(dev); 480 struct pccard_card *card = &sc->card; 481 struct pccard_function *pf; 482 struct pccard_config_entry *cfe; 483 int i; 484 485 device_printf(dev, "CIS version "); 486 if (card->cis1_major == 4) { 487 if (card->cis1_minor == 0) 488 printf("PCCARD 1.0\n"); 489 else if (card->cis1_minor == 1) 490 printf("PCCARD 2.0 or 2.1\n"); 491 } else if (card->cis1_major >= 5) 492 printf("PC Card Standard %d.%d\n", card->cis1_major, card->cis1_minor); 493 else 494 printf("unknown (major=%d, minor=%d)\n", 495 card->cis1_major, card->cis1_minor); 496 497 device_printf(dev, "CIS info: "); 498 for (i = 0; i < 4; i++) { 499 if (card->cis1_info[i] == NULL) 500 break; 501 if (i) 502 printf(", "); 503 printf("%s", card->cis1_info[i]); 504 } 505 printf("\n"); 506 507 device_printf(dev, "Manufacturer code 0x%x, product 0x%x\n", 508 card->manufacturer, card->product); 509 510 STAILQ_FOREACH(pf, &card->pf_head, pf_list) { 511 device_printf(dev, "function %d: ", pf->number); 512 513 switch (pf->function) { 514 case PCCARD_FUNCTION_UNSPEC: 515 printf("unspecified"); 516 break; 517 case PCCARD_FUNCTION_MULTIFUNCTION: 518 printf("multi-function"); 519 break; 520 case PCCARD_FUNCTION_MEMORY: 521 printf("memory"); 522 break; 523 case PCCARD_FUNCTION_SERIAL: 524 printf("serial port"); 525 break; 526 case PCCARD_FUNCTION_PARALLEL: 527 printf("parallel port"); 528 break; 529 case PCCARD_FUNCTION_DISK: 530 printf("fixed disk"); 531 break; 532 case PCCARD_FUNCTION_VIDEO: 533 printf("video adapter"); 534 break; 535 case PCCARD_FUNCTION_NETWORK: 536 printf("network adapter"); 537 break; 538 case PCCARD_FUNCTION_AIMS: 539 printf("auto incrementing mass storage"); 540 break; 541 case PCCARD_FUNCTION_SCSI: 542 printf("SCSI bridge"); 543 break; 544 case PCCARD_FUNCTION_SECURITY: 545 printf("Security services"); 546 break; 547 case PCCARD_FUNCTION_INSTRUMENT: 548 printf("Instrument"); 549 break; 550 default: 551 printf("unknown (%d)", pf->function); 552 break; 553 } 554 555 printf(", ccr addr %x mask %x\n", pf->ccr_base, pf->ccr_mask); 556 557 STAILQ_FOREACH(cfe, &pf->cfe_head, cfe_list) { 558 device_printf(dev, "function %d, config table entry " 559 "%d: ", pf->number, cfe->number); 560 561 switch (cfe->iftype) { 562 case PCCARD_IFTYPE_MEMORY: 563 printf("memory card"); 564 break; 565 case PCCARD_IFTYPE_IO: 566 printf("I/O card"); 567 break; 568 default: 569 printf("card type unknown"); 570 break; 571 } 572 573 printf("; irq mask %x", cfe->irqmask); 574 575 if (cfe->num_iospace) { 576 printf("; iomask %lx, iospace", cfe->iomask); 577 578 for (i = 0; i < cfe->num_iospace; i++) { 579 printf(" %lx", cfe->iospace[i].start); 580 if (cfe->iospace[i].length) 581 printf("-%lx", 582 cfe->iospace[i].start + 583 cfe->iospace[i].length - 1); 584 } 585 } 586 if (cfe->num_memspace) { 587 printf("; memspace"); 588 589 for (i = 0; i < cfe->num_memspace; i++) { 590 printf(" %lx", 591 cfe->memspace[i].cardaddr); 592 if (cfe->memspace[i].length) 593 printf("-%lx", 594 cfe->memspace[i].cardaddr + 595 cfe->memspace[i].length - 1); 596 if (cfe->memspace[i].hostaddr) 597 printf("@%lx", 598 cfe->memspace[i].hostaddr); 599 } 600 } 601 if (cfe->maxtwins) 602 printf("; maxtwins %d", cfe->maxtwins); 603 604 printf(";"); 605 606 if (cfe->flags & PCCARD_CFE_MWAIT_REQUIRED) 607 printf(" mwait_required"); 608 if (cfe->flags & PCCARD_CFE_RDYBSY_ACTIVE) 609 printf(" rdybsy_active"); 610 if (cfe->flags & PCCARD_CFE_WP_ACTIVE) 611 printf(" wp_active"); 612 if (cfe->flags & PCCARD_CFE_BVD_ACTIVE) 613 printf(" bvd_active"); 614 if (cfe->flags & PCCARD_CFE_IO8) 615 printf(" io8"); 616 if (cfe->flags & PCCARD_CFE_IO16) 617 printf(" io16"); 618 if (cfe->flags & PCCARD_CFE_IRQSHARE) 619 printf(" irqshare"); 620 if (cfe->flags & PCCARD_CFE_IRQPULSE) 621 printf(" irqpulse"); 622 if (cfe->flags & PCCARD_CFE_IRQLEVEL) 623 printf(" irqlevel"); 624 if (cfe->flags & PCCARD_CFE_POWERDOWN) 625 printf(" powerdown"); 626 if (cfe->flags & PCCARD_CFE_READONLY) 627 printf(" readonly"); 628 if (cfe->flags & PCCARD_CFE_AUDIO) 629 printf(" audio"); 630 631 printf("\n"); 632 } 633 } 634 635 if (card->error) 636 device_printf(dev, "%d errors found while parsing CIS\n", 637 card->error); 638} 639 640static int 641pccard_parse_cis_tuple(const struct pccard_tuple *tuple, void *arg) 642{ 643 /* most of these are educated guesses */ 644 static struct pccard_config_entry init_cfe = { 645 -1, PCCARD_CFE_RDYBSY_ACTIVE | PCCARD_CFE_WP_ACTIVE | 646 PCCARD_CFE_BVD_ACTIVE, PCCARD_IFTYPE_MEMORY, 647 }; 648 649 struct cis_state *state = arg; 650 651 switch (tuple->code) { 652 case CISTPL_END: 653 /* if we've seen a LONGLINK_MFC, and this is the first 654 * END after it, reset the function list. 655 * 656 * XXX This might also be the right place to start a 657 * new function, but that assumes that a function 658 * definition never crosses any longlink, and I'm not 659 * sure about that. This is probably safe for MFC 660 * cards, but what we have now isn't broken, so I'd 661 * rather not change it. 662 */ 663 if (state->gotmfc == 1) { 664 struct pccard_function *pf, *pfnext; 665 666 for (pf = STAILQ_FIRST(&state->card->pf_head); 667 pf != NULL; pf = pfnext) { 668 pfnext = STAILQ_NEXT(pf, pf_list); 669 free(pf, M_DEVBUF); 670 } 671 672 STAILQ_INIT(&state->card->pf_head); 673 674 state->count = 0; 675 state->gotmfc = 2; 676 state->pf = NULL; 677 } 678 break; 679 case CISTPL_LONGLINK_MFC: 680 /* 681 * this tuple's structure was dealt with in scan_cis. here, 682 * record the fact that the MFC tuple was seen, so that 683 * functions declared before the MFC link can be cleaned 684 * up. 685 */ 686 state->gotmfc = 1; 687 break; 688#ifdef PCCARDCISDEBUG 689 case CISTPL_DEVICE: 690 case CISTPL_DEVICE_A: 691 { 692 u_int reg, dtype, dspeed; 693 694 reg = pccard_tuple_read_1(tuple, 0); 695 dtype = reg & PCCARD_DTYPE_MASK; 696 dspeed = reg & PCCARD_DSPEED_MASK; 697 698 DPRINTF(("CISTPL_DEVICE%s type=", 699 (tuple->code == CISTPL_DEVICE) ? "" : "_A")); 700 switch (dtype) { 701 case PCCARD_DTYPE_NULL: 702 DPRINTF(("null")); 703 break; 704 case PCCARD_DTYPE_ROM: 705 DPRINTF(("rom")); 706 break; 707 case PCCARD_DTYPE_OTPROM: 708 DPRINTF(("otprom")); 709 break; 710 case PCCARD_DTYPE_EPROM: 711 DPRINTF(("eprom")); 712 break; 713 case PCCARD_DTYPE_EEPROM: 714 DPRINTF(("eeprom")); 715 break; 716 case PCCARD_DTYPE_FLASH: 717 DPRINTF(("flash")); 718 break; 719 case PCCARD_DTYPE_SRAM: 720 DPRINTF(("sram")); 721 break; 722 case PCCARD_DTYPE_DRAM: 723 DPRINTF(("dram")); 724 break; 725 case PCCARD_DTYPE_FUNCSPEC: 726 DPRINTF(("funcspec")); 727 break; 728 case PCCARD_DTYPE_EXTEND: 729 DPRINTF(("extend")); 730 break; 731 default: 732 DPRINTF(("reserved")); 733 break; 734 } 735 DPRINTF((" speed=")); 736 switch (dspeed) { 737 case PCCARD_DSPEED_NULL: 738 DPRINTF(("null")); 739 break; 740 case PCCARD_DSPEED_250NS: 741 DPRINTF(("250ns")); 742 break; 743 case PCCARD_DSPEED_200NS: 744 DPRINTF(("200ns")); 745 break; 746 case PCCARD_DSPEED_150NS: 747 DPRINTF(("150ns")); 748 break; 749 case PCCARD_DSPEED_100NS: 750 DPRINTF(("100ns")); 751 break; 752 case PCCARD_DSPEED_EXT: 753 DPRINTF(("ext")); 754 break; 755 default: 756 DPRINTF(("reserved")); 757 break; 758 } 759 } 760 DPRINTF(("\n")); 761 break; 762#endif 763 case CISTPL_VERS_1: 764 if (tuple->length < 6) { 765 DPRINTF(("CISTPL_VERS_1 too short %d\n", 766 tuple->length)); 767 break; 768 } { 769 int start, i, ch, count; 770 771 state->card->cis1_major = pccard_tuple_read_1(tuple, 0); 772 state->card->cis1_minor = pccard_tuple_read_1(tuple, 1); 773 774 for (count = 0, start = 0, i = 0; 775 (count < 4) && ((i + 4) < 256); i++) { 776 ch = pccard_tuple_read_1(tuple, 2 + i); 777 if (ch == 0xff) 778 break; 779 state->card->cis1_info_buf[i] = ch; 780 if (ch == 0) { 781 state->card->cis1_info[count] = 782 state->card->cis1_info_buf + start; 783 start = i + 1; 784 count++; 785 } 786 } 787 DPRINTF(("CISTPL_VERS_1\n")); 788 } 789 break; 790 case CISTPL_MANFID: 791 if (tuple->length < 4) { 792 DPRINTF(("CISTPL_MANFID too short %d\n", 793 tuple->length)); 794 break; 795 } 796 state->card->manufacturer = pccard_tuple_read_2(tuple, 0); 797 state->card->product = pccard_tuple_read_2(tuple, 2); 798 /* 799 * This is for xe driver. But not limited to that driver. 800 * In PC Card Standard, 801 * Manufacturer ID: 2byte. 802 * Product ID: typically 2bytes, but there's no limit on its 803 * size. prodext is a two byte field, so maybe we should 804 * also handle the '6' case. So far no cards have surfaced 805 * with a length of '6'. 806 */ 807 if (tuple->length == 5 ) 808 state->card->prodext = pccard_tuple_read_1(tuple, 4); 809 DPRINTF(("CISTPL_MANFID\n")); 810 break; 811 case CISTPL_FUNCID: 812 if (tuple->length < 1) { 813 DPRINTF(("CISTPL_FUNCID too short %d\n", 814 tuple->length)); 815 break; 816 } 817 if ((state->pf == NULL) || (state->gotmfc == 2)) { 818 state->pf = malloc(sizeof(*state->pf), M_DEVBUF, 819 M_NOWAIT | M_ZERO); 820 state->pf->number = state->count++; 821 state->pf->last_config_index = -1; 822 STAILQ_INIT(&state->pf->cfe_head); 823 824 STAILQ_INSERT_TAIL(&state->card->pf_head, state->pf, 825 pf_list); 826 } 827 state->pf->function = pccard_tuple_read_1(tuple, 0); 828 829 DPRINTF(("CISTPL_FUNCID\n")); 830 break; 831 case CISTPL_FUNCE: 832 if (state->pf == NULL || state->pf->function <= 0) { 833 DPRINTF(("CISTPL_FUNCE is not followed by " 834 "valid CISTPL_FUNCID\n")); 835 break; 836 } 837 if (tuple->length >= 2) 838 decode_funce(tuple, state->pf); 839 DPRINTF(("CISTPL_FUNCE\n")); 840 break; 841 case CISTPL_CONFIG: 842 if (tuple->length < 3) { 843 DPRINTF(("CISTPL_CONFIG too short %d\n", 844 tuple->length)); 845 break; 846 } { 847 u_int reg, rasz, rmsz, rfsz; 848 int i; 849 850 reg = pccard_tuple_read_1(tuple, 0); 851 rasz = 1 + ((reg & PCCARD_TPCC_RASZ_MASK) >> 852 PCCARD_TPCC_RASZ_SHIFT); 853 rmsz = 1 + ((reg & PCCARD_TPCC_RMSZ_MASK) >> 854 PCCARD_TPCC_RMSZ_SHIFT); 855 rfsz = ((reg & PCCARD_TPCC_RFSZ_MASK) >> 856 PCCARD_TPCC_RFSZ_SHIFT); 857 858 if (tuple->length < (rasz + rmsz + rfsz)) { 859 DPRINTF(("CISTPL_CONFIG (%d,%d,%d) too " 860 "short %d\n", rasz, rmsz, rfsz, 861 tuple->length)); 862 break; 863 } 864 if (state->pf == NULL) { 865 state->pf = malloc(sizeof(*state->pf), 866 M_DEVBUF, M_NOWAIT | M_ZERO); 867 state->pf->number = state->count++; 868 state->pf->last_config_index = -1; 869 STAILQ_INIT(&state->pf->cfe_head); 870 871 STAILQ_INSERT_TAIL(&state->card->pf_head, 872 state->pf, pf_list); 873 874 state->pf->function = PCCARD_FUNCTION_UNSPEC; 875 } 876 state->pf->last_config_index = 877 pccard_tuple_read_1(tuple, 1); 878 879 state->pf->ccr_base = 0; 880 for (i = 0; i < rasz; i++) 881 state->pf->ccr_base |= 882 ((pccard_tuple_read_1(tuple, 2 + i)) << 883 (i * 8)); 884 885 state->pf->ccr_mask = 0; 886 for (i = 0; i < rmsz; i++) 887 state->pf->ccr_mask |= 888 ((pccard_tuple_read_1(tuple, 889 2 + rasz + i)) << (i * 8)); 890 891 /* skip the reserved area and subtuples */ 892 893 /* reset the default cfe for each cfe list */ 894 state->temp_cfe = init_cfe; 895 state->default_cfe = &state->temp_cfe; 896 } 897 DPRINTF(("CISTPL_CONFIG\n")); 898 break; 899 case CISTPL_CFTABLE_ENTRY: 900 {
| 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/pccardvarp.h> 49#include <dev/pccard/pccard_cis.h> 50 51#include "card_if.h" 52 53extern int pccard_cis_debug; 54 55#define PCCARDCISDEBUG 56#ifdef PCCARDCISDEBUG 57#define DPRINTF(arg) do { if (pccard_cis_debug) printf arg; } while (0) 58#define DEVPRINTF(arg) do { if (pccard_cis_debug) device_printf arg; } while (0) 59#else 60#define DPRINTF(arg) 61#define DEVPRINTF(arg) 62#endif 63 64#define PCCARD_CIS_SIZE 4096 65 66struct cis_state { 67 int count; 68 int gotmfc; 69 struct pccard_config_entry temp_cfe; 70 struct pccard_config_entry *default_cfe; 71 struct pccard_card *card; 72 struct pccard_function *pf; 73}; 74 75static int pccard_parse_cis_tuple(const struct pccard_tuple *, void *); 76static int decode_funce(const struct pccard_tuple *, struct pccard_function *); 77 78void 79pccard_read_cis(struct pccard_softc *sc) 80{ 81 struct cis_state state; 82 83 bzero(&state, sizeof state); 84 state.card = &sc->card; 85 state.card->error = 0; 86 state.card->cis1_major = -1; 87 state.card->cis1_minor = -1; 88 state.card->cis1_info[0] = NULL; 89 state.card->cis1_info[1] = NULL; 90 state.card->cis1_info[2] = NULL; 91 state.card->cis1_info[3] = NULL; 92 state.card->manufacturer = PCMCIA_VENDOR_INVALID; 93 state.card->product = PCMCIA_PRODUCT_INVALID; 94 STAILQ_INIT(&state.card->pf_head); 95 state.pf = NULL; 96 97 /* 98 * XXX The following shouldn't be needed, but some slow cards 99 * XXX seem to need it still. Need to investigate if there's 100 * XXX a way to tell if the card is 'ready' or not rather than 101 * XXX sleeping like this. We're called just after the power 102 * XXX up of the socket. The standard timing diagrams don't 103 * XXX seem to indicate that a delay is required. The old 104 * XXX delay was 1s. This delay is .1s. 105 */ 106 pause("pccard", hz / 10); 107 if (pccard_scan_cis(device_get_parent(sc->dev), sc->dev, 108 pccard_parse_cis_tuple, &state) == -1) 109 state.card->error++; 110} 111 112int 113pccard_scan_cis(device_t bus, device_t dev, pccard_scan_t fct, void *arg) 114{ 115 struct resource *res; 116 int rid; 117 struct pccard_tuple tuple; 118 int longlink_present; 119 int longlink_common; 120 u_long longlink_addr; /* Type suspect */ 121 int mfc_count; 122 int mfc_index; 123#ifdef PCCARDCISDEBUG 124 int cis_none_cnt = 10; /* Only report 10 CIS_NONEs */ 125#endif 126 struct { 127 int common; 128 u_long addr; 129 } mfc[256 / 5]; 130 int ret; 131 132 ret = 0; 133 134 /* allocate some memory */ 135 136 /* 137 * Some reports from the field suggest that a 64k memory boundary 138 * helps card CIS being able to be read. Try it here and see what 139 * the results actually are. I'm not sure I understand why this 140 * would make cards work better, but it is easy enough to test. 141 */ 142 rid = 0; 143 res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, 0, ~0, 144 PCCARD_CIS_SIZE, RF_ACTIVE | rman_make_alignment_flags(64*1024)); 145 if (res == NULL) { 146 device_printf(dev, "can't alloc memory to read attributes\n"); 147 return -1; 148 } 149 CARD_SET_RES_FLAGS(bus, dev, SYS_RES_MEMORY, rid, PCCARD_A_MEM_ATTR); 150 tuple.memt = rman_get_bustag(res); 151 tuple.memh = rman_get_bushandle(res); 152 tuple.ptr = 0; 153 154 DPRINTF(("cis mem map 0x%x (resource: 0x%lx)\n", 155 (unsigned int) tuple.memh, rman_get_start(res))); 156 157 tuple.mult = 2; 158 159 longlink_present = 1; 160 longlink_common = 1; 161 longlink_addr = 0; 162 163 mfc_count = 0; 164 mfc_index = 0; 165 166 DEVPRINTF((dev, "CIS tuple chain:\n")); 167 168 while (1) { 169 while (1) { 170 /* 171 * Perform boundary check for insane cards. 172 * If CIS is too long, simulate CIS end. 173 * (This check may not be sufficient for 174 * malicious cards.) 175 */ 176 if (tuple.mult * tuple.ptr >= PCCARD_CIS_SIZE - 1 177 - 32 /* ad hoc value */ ) { 178 printf("CIS is too long -- truncating\n"); 179 tuple.code = CISTPL_END; 180 } else { 181 /* get the tuple code */ 182 tuple.code = pccard_cis_read_1(&tuple, tuple.ptr); 183 } 184 185 /* two special-case tuples */ 186 187 if (tuple.code == CISTPL_NULL) { 188#ifdef PCCARDCISDEBUG 189 if (cis_none_cnt > 0) 190 DPRINTF(("CISTPL_NONE\n 00\n")); 191 else if (cis_none_cnt == 0) 192 DPRINTF(("TOO MANY CIS_NONE\n")); 193 cis_none_cnt--; 194#endif 195 if ((*fct)(&tuple, arg)) { 196 ret = 1; 197 goto done; 198 } 199 tuple.ptr++; 200 continue; 201 } else if (tuple.code == CISTPL_END) { 202 DPRINTF(("CISTPL_END\n ff\n")); 203 /* Call the function for the END tuple, since 204 the CIS semantics depend on it */ 205 if ((*fct)(&tuple, arg)) { 206 ret = 1; 207 goto done; 208 } 209 tuple.ptr++; 210 break; 211 } 212 /* now all the normal tuples */ 213 214 tuple.length = pccard_cis_read_1(&tuple, tuple.ptr + 1); 215 switch (tuple.code) { 216 case CISTPL_LONGLINK_A: 217 case CISTPL_LONGLINK_C: 218 if ((*fct)(&tuple, arg)) { 219 ret = 1; 220 goto done; 221 } 222 if (tuple.length < 4) { 223 DPRINTF(("CISTPL_LONGLINK_%s too " 224 "short %d\n", 225 longlink_common ? "C" : "A", 226 tuple.length)); 227 break; 228 } 229 longlink_present = 1; 230 longlink_common = (tuple.code == 231 CISTPL_LONGLINK_C) ? 1 : 0; 232 longlink_addr = pccard_tuple_read_4(&tuple, 0); 233 DPRINTF(("CISTPL_LONGLINK_%s %lx\n", 234 longlink_common ? "C" : "A", 235 longlink_addr)); 236 break; 237 case CISTPL_NO_LINK: 238 if ((*fct)(&tuple, arg)) { 239 ret = 1; 240 goto done; 241 } 242 longlink_present = 0; 243 DPRINTF(("CISTPL_NO_LINK\n")); 244 break; 245 case CISTPL_CHECKSUM: 246 if ((*fct)(&tuple, arg)) { 247 ret = 1; 248 goto done; 249 } 250 if (tuple.length < 5) { 251 DPRINTF(("CISTPL_CHECKSUM too " 252 "short %d\n", tuple.length)); 253 break; 254 } { 255 int16_t offset; 256 u_long addr, length; 257 u_int cksum, sum; 258 int i; 259 260 offset = (uint16_t) 261 pccard_tuple_read_2(&tuple, 0); 262 length = pccard_tuple_read_2(&tuple, 2); 263 cksum = pccard_tuple_read_1(&tuple, 4); 264 265 addr = tuple.ptr + offset; 266 267 DPRINTF(("CISTPL_CHECKSUM addr=%lx " 268 "len=%lx cksum=%x", 269 addr, length, cksum)); 270 271 /* 272 * XXX do more work to deal with 273 * distant regions 274 */ 275 if ((addr >= PCCARD_CIS_SIZE) || 276 ((addr + length) >= 277 PCCARD_CIS_SIZE)) { 278 DPRINTF((" skipped, " 279 "too distant\n")); 280 break; 281 } 282 sum = 0; 283 for (i = 0; i < length; i++) 284 sum += 285 bus_space_read_1(tuple.memt, 286 tuple.memh, 287 addr + tuple.mult * i); 288 if (cksum != (sum & 0xff)) { 289 DPRINTF((" failed sum=%x\n", 290 sum)); 291 device_printf(dev, 292 "CIS checksum failed\n"); 293#if 0 294 /* 295 * XXX Some working cards have 296 * XXX bad checksums!! 297 */ 298 ret = -1; 299#endif 300 } else { 301 DPRINTF((" ok\n")); 302 } 303 } 304 break; 305 case CISTPL_LONGLINK_MFC: 306 if (tuple.length < 1) { 307 DPRINTF(("CISTPL_LONGLINK_MFC too " 308 "short %d\n", tuple.length)); 309 break; 310 } 311 if (((tuple.length - 1) % 5) != 0) { 312 DPRINTF(("CISTPL_LONGLINK_MFC bogus " 313 "length %d\n", tuple.length)); 314 break; 315 } 316 /* 317 * this is kind of ad hoc, as I don't have 318 * any real documentation 319 */ 320 { 321 int i, tmp_count; 322 323 /* 324 * put count into tmp var so that 325 * if we have to bail (because it's 326 * a bogus count) it won't be 327 * remembered for later use. 328 */ 329 tmp_count = 330 pccard_tuple_read_1(&tuple, 0); 331 332 DPRINTF(("CISTPL_LONGLINK_MFC %d", 333 tmp_count)); 334 335 /* 336 * make _sure_ it's the right size; 337 * if too short, it may be a weird 338 * (unknown/undefined) format 339 */ 340 if (tuple.length != (tmp_count*5 + 1)) { 341 DPRINTF((" bogus length %d\n", 342 tuple.length)); 343 break; 344 } 345 /* 346 * sanity check for a programming 347 * error which is difficult to find 348 * when debugging. 349 */ 350 if (tmp_count > 351 howmany(sizeof mfc, sizeof mfc[0])) 352 panic("CISTPL_LONGLINK_MFC mfc " 353 "count would blow stack"); 354 mfc_count = tmp_count; 355 for (i = 0; i < mfc_count; i++) { 356 mfc[i].common = 357 (pccard_tuple_read_1(&tuple, 358 1 + 5 * i) == 359 PCCARD_MFC_MEM_COMMON) ? 360 1 : 0; 361 mfc[i].addr = 362 pccard_tuple_read_4(&tuple, 363 1 + 5 * i + 1); 364 DPRINTF((" %s:%lx", 365 mfc[i].common ? "common" : 366 "attr", mfc[i].addr)); 367 } 368 DPRINTF(("\n")); 369 } 370 /* 371 * for LONGLINK_MFC, fall through to the 372 * function. This tuple has structural and 373 * semantic content. 374 */ 375 default: 376 { 377 if ((*fct)(&tuple, arg)) { 378 ret = 1; 379 goto done; 380 } 381 } 382 break; 383 } /* switch */ 384#ifdef PCCARDCISDEBUG 385 /* print the tuple */ 386 { 387 int i; 388 389 DPRINTF((" %02x %02x", tuple.code, 390 tuple.length)); 391 392 for (i = 0; i < tuple.length; i++) { 393 DPRINTF((" %02x", 394 pccard_tuple_read_1(&tuple, i))); 395 if ((i % 16) == 13) 396 DPRINTF(("\n")); 397 } 398 399 if ((i % 16) != 14) 400 DPRINTF(("\n")); 401 } 402#endif 403 /* skip to the next tuple */ 404 tuple.ptr += 2 + tuple.length; 405 } 406 407 /* 408 * the chain is done. Clean up and move onto the next one, 409 * if any. The loop is here in the case that there is an MFC 410 * card with no longlink (which defaults to existing, == 0). 411 * In general, this means that if one pointer fails, it will 412 * try the next one, instead of just bailing. 413 */ 414 while (1) { 415 if (longlink_present) { 416 CARD_SET_RES_FLAGS(bus, dev, SYS_RES_MEMORY, 417 rid, longlink_common ? 418 PCCARD_A_MEM_COM : PCCARD_A_MEM_ATTR); 419 DPRINTF(("cis mem map %x\n", 420 (unsigned int) tuple.memh)); 421 tuple.mult = longlink_common ? 1 : 2; 422 tuple.ptr = longlink_addr; 423 longlink_present = 0; 424 longlink_common = 1; 425 longlink_addr = 0; 426 } else if (mfc_count && (mfc_index < mfc_count)) { 427 CARD_SET_RES_FLAGS(bus, dev, SYS_RES_MEMORY, 428 rid, mfc[mfc_index].common ? 429 PCCARD_A_MEM_COM : PCCARD_A_MEM_ATTR); 430 DPRINTF(("cis mem map %x\n", 431 (unsigned int) tuple.memh)); 432 /* set parse state, and point at the next one */ 433 tuple.mult = mfc[mfc_index].common ? 1 : 2; 434 tuple.ptr = mfc[mfc_index].addr; 435 mfc_index++; 436 } else { 437 goto done; 438 } 439 440 /* make sure that the link is valid */ 441 tuple.code = pccard_cis_read_1(&tuple, tuple.ptr); 442 if (tuple.code != CISTPL_LINKTARGET) { 443 DPRINTF(("CISTPL_LINKTARGET expected, " 444 "code %02x observed\n", tuple.code)); 445 continue; 446 } 447 tuple.length = pccard_cis_read_1(&tuple, tuple.ptr + 1); 448 if (tuple.length < 3) { 449 DPRINTF(("CISTPL_LINKTARGET too short %d\n", 450 tuple.length)); 451 continue; 452 } 453 if ((pccard_tuple_read_1(&tuple, 0) != 'C') || 454 (pccard_tuple_read_1(&tuple, 1) != 'I') || 455 (pccard_tuple_read_1(&tuple, 2) != 'S')) { 456 DPRINTF(("CISTPL_LINKTARGET magic " 457 "%02x%02x%02x incorrect\n", 458 pccard_tuple_read_1(&tuple, 0), 459 pccard_tuple_read_1(&tuple, 1), 460 pccard_tuple_read_1(&tuple, 2))); 461 continue; 462 } 463 tuple.ptr += 2 + tuple.length; 464 break; 465 } 466 } 467 468done: 469 bus_release_resource(dev, SYS_RES_MEMORY, rid, res); 470 471 return (ret); 472} 473 474/* XXX this is incredibly verbose. Not sure what trt is */ 475 476void 477pccard_print_cis(device_t dev) 478{ 479 struct pccard_softc *sc = PCCARD_SOFTC(dev); 480 struct pccard_card *card = &sc->card; 481 struct pccard_function *pf; 482 struct pccard_config_entry *cfe; 483 int i; 484 485 device_printf(dev, "CIS version "); 486 if (card->cis1_major == 4) { 487 if (card->cis1_minor == 0) 488 printf("PCCARD 1.0\n"); 489 else if (card->cis1_minor == 1) 490 printf("PCCARD 2.0 or 2.1\n"); 491 } else if (card->cis1_major >= 5) 492 printf("PC Card Standard %d.%d\n", card->cis1_major, card->cis1_minor); 493 else 494 printf("unknown (major=%d, minor=%d)\n", 495 card->cis1_major, card->cis1_minor); 496 497 device_printf(dev, "CIS info: "); 498 for (i = 0; i < 4; i++) { 499 if (card->cis1_info[i] == NULL) 500 break; 501 if (i) 502 printf(", "); 503 printf("%s", card->cis1_info[i]); 504 } 505 printf("\n"); 506 507 device_printf(dev, "Manufacturer code 0x%x, product 0x%x\n", 508 card->manufacturer, card->product); 509 510 STAILQ_FOREACH(pf, &card->pf_head, pf_list) { 511 device_printf(dev, "function %d: ", pf->number); 512 513 switch (pf->function) { 514 case PCCARD_FUNCTION_UNSPEC: 515 printf("unspecified"); 516 break; 517 case PCCARD_FUNCTION_MULTIFUNCTION: 518 printf("multi-function"); 519 break; 520 case PCCARD_FUNCTION_MEMORY: 521 printf("memory"); 522 break; 523 case PCCARD_FUNCTION_SERIAL: 524 printf("serial port"); 525 break; 526 case PCCARD_FUNCTION_PARALLEL: 527 printf("parallel port"); 528 break; 529 case PCCARD_FUNCTION_DISK: 530 printf("fixed disk"); 531 break; 532 case PCCARD_FUNCTION_VIDEO: 533 printf("video adapter"); 534 break; 535 case PCCARD_FUNCTION_NETWORK: 536 printf("network adapter"); 537 break; 538 case PCCARD_FUNCTION_AIMS: 539 printf("auto incrementing mass storage"); 540 break; 541 case PCCARD_FUNCTION_SCSI: 542 printf("SCSI bridge"); 543 break; 544 case PCCARD_FUNCTION_SECURITY: 545 printf("Security services"); 546 break; 547 case PCCARD_FUNCTION_INSTRUMENT: 548 printf("Instrument"); 549 break; 550 default: 551 printf("unknown (%d)", pf->function); 552 break; 553 } 554 555 printf(", ccr addr %x mask %x\n", pf->ccr_base, pf->ccr_mask); 556 557 STAILQ_FOREACH(cfe, &pf->cfe_head, cfe_list) { 558 device_printf(dev, "function %d, config table entry " 559 "%d: ", pf->number, cfe->number); 560 561 switch (cfe->iftype) { 562 case PCCARD_IFTYPE_MEMORY: 563 printf("memory card"); 564 break; 565 case PCCARD_IFTYPE_IO: 566 printf("I/O card"); 567 break; 568 default: 569 printf("card type unknown"); 570 break; 571 } 572 573 printf("; irq mask %x", cfe->irqmask); 574 575 if (cfe->num_iospace) { 576 printf("; iomask %lx, iospace", cfe->iomask); 577 578 for (i = 0; i < cfe->num_iospace; i++) { 579 printf(" %lx", cfe->iospace[i].start); 580 if (cfe->iospace[i].length) 581 printf("-%lx", 582 cfe->iospace[i].start + 583 cfe->iospace[i].length - 1); 584 } 585 } 586 if (cfe->num_memspace) { 587 printf("; memspace"); 588 589 for (i = 0; i < cfe->num_memspace; i++) { 590 printf(" %lx", 591 cfe->memspace[i].cardaddr); 592 if (cfe->memspace[i].length) 593 printf("-%lx", 594 cfe->memspace[i].cardaddr + 595 cfe->memspace[i].length - 1); 596 if (cfe->memspace[i].hostaddr) 597 printf("@%lx", 598 cfe->memspace[i].hostaddr); 599 } 600 } 601 if (cfe->maxtwins) 602 printf("; maxtwins %d", cfe->maxtwins); 603 604 printf(";"); 605 606 if (cfe->flags & PCCARD_CFE_MWAIT_REQUIRED) 607 printf(" mwait_required"); 608 if (cfe->flags & PCCARD_CFE_RDYBSY_ACTIVE) 609 printf(" rdybsy_active"); 610 if (cfe->flags & PCCARD_CFE_WP_ACTIVE) 611 printf(" wp_active"); 612 if (cfe->flags & PCCARD_CFE_BVD_ACTIVE) 613 printf(" bvd_active"); 614 if (cfe->flags & PCCARD_CFE_IO8) 615 printf(" io8"); 616 if (cfe->flags & PCCARD_CFE_IO16) 617 printf(" io16"); 618 if (cfe->flags & PCCARD_CFE_IRQSHARE) 619 printf(" irqshare"); 620 if (cfe->flags & PCCARD_CFE_IRQPULSE) 621 printf(" irqpulse"); 622 if (cfe->flags & PCCARD_CFE_IRQLEVEL) 623 printf(" irqlevel"); 624 if (cfe->flags & PCCARD_CFE_POWERDOWN) 625 printf(" powerdown"); 626 if (cfe->flags & PCCARD_CFE_READONLY) 627 printf(" readonly"); 628 if (cfe->flags & PCCARD_CFE_AUDIO) 629 printf(" audio"); 630 631 printf("\n"); 632 } 633 } 634 635 if (card->error) 636 device_printf(dev, "%d errors found while parsing CIS\n", 637 card->error); 638} 639 640static int 641pccard_parse_cis_tuple(const struct pccard_tuple *tuple, void *arg) 642{ 643 /* most of these are educated guesses */ 644 static struct pccard_config_entry init_cfe = { 645 -1, PCCARD_CFE_RDYBSY_ACTIVE | PCCARD_CFE_WP_ACTIVE | 646 PCCARD_CFE_BVD_ACTIVE, PCCARD_IFTYPE_MEMORY, 647 }; 648 649 struct cis_state *state = arg; 650 651 switch (tuple->code) { 652 case CISTPL_END: 653 /* if we've seen a LONGLINK_MFC, and this is the first 654 * END after it, reset the function list. 655 * 656 * XXX This might also be the right place to start a 657 * new function, but that assumes that a function 658 * definition never crosses any longlink, and I'm not 659 * sure about that. This is probably safe for MFC 660 * cards, but what we have now isn't broken, so I'd 661 * rather not change it. 662 */ 663 if (state->gotmfc == 1) { 664 struct pccard_function *pf, *pfnext; 665 666 for (pf = STAILQ_FIRST(&state->card->pf_head); 667 pf != NULL; pf = pfnext) { 668 pfnext = STAILQ_NEXT(pf, pf_list); 669 free(pf, M_DEVBUF); 670 } 671 672 STAILQ_INIT(&state->card->pf_head); 673 674 state->count = 0; 675 state->gotmfc = 2; 676 state->pf = NULL; 677 } 678 break; 679 case CISTPL_LONGLINK_MFC: 680 /* 681 * this tuple's structure was dealt with in scan_cis. here, 682 * record the fact that the MFC tuple was seen, so that 683 * functions declared before the MFC link can be cleaned 684 * up. 685 */ 686 state->gotmfc = 1; 687 break; 688#ifdef PCCARDCISDEBUG 689 case CISTPL_DEVICE: 690 case CISTPL_DEVICE_A: 691 { 692 u_int reg, dtype, dspeed; 693 694 reg = pccard_tuple_read_1(tuple, 0); 695 dtype = reg & PCCARD_DTYPE_MASK; 696 dspeed = reg & PCCARD_DSPEED_MASK; 697 698 DPRINTF(("CISTPL_DEVICE%s type=", 699 (tuple->code == CISTPL_DEVICE) ? "" : "_A")); 700 switch (dtype) { 701 case PCCARD_DTYPE_NULL: 702 DPRINTF(("null")); 703 break; 704 case PCCARD_DTYPE_ROM: 705 DPRINTF(("rom")); 706 break; 707 case PCCARD_DTYPE_OTPROM: 708 DPRINTF(("otprom")); 709 break; 710 case PCCARD_DTYPE_EPROM: 711 DPRINTF(("eprom")); 712 break; 713 case PCCARD_DTYPE_EEPROM: 714 DPRINTF(("eeprom")); 715 break; 716 case PCCARD_DTYPE_FLASH: 717 DPRINTF(("flash")); 718 break; 719 case PCCARD_DTYPE_SRAM: 720 DPRINTF(("sram")); 721 break; 722 case PCCARD_DTYPE_DRAM: 723 DPRINTF(("dram")); 724 break; 725 case PCCARD_DTYPE_FUNCSPEC: 726 DPRINTF(("funcspec")); 727 break; 728 case PCCARD_DTYPE_EXTEND: 729 DPRINTF(("extend")); 730 break; 731 default: 732 DPRINTF(("reserved")); 733 break; 734 } 735 DPRINTF((" speed=")); 736 switch (dspeed) { 737 case PCCARD_DSPEED_NULL: 738 DPRINTF(("null")); 739 break; 740 case PCCARD_DSPEED_250NS: 741 DPRINTF(("250ns")); 742 break; 743 case PCCARD_DSPEED_200NS: 744 DPRINTF(("200ns")); 745 break; 746 case PCCARD_DSPEED_150NS: 747 DPRINTF(("150ns")); 748 break; 749 case PCCARD_DSPEED_100NS: 750 DPRINTF(("100ns")); 751 break; 752 case PCCARD_DSPEED_EXT: 753 DPRINTF(("ext")); 754 break; 755 default: 756 DPRINTF(("reserved")); 757 break; 758 } 759 } 760 DPRINTF(("\n")); 761 break; 762#endif 763 case CISTPL_VERS_1: 764 if (tuple->length < 6) { 765 DPRINTF(("CISTPL_VERS_1 too short %d\n", 766 tuple->length)); 767 break; 768 } { 769 int start, i, ch, count; 770 771 state->card->cis1_major = pccard_tuple_read_1(tuple, 0); 772 state->card->cis1_minor = pccard_tuple_read_1(tuple, 1); 773 774 for (count = 0, start = 0, i = 0; 775 (count < 4) && ((i + 4) < 256); i++) { 776 ch = pccard_tuple_read_1(tuple, 2 + i); 777 if (ch == 0xff) 778 break; 779 state->card->cis1_info_buf[i] = ch; 780 if (ch == 0) { 781 state->card->cis1_info[count] = 782 state->card->cis1_info_buf + start; 783 start = i + 1; 784 count++; 785 } 786 } 787 DPRINTF(("CISTPL_VERS_1\n")); 788 } 789 break; 790 case CISTPL_MANFID: 791 if (tuple->length < 4) { 792 DPRINTF(("CISTPL_MANFID too short %d\n", 793 tuple->length)); 794 break; 795 } 796 state->card->manufacturer = pccard_tuple_read_2(tuple, 0); 797 state->card->product = pccard_tuple_read_2(tuple, 2); 798 /* 799 * This is for xe driver. But not limited to that driver. 800 * In PC Card Standard, 801 * Manufacturer ID: 2byte. 802 * Product ID: typically 2bytes, but there's no limit on its 803 * size. prodext is a two byte field, so maybe we should 804 * also handle the '6' case. So far no cards have surfaced 805 * with a length of '6'. 806 */ 807 if (tuple->length == 5 ) 808 state->card->prodext = pccard_tuple_read_1(tuple, 4); 809 DPRINTF(("CISTPL_MANFID\n")); 810 break; 811 case CISTPL_FUNCID: 812 if (tuple->length < 1) { 813 DPRINTF(("CISTPL_FUNCID too short %d\n", 814 tuple->length)); 815 break; 816 } 817 if ((state->pf == NULL) || (state->gotmfc == 2)) { 818 state->pf = malloc(sizeof(*state->pf), M_DEVBUF, 819 M_NOWAIT | M_ZERO); 820 state->pf->number = state->count++; 821 state->pf->last_config_index = -1; 822 STAILQ_INIT(&state->pf->cfe_head); 823 824 STAILQ_INSERT_TAIL(&state->card->pf_head, state->pf, 825 pf_list); 826 } 827 state->pf->function = pccard_tuple_read_1(tuple, 0); 828 829 DPRINTF(("CISTPL_FUNCID\n")); 830 break; 831 case CISTPL_FUNCE: 832 if (state->pf == NULL || state->pf->function <= 0) { 833 DPRINTF(("CISTPL_FUNCE is not followed by " 834 "valid CISTPL_FUNCID\n")); 835 break; 836 } 837 if (tuple->length >= 2) 838 decode_funce(tuple, state->pf); 839 DPRINTF(("CISTPL_FUNCE\n")); 840 break; 841 case CISTPL_CONFIG: 842 if (tuple->length < 3) { 843 DPRINTF(("CISTPL_CONFIG too short %d\n", 844 tuple->length)); 845 break; 846 } { 847 u_int reg, rasz, rmsz, rfsz; 848 int i; 849 850 reg = pccard_tuple_read_1(tuple, 0); 851 rasz = 1 + ((reg & PCCARD_TPCC_RASZ_MASK) >> 852 PCCARD_TPCC_RASZ_SHIFT); 853 rmsz = 1 + ((reg & PCCARD_TPCC_RMSZ_MASK) >> 854 PCCARD_TPCC_RMSZ_SHIFT); 855 rfsz = ((reg & PCCARD_TPCC_RFSZ_MASK) >> 856 PCCARD_TPCC_RFSZ_SHIFT); 857 858 if (tuple->length < (rasz + rmsz + rfsz)) { 859 DPRINTF(("CISTPL_CONFIG (%d,%d,%d) too " 860 "short %d\n", rasz, rmsz, rfsz, 861 tuple->length)); 862 break; 863 } 864 if (state->pf == NULL) { 865 state->pf = malloc(sizeof(*state->pf), 866 M_DEVBUF, M_NOWAIT | M_ZERO); 867 state->pf->number = state->count++; 868 state->pf->last_config_index = -1; 869 STAILQ_INIT(&state->pf->cfe_head); 870 871 STAILQ_INSERT_TAIL(&state->card->pf_head, 872 state->pf, pf_list); 873 874 state->pf->function = PCCARD_FUNCTION_UNSPEC; 875 } 876 state->pf->last_config_index = 877 pccard_tuple_read_1(tuple, 1); 878 879 state->pf->ccr_base = 0; 880 for (i = 0; i < rasz; i++) 881 state->pf->ccr_base |= 882 ((pccard_tuple_read_1(tuple, 2 + i)) << 883 (i * 8)); 884 885 state->pf->ccr_mask = 0; 886 for (i = 0; i < rmsz; i++) 887 state->pf->ccr_mask |= 888 ((pccard_tuple_read_1(tuple, 889 2 + rasz + i)) << (i * 8)); 890 891 /* skip the reserved area and subtuples */ 892 893 /* reset the default cfe for each cfe list */ 894 state->temp_cfe = init_cfe; 895 state->default_cfe = &state->temp_cfe; 896 } 897 DPRINTF(("CISTPL_CONFIG\n")); 898 break; 899 case CISTPL_CFTABLE_ENTRY: 900 {
|