1 /* 2 * cistpl.c -- 16-bit PCMCIA Card Information Structure parser 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License version 2 as 6 * published by the Free Software Foundation. 7 * 8 * The initial developer of the original code is David A. Hinds 9 * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds 10 * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. 11 * 12 * (C) 1999 David A. Hinds 13 */ 14 15 #include <linux/config.h> 16 #include <linux/module.h> 17 #include <linux/moduleparam.h> 18 #include <linux/kernel.h> 19 #include <linux/string.h> 20 #include <linux/major.h> 21 #include <linux/errno.h> 22 #include <linux/timer.h> 23 #include <linux/slab.h> 24 #include <linux/mm.h> 25 #include <linux/sched.h> 26 #include <linux/pci.h> 27 #include <linux/ioport.h> 28 #include <asm/io.h> 29 #include <asm/byteorder.h> 30 31 #include <pcmcia/cs_types.h> 32 #include <pcmcia/ss.h> 33 #include <pcmcia/cs.h> 34 #include <pcmcia/bulkmem.h> 35 #include <pcmcia/cisreg.h> 36 #include <pcmcia/cistpl.h> 37 #include "cs_internal.h" 38 39 static const u_char mantissa[] = { 40 10, 12, 13, 15, 20, 25, 30, 35, 41 40, 45, 50, 55, 60, 70, 80, 90 42 }; 43 44 static const u_int exponent[] = { 45 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000 46 }; 47 48 /* Convert an extended speed byte to a time in nanoseconds */ 49 #define SPEED_CVT(v) \ 50 (mantissa[(((v)>>3)&15)-1] * exponent[(v)&7] / 10) 51 /* Convert a power byte to a current in 0.1 microamps */ 52 #define POWER_CVT(v) \ 53 (mantissa[((v)>>3)&15] * exponent[(v)&7] / 10) 54 #define POWER_SCALE(v) (exponent[(v)&7]) 55 56 /* Upper limit on reasonable # of tuples */ 57 #define MAX_TUPLES 200 58 59 /*====================================================================*/ 60 61 /* Parameters that can be set with 'insmod' */ 62 63 #define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0444) 64 65 INT_MODULE_PARM(cis_width, 0); /* 16-bit CIS? */ 66 67 void release_cis_mem(struct pcmcia_socket *s) 68 { 69 if (s->cis_mem.flags & MAP_ACTIVE) { 70 s->cis_mem.flags &= ~MAP_ACTIVE; 71 s->ops->set_mem_map(s, &s->cis_mem); 72 if (s->cis_mem.res) { 73 release_resource(s->cis_mem.res); 74 kfree(s->cis_mem.res); 75 s->cis_mem.res = NULL; 76 } 77 iounmap(s->cis_virt); 78 s->cis_virt = NULL; 79 } 80 } 81 EXPORT_SYMBOL(release_cis_mem); 82 83 /* 84 * Map the card memory at "card_offset" into virtual space. 85 * If flags & MAP_ATTRIB, map the attribute space, otherwise 86 * map the memory space. 87 */ 88 static void __iomem * 89 set_cis_map(struct pcmcia_socket *s, unsigned int card_offset, unsigned int flags) 90 { 91 pccard_mem_map *mem = &s->cis_mem; 92 int ret; 93 94 if (!(s->features & SS_CAP_STATIC_MAP) && mem->res == NULL) { 95 mem->res = pcmcia_find_mem_region(0, s->map_size, s->map_size, 0, s); 96 if (mem->res == NULL) { 97 printk(KERN_NOTICE "cs: unable to map card memory!\n"); 98 return NULL; 99 } 100 s->cis_virt = ioremap(mem->res->start, s->map_size); 101 } 102 mem->card_start = card_offset; 103 mem->flags = flags; 104 ret = s->ops->set_mem_map(s, mem); 105 if (ret) { 106 iounmap(s->cis_virt); 107 return NULL; 108 } 109 110 if (s->features & SS_CAP_STATIC_MAP) { 111 if (s->cis_virt) 112 iounmap(s->cis_virt); 113 s->cis_virt = ioremap(mem->static_start, s->map_size); 114 } 115 return s->cis_virt; 116 } 117 118 /*====================================================================== 119 120 Low-level functions to read and write CIS memory. I think the 121 write routine is only useful for writing one-byte registers. 122 123 ======================================================================*/ 124 125 /* Bits in attr field */ 126 #define IS_ATTR 1 127 #define IS_INDIRECT 8 128 129 int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, 130 u_int len, void *ptr) 131 { 132 void __iomem *sys, *end; 133 unsigned char *buf = ptr; 134 135 cs_dbg(s, 3, "pcmcia_read_cis_mem(%d, %#x, %u)\n", attr, addr, len); 136 137 if (attr & IS_INDIRECT) { 138 /* Indirect accesses use a bunch of special registers at fixed 139 locations in common memory */ 140 u_char flags = ICTRL0_COMMON|ICTRL0_AUTOINC|ICTRL0_BYTEGRAN; 141 if (attr & IS_ATTR) { 142 addr *= 2; 143 flags = ICTRL0_AUTOINC; 144 } 145 146 sys = set_cis_map(s, 0, MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0)); 147 if (!sys) { 148 memset(ptr, 0xff, len); 149 return -1; 150 } 151 152 writeb(flags, sys+CISREG_ICTRL0); 153 writeb(addr & 0xff, sys+CISREG_IADDR0); 154 writeb((addr>>8) & 0xff, sys+CISREG_IADDR1); 155 writeb((addr>>16) & 0xff, sys+CISREG_IADDR2); 156 writeb((addr>>24) & 0xff, sys+CISREG_IADDR3); 157 for ( ; len > 0; len--, buf++) 158 *buf = readb(sys+CISREG_IDATA0); 159 } else { 160 u_int inc = 1, card_offset, flags; 161 162 flags = MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0); 163 if (attr) { 164 flags |= MAP_ATTRIB; 165 inc++; 166 addr *= 2; 167 } 168 169 card_offset = addr & ~(s->map_size-1); 170 while (len) { 171 sys = set_cis_map(s, card_offset, flags); 172 if (!sys) { 173 memset(ptr, 0xff, len); 174 return -1; 175 } 176 end = sys + s->map_size; 177 sys = sys + (addr & (s->map_size-1)); 178 for ( ; len > 0; len--, buf++, sys += inc) { 179 if (sys == end) 180 break; 181 *buf = readb(sys); 182 } 183 card_offset += s->map_size; 184 addr = 0; 185 } 186 } 187 cs_dbg(s, 3, " %#2.2x %#2.2x %#2.2x %#2.2x ...\n", 188 *(u_char *)(ptr+0), *(u_char *)(ptr+1), 189 *(u_char *)(ptr+2), *(u_char *)(ptr+3)); 190 return 0; 191 } 192 EXPORT_SYMBOL(pcmcia_read_cis_mem); 193 194 195 void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, 196 u_int len, void *ptr) 197 { 198 void __iomem *sys, *end; 199 unsigned char *buf = ptr; 200 201 cs_dbg(s, 3, "pcmcia_write_cis_mem(%d, %#x, %u)\n", attr, addr, len); 202 203 if (attr & IS_INDIRECT) { 204 /* Indirect accesses use a bunch of special registers at fixed 205 locations in common memory */ 206 u_char flags = ICTRL0_COMMON|ICTRL0_AUTOINC|ICTRL0_BYTEGRAN; 207 if (attr & IS_ATTR) { 208 addr *= 2; 209 flags = ICTRL0_AUTOINC; 210 } 211 212 sys = set_cis_map(s, 0, MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0)); 213 if (!sys) 214 return; /* FIXME: Error */ 215 216 writeb(flags, sys+CISREG_ICTRL0); 217 writeb(addr & 0xff, sys+CISREG_IADDR0); 218 writeb((addr>>8) & 0xff, sys+CISREG_IADDR1); 219 writeb((addr>>16) & 0xff, sys+CISREG_IADDR2); 220 writeb((addr>>24) & 0xff, sys+CISREG_IADDR3); 221 for ( ; len > 0; len--, buf++) 222 writeb(*buf, sys+CISREG_IDATA0); 223 } else { 224 u_int inc = 1, card_offset, flags; 225 226 flags = MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0); 227 if (attr & IS_ATTR) { 228 flags |= MAP_ATTRIB; 229 inc++; 230 addr *= 2; 231 } 232 233 card_offset = addr & ~(s->map_size-1); 234 while (len) { 235 sys = set_cis_map(s, card_offset, flags); 236 if (!sys) 237 return; /* FIXME: error */ 238 239 end = sys + s->map_size; 240 sys = sys + (addr & (s->map_size-1)); 241 for ( ; len > 0; len--, buf++, sys += inc) { 242 if (sys == end) 243 break; 244 writeb(*buf, sys); 245 } 246 card_offset += s->map_size; 247 addr = 0; 248 } 249 } 250 } 251 EXPORT_SYMBOL(pcmcia_write_cis_mem); 252 253 254 /*====================================================================== 255 256 This is a wrapper around read_cis_mem, with the same interface, 257 but which caches information, for cards whose CIS may not be 258 readable all the time. 259 260 ======================================================================*/ 261 262 static void read_cis_cache(struct pcmcia_socket *s, int attr, u_int addr, 263 u_int len, void *ptr) 264 { 265 struct cis_cache_entry *cis; 266 int ret; 267 268 if (s->fake_cis) { 269 if (s->fake_cis_len > addr+len) 270 memcpy(ptr, s->fake_cis+addr, len); 271 else 272 memset(ptr, 0xff, len); 273 return; 274 } 275 276 list_for_each_entry(cis, &s->cis_cache, node) { 277 if (cis->addr == addr && cis->len == len && cis->attr == attr) { 278 memcpy(ptr, cis->cache, len); 279 return; 280 } 281 } 282 283 #ifdef CONFIG_CARDBUS 284 if (s->state & SOCKET_CARDBUS) 285 ret = read_cb_mem(s, attr, addr, len, ptr); 286 else 287 #endif 288 ret = pcmcia_read_cis_mem(s, attr, addr, len, ptr); 289 290 if (ret == 0) { 291 /* Copy data into the cache */ 292 cis = kmalloc(sizeof(struct cis_cache_entry) + len, GFP_KERNEL); 293 if (cis) { 294 cis->addr = addr; 295 cis->len = len; 296 cis->attr = attr; 297 memcpy(cis->cache, ptr, len); 298 list_add(&cis->node, &s->cis_cache); 299 } 300 } 301 } 302 303 static void 304 remove_cis_cache(struct pcmcia_socket *s, int attr, u_int addr, u_int len) 305 { 306 struct cis_cache_entry *cis; 307 308 list_for_each_entry(cis, &s->cis_cache, node) 309 if (cis->addr == addr && cis->len == len && cis->attr == attr) { 310 list_del(&cis->node); 311 kfree(cis); 312 break; 313 } 314 } 315 316 void destroy_cis_cache(struct pcmcia_socket *s) 317 { 318 struct list_head *l, *n; 319 320 list_for_each_safe(l, n, &s->cis_cache) { 321 struct cis_cache_entry *cis = list_entry(l, struct cis_cache_entry, node); 322 323 list_del(&cis->node); 324 kfree(cis); 325 } 326 327 /* 328 * If there was a fake CIS, destroy that as well. 329 */ 330 if (s->fake_cis) { 331 kfree(s->fake_cis); 332 s->fake_cis = NULL; 333 } 334 } 335 EXPORT_SYMBOL(destroy_cis_cache); 336 337 /*====================================================================== 338 339 This verifies if the CIS of a card matches what is in the CIS 340 cache. 341 342 ======================================================================*/ 343 344 int verify_cis_cache(struct pcmcia_socket *s) 345 { 346 struct cis_cache_entry *cis; 347 char *buf; 348 349 buf = kmalloc(256, GFP_KERNEL); 350 if (buf == NULL) 351 return -1; 352 list_for_each_entry(cis, &s->cis_cache, node) { 353 int len = cis->len; 354 355 if (len > 256) 356 len = 256; 357 #ifdef CONFIG_CARDBUS 358 if (s->state & SOCKET_CARDBUS) 359 read_cb_mem(s, cis->attr, cis->addr, len, buf); 360 else 361 #endif 362 pcmcia_read_cis_mem(s, cis->attr, cis->addr, len, buf); 363 364 if (memcmp(buf, cis->cache, len) != 0) { 365 kfree(buf); 366 return -1; 367 } 368 } 369 kfree(buf); 370 return 0; 371 } 372 373 /*====================================================================== 374 375 For really bad cards, we provide a facility for uploading a 376 replacement CIS. 377 378 ======================================================================*/ 379 380 int pcmcia_replace_cis(struct pcmcia_socket *s, cisdump_t *cis) 381 { 382 if (s->fake_cis != NULL) { 383 kfree(s->fake_cis); 384 s->fake_cis = NULL; 385 } 386 if (cis->Length > CISTPL_MAX_CIS_SIZE) 387 return CS_BAD_SIZE; 388 s->fake_cis = kmalloc(cis->Length, GFP_KERNEL); 389 if (s->fake_cis == NULL) 390 return CS_OUT_OF_RESOURCE; 391 s->fake_cis_len = cis->Length; 392 memcpy(s->fake_cis, cis->Data, cis->Length); 393 return CS_SUCCESS; 394 } 395 EXPORT_SYMBOL(pcmcia_replace_cis); 396 397 /*====================================================================== 398 399 The high-level CIS tuple services 400 401 ======================================================================*/ 402 403 typedef struct tuple_flags { 404 u_int link_space:4; 405 u_int has_link:1; 406 u_int mfc_fn:3; 407 u_int space:4; 408 } tuple_flags; 409 410 #define LINK_SPACE(f) (((tuple_flags *)(&(f)))->link_space) 411 #define HAS_LINK(f) (((tuple_flags *)(&(f)))->has_link) 412 #define MFC_FN(f) (((tuple_flags *)(&(f)))->mfc_fn) 413 #define SPACE(f) (((tuple_flags *)(&(f)))->space) 414 415 int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int func, tuple_t *tuple); 416 417 int pccard_get_first_tuple(struct pcmcia_socket *s, unsigned int function, tuple_t *tuple) 418 { 419 if (!s) 420 return CS_BAD_HANDLE; 421 if (!(s->state & SOCKET_PRESENT)) 422 return CS_NO_CARD; 423 tuple->TupleLink = tuple->Flags = 0; 424 #ifdef CONFIG_CARDBUS 425 if (s->state & SOCKET_CARDBUS) { 426 struct pci_dev *dev = s->cb_dev; 427 u_int ptr; 428 pci_bus_read_config_dword(dev->subordinate, 0, PCI_CARDBUS_CIS, &ptr); 429 tuple->CISOffset = ptr & ~7; 430 SPACE(tuple->Flags) = (ptr & 7); 431 } else 432 #endif 433 { 434 /* Assume presence of a LONGLINK_C to address 0 */ 435 tuple->CISOffset = tuple->LinkOffset = 0; 436 SPACE(tuple->Flags) = HAS_LINK(tuple->Flags) = 1; 437 } 438 if (!(s->state & SOCKET_CARDBUS) && (s->functions > 1) && 439 !(tuple->Attributes & TUPLE_RETURN_COMMON)) { 440 cisdata_t req = tuple->DesiredTuple; 441 tuple->DesiredTuple = CISTPL_LONGLINK_MFC; 442 if (pccard_get_next_tuple(s, function, tuple) == CS_SUCCESS) { 443 tuple->DesiredTuple = CISTPL_LINKTARGET; 444 if (pccard_get_next_tuple(s, function, tuple) != CS_SUCCESS) 445 return CS_NO_MORE_ITEMS; 446 } else 447 tuple->CISOffset = tuple->TupleLink = 0; 448 tuple->DesiredTuple = req; 449 } 450 return pccard_get_next_tuple(s, function, tuple); 451 } 452 EXPORT_SYMBOL(pccard_get_first_tuple); 453 454 static int follow_link(struct pcmcia_socket *s, tuple_t *tuple) 455 { 456 u_char link[5]; 457 u_int ofs; 458 459 if (MFC_FN(tuple->Flags)) { 460 /* Get indirect link from the MFC tuple */ 461 read_cis_cache(s, LINK_SPACE(tuple->Flags), 462 tuple->LinkOffset, 5, link); 463 ofs = le32_to_cpu(*(u_int *)(link+1)); 464 SPACE(tuple->Flags) = (link[0] == CISTPL_MFC_ATTR); 465 /* Move to the next indirect link */ 466 tuple->LinkOffset += 5; 467 MFC_FN(tuple->Flags)--; 468 } else if (HAS_LINK(tuple->Flags)) { 469 ofs = tuple->LinkOffset; 470 SPACE(tuple->Flags) = LINK_SPACE(tuple->Flags); 471 HAS_LINK(tuple->Flags) = 0; 472 } else { 473 return -1; 474 } 475 if (!(s->state & SOCKET_CARDBUS) && SPACE(tuple->Flags)) { 476 /* This is ugly, but a common CIS error is to code the long 477 link offset incorrectly, so we check the right spot... */ 478 read_cis_cache(s, SPACE(tuple->Flags), ofs, 5, link); 479 if ((link[0] == CISTPL_LINKTARGET) && (link[1] >= 3) && 480 (strncmp(link+2, "CIS", 3) == 0)) 481 return ofs; 482 remove_cis_cache(s, SPACE(tuple->Flags), ofs, 5); 483 /* Then, we try the wrong spot... */ 484 ofs = ofs >> 1; 485 } 486 read_cis_cache(s, SPACE(tuple->Flags), ofs, 5, link); 487 if ((link[0] == CISTPL_LINKTARGET) && (link[1] >= 3) && 488 (strncmp(link+2, "CIS", 3) == 0)) 489 return ofs; 490 remove_cis_cache(s, SPACE(tuple->Flags), ofs, 5); 491 return -1; 492 } 493 494 int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, tuple_t *tuple) 495 { 496 u_char link[2], tmp; 497 int ofs, i, attr; 498 499 if (!s) 500 return CS_BAD_HANDLE; 501 if (!(s->state & SOCKET_PRESENT)) 502 return CS_NO_CARD; 503 504 link[1] = tuple->TupleLink; 505 ofs = tuple->CISOffset + tuple->TupleLink; 506 attr = SPACE(tuple->Flags); 507 508 for (i = 0; i < MAX_TUPLES; i++) { 509 if (link[1] == 0xff) { 510 link[0] = CISTPL_END; 511 } else { 512 read_cis_cache(s, attr, ofs, 2, link); 513 if (link[0] == CISTPL_NULL) { 514 ofs++; continue; 515 } 516 } 517 518 /* End of chain? Follow long link if possible */ 519 if (link[0] == CISTPL_END) { 520 if ((ofs = follow_link(s, tuple)) < 0) 521 return CS_NO_MORE_ITEMS; 522 attr = SPACE(tuple->Flags); 523 read_cis_cache(s, attr, ofs, 2, link); 524 } 525 526 /* Is this a link tuple? Make a note of it */ 527 if ((link[0] == CISTPL_LONGLINK_A) || 528 (link[0] == CISTPL_LONGLINK_C) || 529 (link[0] == CISTPL_LONGLINK_MFC) || 530 (link[0] == CISTPL_LINKTARGET) || 531 (link[0] == CISTPL_INDIRECT) || 532 (link[0] == CISTPL_NO_LINK)) { 533 switch (link[0]) { 534 case CISTPL_LONGLINK_A: 535 HAS_LINK(tuple->Flags) = 1; 536 LINK_SPACE(tuple->Flags) = attr | IS_ATTR; 537 read_cis_cache(s, attr, ofs+2, 4, &tuple->LinkOffset); 538 break; 539 case CISTPL_LONGLINK_C: 540 HAS_LINK(tuple->Flags) = 1; 541 LINK_SPACE(tuple->Flags) = attr & ~IS_ATTR; 542 read_cis_cache(s, attr, ofs+2, 4, &tuple->LinkOffset); 543 break; 544 case CISTPL_INDIRECT: 545 HAS_LINK(tuple->Flags) = 1; 546 LINK_SPACE(tuple->Flags) = IS_ATTR | IS_INDIRECT; 547 tuple->LinkOffset = 0; 548 break; 549 case CISTPL_LONGLINK_MFC: 550 tuple->LinkOffset = ofs + 3; 551 LINK_SPACE(tuple->Flags) = attr; 552 if (function == BIND_FN_ALL) { 553 /* Follow all the MFC links */ 554 read_cis_cache(s, attr, ofs+2, 1, &tmp); 555 MFC_FN(tuple->Flags) = tmp; 556 } else { 557 /* Follow exactly one of the links */ 558 MFC_FN(tuple->Flags) = 1; 559 tuple->LinkOffset += function * 5; 560 } 561 break; 562 case CISTPL_NO_LINK: 563 HAS_LINK(tuple->Flags) = 0; 564 break; 565 } 566 if ((tuple->Attributes & TUPLE_RETURN_LINK) && 567 (tuple->DesiredTuple == RETURN_FIRST_TUPLE)) 568 break; 569 } else 570 if (tuple->DesiredTuple == RETURN_FIRST_TUPLE) 571 break; 572 573 if (link[0] == tuple->DesiredTuple) 574 break; 575 ofs += link[1] + 2; 576 } 577 if (i == MAX_TUPLES) { 578 cs_dbg(s, 1, "cs: overrun in pcmcia_get_next_tuple\n"); 579 return CS_NO_MORE_ITEMS; 580 } 581 582 tuple->TupleCode = link[0]; 583 tuple->TupleLink = link[1]; 584 tuple->CISOffset = ofs + 2; 585 return CS_SUCCESS; 586 } 587 EXPORT_SYMBOL(pccard_get_next_tuple); 588 589 /*====================================================================*/ 590 591 #define _MIN(a, b) (((a) < (b)) ? (a) : (b)) 592 593 int pccard_get_tuple_data(struct pcmcia_socket *s, tuple_t *tuple) 594 { 595 u_int len; 596 597 if (!s) 598 return CS_BAD_HANDLE; 599 600 if (tuple->TupleLink < tuple->TupleOffset) 601 return CS_NO_MORE_ITEMS; 602 len = tuple->TupleLink - tuple->TupleOffset; 603 tuple->TupleDataLen = tuple->TupleLink; 604 if (len == 0) 605 return CS_SUCCESS; 606 read_cis_cache(s, SPACE(tuple->Flags), 607 tuple->CISOffset + tuple->TupleOffset, 608 _MIN(len, tuple->TupleDataMax), tuple->TupleData); 609 return CS_SUCCESS; 610 } 611 EXPORT_SYMBOL(pccard_get_tuple_data); 612 613 614 /*====================================================================== 615 616 Parsing routines for individual tuples 617 618 ======================================================================*/ 619 620 static int parse_device(tuple_t *tuple, cistpl_device_t *device) 621 { 622 int i; 623 u_char scale; 624 u_char *p, *q; 625 626 p = (u_char *)tuple->TupleData; 627 q = p + tuple->TupleDataLen; 628 629 device->ndev = 0; 630 for (i = 0; i < CISTPL_MAX_DEVICES; i++) { 631 632 if (*p == 0xff) break; 633 device->dev[i].type = (*p >> 4); 634 device->dev[i].wp = (*p & 0x08) ? 1 : 0; 635 switch (*p & 0x07) { 636 case 0: device->dev[i].speed = 0; break; 637 case 1: device->dev[i].speed = 250; break; 638 case 2: device->dev[i].speed = 200; break; 639 case 3: device->dev[i].speed = 150; break; 640 case 4: device->dev[i].speed = 100; break; 641 case 7: 642 if (++p == q) return CS_BAD_TUPLE; 643 device->dev[i].speed = SPEED_CVT(*p); 644 while (*p & 0x80) 645 if (++p == q) return CS_BAD_TUPLE; 646 break; 647 default: 648 return CS_BAD_TUPLE; 649 } 650 651 if (++p == q) return CS_BAD_TUPLE; 652 if (*p == 0xff) break; 653 scale = *p & 7; 654 if (scale == 7) return CS_BAD_TUPLE; 655 device->dev[i].size = ((*p >> 3) + 1) * (512 << (scale*2)); 656 device->ndev++; 657 if (++p == q) break; 658 } 659 660 return CS_SUCCESS; 661 } 662 663 /*====================================================================*/ 664 665 static int parse_checksum(tuple_t *tuple, cistpl_checksum_t *csum) 666 { 667 u_char *p; 668 if (tuple->TupleDataLen < 5) 669 return CS_BAD_TUPLE; 670 p = (u_char *)tuple->TupleData; 671 csum->addr = tuple->CISOffset+(short)le16_to_cpu(*(u_short *)p)-2; 672 csum->len = le16_to_cpu(*(u_short *)(p + 2)); 673 csum->sum = *(p+4); 674 return CS_SUCCESS; 675 } 676 677 /*====================================================================*/ 678 679 static int parse_longlink(tuple_t *tuple, cistpl_longlink_t *link) 680 { 681 if (tuple->TupleDataLen < 4) 682 return CS_BAD_TUPLE; 683 link->addr = le32_to_cpu(*(u_int *)tuple->TupleData); 684 return CS_SUCCESS; 685 } 686 687 /*====================================================================*/ 688 689 static int parse_longlink_mfc(tuple_t *tuple, 690 cistpl_longlink_mfc_t *link) 691 { 692 u_char *p; 693 int i; 694 695 p = (u_char *)tuple->TupleData; 696 697 link->nfn = *p; p++; 698 if (tuple->TupleDataLen <= link->nfn*5) 699 return CS_BAD_TUPLE; 700 for (i = 0; i < link->nfn; i++) { 701 link->fn[i].space = *p; p++; 702 link->fn[i].addr = le32_to_cpu(*(u_int *)p); p += 4; 703 } 704 return CS_SUCCESS; 705 } 706 707 /*====================================================================*/ 708 709 static int parse_strings(u_char *p, u_char *q, int max, 710 char *s, u_char *ofs, u_char *found) 711 { 712 int i, j, ns; 713 714 if (p == q) return CS_BAD_TUPLE; 715 ns = 0; j = 0; 716 for (i = 0; i < max; i++) { 717 if (*p == 0xff) break; 718 ofs[i] = j; 719 ns++; 720 for (;;) { 721 s[j++] = (*p == 0xff) ? '\0' : *p; 722 if ((*p == '\0') || (*p == 0xff)) break; 723 if (++p == q) return CS_BAD_TUPLE; 724 } 725 if ((*p == 0xff) || (++p == q)) break; 726 } 727 if (found) { 728 *found = ns; 729 return CS_SUCCESS; 730 } else { 731 return (ns == max) ? CS_SUCCESS : CS_BAD_TUPLE; 732 } 733 } 734 735 /*====================================================================*/ 736 737 static int parse_vers_1(tuple_t *tuple, cistpl_vers_1_t *vers_1) 738 { 739 u_char *p, *q; 740 741 p = (u_char *)tuple->TupleData; 742 q = p + tuple->TupleDataLen; 743 744 vers_1->major = *p; p++; 745 vers_1->minor = *p; p++; 746 if (p >= q) return CS_BAD_TUPLE; 747 748 return parse_strings(p, q, CISTPL_VERS_1_MAX_PROD_STRINGS, 749 vers_1->str, vers_1->ofs, &vers_1->ns); 750 } 751 752 /*====================================================================*/ 753 754 static int parse_altstr(tuple_t *tuple, cistpl_altstr_t *altstr) 755 { 756 u_char *p, *q; 757 758 p = (u_char *)tuple->TupleData; 759 q = p + tuple->TupleDataLen; 760 761 return parse_strings(p, q, CISTPL_MAX_ALTSTR_STRINGS, 762 altstr->str, altstr->ofs, &altstr->ns); 763 } 764 765 /*====================================================================*/ 766 767 static int parse_jedec(tuple_t *tuple, cistpl_jedec_t *jedec) 768 { 769 u_char *p, *q; 770 int nid; 771 772 p = (u_char *)tuple->TupleData; 773 q = p + tuple->TupleDataLen; 774 775 for (nid = 0; nid < CISTPL_MAX_DEVICES; nid++) { 776 if (p > q-2) break; 777 jedec->id[nid].mfr = p[0]; 778 jedec->id[nid].info = p[1]; 779 p += 2; 780 } 781 jedec->nid = nid; 782 return CS_SUCCESS; 783 } 784 785 /*====================================================================*/ 786 787 static int parse_manfid(tuple_t *tuple, cistpl_manfid_t *m) 788 { 789 u_short *p; 790 if (tuple->TupleDataLen < 4) 791 return CS_BAD_TUPLE; 792 p = (u_short *)tuple->TupleData; 793 m->manf = le16_to_cpu(p[0]); 794 m->card = le16_to_cpu(p[1]); 795 return CS_SUCCESS; 796 } 797 798 /*====================================================================*/ 799 800 static int parse_funcid(tuple_t *tuple, cistpl_funcid_t *f) 801 { 802 u_char *p; 803 if (tuple->TupleDataLen < 2) 804 return CS_BAD_TUPLE; 805 p = (u_char *)tuple->TupleData; 806 f->func = p[0]; 807 f->sysinit = p[1]; 808 return CS_SUCCESS; 809 } 810 811 /*====================================================================*/ 812 813 static int parse_funce(tuple_t *tuple, cistpl_funce_t *f) 814 { 815 u_char *p; 816 int i; 817 if (tuple->TupleDataLen < 1) 818 return CS_BAD_TUPLE; 819 p = (u_char *)tuple->TupleData; 820 f->type = p[0]; 821 for (i = 1; i < tuple->TupleDataLen; i++) 822 f->data[i-1] = p[i]; 823 return CS_SUCCESS; 824 } 825 826 /*====================================================================*/ 827 828 static int parse_config(tuple_t *tuple, cistpl_config_t *config) 829 { 830 int rasz, rmsz, i; 831 u_char *p; 832 833 p = (u_char *)tuple->TupleData; 834 rasz = *p & 0x03; 835 rmsz = (*p & 0x3c) >> 2; 836 if (tuple->TupleDataLen < rasz+rmsz+4) 837 return CS_BAD_TUPLE; 838 config->last_idx = *(++p); 839 p++; 840 config->base = 0; 841 for (i = 0; i <= rasz; i++) 842 config->base += p[i] << (8*i); 843 p += rasz+1; 844 for (i = 0; i < 4; i++) 845 config->rmask[i] = 0; 846 for (i = 0; i <= rmsz; i++) 847 config->rmask[i>>2] += p[i] << (8*(i%4)); 848 config->subtuples = tuple->TupleDataLen - (rasz+rmsz+4); 849 return CS_SUCCESS; 850 } 851 852 /*====================================================================== 853 854 The following routines are all used to parse the nightmarish 855 config table entries. 856 857 ======================================================================*/ 858 859 static u_char *parse_power(u_char *p, u_char *q, 860 cistpl_power_t *pwr) 861 { 862 int i; 863 u_int scale; 864 865 if (p == q) return NULL; 866 pwr->present = *p; 867 pwr->flags = 0; 868 p++; 869 for (i = 0; i < 7; i++) 870 if (pwr->present & (1<<i)) { 871 if (p == q) return NULL; 872 pwr->param[i] = POWER_CVT(*p); 873 scale = POWER_SCALE(*p); 874 while (*p & 0x80) { 875 if (++p == q) return NULL; 876 if ((*p & 0x7f) < 100) 877 pwr->param[i] += (*p & 0x7f) * scale / 100; 878 else if (*p == 0x7d) 879 pwr->flags |= CISTPL_POWER_HIGHZ_OK; 880 else if (*p == 0x7e) 881 pwr->param[i] = 0; 882 else if (*p == 0x7f) 883 pwr->flags |= CISTPL_POWER_HIGHZ_REQ; 884 else 885 return NULL; 886 } 887 p++; 888 } 889 return p; 890 } 891 892 /*====================================================================*/ 893 894 static u_char *parse_timing(u_char *p, u_char *q, 895 cistpl_timing_t *timing) 896 { 897 u_char scale; 898 899 if (p == q) return NULL; 900 scale = *p; 901 if ((scale & 3) != 3) { 902 if (++p == q) return NULL; 903 timing->wait = SPEED_CVT(*p); 904 timing->waitscale = exponent[scale & 3]; 905 } else 906 timing->wait = 0; 907 scale >>= 2; 908 if ((scale & 7) != 7) { 909 if (++p == q) return NULL; 910 timing->ready = SPEED_CVT(*p); 911 timing->rdyscale = exponent[scale & 7]; 912 } else 913 timing->ready = 0; 914 scale >>= 3; 915 if (scale != 7) { 916 if (++p == q) return NULL; 917 timing->reserved = SPEED_CVT(*p); 918 timing->rsvscale = exponent[scale]; 919 } else 920 timing->reserved = 0; 921 p++; 922 return p; 923 } 924 925 /*====================================================================*/ 926 927 static u_char *parse_io(u_char *p, u_char *q, cistpl_io_t *io) 928 { 929 int i, j, bsz, lsz; 930 931 if (p == q) return NULL; 932 io->flags = *p; 933 934 if (!(*p & 0x80)) { 935 io->nwin = 1; 936 io->win[0].base = 0; 937 io->win[0].len = (1 << (io->flags & CISTPL_IO_LINES_MASK)); 938 return p+1; 939 } 940 941 if (++p == q) return NULL; 942 io->nwin = (*p & 0x0f) + 1; 943 bsz = (*p & 0x30) >> 4; 944 if (bsz == 3) bsz++; 945 lsz = (*p & 0xc0) >> 6; 946 if (lsz == 3) lsz++; 947 p++; 948 949 for (i = 0; i < io->nwin; i++) { 950 io->win[i].base = 0; 951 io->win[i].len = 1; 952 for (j = 0; j < bsz; j++, p++) { 953 if (p == q) return NULL; 954 io->win[i].base += *p << (j*8); 955 } 956 for (j = 0; j < lsz; j++, p++) { 957 if (p == q) return NULL; 958 io->win[i].len += *p << (j*8); 959 } 960 } 961 return p; 962 } 963 964 /*====================================================================*/ 965 966 static u_char *parse_mem(u_char *p, u_char *q, cistpl_mem_t *mem) 967 { 968 int i, j, asz, lsz, has_ha; 969 u_int len, ca, ha; 970 971 if (p == q) return NULL; 972 973 mem->nwin = (*p & 0x07) + 1; 974 lsz = (*p & 0x18) >> 3; 975 asz = (*p & 0x60) >> 5; 976 has_ha = (*p & 0x80); 977 if (++p == q) return NULL; 978 979 for (i = 0; i < mem->nwin; i++) { 980 len = ca = ha = 0; 981 for (j = 0; j < lsz; j++, p++) { 982 if (p == q) return NULL; 983 len += *p << (j*8); 984 } 985 for (j = 0; j < asz; j++, p++) { 986 if (p == q) return NULL; 987 ca += *p << (j*8); 988 } 989 if (has_ha) 990 for (j = 0; j < asz; j++, p++) { 991 if (p == q) return NULL; 992 ha += *p << (j*8); 993 } 994 mem->win[i].len = len << 8; 995 mem->win[i].card_addr = ca << 8; 996 mem->win[i].host_addr = ha << 8; 997 } 998 return p; 999 } 1000 1001 /*====================================================================*/ 1002 1003 static u_char *parse_irq(u_char *p, u_char *q, cistpl_irq_t *irq) 1004 { 1005 if (p == q) return NULL; 1006 irq->IRQInfo1 = *p; p++; 1007 if (irq->IRQInfo1 & IRQ_INFO2_VALID) { 1008 if (p+2 > q) return NULL; 1009 irq->IRQInfo2 = (p[1]<<8) + p[0]; 1010 p += 2; 1011 } 1012 return p; 1013 } 1014 1015 /*====================================================================*/ 1016 1017 static int parse_cftable_entry(tuple_t *tuple, 1018 cistpl_cftable_entry_t *entry) 1019 { 1020 u_char *p, *q, features; 1021 1022 p = tuple->TupleData; 1023 q = p + tuple->TupleDataLen; 1024 entry->index = *p & 0x3f; 1025 entry->flags = 0; 1026 if (*p & 0x40) 1027 entry->flags |= CISTPL_CFTABLE_DEFAULT; 1028 if (*p & 0x80) { 1029 if (++p == q) return CS_BAD_TUPLE; 1030 if (*p & 0x10) 1031 entry->flags |= CISTPL_CFTABLE_BVDS; 1032 if (*p & 0x20) 1033 entry->flags |= CISTPL_CFTABLE_WP; 1034 if (*p & 0x40) 1035 entry->flags |= CISTPL_CFTABLE_RDYBSY; 1036 if (*p & 0x80) 1037 entry->flags |= CISTPL_CFTABLE_MWAIT; 1038 entry->interface = *p & 0x0f; 1039 } else 1040 entry->interface = 0; 1041 1042 /* Process optional features */ 1043 if (++p == q) return CS_BAD_TUPLE; 1044 features = *p; p++; 1045 1046 /* Power options */ 1047 if ((features & 3) > 0) { 1048 p = parse_power(p, q, &entry->vcc); 1049 if (p == NULL) return CS_BAD_TUPLE; 1050 } else 1051 entry->vcc.present = 0; 1052 if ((features & 3) > 1) { 1053 p = parse_power(p, q, &entry->vpp1); 1054 if (p == NULL) return CS_BAD_TUPLE; 1055 } else 1056 entry->vpp1.present = 0; 1057 if ((features & 3) > 2) { 1058 p = parse_power(p, q, &entry->vpp2); 1059 if (p == NULL) return CS_BAD_TUPLE; 1060 } else 1061 entry->vpp2.present = 0; 1062 1063 /* Timing options */ 1064 if (features & 0x04) { 1065 p = parse_timing(p, q, &entry->timing); 1066 if (p == NULL) return CS_BAD_TUPLE; 1067 } else { 1068 entry->timing.wait = 0; 1069 entry->timing.ready = 0; 1070 entry->timing.reserved = 0; 1071 } 1072 1073 /* I/O window options */ 1074 if (features & 0x08) { 1075 p = parse_io(p, q, &entry->io); 1076 if (p == NULL) return CS_BAD_TUPLE; 1077 } else 1078 entry->io.nwin = 0; 1079 1080 /* Interrupt options */ 1081 if (features & 0x10) { 1082 p = parse_irq(p, q, &entry->irq); 1083 if (p == NULL) return CS_BAD_TUPLE; 1084 } else 1085 entry->irq.IRQInfo1 = 0; 1086 1087 switch (features & 0x60) { 1088 case 0x00: 1089 entry->mem.nwin = 0; 1090 break; 1091 case 0x20: 1092 entry->mem.nwin = 1; 1093 entry->mem.win[0].len = le16_to_cpu(*(u_short *)p) << 8; 1094 entry->mem.win[0].card_addr = 0; 1095 entry->mem.win[0].host_addr = 0; 1096 p += 2; 1097 if (p > q) return CS_BAD_TUPLE; 1098 break; 1099 case 0x40: 1100 entry->mem.nwin = 1; 1101 entry->mem.win[0].len = le16_to_cpu(*(u_short *)p) << 8; 1102 entry->mem.win[0].card_addr = 1103 le16_to_cpu(*(u_short *)(p+2)) << 8; 1104 entry->mem.win[0].host_addr = 0; 1105 p += 4; 1106 if (p > q) return CS_BAD_TUPLE; 1107 break; 1108 case 0x60: 1109 p = parse_mem(p, q, &entry->mem); 1110 if (p == NULL) return CS_BAD_TUPLE; 1111 break; 1112 } 1113 1114 /* Misc features */ 1115 if (features & 0x80) { 1116 if (p == q) return CS_BAD_TUPLE; 1117 entry->flags |= (*p << 8); 1118 while (*p & 0x80) 1119 if (++p == q) return CS_BAD_TUPLE; 1120 p++; 1121 } 1122 1123 entry->subtuples = q-p; 1124 1125 return CS_SUCCESS; 1126 } 1127 1128 /*====================================================================*/ 1129 1130 #ifdef CONFIG_CARDBUS 1131 1132 static int parse_bar(tuple_t *tuple, cistpl_bar_t *bar) 1133 { 1134 u_char *p; 1135 if (tuple->TupleDataLen < 6) 1136 return CS_BAD_TUPLE; 1137 p = (u_char *)tuple->TupleData; 1138 bar->attr = *p; 1139 p += 2; 1140 bar->size = le32_to_cpu(*(u_int *)p); 1141 return CS_SUCCESS; 1142 } 1143 1144 static int parse_config_cb(tuple_t *tuple, cistpl_config_t *config) 1145 { 1146 u_char *p; 1147 1148 p = (u_char *)tuple->TupleData; 1149 if ((*p != 3) || (tuple->TupleDataLen < 6)) 1150 return CS_BAD_TUPLE; 1151 config->last_idx = *(++p); 1152 p++; 1153 config->base = le32_to_cpu(*(u_int *)p); 1154 config->subtuples = tuple->TupleDataLen - 6; 1155 return CS_SUCCESS; 1156 } 1157 1158 static int parse_cftable_entry_cb(tuple_t *tuple, 1159 cistpl_cftable_entry_cb_t *entry) 1160 { 1161 u_char *p, *q, features; 1162 1163 p = tuple->TupleData; 1164 q = p + tuple->TupleDataLen; 1165 entry->index = *p & 0x3f; 1166 entry->flags = 0; 1167 if (*p & 0x40) 1168 entry->flags |= CISTPL_CFTABLE_DEFAULT; 1169 1170 /* Process optional features */ 1171 if (++p == q) return CS_BAD_TUPLE; 1172 features = *p; p++; 1173 1174 /* Power options */ 1175 if ((features & 3) > 0) { 1176 p = parse_power(p, q, &entry->vcc); 1177 if (p == NULL) return CS_BAD_TUPLE; 1178 } else 1179 entry->vcc.present = 0; 1180 if ((features & 3) > 1) { 1181 p = parse_power(p, q, &entry->vpp1); 1182 if (p == NULL) return CS_BAD_TUPLE; 1183 } else 1184 entry->vpp1.present = 0; 1185 if ((features & 3) > 2) { 1186 p = parse_power(p, q, &entry->vpp2); 1187 if (p == NULL) return CS_BAD_TUPLE; 1188 } else 1189 entry->vpp2.present = 0; 1190 1191 /* I/O window options */ 1192 if (features & 0x08) { 1193 if (p == q) return CS_BAD_TUPLE; 1194 entry->io = *p; p++; 1195 } else 1196 entry->io = 0; 1197 1198 /* Interrupt options */ 1199 if (features & 0x10) { 1200 p = parse_irq(p, q, &entry->irq); 1201 if (p == NULL) return CS_BAD_TUPLE; 1202 } else 1203 entry->irq.IRQInfo1 = 0; 1204 1205 if (features & 0x20) { 1206 if (p == q) return CS_BAD_TUPLE; 1207 entry->mem = *p; p++; 1208 } else 1209 entry->mem = 0; 1210 1211 /* Misc features */ 1212 if (features & 0x80) { 1213 if (p == q) return CS_BAD_TUPLE; 1214 entry->flags |= (*p << 8); 1215 if (*p & 0x80) { 1216 if (++p == q) return CS_BAD_TUPLE; 1217 entry->flags |= (*p << 16); 1218 } 1219 while (*p & 0x80) 1220 if (++p == q) return CS_BAD_TUPLE; 1221 p++; 1222 } 1223 1224 entry->subtuples = q-p; 1225 1226 return CS_SUCCESS; 1227 } 1228 1229 #endif 1230 1231 /*====================================================================*/ 1232 1233 static int parse_device_geo(tuple_t *tuple, cistpl_device_geo_t *geo) 1234 { 1235 u_char *p, *q; 1236 int n; 1237 1238 p = (u_char *)tuple->TupleData; 1239 q = p + tuple->TupleDataLen; 1240 1241 for (n = 0; n < CISTPL_MAX_DEVICES; n++) { 1242 if (p > q-6) break; 1243 geo->geo[n].buswidth = p[0]; 1244 geo->geo[n].erase_block = 1 << (p[1]-1); 1245 geo->geo[n].read_block = 1 << (p[2]-1); 1246 geo->geo[n].write_block = 1 << (p[3]-1); 1247 geo->geo[n].partition = 1 << (p[4]-1); 1248 geo->geo[n].interleave = 1 << (p[5]-1); 1249 p += 6; 1250 } 1251 geo->ngeo = n; 1252 return CS_SUCCESS; 1253 } 1254 1255 /*====================================================================*/ 1256 1257 static int parse_vers_2(tuple_t *tuple, cistpl_vers_2_t *v2) 1258 { 1259 u_char *p, *q; 1260 1261 if (tuple->TupleDataLen < 10) 1262 return CS_BAD_TUPLE; 1263 1264 p = tuple->TupleData; 1265 q = p + tuple->TupleDataLen; 1266 1267 v2->vers = p[0]; 1268 v2->comply = p[1]; 1269 v2->dindex = le16_to_cpu(*(u_short *)(p+2)); 1270 v2->vspec8 = p[6]; 1271 v2->vspec9 = p[7]; 1272 v2->nhdr = p[8]; 1273 p += 9; 1274 return parse_strings(p, q, 2, v2->str, &v2->vendor, NULL); 1275 } 1276 1277 /*====================================================================*/ 1278 1279 static int parse_org(tuple_t *tuple, cistpl_org_t *org) 1280 { 1281 u_char *p, *q; 1282 int i; 1283 1284 p = tuple->TupleData; 1285 q = p + tuple->TupleDataLen; 1286 if (p == q) return CS_BAD_TUPLE; 1287 org->data_org = *p; 1288 if (++p == q) return CS_BAD_TUPLE; 1289 for (i = 0; i < 30; i++) { 1290 org->desc[i] = *p; 1291 if (*p == '\0') break; 1292 if (++p == q) return CS_BAD_TUPLE; 1293 } 1294 return CS_SUCCESS; 1295 } 1296 1297 /*====================================================================*/ 1298 1299 static int parse_format(tuple_t *tuple, cistpl_format_t *fmt) 1300 { 1301 u_char *p; 1302 1303 if (tuple->TupleDataLen < 10) 1304 return CS_BAD_TUPLE; 1305 1306 p = tuple->TupleData; 1307 1308 fmt->type = p[0]; 1309 fmt->edc = p[1]; 1310 fmt->offset = le32_to_cpu(*(u_int *)(p+2)); 1311 fmt->length = le32_to_cpu(*(u_int *)(p+6)); 1312 1313 return CS_SUCCESS; 1314 } 1315 1316 /*====================================================================*/ 1317 1318 int pccard_parse_tuple(tuple_t *tuple, cisparse_t *parse) 1319 { 1320 int ret = CS_SUCCESS; 1321 1322 if (tuple->TupleDataLen > tuple->TupleDataMax) 1323 return CS_BAD_TUPLE; 1324 switch (tuple->TupleCode) { 1325 case CISTPL_DEVICE: 1326 case CISTPL_DEVICE_A: 1327 ret = parse_device(tuple, &parse->device); 1328 break; 1329 #ifdef CONFIG_CARDBUS 1330 case CISTPL_BAR: 1331 ret = parse_bar(tuple, &parse->bar); 1332 break; 1333 case CISTPL_CONFIG_CB: 1334 ret = parse_config_cb(tuple, &parse->config); 1335 break; 1336 case CISTPL_CFTABLE_ENTRY_CB: 1337 ret = parse_cftable_entry_cb(tuple, &parse->cftable_entry_cb); 1338 break; 1339 #endif 1340 case CISTPL_CHECKSUM: 1341 ret = parse_checksum(tuple, &parse->checksum); 1342 break; 1343 case CISTPL_LONGLINK_A: 1344 case CISTPL_LONGLINK_C: 1345 ret = parse_longlink(tuple, &parse->longlink); 1346 break; 1347 case CISTPL_LONGLINK_MFC: 1348 ret = parse_longlink_mfc(tuple, &parse->longlink_mfc); 1349 break; 1350 case CISTPL_VERS_1: 1351 ret = parse_vers_1(tuple, &parse->version_1); 1352 break; 1353 case CISTPL_ALTSTR: 1354 ret = parse_altstr(tuple, &parse->altstr); 1355 break; 1356 case CISTPL_JEDEC_A: 1357 case CISTPL_JEDEC_C: 1358 ret = parse_jedec(tuple, &parse->jedec); 1359 break; 1360 case CISTPL_MANFID: 1361 ret = parse_manfid(tuple, &parse->manfid); 1362 break; 1363 case CISTPL_FUNCID: 1364 ret = parse_funcid(tuple, &parse->funcid); 1365 break; 1366 case CISTPL_FUNCE: 1367 ret = parse_funce(tuple, &parse->funce); 1368 break; 1369 case CISTPL_CONFIG: 1370 ret = parse_config(tuple, &parse->config); 1371 break; 1372 case CISTPL_CFTABLE_ENTRY: 1373 ret = parse_cftable_entry(tuple, &parse->cftable_entry); 1374 break; 1375 case CISTPL_DEVICE_GEO: 1376 case CISTPL_DEVICE_GEO_A: 1377 ret = parse_device_geo(tuple, &parse->device_geo); 1378 break; 1379 case CISTPL_VERS_2: 1380 ret = parse_vers_2(tuple, &parse->vers_2); 1381 break; 1382 case CISTPL_ORG: 1383 ret = parse_org(tuple, &parse->org); 1384 break; 1385 case CISTPL_FORMAT: 1386 case CISTPL_FORMAT_A: 1387 ret = parse_format(tuple, &parse->format); 1388 break; 1389 case CISTPL_NO_LINK: 1390 case CISTPL_LINKTARGET: 1391 ret = CS_SUCCESS; 1392 break; 1393 default: 1394 ret = CS_UNSUPPORTED_FUNCTION; 1395 break; 1396 } 1397 return ret; 1398 } 1399 EXPORT_SYMBOL(pccard_parse_tuple); 1400 1401 /*====================================================================== 1402 1403 This is used internally by Card Services to look up CIS stuff. 1404 1405 ======================================================================*/ 1406 1407 int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function, cisdata_t code, void *parse) 1408 { 1409 tuple_t tuple; 1410 cisdata_t *buf; 1411 int ret; 1412 1413 buf = kmalloc(256, GFP_KERNEL); 1414 if (buf == NULL) 1415 return CS_OUT_OF_RESOURCE; 1416 tuple.DesiredTuple = code; 1417 tuple.Attributes = TUPLE_RETURN_COMMON; 1418 ret = pccard_get_first_tuple(s, function, &tuple); 1419 if (ret != CS_SUCCESS) goto done; 1420 tuple.TupleData = buf; 1421 tuple.TupleOffset = 0; 1422 tuple.TupleDataMax = 255; 1423 ret = pccard_get_tuple_data(s, &tuple); 1424 if (ret != CS_SUCCESS) goto done; 1425 ret = pccard_parse_tuple(&tuple, parse); 1426 done: 1427 kfree(buf); 1428 return ret; 1429 } 1430 EXPORT_SYMBOL(pccard_read_tuple); 1431 1432 /*====================================================================== 1433 1434 This tries to determine if a card has a sensible CIS. It returns 1435 the number of tuples in the CIS, or 0 if the CIS looks bad. The 1436 checks include making sure several critical tuples are present and 1437 valid; seeing if the total number of tuples is reasonable; and 1438 looking for tuples that use reserved codes. 1439 1440 ======================================================================*/ 1441 1442 int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function, cisinfo_t *info) 1443 { 1444 tuple_t *tuple; 1445 cisparse_t *p; 1446 int ret, reserved, dev_ok = 0, ident_ok = 0; 1447 1448 if (!s) 1449 return CS_BAD_HANDLE; 1450 1451 tuple = kmalloc(sizeof(*tuple), GFP_KERNEL); 1452 if (tuple == NULL) 1453 return CS_OUT_OF_RESOURCE; 1454 p = kmalloc(sizeof(*p), GFP_KERNEL); 1455 if (p == NULL) { 1456 kfree(tuple); 1457 return CS_OUT_OF_RESOURCE; 1458 } 1459 1460 info->Chains = reserved = 0; 1461 tuple->DesiredTuple = RETURN_FIRST_TUPLE; 1462 tuple->Attributes = TUPLE_RETURN_COMMON; 1463 ret = pccard_get_first_tuple(s, function, tuple); 1464 if (ret != CS_SUCCESS) 1465 goto done; 1466 1467 /* First tuple should be DEVICE; we should really have either that 1468 or a CFTABLE_ENTRY of some sort */ 1469 if ((tuple->TupleCode == CISTPL_DEVICE) || 1470 (pccard_read_tuple(s, function, CISTPL_CFTABLE_ENTRY, p) == CS_SUCCESS) || 1471 (pccard_read_tuple(s, function, CISTPL_CFTABLE_ENTRY_CB, p) == CS_SUCCESS)) 1472 dev_ok++; 1473 1474 /* All cards should have a MANFID tuple, and/or a VERS_1 or VERS_2 1475 tuple, for card identification. Certain old D-Link and Linksys 1476 cards have only a broken VERS_2 tuple; hence the bogus test. */ 1477 if ((pccard_read_tuple(s, function, CISTPL_MANFID, p) == CS_SUCCESS) || 1478 (pccard_read_tuple(s, function, CISTPL_VERS_1, p) == CS_SUCCESS) || 1479 (pccard_read_tuple(s, function, CISTPL_VERS_2, p) != CS_NO_MORE_ITEMS)) 1480 ident_ok++; 1481 1482 if (!dev_ok && !ident_ok) 1483 goto done; 1484 1485 for (info->Chains = 1; info->Chains < MAX_TUPLES; info->Chains++) { 1486 ret = pccard_get_next_tuple(s, function, tuple); 1487 if (ret != CS_SUCCESS) break; 1488 if (((tuple->TupleCode > 0x23) && (tuple->TupleCode < 0x40)) || 1489 ((tuple->TupleCode > 0x47) && (tuple->TupleCode < 0x80)) || 1490 ((tuple->TupleCode > 0x90) && (tuple->TupleCode < 0xff))) 1491 reserved++; 1492 } 1493 if ((info->Chains == MAX_TUPLES) || (reserved > 5) || 1494 ((!dev_ok || !ident_ok) && (info->Chains > 10))) 1495 info->Chains = 0; 1496 1497 done: 1498 kfree(tuple); 1499 kfree(p); 1500 return CS_SUCCESS; 1501 } 1502 EXPORT_SYMBOL(pccard_validate_cis); 1503