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