1 /*======================================================================
3 PCMCIA Card Information Structure parser
5 cistpl.c 1.99 2002/10/24 06:11:48
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/
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.
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.
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.
32 ======================================================================*/
34 #include <linux/config.h>
35 #include <linux/module.h>
36 #include <linux/kernel.h>
37 #include <linux/string.h>
38 #include <linux/major.h>
39 #include <linux/errno.h>
40 #include <linux/timer.h>
41 #include <linux/slab.h>
43 #include <linux/sched.h>
44 #include <linux/pci.h>
45 #include <linux/ioport.h>
47 #include <asm/byteorder.h>
49 #include <pcmcia/cs_types.h>
50 #include <pcmcia/ss.h>
51 #include <pcmcia/cs.h>
52 #include <pcmcia/bulkmem.h>
53 #include <pcmcia/cisreg.h>
54 #include <pcmcia/cistpl.h>
55 #include "cs_internal.h"
57 static const u_char mantissa
[] = {
58 10, 12, 13, 15, 20, 25, 30, 35,
59 40, 45, 50, 55, 60, 70, 80, 90
62 static const u_int exponent
[] = {
63 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000
66 /* Convert an extended speed byte to a time in nanoseconds */
67 #define SPEED_CVT(v) \
68 (mantissa[(((v)>>3)&15)-1] * exponent[(v)&7] / 10)
69 /* Convert a power byte to a current in 0.1 microamps */
70 #define POWER_CVT(v) \
71 (mantissa[((v)>>3)&15] * exponent[(v)&7] / 10)
72 #define POWER_SCALE(v) (exponent[(v)&7])
74 /* Upper limit on reasonable # of tuples */
75 #define MAX_TUPLES 200
77 /*====================================================================*/
79 /* Parameters that can be set with 'insmod' */
81 #define INT_MODULE_PARM(n, v) static int n = v; MODULE_PARM(n, "i")
83 INT_MODULE_PARM(cis_width
, 0); /* 16-bit CIS? */
85 void release_cis_mem(struct pcmcia_socket
*s
)
87 if (s
->cis_mem
.sys_start
!= 0) {
88 s
->cis_mem
.flags
&= ~MAP_ACTIVE
;
89 s
->ss_entry
->set_mem_map(s
, &s
->cis_mem
);
90 if (!(s
->features
& SS_CAP_STATIC_MAP
))
91 release_mem_region(s
->cis_mem
.sys_start
, s
->map_size
);
93 s
->cis_mem
.sys_start
= 0;
99 * Map the card memory at "card_offset" into virtual space.
100 * If flags & MAP_ATTRIB, map the attribute space, otherwise
101 * map the memory space.
103 static unsigned char *
104 set_cis_map(struct pcmcia_socket
*s
, unsigned int card_offset
, unsigned int flags
)
106 pccard_mem_map
*mem
= &s
->cis_mem
;
107 if (!(s
->features
& SS_CAP_STATIC_MAP
) &&
108 mem
->sys_start
== 0) {
111 if (find_mem_region(&mem
->sys_start
, s
->map_size
,
112 s
->map_size
, 0, "card services", s
)) {
113 printk(KERN_NOTICE
"cs: unable to map card memory!\n");
116 mem
->sys_stop
= mem
->sys_start
+s
->map_size
-1;
117 s
->cis_virt
= ioremap(mem
->sys_start
, s
->map_size
);
119 mem
->card_start
= card_offset
;
121 s
->ss_entry
->set_mem_map(s
, mem
);
122 if (s
->features
& SS_CAP_STATIC_MAP
) {
124 iounmap(s
->cis_virt
);
125 s
->cis_virt
= ioremap(mem
->sys_start
, s
->map_size
);
130 /*======================================================================
132 Low-level functions to read and write CIS memory. I think the
133 write routine is only useful for writing one-byte registers.
135 ======================================================================*/
137 /* Bits in attr field */
139 #define IS_INDIRECT 8
141 int read_cis_mem(struct pcmcia_socket
*s
, int attr
, u_int addr
,
142 u_int len
, void *ptr
)
144 u_char
*sys
, *end
, *buf
= ptr
;
146 DEBUG(3, "cs: read_cis_mem(%d, %#x, %u)\n", attr
, addr
, len
);
148 if (attr
& IS_INDIRECT
) {
149 /* Indirect accesses use a bunch of special registers at fixed
150 locations in common memory */
151 u_char flags
= ICTRL0_COMMON
|ICTRL0_AUTOINC
|ICTRL0_BYTEGRAN
;
152 if (attr
& IS_ATTR
) {
154 flags
= ICTRL0_AUTOINC
;
157 sys
= set_cis_map(s
, 0, MAP_ACTIVE
| ((cis_width
) ? MAP_16BIT
: 0));
159 memset(ptr
, 0xff, len
);
163 writeb(flags
, sys
+CISREG_ICTRL0
);
164 writeb(addr
& 0xff, sys
+CISREG_IADDR0
);
165 writeb((addr
>>8) & 0xff, sys
+CISREG_IADDR1
);
166 writeb((addr
>>16) & 0xff, sys
+CISREG_IADDR2
);
167 writeb((addr
>>24) & 0xff, sys
+CISREG_IADDR3
);
168 for ( ; len
> 0; len
--, buf
++)
169 *buf
= readb(sys
+CISREG_IDATA0
);
171 u_int inc
= 1, card_offset
, flags
;
173 flags
= MAP_ACTIVE
| ((cis_width
) ? MAP_16BIT
: 0);
180 card_offset
= addr
& ~(s
->map_size
-1);
182 sys
= set_cis_map(s
, card_offset
, flags
);
184 memset(ptr
, 0xff, len
);
187 end
= sys
+ s
->map_size
;
188 sys
= sys
+ (addr
& (s
->map_size
-1));
189 for ( ; len
> 0; len
--, buf
++, sys
+= inc
) {
194 card_offset
+= s
->map_size
;
198 DEBUG(3, "cs: %#2.2x %#2.2x %#2.2x %#2.2x ...\n",
199 *(u_char
*)(ptr
+0), *(u_char
*)(ptr
+1),
200 *(u_char
*)(ptr
+2), *(u_char
*)(ptr
+3));
204 void write_cis_mem(struct pcmcia_socket
*s
, int attr
, u_int addr
,
205 u_int len
, void *ptr
)
207 u_char
*sys
, *end
, *buf
= ptr
;
209 DEBUG(3, "cs: write_cis_mem(%d, %#x, %u)\n", attr
, addr
, len
);
211 if (attr
& IS_INDIRECT
) {
212 /* Indirect accesses use a bunch of special registers at fixed
213 locations in common memory */
214 u_char flags
= ICTRL0_COMMON
|ICTRL0_AUTOINC
|ICTRL0_BYTEGRAN
;
215 if (attr
& IS_ATTR
) {
217 flags
= ICTRL0_AUTOINC
;
220 sys
= set_cis_map(s
, 0, MAP_ACTIVE
| ((cis_width
) ? MAP_16BIT
: 0));
222 return; /* FIXME: Error */
224 writeb(flags
, sys
+CISREG_ICTRL0
);
225 writeb(addr
& 0xff, sys
+CISREG_IADDR0
);
226 writeb((addr
>>8) & 0xff, sys
+CISREG_IADDR1
);
227 writeb((addr
>>16) & 0xff, sys
+CISREG_IADDR2
);
228 writeb((addr
>>24) & 0xff, sys
+CISREG_IADDR3
);
229 for ( ; len
> 0; len
--, buf
++)
230 writeb(*buf
, sys
+CISREG_IDATA0
);
232 u_int inc
= 1, card_offset
, flags
;
234 flags
= MAP_ACTIVE
| ((cis_width
) ? MAP_16BIT
: 0);
235 if (attr
& IS_ATTR
) {
241 card_offset
= addr
& ~(s
->map_size
-1);
243 sys
= set_cis_map(s
, card_offset
, flags
);
245 return; /* FIXME: error */
247 end
= sys
+ s
->map_size
;
248 sys
= sys
+ (addr
& (s
->map_size
-1));
249 for ( ; len
> 0; len
--, buf
++, sys
+= inc
) {
254 card_offset
+= s
->map_size
;
260 /*======================================================================
262 This is a wrapper around read_cis_mem, with the same interface,
263 but which caches information, for cards whose CIS may not be
264 readable all the time.
266 ======================================================================*/
268 static void read_cis_cache(struct pcmcia_socket
*s
, int attr
, u_int addr
,
269 u_int len
, void *ptr
)
271 struct cis_cache_entry
*cis
;
275 if (s
->fake_cis_len
> addr
+len
)
276 memcpy(ptr
, s
->fake_cis
+addr
, len
);
278 memset(ptr
, 0xff, len
);
282 list_for_each_entry(cis
, &s
->cis_cache
, node
) {
283 if (cis
->addr
== addr
&& cis
->len
== len
&& cis
->attr
== attr
) {
284 memcpy(ptr
, cis
->cache
, len
);
289 #ifdef CONFIG_CARDBUS
290 if (s
->state
& SOCKET_CARDBUS
)
291 ret
= read_cb_mem(s
, attr
, addr
, len
, ptr
);
294 ret
= read_cis_mem(s
, attr
, addr
, len
, ptr
);
296 /* Copy data into the cache */
297 cis
= kmalloc(sizeof(struct cis_cache_entry
) + len
, GFP_KERNEL
);
302 memcpy(cis
->cache
, ptr
, len
);
303 list_add(&cis
->node
, &s
->cis_cache
);
308 remove_cis_cache(struct pcmcia_socket
*s
, int attr
, u_int addr
, u_int len
)
310 struct cis_cache_entry
*cis
;
312 list_for_each_entry(cis
, &s
->cis_cache
, node
)
313 if (cis
->addr
== addr
&& cis
->len
== len
&& cis
->attr
== attr
) {
314 list_del(&cis
->node
);
320 void destroy_cis_cache(struct pcmcia_socket
*s
)
322 struct list_head
*l
, *n
;
324 list_for_each_safe(l
, n
, &s
->cis_cache
) {
325 struct cis_cache_entry
*cis
= list_entry(l
, struct cis_cache_entry
, node
);
327 list_del(&cis
->node
);
332 /*======================================================================
334 This verifies if the CIS of a card matches what is in the CIS
337 ======================================================================*/
339 int verify_cis_cache(struct pcmcia_socket
*s
)
341 struct cis_cache_entry
*cis
;
344 list_for_each_entry(cis
, &s
->cis_cache
, node
) {
349 #ifdef CONFIG_CARDBUS
350 if (s
->state
& SOCKET_CARDBUS
)
351 read_cb_mem(s
, cis
->attr
, cis
->addr
, len
, buf
);
354 read_cis_mem(s
, cis
->attr
, cis
->addr
, len
, buf
);
356 if (memcmp(buf
, cis
->cache
, len
) != 0)
362 /*======================================================================
364 For really bad cards, we provide a facility for uploading a
367 ======================================================================*/
369 int pcmcia_replace_cis(client_handle_t handle
, cisdump_t
*cis
)
371 struct pcmcia_socket
*s
;
372 if (CHECK_HANDLE(handle
))
373 return CS_BAD_HANDLE
;
375 if (s
->fake_cis
!= NULL
) {
379 if (cis
->Length
> CISTPL_MAX_CIS_SIZE
)
381 s
->fake_cis
= kmalloc(cis
->Length
, GFP_KERNEL
);
382 if (s
->fake_cis
== NULL
)
383 return CS_OUT_OF_RESOURCE
;
384 s
->fake_cis_len
= cis
->Length
;
385 memcpy(s
->fake_cis
, cis
->Data
, cis
->Length
);
389 /*======================================================================
391 The high-level CIS tuple services
393 ======================================================================*/
395 typedef struct tuple_flags
{
402 #define LINK_SPACE(f) (((tuple_flags *)(&(f)))->link_space)
403 #define HAS_LINK(f) (((tuple_flags *)(&(f)))->has_link)
404 #define MFC_FN(f) (((tuple_flags *)(&(f)))->mfc_fn)
405 #define SPACE(f) (((tuple_flags *)(&(f)))->space)
407 int pcmcia_get_next_tuple(client_handle_t handle
, tuple_t
*tuple
);
409 int pcmcia_get_first_tuple(client_handle_t handle
, tuple_t
*tuple
)
411 struct pcmcia_socket
*s
;
412 if (CHECK_HANDLE(handle
))
413 return CS_BAD_HANDLE
;
415 if (!(s
->state
& SOCKET_PRESENT
))
417 tuple
->TupleLink
= tuple
->Flags
= 0;
418 #ifdef CONFIG_CARDBUS
419 if (s
->state
& SOCKET_CARDBUS
) {
420 struct pci_dev
*dev
= s
->cb_dev
;
422 pci_bus_read_config_dword(dev
->subordinate
, 0, PCI_CARDBUS_CIS
, &ptr
);
423 tuple
->CISOffset
= ptr
& ~7;
424 SPACE(tuple
->Flags
) = (ptr
& 7);
428 /* Assume presence of a LONGLINK_C to address 0 */
429 tuple
->CISOffset
= tuple
->LinkOffset
= 0;
430 SPACE(tuple
->Flags
) = HAS_LINK(tuple
->Flags
) = 1;
432 if (!(s
->state
& SOCKET_CARDBUS
) && (s
->functions
> 1) &&
433 !(tuple
->Attributes
& TUPLE_RETURN_COMMON
)) {
434 cisdata_t req
= tuple
->DesiredTuple
;
435 tuple
->DesiredTuple
= CISTPL_LONGLINK_MFC
;
436 if (pcmcia_get_next_tuple(handle
, tuple
) == CS_SUCCESS
) {
437 tuple
->DesiredTuple
= CISTPL_LINKTARGET
;
438 if (pcmcia_get_next_tuple(handle
, tuple
) != CS_SUCCESS
)
439 return CS_NO_MORE_ITEMS
;
441 tuple
->CISOffset
= tuple
->TupleLink
= 0;
442 tuple
->DesiredTuple
= req
;
444 return pcmcia_get_next_tuple(handle
, tuple
);
447 static int follow_link(struct pcmcia_socket
*s
, tuple_t
*tuple
)
452 if (MFC_FN(tuple
->Flags
)) {
453 /* Get indirect link from the MFC tuple */
454 read_cis_cache(s
, LINK_SPACE(tuple
->Flags
),
455 tuple
->LinkOffset
, 5, link
);
456 ofs
= le32_to_cpu(*(u_int
*)(link
+1));
457 SPACE(tuple
->Flags
) = (link
[0] == CISTPL_MFC_ATTR
);
458 /* Move to the next indirect link */
459 tuple
->LinkOffset
+= 5;
460 MFC_FN(tuple
->Flags
)--;
461 } else if (HAS_LINK(tuple
->Flags
)) {
462 ofs
= tuple
->LinkOffset
;
463 SPACE(tuple
->Flags
) = LINK_SPACE(tuple
->Flags
);
464 HAS_LINK(tuple
->Flags
) = 0;
468 if (!(s
->state
& SOCKET_CARDBUS
) && SPACE(tuple
->Flags
)) {
469 /* This is ugly, but a common CIS error is to code the long
470 link offset incorrectly, so we check the right spot... */
471 read_cis_cache(s
, SPACE(tuple
->Flags
), ofs
, 5, link
);
472 if ((link
[0] == CISTPL_LINKTARGET
) && (link
[1] >= 3) &&
473 (strncmp(link
+2, "CIS", 3) == 0))
475 remove_cis_cache(s
, SPACE(tuple
->Flags
), ofs
, 5);
476 /* Then, we try the wrong spot... */
479 read_cis_cache(s
, SPACE(tuple
->Flags
), ofs
, 5, link
);
480 if ((link
[0] == CISTPL_LINKTARGET
) && (link
[1] >= 3) &&
481 (strncmp(link
+2, "CIS", 3) == 0))
483 remove_cis_cache(s
, SPACE(tuple
->Flags
), ofs
, 5);
487 int pcmcia_get_next_tuple(client_handle_t handle
, tuple_t
*tuple
)
489 struct pcmcia_socket
*s
;
493 if (CHECK_HANDLE(handle
))
494 return CS_BAD_HANDLE
;
496 if (!(s
->state
& SOCKET_PRESENT
))
499 link
[1] = tuple
->TupleLink
;
500 ofs
= tuple
->CISOffset
+ tuple
->TupleLink
;
501 attr
= SPACE(tuple
->Flags
);
503 for (i
= 0; i
< MAX_TUPLES
; i
++) {
504 if (link
[1] == 0xff) {
505 link
[0] = CISTPL_END
;
507 read_cis_cache(s
, attr
, ofs
, 2, link
);
508 if (link
[0] == CISTPL_NULL
) {
513 /* End of chain? Follow long link if possible */
514 if (link
[0] == CISTPL_END
) {
515 if ((ofs
= follow_link(s
, tuple
)) < 0)
516 return CS_NO_MORE_ITEMS
;
517 attr
= SPACE(tuple
->Flags
);
518 read_cis_cache(s
, attr
, ofs
, 2, link
);
521 /* Is this a link tuple? Make a note of it */
522 if ((link
[0] == CISTPL_LONGLINK_A
) ||
523 (link
[0] == CISTPL_LONGLINK_C
) ||
524 (link
[0] == CISTPL_LONGLINK_MFC
) ||
525 (link
[0] == CISTPL_LINKTARGET
) ||
526 (link
[0] == CISTPL_INDIRECT
) ||
527 (link
[0] == CISTPL_NO_LINK
)) {
529 case CISTPL_LONGLINK_A
:
530 HAS_LINK(tuple
->Flags
) = 1;
531 LINK_SPACE(tuple
->Flags
) = attr
| IS_ATTR
;
532 read_cis_cache(s
, attr
, ofs
+2, 4, &tuple
->LinkOffset
);
534 case CISTPL_LONGLINK_C
:
535 HAS_LINK(tuple
->Flags
) = 1;
536 LINK_SPACE(tuple
->Flags
) = attr
& ~IS_ATTR
;
537 read_cis_cache(s
, attr
, ofs
+2, 4, &tuple
->LinkOffset
);
539 case CISTPL_INDIRECT
:
540 HAS_LINK(tuple
->Flags
) = 1;
541 LINK_SPACE(tuple
->Flags
) = IS_ATTR
| IS_INDIRECT
;
542 tuple
->LinkOffset
= 0;
544 case CISTPL_LONGLINK_MFC
:
545 tuple
->LinkOffset
= ofs
+ 3;
546 LINK_SPACE(tuple
->Flags
) = attr
;
547 if (handle
->Function
== BIND_FN_ALL
) {
548 /* Follow all the MFC links */
549 read_cis_cache(s
, attr
, ofs
+2, 1, &tmp
);
550 MFC_FN(tuple
->Flags
) = tmp
;
552 /* Follow exactly one of the links */
553 MFC_FN(tuple
->Flags
) = 1;
554 tuple
->LinkOffset
+= handle
->Function
* 5;
558 HAS_LINK(tuple
->Flags
) = 0;
561 if ((tuple
->Attributes
& TUPLE_RETURN_LINK
) &&
562 (tuple
->DesiredTuple
== RETURN_FIRST_TUPLE
))
565 if (tuple
->DesiredTuple
== RETURN_FIRST_TUPLE
)
568 if (link
[0] == tuple
->DesiredTuple
)
572 if (i
== MAX_TUPLES
) {
573 DEBUG(1, "cs: overrun in pcmcia_get_next_tuple for socket %d\n",
575 return CS_NO_MORE_ITEMS
;
578 tuple
->TupleCode
= link
[0];
579 tuple
->TupleLink
= link
[1];
580 tuple
->CISOffset
= ofs
+ 2;
584 /*====================================================================*/
586 #define _MIN(a, b) (((a) < (b)) ? (a) : (b))
588 int pcmcia_get_tuple_data(client_handle_t handle
, tuple_t
*tuple
)
590 struct pcmcia_socket
*s
;
593 if (CHECK_HANDLE(handle
))
594 return CS_BAD_HANDLE
;
598 if (tuple
->TupleLink
< tuple
->TupleOffset
)
599 return CS_NO_MORE_ITEMS
;
600 len
= tuple
->TupleLink
- tuple
->TupleOffset
;
601 tuple
->TupleDataLen
= tuple
->TupleLink
;
604 read_cis_cache(s
, SPACE(tuple
->Flags
),
605 tuple
->CISOffset
+ tuple
->TupleOffset
,
606 _MIN(len
, tuple
->TupleDataMax
), tuple
->TupleData
);
610 /*======================================================================
612 Parsing routines for individual tuples
614 ======================================================================*/
616 static int parse_device(tuple_t
*tuple
, cistpl_device_t
*device
)
622 p
= (u_char
*)tuple
->TupleData
;
623 q
= p
+ tuple
->TupleDataLen
;
626 for (i
= 0; i
< CISTPL_MAX_DEVICES
; i
++) {
628 if (*p
== 0xff) break;
629 device
->dev
[i
].type
= (*p
>> 4);
630 device
->dev
[i
].wp
= (*p
& 0x08) ? 1 : 0;
632 case 0: device
->dev
[i
].speed
= 0; break;
633 case 1: device
->dev
[i
].speed
= 250; break;
634 case 2: device
->dev
[i
].speed
= 200; break;
635 case 3: device
->dev
[i
].speed
= 150; break;
636 case 4: device
->dev
[i
].speed
= 100; break;
638 if (++p
== q
) return CS_BAD_TUPLE
;
639 device
->dev
[i
].speed
= SPEED_CVT(*p
);
641 if (++p
== q
) return CS_BAD_TUPLE
;
647 if (++p
== q
) return CS_BAD_TUPLE
;
648 if (*p
== 0xff) break;
650 if (scale
== 7) return CS_BAD_TUPLE
;
651 device
->dev
[i
].size
= ((*p
>> 3) + 1) * (512 << (scale
*2));
659 /*====================================================================*/
661 static int parse_checksum(tuple_t
*tuple
, cistpl_checksum_t
*csum
)
664 if (tuple
->TupleDataLen
< 5)
666 p
= (u_char
*)tuple
->TupleData
;
667 csum
->addr
= tuple
->CISOffset
+(short)le16_to_cpu(*(u_short
*)p
)-2;
668 csum
->len
= le16_to_cpu(*(u_short
*)(p
+ 2));
673 /*====================================================================*/
675 static int parse_longlink(tuple_t
*tuple
, cistpl_longlink_t
*link
)
677 if (tuple
->TupleDataLen
< 4)
679 link
->addr
= le32_to_cpu(*(u_int
*)tuple
->TupleData
);
683 /*====================================================================*/
685 static int parse_longlink_mfc(tuple_t
*tuple
,
686 cistpl_longlink_mfc_t
*link
)
691 p
= (u_char
*)tuple
->TupleData
;
694 if (tuple
->TupleDataLen
<= link
->nfn
*5)
696 for (i
= 0; i
< link
->nfn
; i
++) {
697 link
->fn
[i
].space
= *p
; p
++;
698 link
->fn
[i
].addr
= le32_to_cpu(*(u_int
*)p
); p
+= 4;
703 /*====================================================================*/
705 static int parse_strings(u_char
*p
, u_char
*q
, int max
,
706 char *s
, u_char
*ofs
, u_char
*found
)
710 if (p
== q
) return CS_BAD_TUPLE
;
712 for (i
= 0; i
< max
; i
++) {
713 if (*p
== 0xff) break;
717 s
[j
++] = (*p
== 0xff) ? '\0' : *p
;
718 if ((*p
== '\0') || (*p
== 0xff)) break;
719 if (++p
== q
) return CS_BAD_TUPLE
;
721 if ((*p
== 0xff) || (++p
== q
)) break;
727 return (ns
== max
) ? CS_SUCCESS
: CS_BAD_TUPLE
;
731 /*====================================================================*/
733 static int parse_vers_1(tuple_t
*tuple
, cistpl_vers_1_t
*vers_1
)
737 p
= (u_char
*)tuple
->TupleData
;
738 q
= p
+ tuple
->TupleDataLen
;
740 vers_1
->major
= *p
; p
++;
741 vers_1
->minor
= *p
; p
++;
742 if (p
>= q
) return CS_BAD_TUPLE
;
744 return parse_strings(p
, q
, CISTPL_VERS_1_MAX_PROD_STRINGS
,
745 vers_1
->str
, vers_1
->ofs
, &vers_1
->ns
);
748 /*====================================================================*/
750 static int parse_altstr(tuple_t
*tuple
, cistpl_altstr_t
*altstr
)
754 p
= (u_char
*)tuple
->TupleData
;
755 q
= p
+ tuple
->TupleDataLen
;
757 return parse_strings(p
, q
, CISTPL_MAX_ALTSTR_STRINGS
,
758 altstr
->str
, altstr
->ofs
, &altstr
->ns
);
761 /*====================================================================*/
763 static int parse_jedec(tuple_t
*tuple
, cistpl_jedec_t
*jedec
)
768 p
= (u_char
*)tuple
->TupleData
;
769 q
= p
+ tuple
->TupleDataLen
;
771 for (nid
= 0; nid
< CISTPL_MAX_DEVICES
; nid
++) {
773 jedec
->id
[nid
].mfr
= p
[0];
774 jedec
->id
[nid
].info
= p
[1];
781 /*====================================================================*/
783 static int parse_manfid(tuple_t
*tuple
, cistpl_manfid_t
*m
)
786 if (tuple
->TupleDataLen
< 4)
788 p
= (u_short
*)tuple
->TupleData
;
789 m
->manf
= le16_to_cpu(p
[0]);
790 m
->card
= le16_to_cpu(p
[1]);
794 /*====================================================================*/
796 static int parse_funcid(tuple_t
*tuple
, cistpl_funcid_t
*f
)
799 if (tuple
->TupleDataLen
< 2)
801 p
= (u_char
*)tuple
->TupleData
;
807 /*====================================================================*/
809 static int parse_funce(tuple_t
*tuple
, cistpl_funce_t
*f
)
813 if (tuple
->TupleDataLen
< 1)
815 p
= (u_char
*)tuple
->TupleData
;
817 for (i
= 1; i
< tuple
->TupleDataLen
; i
++)
822 /*====================================================================*/
824 static int parse_config(tuple_t
*tuple
, cistpl_config_t
*config
)
829 p
= (u_char
*)tuple
->TupleData
;
831 rmsz
= (*p
& 0x3c) >> 2;
832 if (tuple
->TupleDataLen
< rasz
+rmsz
+4)
834 config
->last_idx
= *(++p
);
837 for (i
= 0; i
<= rasz
; i
++)
838 config
->base
+= p
[i
] << (8*i
);
840 for (i
= 0; i
< 4; i
++)
841 config
->rmask
[i
] = 0;
842 for (i
= 0; i
<= rmsz
; i
++)
843 config
->rmask
[i
>>2] += p
[i
] << (8*(i
%4));
844 config
->subtuples
= tuple
->TupleDataLen
- (rasz
+rmsz
+4);
848 /*======================================================================
850 The following routines are all used to parse the nightmarish
851 config table entries.
853 ======================================================================*/
855 static u_char
*parse_power(u_char
*p
, u_char
*q
,
861 if (p
== q
) return NULL
;
865 for (i
= 0; i
< 7; i
++)
866 if (pwr
->present
& (1<<i
)) {
867 if (p
== q
) return NULL
;
868 pwr
->param
[i
] = POWER_CVT(*p
);
869 scale
= POWER_SCALE(*p
);
871 if (++p
== q
) return NULL
;
872 if ((*p
& 0x7f) < 100)
873 pwr
->param
[i
] += (*p
& 0x7f) * scale
/ 100;
875 pwr
->flags
|= CISTPL_POWER_HIGHZ_OK
;
879 pwr
->flags
|= CISTPL_POWER_HIGHZ_REQ
;
888 /*====================================================================*/
890 static u_char
*parse_timing(u_char
*p
, u_char
*q
,
891 cistpl_timing_t
*timing
)
895 if (p
== q
) return NULL
;
897 if ((scale
& 3) != 3) {
898 if (++p
== q
) return NULL
;
899 timing
->wait
= SPEED_CVT(*p
);
900 timing
->waitscale
= exponent
[scale
& 3];
904 if ((scale
& 7) != 7) {
905 if (++p
== q
) return NULL
;
906 timing
->ready
= SPEED_CVT(*p
);
907 timing
->rdyscale
= exponent
[scale
& 7];
912 if (++p
== q
) return NULL
;
913 timing
->reserved
= SPEED_CVT(*p
);
914 timing
->rsvscale
= exponent
[scale
];
916 timing
->reserved
= 0;
921 /*====================================================================*/
923 static u_char
*parse_io(u_char
*p
, u_char
*q
, cistpl_io_t
*io
)
927 if (p
== q
) return NULL
;
933 io
->win
[0].len
= (1 << (io
->flags
& CISTPL_IO_LINES_MASK
));
937 if (++p
== q
) return NULL
;
938 io
->nwin
= (*p
& 0x0f) + 1;
939 bsz
= (*p
& 0x30) >> 4;
941 lsz
= (*p
& 0xc0) >> 6;
945 for (i
= 0; i
< io
->nwin
; i
++) {
948 for (j
= 0; j
< bsz
; j
++, p
++) {
949 if (p
== q
) return NULL
;
950 io
->win
[i
].base
+= *p
<< (j
*8);
952 for (j
= 0; j
< lsz
; j
++, p
++) {
953 if (p
== q
) return NULL
;
954 io
->win
[i
].len
+= *p
<< (j
*8);
960 /*====================================================================*/
962 static u_char
*parse_mem(u_char
*p
, u_char
*q
, cistpl_mem_t
*mem
)
964 int i
, j
, asz
, lsz
, has_ha
;
967 if (p
== q
) return NULL
;
969 mem
->nwin
= (*p
& 0x07) + 1;
970 lsz
= (*p
& 0x18) >> 3;
971 asz
= (*p
& 0x60) >> 5;
972 has_ha
= (*p
& 0x80);
973 if (++p
== q
) return NULL
;
975 for (i
= 0; i
< mem
->nwin
; i
++) {
977 for (j
= 0; j
< lsz
; j
++, p
++) {
978 if (p
== q
) return NULL
;
981 for (j
= 0; j
< asz
; j
++, p
++) {
982 if (p
== q
) return NULL
;
986 for (j
= 0; j
< asz
; j
++, p
++) {
987 if (p
== q
) return NULL
;
990 mem
->win
[i
].len
= len
<< 8;
991 mem
->win
[i
].card_addr
= ca
<< 8;
992 mem
->win
[i
].host_addr
= ha
<< 8;
997 /*====================================================================*/
999 static u_char
*parse_irq(u_char
*p
, u_char
*q
, cistpl_irq_t
*irq
)
1001 if (p
== q
) return NULL
;
1002 irq
->IRQInfo1
= *p
; p
++;
1003 if (irq
->IRQInfo1
& IRQ_INFO2_VALID
) {
1004 if (p
+2 > q
) return NULL
;
1005 irq
->IRQInfo2
= (p
[1]<<8) + p
[0];
1011 /*====================================================================*/
1013 static int parse_cftable_entry(tuple_t
*tuple
,
1014 cistpl_cftable_entry_t
*entry
)
1016 u_char
*p
, *q
, features
;
1018 p
= tuple
->TupleData
;
1019 q
= p
+ tuple
->TupleDataLen
;
1020 entry
->index
= *p
& 0x3f;
1023 entry
->flags
|= CISTPL_CFTABLE_DEFAULT
;
1025 if (++p
== q
) return CS_BAD_TUPLE
;
1027 entry
->flags
|= CISTPL_CFTABLE_BVDS
;
1029 entry
->flags
|= CISTPL_CFTABLE_WP
;
1031 entry
->flags
|= CISTPL_CFTABLE_RDYBSY
;
1033 entry
->flags
|= CISTPL_CFTABLE_MWAIT
;
1034 entry
->interface
= *p
& 0x0f;
1036 entry
->interface
= 0;
1038 /* Process optional features */
1039 if (++p
== q
) return CS_BAD_TUPLE
;
1043 if ((features
& 3) > 0) {
1044 p
= parse_power(p
, q
, &entry
->vcc
);
1045 if (p
== NULL
) return CS_BAD_TUPLE
;
1047 entry
->vcc
.present
= 0;
1048 if ((features
& 3) > 1) {
1049 p
= parse_power(p
, q
, &entry
->vpp1
);
1050 if (p
== NULL
) return CS_BAD_TUPLE
;
1052 entry
->vpp1
.present
= 0;
1053 if ((features
& 3) > 2) {
1054 p
= parse_power(p
, q
, &entry
->vpp2
);
1055 if (p
== NULL
) return CS_BAD_TUPLE
;
1057 entry
->vpp2
.present
= 0;
1059 /* Timing options */
1060 if (features
& 0x04) {
1061 p
= parse_timing(p
, q
, &entry
->timing
);
1062 if (p
== NULL
) return CS_BAD_TUPLE
;
1064 entry
->timing
.wait
= 0;
1065 entry
->timing
.ready
= 0;
1066 entry
->timing
.reserved
= 0;
1069 /* I/O window options */
1070 if (features
& 0x08) {
1071 p
= parse_io(p
, q
, &entry
->io
);
1072 if (p
== NULL
) return CS_BAD_TUPLE
;
1076 /* Interrupt options */
1077 if (features
& 0x10) {
1078 p
= parse_irq(p
, q
, &entry
->irq
);
1079 if (p
== NULL
) return CS_BAD_TUPLE
;
1081 entry
->irq
.IRQInfo1
= 0;
1083 switch (features
& 0x60) {
1085 entry
->mem
.nwin
= 0;
1088 entry
->mem
.nwin
= 1;
1089 entry
->mem
.win
[0].len
= le16_to_cpu(*(u_short
*)p
) << 8;
1090 entry
->mem
.win
[0].card_addr
= 0;
1091 entry
->mem
.win
[0].host_addr
= 0;
1093 if (p
> q
) return CS_BAD_TUPLE
;
1096 entry
->mem
.nwin
= 1;
1097 entry
->mem
.win
[0].len
= le16_to_cpu(*(u_short
*)p
) << 8;
1098 entry
->mem
.win
[0].card_addr
=
1099 le16_to_cpu(*(u_short
*)(p
+2)) << 8;
1100 entry
->mem
.win
[0].host_addr
= 0;
1102 if (p
> q
) return CS_BAD_TUPLE
;
1105 p
= parse_mem(p
, q
, &entry
->mem
);
1106 if (p
== NULL
) return CS_BAD_TUPLE
;
1111 if (features
& 0x80) {
1112 if (p
== q
) return CS_BAD_TUPLE
;
1113 entry
->flags
|= (*p
<< 8);
1115 if (++p
== q
) return CS_BAD_TUPLE
;
1119 entry
->subtuples
= q
-p
;
1124 /*====================================================================*/
1126 #ifdef CONFIG_CARDBUS
1128 static int parse_bar(tuple_t
*tuple
, cistpl_bar_t
*bar
)
1131 if (tuple
->TupleDataLen
< 6)
1132 return CS_BAD_TUPLE
;
1133 p
= (u_char
*)tuple
->TupleData
;
1136 bar
->size
= le32_to_cpu(*(u_int
*)p
);
1140 static int parse_config_cb(tuple_t
*tuple
, cistpl_config_t
*config
)
1144 p
= (u_char
*)tuple
->TupleData
;
1145 if ((*p
!= 3) || (tuple
->TupleDataLen
< 6))
1146 return CS_BAD_TUPLE
;
1147 config
->last_idx
= *(++p
);
1149 config
->base
= le32_to_cpu(*(u_int
*)p
);
1150 config
->subtuples
= tuple
->TupleDataLen
- 6;
1154 static int parse_cftable_entry_cb(tuple_t
*tuple
,
1155 cistpl_cftable_entry_cb_t
*entry
)
1157 u_char
*p
, *q
, features
;
1159 p
= tuple
->TupleData
;
1160 q
= p
+ tuple
->TupleDataLen
;
1161 entry
->index
= *p
& 0x3f;
1164 entry
->flags
|= CISTPL_CFTABLE_DEFAULT
;
1166 /* Process optional features */
1167 if (++p
== q
) return CS_BAD_TUPLE
;
1171 if ((features
& 3) > 0) {
1172 p
= parse_power(p
, q
, &entry
->vcc
);
1173 if (p
== NULL
) return CS_BAD_TUPLE
;
1175 entry
->vcc
.present
= 0;
1176 if ((features
& 3) > 1) {
1177 p
= parse_power(p
, q
, &entry
->vpp1
);
1178 if (p
== NULL
) return CS_BAD_TUPLE
;
1180 entry
->vpp1
.present
= 0;
1181 if ((features
& 3) > 2) {
1182 p
= parse_power(p
, q
, &entry
->vpp2
);
1183 if (p
== NULL
) return CS_BAD_TUPLE
;
1185 entry
->vpp2
.present
= 0;
1187 /* I/O window options */
1188 if (features
& 0x08) {
1189 if (p
== q
) return CS_BAD_TUPLE
;
1190 entry
->io
= *p
; p
++;
1194 /* Interrupt options */
1195 if (features
& 0x10) {
1196 p
= parse_irq(p
, q
, &entry
->irq
);
1197 if (p
== NULL
) return CS_BAD_TUPLE
;
1199 entry
->irq
.IRQInfo1
= 0;
1201 if (features
& 0x20) {
1202 if (p
== q
) return CS_BAD_TUPLE
;
1203 entry
->mem
= *p
; p
++;
1208 if (features
& 0x80) {
1209 if (p
== q
) return CS_BAD_TUPLE
;
1210 entry
->flags
|= (*p
<< 8);
1212 if (++p
== q
) return CS_BAD_TUPLE
;
1213 entry
->flags
|= (*p
<< 16);
1216 if (++p
== q
) return CS_BAD_TUPLE
;
1220 entry
->subtuples
= q
-p
;
1227 /*====================================================================*/
1229 static int parse_device_geo(tuple_t
*tuple
, cistpl_device_geo_t
*geo
)
1234 p
= (u_char
*)tuple
->TupleData
;
1235 q
= p
+ tuple
->TupleDataLen
;
1237 for (n
= 0; n
< CISTPL_MAX_DEVICES
; n
++) {
1239 geo
->geo
[n
].buswidth
= p
[0];
1240 geo
->geo
[n
].erase_block
= 1 << (p
[1]-1);
1241 geo
->geo
[n
].read_block
= 1 << (p
[2]-1);
1242 geo
->geo
[n
].write_block
= 1 << (p
[3]-1);
1243 geo
->geo
[n
].partition
= 1 << (p
[4]-1);
1244 geo
->geo
[n
].interleave
= 1 << (p
[5]-1);
1251 /*====================================================================*/
1253 static int parse_vers_2(tuple_t
*tuple
, cistpl_vers_2_t
*v2
)
1257 if (tuple
->TupleDataLen
< 10)
1258 return CS_BAD_TUPLE
;
1260 p
= tuple
->TupleData
;
1261 q
= p
+ tuple
->TupleDataLen
;
1265 v2
->dindex
= le16_to_cpu(*(u_short
*)(p
+2));
1270 return parse_strings(p
, q
, 2, v2
->str
, &v2
->vendor
, NULL
);
1273 /*====================================================================*/
1275 static int parse_org(tuple_t
*tuple
, cistpl_org_t
*org
)
1280 p
= tuple
->TupleData
;
1281 q
= p
+ tuple
->TupleDataLen
;
1282 if (p
== q
) return CS_BAD_TUPLE
;
1284 if (++p
== q
) return CS_BAD_TUPLE
;
1285 for (i
= 0; i
< 30; i
++) {
1287 if (*p
== '\0') break;
1288 if (++p
== q
) return CS_BAD_TUPLE
;
1293 /*====================================================================*/
1295 static int parse_format(tuple_t
*tuple
, cistpl_format_t
*fmt
)
1299 if (tuple
->TupleDataLen
< 10)
1300 return CS_BAD_TUPLE
;
1302 p
= tuple
->TupleData
;
1306 fmt
->offset
= le32_to_cpu(*(u_int
*)(p
+2));
1307 fmt
->length
= le32_to_cpu(*(u_int
*)(p
+6));
1312 /*====================================================================*/
1314 int pcmcia_parse_tuple(client_handle_t handle
, tuple_t
*tuple
, cisparse_t
*parse
)
1316 int ret
= CS_SUCCESS
;
1318 if (tuple
->TupleDataLen
> tuple
->TupleDataMax
)
1319 return CS_BAD_TUPLE
;
1320 switch (tuple
->TupleCode
) {
1322 case CISTPL_DEVICE_A
:
1323 ret
= parse_device(tuple
, &parse
->device
);
1325 #ifdef CONFIG_CARDBUS
1327 ret
= parse_bar(tuple
, &parse
->bar
);
1329 case CISTPL_CONFIG_CB
:
1330 ret
= parse_config_cb(tuple
, &parse
->config
);
1332 case CISTPL_CFTABLE_ENTRY_CB
:
1333 ret
= parse_cftable_entry_cb(tuple
, &parse
->cftable_entry_cb
);
1336 case CISTPL_CHECKSUM
:
1337 ret
= parse_checksum(tuple
, &parse
->checksum
);
1339 case CISTPL_LONGLINK_A
:
1340 case CISTPL_LONGLINK_C
:
1341 ret
= parse_longlink(tuple
, &parse
->longlink
);
1343 case CISTPL_LONGLINK_MFC
:
1344 ret
= parse_longlink_mfc(tuple
, &parse
->longlink_mfc
);
1347 ret
= parse_vers_1(tuple
, &parse
->version_1
);
1350 ret
= parse_altstr(tuple
, &parse
->altstr
);
1352 case CISTPL_JEDEC_A
:
1353 case CISTPL_JEDEC_C
:
1354 ret
= parse_jedec(tuple
, &parse
->jedec
);
1357 ret
= parse_manfid(tuple
, &parse
->manfid
);
1360 ret
= parse_funcid(tuple
, &parse
->funcid
);
1363 ret
= parse_funce(tuple
, &parse
->funce
);
1366 ret
= parse_config(tuple
, &parse
->config
);
1368 case CISTPL_CFTABLE_ENTRY
:
1369 ret
= parse_cftable_entry(tuple
, &parse
->cftable_entry
);
1371 case CISTPL_DEVICE_GEO
:
1372 case CISTPL_DEVICE_GEO_A
:
1373 ret
= parse_device_geo(tuple
, &parse
->device_geo
);
1376 ret
= parse_vers_2(tuple
, &parse
->vers_2
);
1379 ret
= parse_org(tuple
, &parse
->org
);
1382 case CISTPL_FORMAT_A
:
1383 ret
= parse_format(tuple
, &parse
->format
);
1385 case CISTPL_NO_LINK
:
1386 case CISTPL_LINKTARGET
:
1390 ret
= CS_UNSUPPORTED_FUNCTION
;
1396 /*======================================================================
1398 This is used internally by Card Services to look up CIS stuff.
1400 ======================================================================*/
1402 int read_tuple(client_handle_t handle
, cisdata_t code
, void *parse
)
1408 tuple
.DesiredTuple
= code
;
1409 tuple
.Attributes
= TUPLE_RETURN_COMMON
;
1410 ret
= pcmcia_get_first_tuple(handle
, &tuple
);
1411 if (ret
!= CS_SUCCESS
) return ret
;
1412 tuple
.TupleData
= buf
;
1413 tuple
.TupleOffset
= 0;
1414 tuple
.TupleDataMax
= sizeof(buf
);
1415 ret
= pcmcia_get_tuple_data(handle
, &tuple
);
1416 if (ret
!= CS_SUCCESS
) return ret
;
1417 ret
= pcmcia_parse_tuple(handle
, &tuple
, parse
);
1421 /*======================================================================
1423 This tries to determine if a card has a sensible CIS. It returns
1424 the number of tuples in the CIS, or 0 if the CIS looks bad. The
1425 checks include making sure several critical tuples are present and
1426 valid; seeing if the total number of tuples is reasonable; and
1427 looking for tuples that use reserved codes.
1429 ======================================================================*/
1431 int pcmcia_validate_cis(client_handle_t handle
, cisinfo_t
*info
)
1435 int ret
, reserved
, dev_ok
= 0, ident_ok
= 0;
1437 if (CHECK_HANDLE(handle
))
1438 return CS_BAD_HANDLE
;
1440 info
->Chains
= reserved
= 0;
1441 tuple
.DesiredTuple
= RETURN_FIRST_TUPLE
;
1442 tuple
.Attributes
= TUPLE_RETURN_COMMON
;
1443 ret
= pcmcia_get_first_tuple(handle
, &tuple
);
1444 if (ret
!= CS_SUCCESS
)
1447 /* First tuple should be DEVICE; we should really have either that
1448 or a CFTABLE_ENTRY of some sort */
1449 if ((tuple
.TupleCode
== CISTPL_DEVICE
) ||
1450 (read_tuple(handle
, CISTPL_CFTABLE_ENTRY
, &p
) == CS_SUCCESS
) ||
1451 (read_tuple(handle
, CISTPL_CFTABLE_ENTRY_CB
, &p
) == CS_SUCCESS
))
1454 /* All cards should have a MANFID tuple, and/or a VERS_1 or VERS_2
1455 tuple, for card identification. Certain old D-Link and Linksys
1456 cards have only a broken VERS_2 tuple; hence the bogus test. */
1457 if ((read_tuple(handle
, CISTPL_MANFID
, &p
) == CS_SUCCESS
) ||
1458 (read_tuple(handle
, CISTPL_VERS_1
, &p
) == CS_SUCCESS
) ||
1459 (read_tuple(handle
, CISTPL_VERS_2
, &p
) != CS_NO_MORE_ITEMS
))
1462 if (!dev_ok
&& !ident_ok
)
1465 for (info
->Chains
= 1; info
->Chains
< MAX_TUPLES
; info
->Chains
++) {
1466 ret
= pcmcia_get_next_tuple(handle
, &tuple
);
1467 if (ret
!= CS_SUCCESS
) break;
1468 if (((tuple
.TupleCode
> 0x23) && (tuple
.TupleCode
< 0x40)) ||
1469 ((tuple
.TupleCode
> 0x47) && (tuple
.TupleCode
< 0x80)) ||
1470 ((tuple
.TupleCode
> 0x90) && (tuple
.TupleCode
< 0xff)))
1473 if ((info
->Chains
== MAX_TUPLES
) || (reserved
> 5) ||
1474 ((!dev_ok
|| !ident_ok
) && (info
->Chains
> 10)))