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