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