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 } 359 list_for_each_entry(cis, &s->cis_cache, node) { 360 int len = cis->len; 361 362 if (len > 256) 363 len = 256; 364 #ifdef CONFIG_CARDBUS 365 if (s->state & SOCKET_CARDBUS) 366 read_cb_mem(s, cis->attr, cis->addr, len, buf); 367 else 368 #endif 369 pcmcia_read_cis_mem(s, cis->attr, cis->addr, len, buf); 370 371 if (memcmp(buf, cis->cache, len) != 0) { 372 kfree(buf); 373 return -1; 374 } 375 } 376 kfree(buf); 377 return 0; 378 } 379 380 /*====================================================================== 381 382 For really bad cards, we provide a facility for uploading a 383 replacement CIS. 384 385 ======================================================================*/ 386 387 int pcmcia_replace_cis(struct pcmcia_socket *s, 388 const u8 *data, const size_t len) 389 { 390 if (len > CISTPL_MAX_CIS_SIZE) { 391 dev_printk(KERN_WARNING, &s->dev, "replacement CIS too big\n"); 392 return -EINVAL; 393 } 394 kfree(s->fake_cis); 395 s->fake_cis = kmalloc(len, GFP_KERNEL); 396 if (s->fake_cis == NULL) { 397 dev_printk(KERN_WARNING, &s->dev, "no memory to replace CIS\n"); 398 return -ENOMEM; 399 } 400 s->fake_cis_len = len; 401 memcpy(s->fake_cis, data, len); 402 return 0; 403 } 404 EXPORT_SYMBOL(pcmcia_replace_cis); 405 406 /*====================================================================== 407 408 The high-level CIS tuple services 409 410 ======================================================================*/ 411 412 typedef struct tuple_flags { 413 u_int link_space:4; 414 u_int has_link:1; 415 u_int mfc_fn:3; 416 u_int space:4; 417 } tuple_flags; 418 419 #define LINK_SPACE(f) (((tuple_flags *)(&(f)))->link_space) 420 #define HAS_LINK(f) (((tuple_flags *)(&(f)))->has_link) 421 #define MFC_FN(f) (((tuple_flags *)(&(f)))->mfc_fn) 422 #define SPACE(f) (((tuple_flags *)(&(f)))->space) 423 424 int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int func, tuple_t *tuple); 425 426 int pccard_get_first_tuple(struct pcmcia_socket *s, unsigned int function, tuple_t *tuple) 427 { 428 if (!s) 429 return -EINVAL; 430 if (!(s->state & SOCKET_PRESENT)) 431 return -ENODEV; 432 tuple->TupleLink = tuple->Flags = 0; 433 #ifdef CONFIG_CARDBUS 434 if (s->state & SOCKET_CARDBUS) { 435 struct pci_dev *dev = s->cb_dev; 436 u_int ptr; 437 pci_bus_read_config_dword(dev->subordinate, 0, PCI_CARDBUS_CIS, &ptr); 438 tuple->CISOffset = ptr & ~7; 439 SPACE(tuple->Flags) = (ptr & 7); 440 } else 441 #endif 442 { 443 /* Assume presence of a LONGLINK_C to address 0 */ 444 tuple->CISOffset = tuple->LinkOffset = 0; 445 SPACE(tuple->Flags) = HAS_LINK(tuple->Flags) = 1; 446 } 447 if (!(s->state & SOCKET_CARDBUS) && (s->functions > 1) && 448 !(tuple->Attributes & TUPLE_RETURN_COMMON)) { 449 cisdata_t req = tuple->DesiredTuple; 450 tuple->DesiredTuple = CISTPL_LONGLINK_MFC; 451 if (pccard_get_next_tuple(s, function, tuple) == 0) { 452 tuple->DesiredTuple = CISTPL_LINKTARGET; 453 if (pccard_get_next_tuple(s, function, tuple) != 0) 454 return -ENOSPC; 455 } else 456 tuple->CISOffset = tuple->TupleLink = 0; 457 tuple->DesiredTuple = req; 458 } 459 return pccard_get_next_tuple(s, function, tuple); 460 } 461 EXPORT_SYMBOL(pccard_get_first_tuple); 462 463 static int follow_link(struct pcmcia_socket *s, tuple_t *tuple) 464 { 465 u_char link[5]; 466 u_int ofs; 467 468 if (MFC_FN(tuple->Flags)) { 469 /* Get indirect link from the MFC tuple */ 470 read_cis_cache(s, LINK_SPACE(tuple->Flags), 471 tuple->LinkOffset, 5, link); 472 ofs = get_unaligned_le32(link + 1); 473 SPACE(tuple->Flags) = (link[0] == CISTPL_MFC_ATTR); 474 /* Move to the next indirect link */ 475 tuple->LinkOffset += 5; 476 MFC_FN(tuple->Flags)--; 477 } else if (HAS_LINK(tuple->Flags)) { 478 ofs = tuple->LinkOffset; 479 SPACE(tuple->Flags) = LINK_SPACE(tuple->Flags); 480 HAS_LINK(tuple->Flags) = 0; 481 } else { 482 return -1; 483 } 484 if (!(s->state & SOCKET_CARDBUS) && SPACE(tuple->Flags)) { 485 /* This is ugly, but a common CIS error is to code the long 486 link offset incorrectly, so we check the right spot... */ 487 read_cis_cache(s, SPACE(tuple->Flags), ofs, 5, link); 488 if ((link[0] == CISTPL_LINKTARGET) && (link[1] >= 3) && 489 (strncmp(link+2, "CIS", 3) == 0)) 490 return ofs; 491 remove_cis_cache(s, SPACE(tuple->Flags), ofs, 5); 492 /* Then, we try the wrong spot... */ 493 ofs = ofs >> 1; 494 } 495 read_cis_cache(s, SPACE(tuple->Flags), ofs, 5, link); 496 if ((link[0] == CISTPL_LINKTARGET) && (link[1] >= 3) && 497 (strncmp(link+2, "CIS", 3) == 0)) 498 return ofs; 499 remove_cis_cache(s, SPACE(tuple->Flags), ofs, 5); 500 return -1; 501 } 502 503 int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, tuple_t *tuple) 504 { 505 u_char link[2], tmp; 506 int ofs, i, attr; 507 508 if (!s) 509 return -EINVAL; 510 if (!(s->state & SOCKET_PRESENT)) 511 return -ENODEV; 512 513 link[1] = tuple->TupleLink; 514 ofs = tuple->CISOffset + tuple->TupleLink; 515 attr = SPACE(tuple->Flags); 516 517 for (i = 0; i < MAX_TUPLES; i++) { 518 if (link[1] == 0xff) { 519 link[0] = CISTPL_END; 520 } else { 521 read_cis_cache(s, attr, ofs, 2, link); 522 if (link[0] == CISTPL_NULL) { 523 ofs++; continue; 524 } 525 } 526 527 /* End of chain? Follow long link if possible */ 528 if (link[0] == CISTPL_END) { 529 if ((ofs = follow_link(s, tuple)) < 0) 530 return -ENOSPC; 531 attr = SPACE(tuple->Flags); 532 read_cis_cache(s, attr, ofs, 2, link); 533 } 534 535 /* Is this a link tuple? Make a note of it */ 536 if ((link[0] == CISTPL_LONGLINK_A) || 537 (link[0] == CISTPL_LONGLINK_C) || 538 (link[0] == CISTPL_LONGLINK_MFC) || 539 (link[0] == CISTPL_LINKTARGET) || 540 (link[0] == CISTPL_INDIRECT) || 541 (link[0] == CISTPL_NO_LINK)) { 542 switch (link[0]) { 543 case CISTPL_LONGLINK_A: 544 HAS_LINK(tuple->Flags) = 1; 545 LINK_SPACE(tuple->Flags) = attr | IS_ATTR; 546 read_cis_cache(s, attr, ofs+2, 4, &tuple->LinkOffset); 547 break; 548 case CISTPL_LONGLINK_C: 549 HAS_LINK(tuple->Flags) = 1; 550 LINK_SPACE(tuple->Flags) = attr & ~IS_ATTR; 551 read_cis_cache(s, attr, ofs+2, 4, &tuple->LinkOffset); 552 break; 553 case CISTPL_INDIRECT: 554 HAS_LINK(tuple->Flags) = 1; 555 LINK_SPACE(tuple->Flags) = IS_ATTR | IS_INDIRECT; 556 tuple->LinkOffset = 0; 557 break; 558 case CISTPL_LONGLINK_MFC: 559 tuple->LinkOffset = ofs + 3; 560 LINK_SPACE(tuple->Flags) = attr; 561 if (function == BIND_FN_ALL) { 562 /* Follow all the MFC links */ 563 read_cis_cache(s, attr, ofs+2, 1, &tmp); 564 MFC_FN(tuple->Flags) = tmp; 565 } else { 566 /* Follow exactly one of the links */ 567 MFC_FN(tuple->Flags) = 1; 568 tuple->LinkOffset += function * 5; 569 } 570 break; 571 case CISTPL_NO_LINK: 572 HAS_LINK(tuple->Flags) = 0; 573 break; 574 } 575 if ((tuple->Attributes & TUPLE_RETURN_LINK) && 576 (tuple->DesiredTuple == RETURN_FIRST_TUPLE)) 577 break; 578 } else 579 if (tuple->DesiredTuple == RETURN_FIRST_TUPLE) 580 break; 581 582 if (link[0] == tuple->DesiredTuple) 583 break; 584 ofs += link[1] + 2; 585 } 586 if (i == MAX_TUPLES) { 587 cs_dbg(s, 1, "cs: overrun in pcmcia_get_next_tuple\n"); 588 return -ENOSPC; 589 } 590 591 tuple->TupleCode = link[0]; 592 tuple->TupleLink = link[1]; 593 tuple->CISOffset = ofs + 2; 594 return 0; 595 } 596 EXPORT_SYMBOL(pccard_get_next_tuple); 597 598 /*====================================================================*/ 599 600 #define _MIN(a, b) (((a) < (b)) ? (a) : (b)) 601 602 int pccard_get_tuple_data(struct pcmcia_socket *s, tuple_t *tuple) 603 { 604 u_int len; 605 606 if (!s) 607 return -EINVAL; 608 609 if (tuple->TupleLink < tuple->TupleOffset) 610 return -ENOSPC; 611 len = tuple->TupleLink - tuple->TupleOffset; 612 tuple->TupleDataLen = tuple->TupleLink; 613 if (len == 0) 614 return 0; 615 read_cis_cache(s, SPACE(tuple->Flags), 616 tuple->CISOffset + tuple->TupleOffset, 617 _MIN(len, tuple->TupleDataMax), tuple->TupleData); 618 return 0; 619 } 620 EXPORT_SYMBOL(pccard_get_tuple_data); 621 622 623 /*====================================================================== 624 625 Parsing routines for individual tuples 626 627 ======================================================================*/ 628 629 static int parse_device(tuple_t *tuple, cistpl_device_t *device) 630 { 631 int i; 632 u_char scale; 633 u_char *p, *q; 634 635 p = (u_char *)tuple->TupleData; 636 q = p + tuple->TupleDataLen; 637 638 device->ndev = 0; 639 for (i = 0; i < CISTPL_MAX_DEVICES; i++) { 640 641 if (*p == 0xff) break; 642 device->dev[i].type = (*p >> 4); 643 device->dev[i].wp = (*p & 0x08) ? 1 : 0; 644 switch (*p & 0x07) { 645 case 0: device->dev[i].speed = 0; break; 646 case 1: device->dev[i].speed = 250; break; 647 case 2: device->dev[i].speed = 200; break; 648 case 3: device->dev[i].speed = 150; break; 649 case 4: device->dev[i].speed = 100; break; 650 case 7: 651 if (++p == q) 652 return -EINVAL; 653 device->dev[i].speed = SPEED_CVT(*p); 654 while (*p & 0x80) 655 if (++p == q) 656 return -EINVAL; 657 break; 658 default: 659 return -EINVAL; 660 } 661 662 if (++p == q) 663 return -EINVAL; 664 if (*p == 0xff) 665 break; 666 scale = *p & 7; 667 if (scale == 7) 668 return -EINVAL; 669 device->dev[i].size = ((*p >> 3) + 1) * (512 << (scale*2)); 670 device->ndev++; 671 if (++p == q) 672 break; 673 } 674 675 return 0; 676 } 677 678 /*====================================================================*/ 679 680 static int parse_checksum(tuple_t *tuple, cistpl_checksum_t *csum) 681 { 682 u_char *p; 683 if (tuple->TupleDataLen < 5) 684 return -EINVAL; 685 p = (u_char *) tuple->TupleData; 686 csum->addr = tuple->CISOffset + get_unaligned_le16(p) - 2; 687 csum->len = get_unaligned_le16(p + 2); 688 csum->sum = *(p + 4); 689 return 0; 690 } 691 692 /*====================================================================*/ 693 694 static int parse_longlink(tuple_t *tuple, cistpl_longlink_t *link) 695 { 696 if (tuple->TupleDataLen < 4) 697 return -EINVAL; 698 link->addr = get_unaligned_le32(tuple->TupleData); 699 return 0; 700 } 701 702 /*====================================================================*/ 703 704 static int parse_longlink_mfc(tuple_t *tuple, 705 cistpl_longlink_mfc_t *link) 706 { 707 u_char *p; 708 int i; 709 710 p = (u_char *)tuple->TupleData; 711 712 link->nfn = *p; p++; 713 if (tuple->TupleDataLen <= link->nfn*5) 714 return -EINVAL; 715 for (i = 0; i < link->nfn; i++) { 716 link->fn[i].space = *p; p++; 717 link->fn[i].addr = get_unaligned_le32(p); 718 p += 4; 719 } 720 return 0; 721 } 722 723 /*====================================================================*/ 724 725 static int parse_strings(u_char *p, u_char *q, int max, 726 char *s, u_char *ofs, u_char *found) 727 { 728 int i, j, ns; 729 730 if (p == q) 731 return -EINVAL; 732 ns = 0; j = 0; 733 for (i = 0; i < max; i++) { 734 if (*p == 0xff) 735 break; 736 ofs[i] = j; 737 ns++; 738 for (;;) { 739 s[j++] = (*p == 0xff) ? '\0' : *p; 740 if ((*p == '\0') || (*p == 0xff)) break; 741 if (++p == q) 742 return -EINVAL; 743 } 744 if ((*p == 0xff) || (++p == q)) break; 745 } 746 if (found) { 747 *found = ns; 748 return 0; 749 } else { 750 return (ns == max) ? 0 : -EINVAL; 751 } 752 } 753 754 /*====================================================================*/ 755 756 static int parse_vers_1(tuple_t *tuple, cistpl_vers_1_t *vers_1) 757 { 758 u_char *p, *q; 759 760 p = (u_char *)tuple->TupleData; 761 q = p + tuple->TupleDataLen; 762 763 vers_1->major = *p; p++; 764 vers_1->minor = *p; p++; 765 if (p >= q) 766 return -EINVAL; 767 768 return parse_strings(p, q, CISTPL_VERS_1_MAX_PROD_STRINGS, 769 vers_1->str, vers_1->ofs, &vers_1->ns); 770 } 771 772 /*====================================================================*/ 773 774 static int parse_altstr(tuple_t *tuple, cistpl_altstr_t *altstr) 775 { 776 u_char *p, *q; 777 778 p = (u_char *)tuple->TupleData; 779 q = p + tuple->TupleDataLen; 780 781 return parse_strings(p, q, CISTPL_MAX_ALTSTR_STRINGS, 782 altstr->str, altstr->ofs, &altstr->ns); 783 } 784 785 /*====================================================================*/ 786 787 static int parse_jedec(tuple_t *tuple, cistpl_jedec_t *jedec) 788 { 789 u_char *p, *q; 790 int nid; 791 792 p = (u_char *)tuple->TupleData; 793 q = p + tuple->TupleDataLen; 794 795 for (nid = 0; nid < CISTPL_MAX_DEVICES; nid++) { 796 if (p > q-2) break; 797 jedec->id[nid].mfr = p[0]; 798 jedec->id[nid].info = p[1]; 799 p += 2; 800 } 801 jedec->nid = nid; 802 return 0; 803 } 804 805 /*====================================================================*/ 806 807 static int parse_manfid(tuple_t *tuple, cistpl_manfid_t *m) 808 { 809 if (tuple->TupleDataLen < 4) 810 return -EINVAL; 811 m->manf = get_unaligned_le16(tuple->TupleData); 812 m->card = get_unaligned_le16(tuple->TupleData + 2); 813 return 0; 814 } 815 816 /*====================================================================*/ 817 818 static int parse_funcid(tuple_t *tuple, cistpl_funcid_t *f) 819 { 820 u_char *p; 821 if (tuple->TupleDataLen < 2) 822 return -EINVAL; 823 p = (u_char *)tuple->TupleData; 824 f->func = p[0]; 825 f->sysinit = p[1]; 826 return 0; 827 } 828 829 /*====================================================================*/ 830 831 static int parse_funce(tuple_t *tuple, cistpl_funce_t *f) 832 { 833 u_char *p; 834 int i; 835 if (tuple->TupleDataLen < 1) 836 return -EINVAL; 837 p = (u_char *)tuple->TupleData; 838 f->type = p[0]; 839 for (i = 1; i < tuple->TupleDataLen; i++) 840 f->data[i-1] = p[i]; 841 return 0; 842 } 843 844 /*====================================================================*/ 845 846 static int parse_config(tuple_t *tuple, cistpl_config_t *config) 847 { 848 int rasz, rmsz, i; 849 u_char *p; 850 851 p = (u_char *)tuple->TupleData; 852 rasz = *p & 0x03; 853 rmsz = (*p & 0x3c) >> 2; 854 if (tuple->TupleDataLen < rasz+rmsz+4) 855 return -EINVAL; 856 config->last_idx = *(++p); 857 p++; 858 config->base = 0; 859 for (i = 0; i <= rasz; i++) 860 config->base += p[i] << (8*i); 861 p += rasz+1; 862 for (i = 0; i < 4; i++) 863 config->rmask[i] = 0; 864 for (i = 0; i <= rmsz; i++) 865 config->rmask[i>>2] += p[i] << (8*(i%4)); 866 config->subtuples = tuple->TupleDataLen - (rasz+rmsz+4); 867 return 0; 868 } 869 870 /*====================================================================== 871 872 The following routines are all used to parse the nightmarish 873 config table entries. 874 875 ======================================================================*/ 876 877 static u_char *parse_power(u_char *p, u_char *q, 878 cistpl_power_t *pwr) 879 { 880 int i; 881 u_int scale; 882 883 if (p == q) return NULL; 884 pwr->present = *p; 885 pwr->flags = 0; 886 p++; 887 for (i = 0; i < 7; i++) 888 if (pwr->present & (1<<i)) { 889 if (p == q) return NULL; 890 pwr->param[i] = POWER_CVT(*p); 891 scale = POWER_SCALE(*p); 892 while (*p & 0x80) { 893 if (++p == q) return NULL; 894 if ((*p & 0x7f) < 100) 895 pwr->param[i] += (*p & 0x7f) * scale / 100; 896 else if (*p == 0x7d) 897 pwr->flags |= CISTPL_POWER_HIGHZ_OK; 898 else if (*p == 0x7e) 899 pwr->param[i] = 0; 900 else if (*p == 0x7f) 901 pwr->flags |= CISTPL_POWER_HIGHZ_REQ; 902 else 903 return NULL; 904 } 905 p++; 906 } 907 return p; 908 } 909 910 /*====================================================================*/ 911 912 static u_char *parse_timing(u_char *p, u_char *q, 913 cistpl_timing_t *timing) 914 { 915 u_char scale; 916 917 if (p == q) return NULL; 918 scale = *p; 919 if ((scale & 3) != 3) { 920 if (++p == q) return NULL; 921 timing->wait = SPEED_CVT(*p); 922 timing->waitscale = exponent[scale & 3]; 923 } else 924 timing->wait = 0; 925 scale >>= 2; 926 if ((scale & 7) != 7) { 927 if (++p == q) return NULL; 928 timing->ready = SPEED_CVT(*p); 929 timing->rdyscale = exponent[scale & 7]; 930 } else 931 timing->ready = 0; 932 scale >>= 3; 933 if (scale != 7) { 934 if (++p == q) return NULL; 935 timing->reserved = SPEED_CVT(*p); 936 timing->rsvscale = exponent[scale]; 937 } else 938 timing->reserved = 0; 939 p++; 940 return p; 941 } 942 943 /*====================================================================*/ 944 945 static u_char *parse_io(u_char *p, u_char *q, cistpl_io_t *io) 946 { 947 int i, j, bsz, lsz; 948 949 if (p == q) return NULL; 950 io->flags = *p; 951 952 if (!(*p & 0x80)) { 953 io->nwin = 1; 954 io->win[0].base = 0; 955 io->win[0].len = (1 << (io->flags & CISTPL_IO_LINES_MASK)); 956 return p+1; 957 } 958 959 if (++p == q) return NULL; 960 io->nwin = (*p & 0x0f) + 1; 961 bsz = (*p & 0x30) >> 4; 962 if (bsz == 3) bsz++; 963 lsz = (*p & 0xc0) >> 6; 964 if (lsz == 3) lsz++; 965 p++; 966 967 for (i = 0; i < io->nwin; i++) { 968 io->win[i].base = 0; 969 io->win[i].len = 1; 970 for (j = 0; j < bsz; j++, p++) { 971 if (p == q) return NULL; 972 io->win[i].base += *p << (j*8); 973 } 974 for (j = 0; j < lsz; j++, p++) { 975 if (p == q) return NULL; 976 io->win[i].len += *p << (j*8); 977 } 978 } 979 return p; 980 } 981 982 /*====================================================================*/ 983 984 static u_char *parse_mem(u_char *p, u_char *q, cistpl_mem_t *mem) 985 { 986 int i, j, asz, lsz, has_ha; 987 u_int len, ca, ha; 988 989 if (p == q) return NULL; 990 991 mem->nwin = (*p & 0x07) + 1; 992 lsz = (*p & 0x18) >> 3; 993 asz = (*p & 0x60) >> 5; 994 has_ha = (*p & 0x80); 995 if (++p == q) return NULL; 996 997 for (i = 0; i < mem->nwin; i++) { 998 len = ca = ha = 0; 999 for (j = 0; j < lsz; j++, p++) { 1000 if (p == q) return NULL; 1001 len += *p << (j*8); 1002 } 1003 for (j = 0; j < asz; j++, p++) { 1004 if (p == q) return NULL; 1005 ca += *p << (j*8); 1006 } 1007 if (has_ha) 1008 for (j = 0; j < asz; j++, p++) { 1009 if (p == q) return NULL; 1010 ha += *p << (j*8); 1011 } 1012 mem->win[i].len = len << 8; 1013 mem->win[i].card_addr = ca << 8; 1014 mem->win[i].host_addr = ha << 8; 1015 } 1016 return p; 1017 } 1018 1019 /*====================================================================*/ 1020 1021 static u_char *parse_irq(u_char *p, u_char *q, cistpl_irq_t *irq) 1022 { 1023 if (p == q) 1024 return NULL; 1025 irq->IRQInfo1 = *p; p++; 1026 if (irq->IRQInfo1 & IRQ_INFO2_VALID) { 1027 if (p+2 > q) 1028 return NULL; 1029 irq->IRQInfo2 = (p[1]<<8) + p[0]; 1030 p += 2; 1031 } 1032 return p; 1033 } 1034 1035 /*====================================================================*/ 1036 1037 static int parse_cftable_entry(tuple_t *tuple, 1038 cistpl_cftable_entry_t *entry) 1039 { 1040 u_char *p, *q, features; 1041 1042 p = tuple->TupleData; 1043 q = p + tuple->TupleDataLen; 1044 entry->index = *p & 0x3f; 1045 entry->flags = 0; 1046 if (*p & 0x40) 1047 entry->flags |= CISTPL_CFTABLE_DEFAULT; 1048 if (*p & 0x80) { 1049 if (++p == q) 1050 return -EINVAL; 1051 if (*p & 0x10) 1052 entry->flags |= CISTPL_CFTABLE_BVDS; 1053 if (*p & 0x20) 1054 entry->flags |= CISTPL_CFTABLE_WP; 1055 if (*p & 0x40) 1056 entry->flags |= CISTPL_CFTABLE_RDYBSY; 1057 if (*p & 0x80) 1058 entry->flags |= CISTPL_CFTABLE_MWAIT; 1059 entry->interface = *p & 0x0f; 1060 } else 1061 entry->interface = 0; 1062 1063 /* Process optional features */ 1064 if (++p == q) 1065 return -EINVAL; 1066 features = *p; p++; 1067 1068 /* Power options */ 1069 if ((features & 3) > 0) { 1070 p = parse_power(p, q, &entry->vcc); 1071 if (p == NULL) 1072 return -EINVAL; 1073 } else 1074 entry->vcc.present = 0; 1075 if ((features & 3) > 1) { 1076 p = parse_power(p, q, &entry->vpp1); 1077 if (p == NULL) 1078 return -EINVAL; 1079 } else 1080 entry->vpp1.present = 0; 1081 if ((features & 3) > 2) { 1082 p = parse_power(p, q, &entry->vpp2); 1083 if (p == NULL) 1084 return -EINVAL; 1085 } else 1086 entry->vpp2.present = 0; 1087 1088 /* Timing options */ 1089 if (features & 0x04) { 1090 p = parse_timing(p, q, &entry->timing); 1091 if (p == NULL) 1092 return -EINVAL; 1093 } else { 1094 entry->timing.wait = 0; 1095 entry->timing.ready = 0; 1096 entry->timing.reserved = 0; 1097 } 1098 1099 /* I/O window options */ 1100 if (features & 0x08) { 1101 p = parse_io(p, q, &entry->io); 1102 if (p == NULL) 1103 return -EINVAL; 1104 } else 1105 entry->io.nwin = 0; 1106 1107 /* Interrupt options */ 1108 if (features & 0x10) { 1109 p = parse_irq(p, q, &entry->irq); 1110 if (p == NULL) 1111 return -EINVAL; 1112 } else 1113 entry->irq.IRQInfo1 = 0; 1114 1115 switch (features & 0x60) { 1116 case 0x00: 1117 entry->mem.nwin = 0; 1118 break; 1119 case 0x20: 1120 entry->mem.nwin = 1; 1121 entry->mem.win[0].len = get_unaligned_le16(p) << 8; 1122 entry->mem.win[0].card_addr = 0; 1123 entry->mem.win[0].host_addr = 0; 1124 p += 2; 1125 if (p > q) 1126 return -EINVAL; 1127 break; 1128 case 0x40: 1129 entry->mem.nwin = 1; 1130 entry->mem.win[0].len = get_unaligned_le16(p) << 8; 1131 entry->mem.win[0].card_addr = get_unaligned_le16(p + 2) << 8; 1132 entry->mem.win[0].host_addr = 0; 1133 p += 4; 1134 if (p > q) 1135 return -EINVAL; 1136 break; 1137 case 0x60: 1138 p = parse_mem(p, q, &entry->mem); 1139 if (p == NULL) 1140 return -EINVAL; 1141 break; 1142 } 1143 1144 /* Misc features */ 1145 if (features & 0x80) { 1146 if (p == q) 1147 return -EINVAL; 1148 entry->flags |= (*p << 8); 1149 while (*p & 0x80) 1150 if (++p == q) 1151 return -EINVAL; 1152 p++; 1153 } 1154 1155 entry->subtuples = q-p; 1156 1157 return 0; 1158 } 1159 1160 /*====================================================================*/ 1161 1162 #ifdef CONFIG_CARDBUS 1163 1164 static int parse_bar(tuple_t *tuple, cistpl_bar_t *bar) 1165 { 1166 u_char *p; 1167 if (tuple->TupleDataLen < 6) 1168 return -EINVAL; 1169 p = (u_char *)tuple->TupleData; 1170 bar->attr = *p; 1171 p += 2; 1172 bar->size = get_unaligned_le32(p); 1173 return 0; 1174 } 1175 1176 static int parse_config_cb(tuple_t *tuple, cistpl_config_t *config) 1177 { 1178 u_char *p; 1179 1180 p = (u_char *)tuple->TupleData; 1181 if ((*p != 3) || (tuple->TupleDataLen < 6)) 1182 return -EINVAL; 1183 config->last_idx = *(++p); 1184 p++; 1185 config->base = get_unaligned_le32(p); 1186 config->subtuples = tuple->TupleDataLen - 6; 1187 return 0; 1188 } 1189 1190 static int parse_cftable_entry_cb(tuple_t *tuple, 1191 cistpl_cftable_entry_cb_t *entry) 1192 { 1193 u_char *p, *q, features; 1194 1195 p = tuple->TupleData; 1196 q = p + tuple->TupleDataLen; 1197 entry->index = *p & 0x3f; 1198 entry->flags = 0; 1199 if (*p & 0x40) 1200 entry->flags |= CISTPL_CFTABLE_DEFAULT; 1201 1202 /* Process optional features */ 1203 if (++p == q) 1204 return -EINVAL; 1205 features = *p; p++; 1206 1207 /* Power options */ 1208 if ((features & 3) > 0) { 1209 p = parse_power(p, q, &entry->vcc); 1210 if (p == NULL) 1211 return -EINVAL; 1212 } else 1213 entry->vcc.present = 0; 1214 if ((features & 3) > 1) { 1215 p = parse_power(p, q, &entry->vpp1); 1216 if (p == NULL) 1217 return -EINVAL; 1218 } else 1219 entry->vpp1.present = 0; 1220 if ((features & 3) > 2) { 1221 p = parse_power(p, q, &entry->vpp2); 1222 if (p == NULL) 1223 return -EINVAL; 1224 } else 1225 entry->vpp2.present = 0; 1226 1227 /* I/O window options */ 1228 if (features & 0x08) { 1229 if (p == q) 1230 return -EINVAL; 1231 entry->io = *p; p++; 1232 } else 1233 entry->io = 0; 1234 1235 /* Interrupt options */ 1236 if (features & 0x10) { 1237 p = parse_irq(p, q, &entry->irq); 1238 if (p == NULL) 1239 return -EINVAL; 1240 } else 1241 entry->irq.IRQInfo1 = 0; 1242 1243 if (features & 0x20) { 1244 if (p == q) 1245 return -EINVAL; 1246 entry->mem = *p; p++; 1247 } else 1248 entry->mem = 0; 1249 1250 /* Misc features */ 1251 if (features & 0x80) { 1252 if (p == q) 1253 return -EINVAL; 1254 entry->flags |= (*p << 8); 1255 if (*p & 0x80) { 1256 if (++p == q) 1257 return -EINVAL; 1258 entry->flags |= (*p << 16); 1259 } 1260 while (*p & 0x80) 1261 if (++p == q) 1262 return -EINVAL; 1263 p++; 1264 } 1265 1266 entry->subtuples = q-p; 1267 1268 return 0; 1269 } 1270 1271 #endif 1272 1273 /*====================================================================*/ 1274 1275 static int parse_device_geo(tuple_t *tuple, cistpl_device_geo_t *geo) 1276 { 1277 u_char *p, *q; 1278 int n; 1279 1280 p = (u_char *)tuple->TupleData; 1281 q = p + tuple->TupleDataLen; 1282 1283 for (n = 0; n < CISTPL_MAX_DEVICES; n++) { 1284 if (p > q-6) break; 1285 geo->geo[n].buswidth = p[0]; 1286 geo->geo[n].erase_block = 1 << (p[1]-1); 1287 geo->geo[n].read_block = 1 << (p[2]-1); 1288 geo->geo[n].write_block = 1 << (p[3]-1); 1289 geo->geo[n].partition = 1 << (p[4]-1); 1290 geo->geo[n].interleave = 1 << (p[5]-1); 1291 p += 6; 1292 } 1293 geo->ngeo = n; 1294 return 0; 1295 } 1296 1297 /*====================================================================*/ 1298 1299 static int parse_vers_2(tuple_t *tuple, cistpl_vers_2_t *v2) 1300 { 1301 u_char *p, *q; 1302 1303 if (tuple->TupleDataLen < 10) 1304 return -EINVAL; 1305 1306 p = tuple->TupleData; 1307 q = p + tuple->TupleDataLen; 1308 1309 v2->vers = p[0]; 1310 v2->comply = p[1]; 1311 v2->dindex = get_unaligned_le16(p +2 ); 1312 v2->vspec8 = p[6]; 1313 v2->vspec9 = p[7]; 1314 v2->nhdr = p[8]; 1315 p += 9; 1316 return parse_strings(p, q, 2, v2->str, &v2->vendor, NULL); 1317 } 1318 1319 /*====================================================================*/ 1320 1321 static int parse_org(tuple_t *tuple, cistpl_org_t *org) 1322 { 1323 u_char *p, *q; 1324 int i; 1325 1326 p = tuple->TupleData; 1327 q = p + tuple->TupleDataLen; 1328 if (p == q) 1329 return -EINVAL; 1330 org->data_org = *p; 1331 if (++p == q) 1332 return -EINVAL; 1333 for (i = 0; i < 30; i++) { 1334 org->desc[i] = *p; 1335 if (*p == '\0') break; 1336 if (++p == q) 1337 return -EINVAL; 1338 } 1339 return 0; 1340 } 1341 1342 /*====================================================================*/ 1343 1344 static int parse_format(tuple_t *tuple, cistpl_format_t *fmt) 1345 { 1346 u_char *p; 1347 1348 if (tuple->TupleDataLen < 10) 1349 return -EINVAL; 1350 1351 p = tuple->TupleData; 1352 1353 fmt->type = p[0]; 1354 fmt->edc = p[1]; 1355 fmt->offset = get_unaligned_le32(p + 2); 1356 fmt->length = get_unaligned_le32(p + 6); 1357 1358 return 0; 1359 } 1360 1361 /*====================================================================*/ 1362 1363 int pcmcia_parse_tuple(tuple_t *tuple, cisparse_t *parse) 1364 { 1365 int ret = 0; 1366 1367 if (tuple->TupleDataLen > tuple->TupleDataMax) 1368 return -EINVAL; 1369 switch (tuple->TupleCode) { 1370 case CISTPL_DEVICE: 1371 case CISTPL_DEVICE_A: 1372 ret = parse_device(tuple, &parse->device); 1373 break; 1374 #ifdef CONFIG_CARDBUS 1375 case CISTPL_BAR: 1376 ret = parse_bar(tuple, &parse->bar); 1377 break; 1378 case CISTPL_CONFIG_CB: 1379 ret = parse_config_cb(tuple, &parse->config); 1380 break; 1381 case CISTPL_CFTABLE_ENTRY_CB: 1382 ret = parse_cftable_entry_cb(tuple, &parse->cftable_entry_cb); 1383 break; 1384 #endif 1385 case CISTPL_CHECKSUM: 1386 ret = parse_checksum(tuple, &parse->checksum); 1387 break; 1388 case CISTPL_LONGLINK_A: 1389 case CISTPL_LONGLINK_C: 1390 ret = parse_longlink(tuple, &parse->longlink); 1391 break; 1392 case CISTPL_LONGLINK_MFC: 1393 ret = parse_longlink_mfc(tuple, &parse->longlink_mfc); 1394 break; 1395 case CISTPL_VERS_1: 1396 ret = parse_vers_1(tuple, &parse->version_1); 1397 break; 1398 case CISTPL_ALTSTR: 1399 ret = parse_altstr(tuple, &parse->altstr); 1400 break; 1401 case CISTPL_JEDEC_A: 1402 case CISTPL_JEDEC_C: 1403 ret = parse_jedec(tuple, &parse->jedec); 1404 break; 1405 case CISTPL_MANFID: 1406 ret = parse_manfid(tuple, &parse->manfid); 1407 break; 1408 case CISTPL_FUNCID: 1409 ret = parse_funcid(tuple, &parse->funcid); 1410 break; 1411 case CISTPL_FUNCE: 1412 ret = parse_funce(tuple, &parse->funce); 1413 break; 1414 case CISTPL_CONFIG: 1415 ret = parse_config(tuple, &parse->config); 1416 break; 1417 case CISTPL_CFTABLE_ENTRY: 1418 ret = parse_cftable_entry(tuple, &parse->cftable_entry); 1419 break; 1420 case CISTPL_DEVICE_GEO: 1421 case CISTPL_DEVICE_GEO_A: 1422 ret = parse_device_geo(tuple, &parse->device_geo); 1423 break; 1424 case CISTPL_VERS_2: 1425 ret = parse_vers_2(tuple, &parse->vers_2); 1426 break; 1427 case CISTPL_ORG: 1428 ret = parse_org(tuple, &parse->org); 1429 break; 1430 case CISTPL_FORMAT: 1431 case CISTPL_FORMAT_A: 1432 ret = parse_format(tuple, &parse->format); 1433 break; 1434 case CISTPL_NO_LINK: 1435 case CISTPL_LINKTARGET: 1436 ret = 0; 1437 break; 1438 default: 1439 ret = -EINVAL; 1440 break; 1441 } 1442 if (ret) 1443 __cs_dbg(0, "parse_tuple failed %d\n", ret); 1444 return ret; 1445 } 1446 EXPORT_SYMBOL(pcmcia_parse_tuple); 1447 1448 /*====================================================================== 1449 1450 This is used internally by Card Services to look up CIS stuff. 1451 1452 ======================================================================*/ 1453 1454 int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function, cisdata_t code, void *parse) 1455 { 1456 tuple_t tuple; 1457 cisdata_t *buf; 1458 int ret; 1459 1460 buf = kmalloc(256, GFP_KERNEL); 1461 if (buf == NULL) { 1462 dev_printk(KERN_WARNING, &s->dev, "no memory to read tuple\n"); 1463 return -ENOMEM; 1464 } 1465 tuple.DesiredTuple = code; 1466 tuple.Attributes = TUPLE_RETURN_COMMON; 1467 ret = pccard_get_first_tuple(s, function, &tuple); 1468 if (ret != 0) 1469 goto done; 1470 tuple.TupleData = buf; 1471 tuple.TupleOffset = 0; 1472 tuple.TupleDataMax = 255; 1473 ret = pccard_get_tuple_data(s, &tuple); 1474 if (ret != 0) 1475 goto done; 1476 ret = pcmcia_parse_tuple(&tuple, parse); 1477 done: 1478 kfree(buf); 1479 return ret; 1480 } 1481 EXPORT_SYMBOL(pccard_read_tuple); 1482 1483 /*====================================================================== 1484 1485 This tries to determine if a card has a sensible CIS. It returns 1486 the number of tuples in the CIS, or 0 if the CIS looks bad. The 1487 checks include making sure several critical tuples are present and 1488 valid; seeing if the total number of tuples is reasonable; and 1489 looking for tuples that use reserved codes. 1490 1491 ======================================================================*/ 1492 1493 int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function, unsigned int *info) 1494 { 1495 tuple_t *tuple; 1496 cisparse_t *p; 1497 unsigned int count = 0; 1498 int ret, reserved, dev_ok = 0, ident_ok = 0; 1499 1500 if (!s) 1501 return -EINVAL; 1502 1503 tuple = kmalloc(sizeof(*tuple), GFP_KERNEL); 1504 if (tuple == NULL) { 1505 dev_printk(KERN_WARNING, &s->dev, "no memory to validate CIS\n"); 1506 return -ENOMEM; 1507 } 1508 p = kmalloc(sizeof(*p), GFP_KERNEL); 1509 if (p == NULL) { 1510 kfree(tuple); 1511 dev_printk(KERN_WARNING, &s->dev, "no memory to validate CIS\n"); 1512 return -ENOMEM; 1513 } 1514 1515 count = reserved = 0; 1516 tuple->DesiredTuple = RETURN_FIRST_TUPLE; 1517 tuple->Attributes = TUPLE_RETURN_COMMON; 1518 ret = pccard_get_first_tuple(s, function, tuple); 1519 if (ret != 0) 1520 goto done; 1521 1522 /* First tuple should be DEVICE; we should really have either that 1523 or a CFTABLE_ENTRY of some sort */ 1524 if ((tuple->TupleCode == CISTPL_DEVICE) || 1525 (pccard_read_tuple(s, function, CISTPL_CFTABLE_ENTRY, p) == 0) || 1526 (pccard_read_tuple(s, function, CISTPL_CFTABLE_ENTRY_CB, p) == 0)) 1527 dev_ok++; 1528 1529 /* All cards should have a MANFID tuple, and/or a VERS_1 or VERS_2 1530 tuple, for card identification. Certain old D-Link and Linksys 1531 cards have only a broken VERS_2 tuple; hence the bogus test. */ 1532 if ((pccard_read_tuple(s, function, CISTPL_MANFID, p) == 0) || 1533 (pccard_read_tuple(s, function, CISTPL_VERS_1, p) == 0) || 1534 (pccard_read_tuple(s, function, CISTPL_VERS_2, p) != -ENOSPC)) 1535 ident_ok++; 1536 1537 if (!dev_ok && !ident_ok) 1538 goto done; 1539 1540 for (count = 1; count < MAX_TUPLES; count++) { 1541 ret = pccard_get_next_tuple(s, function, tuple); 1542 if (ret != 0) 1543 break; 1544 if (((tuple->TupleCode > 0x23) && (tuple->TupleCode < 0x40)) || 1545 ((tuple->TupleCode > 0x47) && (tuple->TupleCode < 0x80)) || 1546 ((tuple->TupleCode > 0x90) && (tuple->TupleCode < 0xff))) 1547 reserved++; 1548 } 1549 if ((count == MAX_TUPLES) || (reserved > 5) || 1550 ((!dev_ok || !ident_ok) && (count > 10))) 1551 count = 0; 1552 1553 done: 1554 if (info) 1555 *info = count; 1556 kfree(tuple); 1557 kfree(p); 1558 return 0; 1559 } 1560 EXPORT_SYMBOL(pccard_validate_cis); 1561