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