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