lpfc: Initiator sends wrong BBCredit value for either FLOGI or FLOGI_ACC
[linux-2.6/btrfs-unstable.git] / drivers / pcmcia / cistpl.c
blob64d0515b76bd5ade5136b46a566f78d9c23ba831
1 /*
2 * cistpl.c -- 16-bit PCMCIA Card Information Structure parser
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.
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.
12 * (C) 1999 David A. Hinds
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 <linux/io.h>
27 #include <asm/byteorder.h>
28 #include <asm/unaligned.h>
30 #include <pcmcia/ss.h>
31 #include <pcmcia/cisreg.h>
32 #include <pcmcia/cistpl.h>
33 #include "cs_internal.h"
35 static const u_char mantissa[] = {
36 10, 12, 13, 15, 20, 25, 30, 35,
37 40, 45, 50, 55, 60, 70, 80, 90
40 static const u_int exponent[] = {
41 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000
44 /* Convert an extended speed byte to a time in nanoseconds */
45 #define SPEED_CVT(v) \
46 (mantissa[(((v)>>3)&15)-1] * exponent[(v)&7] / 10)
47 /* Convert a power byte to a current in 0.1 microamps */
48 #define POWER_CVT(v) \
49 (mantissa[((v)>>3)&15] * exponent[(v)&7] / 10)
50 #define POWER_SCALE(v) (exponent[(v)&7])
52 /* Upper limit on reasonable # of tuples */
53 #define MAX_TUPLES 200
55 /* Bits in IRQInfo1 field */
56 #define IRQ_INFO2_VALID 0x10
58 /* 16-bit CIS? */
59 static int cis_width;
60 module_param(cis_width, int, 0444);
62 void release_cis_mem(struct pcmcia_socket *s)
64 mutex_lock(&s->ops_mutex);
65 if (s->cis_mem.flags & MAP_ACTIVE) {
66 s->cis_mem.flags &= ~MAP_ACTIVE;
67 s->ops->set_mem_map(s, &s->cis_mem);
68 if (s->cis_mem.res) {
69 release_resource(s->cis_mem.res);
70 kfree(s->cis_mem.res);
71 s->cis_mem.res = NULL;
73 iounmap(s->cis_virt);
74 s->cis_virt = NULL;
76 mutex_unlock(&s->ops_mutex);
79 /**
80 * set_cis_map() - map the card memory at "card_offset" into virtual space.
82 * If flags & MAP_ATTRIB, map the attribute space, otherwise
83 * map the memory space.
85 * Must be called with ops_mutex held.
87 static void __iomem *set_cis_map(struct pcmcia_socket *s,
88 unsigned int card_offset, unsigned int flags)
90 pccard_mem_map *mem = &s->cis_mem;
91 int ret;
93 if (!(s->features & SS_CAP_STATIC_MAP) && (mem->res == NULL)) {
94 mem->res = pcmcia_find_mem_region(0, s->map_size,
95 s->map_size, 0, s);
96 if (mem->res == NULL) {
97 dev_printk(KERN_NOTICE, &s->dev,
98 "cs: unable to map card memory!\n");
99 return NULL;
101 s->cis_virt = NULL;
104 if (!(s->features & SS_CAP_STATIC_MAP) && (!s->cis_virt))
105 s->cis_virt = ioremap(mem->res->start, s->map_size);
107 mem->card_start = card_offset;
108 mem->flags = flags;
110 ret = s->ops->set_mem_map(s, mem);
111 if (ret) {
112 iounmap(s->cis_virt);
113 s->cis_virt = NULL;
114 return NULL;
117 if (s->features & SS_CAP_STATIC_MAP) {
118 if (s->cis_virt)
119 iounmap(s->cis_virt);
120 s->cis_virt = ioremap(mem->static_start, s->map_size);
123 return s->cis_virt;
127 /* Bits in attr field */
128 #define IS_ATTR 1
129 #define IS_INDIRECT 8
132 * pcmcia_read_cis_mem() - low-level function to read CIS memory
134 * must be called with ops_mutex held
136 int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
137 u_int len, void *ptr)
139 void __iomem *sys, *end;
140 unsigned char *buf = ptr;
142 dev_dbg(&s->dev, "pcmcia_read_cis_mem(%d, %#x, %u)\n", attr, addr, len);
144 if (attr & IS_INDIRECT) {
145 /* Indirect accesses use a bunch of special registers at fixed
146 locations in common memory */
147 u_char flags = ICTRL0_COMMON|ICTRL0_AUTOINC|ICTRL0_BYTEGRAN;
148 if (attr & IS_ATTR) {
149 addr *= 2;
150 flags = ICTRL0_AUTOINC;
153 sys = set_cis_map(s, 0, MAP_ACTIVE |
154 ((cis_width) ? MAP_16BIT : 0));
155 if (!sys) {
156 dev_dbg(&s->dev, "could not map memory\n");
157 memset(ptr, 0xff, len);
158 return -1;
161 writeb(flags, sys+CISREG_ICTRL0);
162 writeb(addr & 0xff, sys+CISREG_IADDR0);
163 writeb((addr>>8) & 0xff, sys+CISREG_IADDR1);
164 writeb((addr>>16) & 0xff, sys+CISREG_IADDR2);
165 writeb((addr>>24) & 0xff, sys+CISREG_IADDR3);
166 for ( ; len > 0; len--, buf++)
167 *buf = readb(sys+CISREG_IDATA0);
168 } else {
169 u_int inc = 1, card_offset, flags;
171 if (addr > CISTPL_MAX_CIS_SIZE) {
172 dev_dbg(&s->dev,
173 "attempt to read CIS mem at addr %#x", addr);
174 memset(ptr, 0xff, len);
175 return -1;
178 flags = MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0);
179 if (attr) {
180 flags |= MAP_ATTRIB;
181 inc++;
182 addr *= 2;
185 card_offset = addr & ~(s->map_size-1);
186 while (len) {
187 sys = set_cis_map(s, card_offset, flags);
188 if (!sys) {
189 dev_dbg(&s->dev, "could not map memory\n");
190 memset(ptr, 0xff, len);
191 return -1;
193 end = sys + s->map_size;
194 sys = sys + (addr & (s->map_size-1));
195 for ( ; len > 0; len--, buf++, sys += inc) {
196 if (sys == end)
197 break;
198 *buf = readb(sys);
200 card_offset += s->map_size;
201 addr = 0;
204 dev_dbg(&s->dev, " %#2.2x %#2.2x %#2.2x %#2.2x ...\n",
205 *(u_char *)(ptr+0), *(u_char *)(ptr+1),
206 *(u_char *)(ptr+2), *(u_char *)(ptr+3));
207 return 0;
212 * pcmcia_write_cis_mem() - low-level function to write CIS memory
214 * Probably only useful for writing one-byte registers. Must be called
215 * with ops_mutex held.
217 int pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
218 u_int len, void *ptr)
220 void __iomem *sys, *end;
221 unsigned char *buf = ptr;
223 dev_dbg(&s->dev,
224 "pcmcia_write_cis_mem(%d, %#x, %u)\n", attr, addr, len);
226 if (attr & IS_INDIRECT) {
227 /* Indirect accesses use a bunch of special registers at fixed
228 locations in common memory */
229 u_char flags = ICTRL0_COMMON|ICTRL0_AUTOINC|ICTRL0_BYTEGRAN;
230 if (attr & IS_ATTR) {
231 addr *= 2;
232 flags = ICTRL0_AUTOINC;
235 sys = set_cis_map(s, 0, MAP_ACTIVE |
236 ((cis_width) ? MAP_16BIT : 0));
237 if (!sys) {
238 dev_dbg(&s->dev, "could not map memory\n");
239 return -EINVAL;
242 writeb(flags, sys+CISREG_ICTRL0);
243 writeb(addr & 0xff, sys+CISREG_IADDR0);
244 writeb((addr>>8) & 0xff, sys+CISREG_IADDR1);
245 writeb((addr>>16) & 0xff, sys+CISREG_IADDR2);
246 writeb((addr>>24) & 0xff, sys+CISREG_IADDR3);
247 for ( ; len > 0; len--, buf++)
248 writeb(*buf, sys+CISREG_IDATA0);
249 } else {
250 u_int inc = 1, card_offset, flags;
252 flags = MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0);
253 if (attr & IS_ATTR) {
254 flags |= MAP_ATTRIB;
255 inc++;
256 addr *= 2;
259 card_offset = addr & ~(s->map_size-1);
260 while (len) {
261 sys = set_cis_map(s, card_offset, flags);
262 if (!sys) {
263 dev_dbg(&s->dev, "could not map memory\n");
264 return -EINVAL;
267 end = sys + s->map_size;
268 sys = sys + (addr & (s->map_size-1));
269 for ( ; len > 0; len--, buf++, sys += inc) {
270 if (sys == end)
271 break;
272 writeb(*buf, sys);
274 card_offset += s->map_size;
275 addr = 0;
278 return 0;
283 * read_cis_cache() - read CIS memory or its associated cache
285 * This is a wrapper around read_cis_mem, with the same interface,
286 * but which caches information, for cards whose CIS may not be
287 * readable all the time.
289 static int read_cis_cache(struct pcmcia_socket *s, int attr, u_int addr,
290 size_t len, void *ptr)
292 struct cis_cache_entry *cis;
293 int ret = 0;
295 if (s->state & SOCKET_CARDBUS)
296 return -EINVAL;
298 mutex_lock(&s->ops_mutex);
299 if (s->fake_cis) {
300 if (s->fake_cis_len >= addr+len)
301 memcpy(ptr, s->fake_cis+addr, len);
302 else {
303 memset(ptr, 0xff, len);
304 ret = -EINVAL;
306 mutex_unlock(&s->ops_mutex);
307 return ret;
310 list_for_each_entry(cis, &s->cis_cache, node) {
311 if (cis->addr == addr && cis->len == len && cis->attr == attr) {
312 memcpy(ptr, cis->cache, len);
313 mutex_unlock(&s->ops_mutex);
314 return 0;
318 ret = pcmcia_read_cis_mem(s, attr, addr, len, ptr);
320 if (ret == 0) {
321 /* Copy data into the cache */
322 cis = kmalloc(sizeof(struct cis_cache_entry) + len, GFP_KERNEL);
323 if (cis) {
324 cis->addr = addr;
325 cis->len = len;
326 cis->attr = attr;
327 memcpy(cis->cache, ptr, len);
328 list_add(&cis->node, &s->cis_cache);
331 mutex_unlock(&s->ops_mutex);
333 return ret;
336 static void
337 remove_cis_cache(struct pcmcia_socket *s, int attr, u_int addr, u_int len)
339 struct cis_cache_entry *cis;
341 mutex_lock(&s->ops_mutex);
342 list_for_each_entry(cis, &s->cis_cache, node)
343 if (cis->addr == addr && cis->len == len && cis->attr == attr) {
344 list_del(&cis->node);
345 kfree(cis);
346 break;
348 mutex_unlock(&s->ops_mutex);
352 * destroy_cis_cache() - destroy the CIS cache
353 * @s: pcmcia_socket for which CIS cache shall be destroyed
355 * This destroys the CIS cache but keeps any fake CIS alive. Must be
356 * called with ops_mutex held.
358 void destroy_cis_cache(struct pcmcia_socket *s)
360 struct list_head *l, *n;
361 struct cis_cache_entry *cis;
363 list_for_each_safe(l, n, &s->cis_cache) {
364 cis = list_entry(l, struct cis_cache_entry, node);
365 list_del(&cis->node);
366 kfree(cis);
371 * verify_cis_cache() - does the CIS match what is in the CIS cache?
373 int verify_cis_cache(struct pcmcia_socket *s)
375 struct cis_cache_entry *cis;
376 char *buf;
377 int ret;
379 if (s->state & SOCKET_CARDBUS)
380 return -EINVAL;
382 buf = kmalloc(256, GFP_KERNEL);
383 if (buf == NULL) {
384 dev_printk(KERN_WARNING, &s->dev,
385 "no memory for verifying CIS\n");
386 return -ENOMEM;
388 mutex_lock(&s->ops_mutex);
389 list_for_each_entry(cis, &s->cis_cache, node) {
390 int len = cis->len;
392 if (len > 256)
393 len = 256;
395 ret = pcmcia_read_cis_mem(s, cis->attr, cis->addr, len, buf);
396 if (ret || memcmp(buf, cis->cache, len) != 0) {
397 kfree(buf);
398 mutex_unlock(&s->ops_mutex);
399 return -1;
402 kfree(buf);
403 mutex_unlock(&s->ops_mutex);
404 return 0;
408 * pcmcia_replace_cis() - use a replacement CIS instead of the card's CIS
410 * For really bad cards, we provide a facility for uploading a
411 * replacement CIS.
413 int pcmcia_replace_cis(struct pcmcia_socket *s,
414 const u8 *data, const size_t len)
416 if (len > CISTPL_MAX_CIS_SIZE) {
417 dev_printk(KERN_WARNING, &s->dev, "replacement CIS too big\n");
418 return -EINVAL;
420 mutex_lock(&s->ops_mutex);
421 kfree(s->fake_cis);
422 s->fake_cis = kmalloc(len, GFP_KERNEL);
423 if (s->fake_cis == NULL) {
424 dev_printk(KERN_WARNING, &s->dev, "no memory to replace CIS\n");
425 mutex_unlock(&s->ops_mutex);
426 return -ENOMEM;
428 s->fake_cis_len = len;
429 memcpy(s->fake_cis, data, len);
430 dev_info(&s->dev, "Using replacement CIS\n");
431 mutex_unlock(&s->ops_mutex);
432 return 0;
435 /* The high-level CIS tuple services */
437 typedef struct tuple_flags {
438 u_int link_space:4;
439 u_int has_link:1;
440 u_int mfc_fn:3;
441 u_int space:4;
442 } tuple_flags;
444 #define LINK_SPACE(f) (((tuple_flags *)(&(f)))->link_space)
445 #define HAS_LINK(f) (((tuple_flags *)(&(f)))->has_link)
446 #define MFC_FN(f) (((tuple_flags *)(&(f)))->mfc_fn)
447 #define SPACE(f) (((tuple_flags *)(&(f)))->space)
449 int pccard_get_first_tuple(struct pcmcia_socket *s, unsigned int function,
450 tuple_t *tuple)
452 if (!s)
453 return -EINVAL;
455 if (!(s->state & SOCKET_PRESENT) || (s->state & SOCKET_CARDBUS))
456 return -ENODEV;
457 tuple->TupleLink = tuple->Flags = 0;
459 /* Assume presence of a LONGLINK_C to address 0 */
460 tuple->CISOffset = tuple->LinkOffset = 0;
461 SPACE(tuple->Flags) = HAS_LINK(tuple->Flags) = 1;
463 if ((s->functions > 1) && !(tuple->Attributes & TUPLE_RETURN_COMMON)) {
464 cisdata_t req = tuple->DesiredTuple;
465 tuple->DesiredTuple = CISTPL_LONGLINK_MFC;
466 if (pccard_get_next_tuple(s, function, tuple) == 0) {
467 tuple->DesiredTuple = CISTPL_LINKTARGET;
468 if (pccard_get_next_tuple(s, function, tuple) != 0)
469 return -ENOSPC;
470 } else
471 tuple->CISOffset = tuple->TupleLink = 0;
472 tuple->DesiredTuple = req;
474 return pccard_get_next_tuple(s, function, tuple);
477 static int follow_link(struct pcmcia_socket *s, tuple_t *tuple)
479 u_char link[5];
480 u_int ofs;
481 int ret;
483 if (MFC_FN(tuple->Flags)) {
484 /* Get indirect link from the MFC tuple */
485 ret = read_cis_cache(s, LINK_SPACE(tuple->Flags),
486 tuple->LinkOffset, 5, link);
487 if (ret)
488 return -1;
489 ofs = get_unaligned_le32(link + 1);
490 SPACE(tuple->Flags) = (link[0] == CISTPL_MFC_ATTR);
491 /* Move to the next indirect link */
492 tuple->LinkOffset += 5;
493 MFC_FN(tuple->Flags)--;
494 } else if (HAS_LINK(tuple->Flags)) {
495 ofs = tuple->LinkOffset;
496 SPACE(tuple->Flags) = LINK_SPACE(tuple->Flags);
497 HAS_LINK(tuple->Flags) = 0;
498 } else
499 return -1;
501 if (SPACE(tuple->Flags)) {
502 /* This is ugly, but a common CIS error is to code the long
503 link offset incorrectly, so we check the right spot... */
504 ret = read_cis_cache(s, SPACE(tuple->Flags), ofs, 5, link);
505 if (ret)
506 return -1;
507 if ((link[0] == CISTPL_LINKTARGET) && (link[1] >= 3) &&
508 (strncmp(link+2, "CIS", 3) == 0))
509 return ofs;
510 remove_cis_cache(s, SPACE(tuple->Flags), ofs, 5);
511 /* Then, we try the wrong spot... */
512 ofs = ofs >> 1;
514 ret = read_cis_cache(s, SPACE(tuple->Flags), ofs, 5, link);
515 if (ret)
516 return -1;
517 if ((link[0] == CISTPL_LINKTARGET) && (link[1] >= 3) &&
518 (strncmp(link+2, "CIS", 3) == 0))
519 return ofs;
520 remove_cis_cache(s, SPACE(tuple->Flags), ofs, 5);
521 return -1;
524 int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function,
525 tuple_t *tuple)
527 u_char link[2], tmp;
528 int ofs, i, attr;
529 int ret;
531 if (!s)
532 return -EINVAL;
533 if (!(s->state & SOCKET_PRESENT) || (s->state & SOCKET_CARDBUS))
534 return -ENODEV;
536 link[1] = tuple->TupleLink;
537 ofs = tuple->CISOffset + tuple->TupleLink;
538 attr = SPACE(tuple->Flags);
540 for (i = 0; i < MAX_TUPLES; i++) {
541 if (link[1] == 0xff)
542 link[0] = CISTPL_END;
543 else {
544 ret = read_cis_cache(s, attr, ofs, 2, link);
545 if (ret)
546 return -1;
547 if (link[0] == CISTPL_NULL) {
548 ofs++;
549 continue;
553 /* End of chain? Follow long link if possible */
554 if (link[0] == CISTPL_END) {
555 ofs = follow_link(s, tuple);
556 if (ofs < 0)
557 return -ENOSPC;
558 attr = SPACE(tuple->Flags);
559 ret = read_cis_cache(s, attr, ofs, 2, link);
560 if (ret)
561 return -1;
564 /* Is this a link tuple? Make a note of it */
565 if ((link[0] == CISTPL_LONGLINK_A) ||
566 (link[0] == CISTPL_LONGLINK_C) ||
567 (link[0] == CISTPL_LONGLINK_MFC) ||
568 (link[0] == CISTPL_LINKTARGET) ||
569 (link[0] == CISTPL_INDIRECT) ||
570 (link[0] == CISTPL_NO_LINK)) {
571 switch (link[0]) {
572 case CISTPL_LONGLINK_A:
573 HAS_LINK(tuple->Flags) = 1;
574 LINK_SPACE(tuple->Flags) = attr | IS_ATTR;
575 ret = read_cis_cache(s, attr, ofs+2, 4,
576 &tuple->LinkOffset);
577 if (ret)
578 return -1;
579 break;
580 case CISTPL_LONGLINK_C:
581 HAS_LINK(tuple->Flags) = 1;
582 LINK_SPACE(tuple->Flags) = attr & ~IS_ATTR;
583 ret = read_cis_cache(s, attr, ofs+2, 4,
584 &tuple->LinkOffset);
585 if (ret)
586 return -1;
587 break;
588 case CISTPL_INDIRECT:
589 HAS_LINK(tuple->Flags) = 1;
590 LINK_SPACE(tuple->Flags) = IS_ATTR |
591 IS_INDIRECT;
592 tuple->LinkOffset = 0;
593 break;
594 case CISTPL_LONGLINK_MFC:
595 tuple->LinkOffset = ofs + 3;
596 LINK_SPACE(tuple->Flags) = attr;
597 if (function == BIND_FN_ALL) {
598 /* Follow all the MFC links */
599 ret = read_cis_cache(s, attr, ofs+2,
600 1, &tmp);
601 if (ret)
602 return -1;
603 MFC_FN(tuple->Flags) = tmp;
604 } else {
605 /* Follow exactly one of the links */
606 MFC_FN(tuple->Flags) = 1;
607 tuple->LinkOffset += function * 5;
609 break;
610 case CISTPL_NO_LINK:
611 HAS_LINK(tuple->Flags) = 0;
612 break;
614 if ((tuple->Attributes & TUPLE_RETURN_LINK) &&
615 (tuple->DesiredTuple == RETURN_FIRST_TUPLE))
616 break;
617 } else
618 if (tuple->DesiredTuple == RETURN_FIRST_TUPLE)
619 break;
621 if (link[0] == tuple->DesiredTuple)
622 break;
623 ofs += link[1] + 2;
625 if (i == MAX_TUPLES) {
626 dev_dbg(&s->dev, "cs: overrun in pcmcia_get_next_tuple\n");
627 return -ENOSPC;
630 tuple->TupleCode = link[0];
631 tuple->TupleLink = link[1];
632 tuple->CISOffset = ofs + 2;
633 return 0;
636 int pccard_get_tuple_data(struct pcmcia_socket *s, tuple_t *tuple)
638 u_int len;
639 int ret;
641 if (!s)
642 return -EINVAL;
644 if (tuple->TupleLink < tuple->TupleOffset)
645 return -ENOSPC;
646 len = tuple->TupleLink - tuple->TupleOffset;
647 tuple->TupleDataLen = tuple->TupleLink;
648 if (len == 0)
649 return 0;
650 ret = read_cis_cache(s, SPACE(tuple->Flags),
651 tuple->CISOffset + tuple->TupleOffset,
652 min(len, (u_int) tuple->TupleDataMax),
653 tuple->TupleData);
654 if (ret)
655 return -1;
656 return 0;
660 /* Parsing routines for individual tuples */
662 static int parse_device(tuple_t *tuple, cistpl_device_t *device)
664 int i;
665 u_char scale;
666 u_char *p, *q;
668 p = (u_char *)tuple->TupleData;
669 q = p + tuple->TupleDataLen;
671 device->ndev = 0;
672 for (i = 0; i < CISTPL_MAX_DEVICES; i++) {
674 if (*p == 0xff)
675 break;
676 device->dev[i].type = (*p >> 4);
677 device->dev[i].wp = (*p & 0x08) ? 1 : 0;
678 switch (*p & 0x07) {
679 case 0:
680 device->dev[i].speed = 0;
681 break;
682 case 1:
683 device->dev[i].speed = 250;
684 break;
685 case 2:
686 device->dev[i].speed = 200;
687 break;
688 case 3:
689 device->dev[i].speed = 150;
690 break;
691 case 4:
692 device->dev[i].speed = 100;
693 break;
694 case 7:
695 if (++p == q)
696 return -EINVAL;
697 device->dev[i].speed = SPEED_CVT(*p);
698 while (*p & 0x80)
699 if (++p == q)
700 return -EINVAL;
701 break;
702 default:
703 return -EINVAL;
706 if (++p == q)
707 return -EINVAL;
708 if (*p == 0xff)
709 break;
710 scale = *p & 7;
711 if (scale == 7)
712 return -EINVAL;
713 device->dev[i].size = ((*p >> 3) + 1) * (512 << (scale*2));
714 device->ndev++;
715 if (++p == q)
716 break;
719 return 0;
723 static int parse_checksum(tuple_t *tuple, cistpl_checksum_t *csum)
725 u_char *p;
726 if (tuple->TupleDataLen < 5)
727 return -EINVAL;
728 p = (u_char *) tuple->TupleData;
729 csum->addr = tuple->CISOffset + get_unaligned_le16(p) - 2;
730 csum->len = get_unaligned_le16(p + 2);
731 csum->sum = *(p + 4);
732 return 0;
736 static int parse_longlink(tuple_t *tuple, cistpl_longlink_t *link)
738 if (tuple->TupleDataLen < 4)
739 return -EINVAL;
740 link->addr = get_unaligned_le32(tuple->TupleData);
741 return 0;
745 static int parse_longlink_mfc(tuple_t *tuple, cistpl_longlink_mfc_t *link)
747 u_char *p;
748 int i;
750 p = (u_char *)tuple->TupleData;
752 link->nfn = *p; p++;
753 if (tuple->TupleDataLen <= link->nfn*5)
754 return -EINVAL;
755 for (i = 0; i < link->nfn; i++) {
756 link->fn[i].space = *p; p++;
757 link->fn[i].addr = get_unaligned_le32(p);
758 p += 4;
760 return 0;
764 static int parse_strings(u_char *p, u_char *q, int max,
765 char *s, u_char *ofs, u_char *found)
767 int i, j, ns;
769 if (p == q)
770 return -EINVAL;
771 ns = 0; j = 0;
772 for (i = 0; i < max; i++) {
773 if (*p == 0xff)
774 break;
775 ofs[i] = j;
776 ns++;
777 for (;;) {
778 s[j++] = (*p == 0xff) ? '\0' : *p;
779 if ((*p == '\0') || (*p == 0xff))
780 break;
781 if (++p == q)
782 return -EINVAL;
784 if ((*p == 0xff) || (++p == q))
785 break;
787 if (found) {
788 *found = ns;
789 return 0;
792 return (ns == max) ? 0 : -EINVAL;
796 static int parse_vers_1(tuple_t *tuple, cistpl_vers_1_t *vers_1)
798 u_char *p, *q;
800 p = (u_char *)tuple->TupleData;
801 q = p + tuple->TupleDataLen;
803 vers_1->major = *p; p++;
804 vers_1->minor = *p; p++;
805 if (p >= q)
806 return -EINVAL;
808 return parse_strings(p, q, CISTPL_VERS_1_MAX_PROD_STRINGS,
809 vers_1->str, vers_1->ofs, &vers_1->ns);
813 static int parse_altstr(tuple_t *tuple, cistpl_altstr_t *altstr)
815 u_char *p, *q;
817 p = (u_char *)tuple->TupleData;
818 q = p + tuple->TupleDataLen;
820 return parse_strings(p, q, CISTPL_MAX_ALTSTR_STRINGS,
821 altstr->str, altstr->ofs, &altstr->ns);
825 static int parse_jedec(tuple_t *tuple, cistpl_jedec_t *jedec)
827 u_char *p, *q;
828 int nid;
830 p = (u_char *)tuple->TupleData;
831 q = p + tuple->TupleDataLen;
833 for (nid = 0; nid < CISTPL_MAX_DEVICES; nid++) {
834 if (p > q-2)
835 break;
836 jedec->id[nid].mfr = p[0];
837 jedec->id[nid].info = p[1];
838 p += 2;
840 jedec->nid = nid;
841 return 0;
845 static int parse_manfid(tuple_t *tuple, cistpl_manfid_t *m)
847 if (tuple->TupleDataLen < 4)
848 return -EINVAL;
849 m->manf = get_unaligned_le16(tuple->TupleData);
850 m->card = get_unaligned_le16(tuple->TupleData + 2);
851 return 0;
855 static int parse_funcid(tuple_t *tuple, cistpl_funcid_t *f)
857 u_char *p;
858 if (tuple->TupleDataLen < 2)
859 return -EINVAL;
860 p = (u_char *)tuple->TupleData;
861 f->func = p[0];
862 f->sysinit = p[1];
863 return 0;
867 static int parse_funce(tuple_t *tuple, cistpl_funce_t *f)
869 u_char *p;
870 int i;
871 if (tuple->TupleDataLen < 1)
872 return -EINVAL;
873 p = (u_char *)tuple->TupleData;
874 f->type = p[0];
875 for (i = 1; i < tuple->TupleDataLen; i++)
876 f->data[i-1] = p[i];
877 return 0;
881 static int parse_config(tuple_t *tuple, cistpl_config_t *config)
883 int rasz, rmsz, i;
884 u_char *p;
886 p = (u_char *)tuple->TupleData;
887 rasz = *p & 0x03;
888 rmsz = (*p & 0x3c) >> 2;
889 if (tuple->TupleDataLen < rasz+rmsz+4)
890 return -EINVAL;
891 config->last_idx = *(++p);
892 p++;
893 config->base = 0;
894 for (i = 0; i <= rasz; i++)
895 config->base += p[i] << (8*i);
896 p += rasz+1;
897 for (i = 0; i < 4; i++)
898 config->rmask[i] = 0;
899 for (i = 0; i <= rmsz; i++)
900 config->rmask[i>>2] += p[i] << (8*(i%4));
901 config->subtuples = tuple->TupleDataLen - (rasz+rmsz+4);
902 return 0;
905 /* The following routines are all used to parse the nightmarish
906 * config table entries.
909 static u_char *parse_power(u_char *p, u_char *q, cistpl_power_t *pwr)
911 int i;
912 u_int scale;
914 if (p == q)
915 return NULL;
916 pwr->present = *p;
917 pwr->flags = 0;
918 p++;
919 for (i = 0; i < 7; i++)
920 if (pwr->present & (1<<i)) {
921 if (p == q)
922 return NULL;
923 pwr->param[i] = POWER_CVT(*p);
924 scale = POWER_SCALE(*p);
925 while (*p & 0x80) {
926 if (++p == q)
927 return NULL;
928 if ((*p & 0x7f) < 100)
929 pwr->param[i] +=
930 (*p & 0x7f) * scale / 100;
931 else if (*p == 0x7d)
932 pwr->flags |= CISTPL_POWER_HIGHZ_OK;
933 else if (*p == 0x7e)
934 pwr->param[i] = 0;
935 else if (*p == 0x7f)
936 pwr->flags |= CISTPL_POWER_HIGHZ_REQ;
937 else
938 return NULL;
940 p++;
942 return p;
946 static u_char *parse_timing(u_char *p, u_char *q, cistpl_timing_t *timing)
948 u_char scale;
950 if (p == q)
951 return NULL;
952 scale = *p;
953 if ((scale & 3) != 3) {
954 if (++p == q)
955 return NULL;
956 timing->wait = SPEED_CVT(*p);
957 timing->waitscale = exponent[scale & 3];
958 } else
959 timing->wait = 0;
960 scale >>= 2;
961 if ((scale & 7) != 7) {
962 if (++p == q)
963 return NULL;
964 timing->ready = SPEED_CVT(*p);
965 timing->rdyscale = exponent[scale & 7];
966 } else
967 timing->ready = 0;
968 scale >>= 3;
969 if (scale != 7) {
970 if (++p == q)
971 return NULL;
972 timing->reserved = SPEED_CVT(*p);
973 timing->rsvscale = exponent[scale];
974 } else
975 timing->reserved = 0;
976 p++;
977 return p;
981 static u_char *parse_io(u_char *p, u_char *q, cistpl_io_t *io)
983 int i, j, bsz, lsz;
985 if (p == q)
986 return NULL;
987 io->flags = *p;
989 if (!(*p & 0x80)) {
990 io->nwin = 1;
991 io->win[0].base = 0;
992 io->win[0].len = (1 << (io->flags & CISTPL_IO_LINES_MASK));
993 return p+1;
996 if (++p == q)
997 return NULL;
998 io->nwin = (*p & 0x0f) + 1;
999 bsz = (*p & 0x30) >> 4;
1000 if (bsz == 3)
1001 bsz++;
1002 lsz = (*p & 0xc0) >> 6;
1003 if (lsz == 3)
1004 lsz++;
1005 p++;
1007 for (i = 0; i < io->nwin; i++) {
1008 io->win[i].base = 0;
1009 io->win[i].len = 1;
1010 for (j = 0; j < bsz; j++, p++) {
1011 if (p == q)
1012 return NULL;
1013 io->win[i].base += *p << (j*8);
1015 for (j = 0; j < lsz; j++, p++) {
1016 if (p == q)
1017 return NULL;
1018 io->win[i].len += *p << (j*8);
1021 return p;
1025 static u_char *parse_mem(u_char *p, u_char *q, cistpl_mem_t *mem)
1027 int i, j, asz, lsz, has_ha;
1028 u_int len, ca, ha;
1030 if (p == q)
1031 return NULL;
1033 mem->nwin = (*p & 0x07) + 1;
1034 lsz = (*p & 0x18) >> 3;
1035 asz = (*p & 0x60) >> 5;
1036 has_ha = (*p & 0x80);
1037 if (++p == q)
1038 return NULL;
1040 for (i = 0; i < mem->nwin; i++) {
1041 len = ca = ha = 0;
1042 for (j = 0; j < lsz; j++, p++) {
1043 if (p == q)
1044 return NULL;
1045 len += *p << (j*8);
1047 for (j = 0; j < asz; j++, p++) {
1048 if (p == q)
1049 return NULL;
1050 ca += *p << (j*8);
1052 if (has_ha)
1053 for (j = 0; j < asz; j++, p++) {
1054 if (p == q)
1055 return NULL;
1056 ha += *p << (j*8);
1058 mem->win[i].len = len << 8;
1059 mem->win[i].card_addr = ca << 8;
1060 mem->win[i].host_addr = ha << 8;
1062 return p;
1066 static u_char *parse_irq(u_char *p, u_char *q, cistpl_irq_t *irq)
1068 if (p == q)
1069 return NULL;
1070 irq->IRQInfo1 = *p; p++;
1071 if (irq->IRQInfo1 & IRQ_INFO2_VALID) {
1072 if (p+2 > q)
1073 return NULL;
1074 irq->IRQInfo2 = (p[1]<<8) + p[0];
1075 p += 2;
1077 return p;
1081 static int parse_cftable_entry(tuple_t *tuple,
1082 cistpl_cftable_entry_t *entry)
1084 u_char *p, *q, features;
1086 p = tuple->TupleData;
1087 q = p + tuple->TupleDataLen;
1088 entry->index = *p & 0x3f;
1089 entry->flags = 0;
1090 if (*p & 0x40)
1091 entry->flags |= CISTPL_CFTABLE_DEFAULT;
1092 if (*p & 0x80) {
1093 if (++p == q)
1094 return -EINVAL;
1095 if (*p & 0x10)
1096 entry->flags |= CISTPL_CFTABLE_BVDS;
1097 if (*p & 0x20)
1098 entry->flags |= CISTPL_CFTABLE_WP;
1099 if (*p & 0x40)
1100 entry->flags |= CISTPL_CFTABLE_RDYBSY;
1101 if (*p & 0x80)
1102 entry->flags |= CISTPL_CFTABLE_MWAIT;
1103 entry->interface = *p & 0x0f;
1104 } else
1105 entry->interface = 0;
1107 /* Process optional features */
1108 if (++p == q)
1109 return -EINVAL;
1110 features = *p; p++;
1112 /* Power options */
1113 if ((features & 3) > 0) {
1114 p = parse_power(p, q, &entry->vcc);
1115 if (p == NULL)
1116 return -EINVAL;
1117 } else
1118 entry->vcc.present = 0;
1119 if ((features & 3) > 1) {
1120 p = parse_power(p, q, &entry->vpp1);
1121 if (p == NULL)
1122 return -EINVAL;
1123 } else
1124 entry->vpp1.present = 0;
1125 if ((features & 3) > 2) {
1126 p = parse_power(p, q, &entry->vpp2);
1127 if (p == NULL)
1128 return -EINVAL;
1129 } else
1130 entry->vpp2.present = 0;
1132 /* Timing options */
1133 if (features & 0x04) {
1134 p = parse_timing(p, q, &entry->timing);
1135 if (p == NULL)
1136 return -EINVAL;
1137 } else {
1138 entry->timing.wait = 0;
1139 entry->timing.ready = 0;
1140 entry->timing.reserved = 0;
1143 /* I/O window options */
1144 if (features & 0x08) {
1145 p = parse_io(p, q, &entry->io);
1146 if (p == NULL)
1147 return -EINVAL;
1148 } else
1149 entry->io.nwin = 0;
1151 /* Interrupt options */
1152 if (features & 0x10) {
1153 p = parse_irq(p, q, &entry->irq);
1154 if (p == NULL)
1155 return -EINVAL;
1156 } else
1157 entry->irq.IRQInfo1 = 0;
1159 switch (features & 0x60) {
1160 case 0x00:
1161 entry->mem.nwin = 0;
1162 break;
1163 case 0x20:
1164 entry->mem.nwin = 1;
1165 entry->mem.win[0].len = get_unaligned_le16(p) << 8;
1166 entry->mem.win[0].card_addr = 0;
1167 entry->mem.win[0].host_addr = 0;
1168 p += 2;
1169 if (p > q)
1170 return -EINVAL;
1171 break;
1172 case 0x40:
1173 entry->mem.nwin = 1;
1174 entry->mem.win[0].len = get_unaligned_le16(p) << 8;
1175 entry->mem.win[0].card_addr = get_unaligned_le16(p + 2) << 8;
1176 entry->mem.win[0].host_addr = 0;
1177 p += 4;
1178 if (p > q)
1179 return -EINVAL;
1180 break;
1181 case 0x60:
1182 p = parse_mem(p, q, &entry->mem);
1183 if (p == NULL)
1184 return -EINVAL;
1185 break;
1188 /* Misc features */
1189 if (features & 0x80) {
1190 if (p == q)
1191 return -EINVAL;
1192 entry->flags |= (*p << 8);
1193 while (*p & 0x80)
1194 if (++p == q)
1195 return -EINVAL;
1196 p++;
1199 entry->subtuples = q-p;
1201 return 0;
1205 static int parse_device_geo(tuple_t *tuple, cistpl_device_geo_t *geo)
1207 u_char *p, *q;
1208 int n;
1210 p = (u_char *)tuple->TupleData;
1211 q = p + tuple->TupleDataLen;
1213 for (n = 0; n < CISTPL_MAX_DEVICES; n++) {
1214 if (p > q-6)
1215 break;
1216 geo->geo[n].buswidth = p[0];
1217 geo->geo[n].erase_block = 1 << (p[1]-1);
1218 geo->geo[n].read_block = 1 << (p[2]-1);
1219 geo->geo[n].write_block = 1 << (p[3]-1);
1220 geo->geo[n].partition = 1 << (p[4]-1);
1221 geo->geo[n].interleave = 1 << (p[5]-1);
1222 p += 6;
1224 geo->ngeo = n;
1225 return 0;
1229 static int parse_vers_2(tuple_t *tuple, cistpl_vers_2_t *v2)
1231 u_char *p, *q;
1233 if (tuple->TupleDataLen < 10)
1234 return -EINVAL;
1236 p = tuple->TupleData;
1237 q = p + tuple->TupleDataLen;
1239 v2->vers = p[0];
1240 v2->comply = p[1];
1241 v2->dindex = get_unaligned_le16(p + 2);
1242 v2->vspec8 = p[6];
1243 v2->vspec9 = p[7];
1244 v2->nhdr = p[8];
1245 p += 9;
1246 return parse_strings(p, q, 2, v2->str, &v2->vendor, NULL);
1250 static int parse_org(tuple_t *tuple, cistpl_org_t *org)
1252 u_char *p, *q;
1253 int i;
1255 p = tuple->TupleData;
1256 q = p + tuple->TupleDataLen;
1257 if (p == q)
1258 return -EINVAL;
1259 org->data_org = *p;
1260 if (++p == q)
1261 return -EINVAL;
1262 for (i = 0; i < 30; i++) {
1263 org->desc[i] = *p;
1264 if (*p == '\0')
1265 break;
1266 if (++p == q)
1267 return -EINVAL;
1269 return 0;
1273 static int parse_format(tuple_t *tuple, cistpl_format_t *fmt)
1275 u_char *p;
1277 if (tuple->TupleDataLen < 10)
1278 return -EINVAL;
1280 p = tuple->TupleData;
1282 fmt->type = p[0];
1283 fmt->edc = p[1];
1284 fmt->offset = get_unaligned_le32(p + 2);
1285 fmt->length = get_unaligned_le32(p + 6);
1287 return 0;
1291 int pcmcia_parse_tuple(tuple_t *tuple, cisparse_t *parse)
1293 int ret = 0;
1295 if (tuple->TupleDataLen > tuple->TupleDataMax)
1296 return -EINVAL;
1297 switch (tuple->TupleCode) {
1298 case CISTPL_DEVICE:
1299 case CISTPL_DEVICE_A:
1300 ret = parse_device(tuple, &parse->device);
1301 break;
1302 case CISTPL_CHECKSUM:
1303 ret = parse_checksum(tuple, &parse->checksum);
1304 break;
1305 case CISTPL_LONGLINK_A:
1306 case CISTPL_LONGLINK_C:
1307 ret = parse_longlink(tuple, &parse->longlink);
1308 break;
1309 case CISTPL_LONGLINK_MFC:
1310 ret = parse_longlink_mfc(tuple, &parse->longlink_mfc);
1311 break;
1312 case CISTPL_VERS_1:
1313 ret = parse_vers_1(tuple, &parse->version_1);
1314 break;
1315 case CISTPL_ALTSTR:
1316 ret = parse_altstr(tuple, &parse->altstr);
1317 break;
1318 case CISTPL_JEDEC_A:
1319 case CISTPL_JEDEC_C:
1320 ret = parse_jedec(tuple, &parse->jedec);
1321 break;
1322 case CISTPL_MANFID:
1323 ret = parse_manfid(tuple, &parse->manfid);
1324 break;
1325 case CISTPL_FUNCID:
1326 ret = parse_funcid(tuple, &parse->funcid);
1327 break;
1328 case CISTPL_FUNCE:
1329 ret = parse_funce(tuple, &parse->funce);
1330 break;
1331 case CISTPL_CONFIG:
1332 ret = parse_config(tuple, &parse->config);
1333 break;
1334 case CISTPL_CFTABLE_ENTRY:
1335 ret = parse_cftable_entry(tuple, &parse->cftable_entry);
1336 break;
1337 case CISTPL_DEVICE_GEO:
1338 case CISTPL_DEVICE_GEO_A:
1339 ret = parse_device_geo(tuple, &parse->device_geo);
1340 break;
1341 case CISTPL_VERS_2:
1342 ret = parse_vers_2(tuple, &parse->vers_2);
1343 break;
1344 case CISTPL_ORG:
1345 ret = parse_org(tuple, &parse->org);
1346 break;
1347 case CISTPL_FORMAT:
1348 case CISTPL_FORMAT_A:
1349 ret = parse_format(tuple, &parse->format);
1350 break;
1351 case CISTPL_NO_LINK:
1352 case CISTPL_LINKTARGET:
1353 ret = 0;
1354 break;
1355 default:
1356 ret = -EINVAL;
1357 break;
1359 if (ret)
1360 pr_debug("parse_tuple failed %d\n", ret);
1361 return ret;
1363 EXPORT_SYMBOL(pcmcia_parse_tuple);
1367 * pccard_validate_cis() - check whether card has a sensible CIS
1368 * @s: the struct pcmcia_socket we are to check
1369 * @info: returns the number of tuples in the (valid) CIS, or 0
1371 * This tries to determine if a card has a sensible CIS. In @info, it
1372 * returns the number of tuples in the CIS, or 0 if the CIS looks bad. The
1373 * checks include making sure several critical tuples are present and
1374 * valid; seeing if the total number of tuples is reasonable; and
1375 * looking for tuples that use reserved codes.
1377 * The function returns 0 on success.
1379 int pccard_validate_cis(struct pcmcia_socket *s, unsigned int *info)
1381 tuple_t *tuple;
1382 cisparse_t *p;
1383 unsigned int count = 0;
1384 int ret, reserved, dev_ok = 0, ident_ok = 0;
1386 if (!s)
1387 return -EINVAL;
1389 if (s->functions || !(s->state & SOCKET_PRESENT)) {
1390 WARN_ON(1);
1391 return -EINVAL;
1394 /* We do not want to validate the CIS cache... */
1395 mutex_lock(&s->ops_mutex);
1396 destroy_cis_cache(s);
1397 mutex_unlock(&s->ops_mutex);
1399 tuple = kmalloc(sizeof(*tuple), GFP_KERNEL);
1400 if (tuple == NULL) {
1401 dev_warn(&s->dev, "no memory to validate CIS\n");
1402 return -ENOMEM;
1404 p = kmalloc(sizeof(*p), GFP_KERNEL);
1405 if (p == NULL) {
1406 kfree(tuple);
1407 dev_warn(&s->dev, "no memory to validate CIS\n");
1408 return -ENOMEM;
1411 count = reserved = 0;
1412 tuple->DesiredTuple = RETURN_FIRST_TUPLE;
1413 tuple->Attributes = TUPLE_RETURN_COMMON;
1414 ret = pccard_get_first_tuple(s, BIND_FN_ALL, tuple);
1415 if (ret != 0)
1416 goto done;
1418 /* First tuple should be DEVICE; we should really have either that
1419 or a CFTABLE_ENTRY of some sort */
1420 if ((tuple->TupleCode == CISTPL_DEVICE) ||
1421 (!pccard_read_tuple(s, BIND_FN_ALL, CISTPL_CFTABLE_ENTRY, p)) ||
1422 (!pccard_read_tuple(s, BIND_FN_ALL, CISTPL_CFTABLE_ENTRY_CB, p)))
1423 dev_ok++;
1425 /* All cards should have a MANFID tuple, and/or a VERS_1 or VERS_2
1426 tuple, for card identification. Certain old D-Link and Linksys
1427 cards have only a broken VERS_2 tuple; hence the bogus test. */
1428 if ((pccard_read_tuple(s, BIND_FN_ALL, CISTPL_MANFID, p) == 0) ||
1429 (pccard_read_tuple(s, BIND_FN_ALL, CISTPL_VERS_1, p) == 0) ||
1430 (pccard_read_tuple(s, BIND_FN_ALL, CISTPL_VERS_2, p) != -ENOSPC))
1431 ident_ok++;
1433 if (!dev_ok && !ident_ok)
1434 goto done;
1436 for (count = 1; count < MAX_TUPLES; count++) {
1437 ret = pccard_get_next_tuple(s, BIND_FN_ALL, tuple);
1438 if (ret != 0)
1439 break;
1440 if (((tuple->TupleCode > 0x23) && (tuple->TupleCode < 0x40)) ||
1441 ((tuple->TupleCode > 0x47) && (tuple->TupleCode < 0x80)) ||
1442 ((tuple->TupleCode > 0x90) && (tuple->TupleCode < 0xff)))
1443 reserved++;
1445 if ((count == MAX_TUPLES) || (reserved > 5) ||
1446 ((!dev_ok || !ident_ok) && (count > 10)))
1447 count = 0;
1449 ret = 0;
1451 done:
1452 /* invalidate CIS cache on failure */
1453 if (!dev_ok || !ident_ok || !count) {
1454 #if defined(CONFIG_MTD_PCMCIA_ANONYMOUS)
1455 /* Set up as an anonymous card. If we don't have anonymous
1456 memory support then just error the card as there is no
1457 point trying to second guess.
1459 Note: some cards have just a device entry, it may be
1460 worth extending support to cover these in future */
1461 if (!dev_ok || !ident_ok) {
1462 dev_info(&s->dev, "no CIS, assuming an anonymous memory card.\n");
1463 pcmcia_replace_cis(s, "\xFF", 1);
1464 count = 1;
1465 ret = 0;
1466 } else
1467 #endif
1469 mutex_lock(&s->ops_mutex);
1470 destroy_cis_cache(s);
1471 mutex_unlock(&s->ops_mutex);
1472 ret = -EIO;
1476 if (info)
1477 *info = count;
1478 kfree(tuple);
1479 kfree(p);
1480 return ret;
1484 #define to_socket(_dev) container_of(_dev, struct pcmcia_socket, dev)
1486 static ssize_t pccard_extract_cis(struct pcmcia_socket *s, char *buf,
1487 loff_t off, size_t count)
1489 tuple_t tuple;
1490 int status, i;
1491 loff_t pointer = 0;
1492 ssize_t ret = 0;
1493 u_char *tuplebuffer;
1494 u_char *tempbuffer;
1496 tuplebuffer = kmalloc(sizeof(u_char) * 256, GFP_KERNEL);
1497 if (!tuplebuffer)
1498 return -ENOMEM;
1500 tempbuffer = kmalloc(sizeof(u_char) * 258, GFP_KERNEL);
1501 if (!tempbuffer) {
1502 ret = -ENOMEM;
1503 goto free_tuple;
1506 memset(&tuple, 0, sizeof(tuple_t));
1508 tuple.Attributes = TUPLE_RETURN_LINK | TUPLE_RETURN_COMMON;
1509 tuple.DesiredTuple = RETURN_FIRST_TUPLE;
1510 tuple.TupleOffset = 0;
1512 status = pccard_get_first_tuple(s, BIND_FN_ALL, &tuple);
1513 while (!status) {
1514 tuple.TupleData = tuplebuffer;
1515 tuple.TupleDataMax = 255;
1516 memset(tuplebuffer, 0, sizeof(u_char) * 255);
1518 status = pccard_get_tuple_data(s, &tuple);
1519 if (status)
1520 break;
1522 if (off < (pointer + 2 + tuple.TupleDataLen)) {
1523 tempbuffer[0] = tuple.TupleCode & 0xff;
1524 tempbuffer[1] = tuple.TupleLink & 0xff;
1525 for (i = 0; i < tuple.TupleDataLen; i++)
1526 tempbuffer[i + 2] = tuplebuffer[i] & 0xff;
1528 for (i = 0; i < (2 + tuple.TupleDataLen); i++) {
1529 if (((i + pointer) >= off) &&
1530 (i + pointer) < (off + count)) {
1531 buf[ret] = tempbuffer[i];
1532 ret++;
1537 pointer += 2 + tuple.TupleDataLen;
1539 if (pointer >= (off + count))
1540 break;
1542 if (tuple.TupleCode == CISTPL_END)
1543 break;
1544 status = pccard_get_next_tuple(s, BIND_FN_ALL, &tuple);
1547 kfree(tempbuffer);
1548 free_tuple:
1549 kfree(tuplebuffer);
1551 return ret;
1555 static ssize_t pccard_show_cis(struct file *filp, struct kobject *kobj,
1556 struct bin_attribute *bin_attr,
1557 char *buf, loff_t off, size_t count)
1559 unsigned int size = 0x200;
1561 if (off >= size)
1562 count = 0;
1563 else {
1564 struct pcmcia_socket *s;
1565 unsigned int chains = 1;
1567 if (off + count > size)
1568 count = size - off;
1570 s = to_socket(container_of(kobj, struct device, kobj));
1572 if (!(s->state & SOCKET_PRESENT))
1573 return -ENODEV;
1574 if (!s->functions && pccard_validate_cis(s, &chains))
1575 return -EIO;
1576 if (!chains)
1577 return -ENODATA;
1579 count = pccard_extract_cis(s, buf, off, count);
1582 return count;
1586 static ssize_t pccard_store_cis(struct file *filp, struct kobject *kobj,
1587 struct bin_attribute *bin_attr,
1588 char *buf, loff_t off, size_t count)
1590 struct pcmcia_socket *s;
1591 int error;
1593 s = to_socket(container_of(kobj, struct device, kobj));
1595 if (off)
1596 return -EINVAL;
1598 if (count >= CISTPL_MAX_CIS_SIZE)
1599 return -EINVAL;
1601 if (!(s->state & SOCKET_PRESENT))
1602 return -ENODEV;
1604 error = pcmcia_replace_cis(s, buf, count);
1605 if (error)
1606 return -EIO;
1608 pcmcia_parse_uevents(s, PCMCIA_UEVENT_REQUERY);
1610 return count;
1614 struct bin_attribute pccard_cis_attr = {
1615 .attr = { .name = "cis", .mode = S_IRUGO | S_IWUSR },
1616 .size = 0x200,
1617 .read = pccard_show_cis,
1618 .write = pccard_store_cis,