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/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>
44 #include <linux/sched.h>
45 #include <linux/pci.h>
46 #include <linux/ioport.h>
48 #include <asm/byteorder.h>
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"
58 static const u_char mantissa
[] = {
59 10, 12, 13, 15, 20, 25, 30, 35,
60 40, 45, 50, 55, 60, 70, 80, 90
63 static const u_int exponent
[] = {
64 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000
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])
75 /* Upper limit on reasonable # of tuples */
76 #define MAX_TUPLES 200
78 /*====================================================================*/
80 /* Parameters that can be set with 'insmod' */
82 #define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0444)
84 INT_MODULE_PARM(cis_width
, 0); /* 16-bit CIS? */
86 void release_cis_mem(struct pcmcia_socket
*s
)
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
);
92 release_resource(s
->cis_mem
.res
);
93 kfree(s
->cis_mem
.res
);
94 s
->cis_mem
.res
= NULL
;
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.
106 static void __iomem
*
107 set_cis_map(struct pcmcia_socket
*s
, unsigned int card_offset
, unsigned int flags
)
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,
113 if (mem
->res
== NULL
) {
114 printk(KERN_NOTICE
"cs: unable to map card memory!\n");
117 s
->cis_virt
= ioremap(mem
->res
->start
, s
->map_size
);
119 mem
->card_start
= card_offset
;
121 s
->ops
->set_mem_map(s
, mem
);
122 if (s
->features
& SS_CAP_STATIC_MAP
) {
124 iounmap(s
->cis_virt
);
125 s
->cis_virt
= ioremap(mem
->static_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 void __iomem
*sys
, *end
;
145 unsigned char *buf
= ptr
;
147 cs_dbg(s
, 3, "read_cis_mem(%d, %#x, %u)\n", attr
, addr
, len
);
149 if (attr
& IS_INDIRECT
) {
150 /* Indirect accesses use a bunch of special registers at fixed
151 locations in common memory */
152 u_char flags
= ICTRL0_COMMON
|ICTRL0_AUTOINC
|ICTRL0_BYTEGRAN
;
153 if (attr
& IS_ATTR
) {
155 flags
= ICTRL0_AUTOINC
;
158 sys
= set_cis_map(s
, 0, MAP_ACTIVE
| ((cis_width
) ? MAP_16BIT
: 0));
160 memset(ptr
, 0xff, len
);
164 writeb(flags
, sys
+CISREG_ICTRL0
);
165 writeb(addr
& 0xff, sys
+CISREG_IADDR0
);
166 writeb((addr
>>8) & 0xff, sys
+CISREG_IADDR1
);
167 writeb((addr
>>16) & 0xff, sys
+CISREG_IADDR2
);
168 writeb((addr
>>24) & 0xff, sys
+CISREG_IADDR3
);
169 for ( ; len
> 0; len
--, buf
++)
170 *buf
= readb(sys
+CISREG_IDATA0
);
172 u_int inc
= 1, card_offset
, flags
;
174 flags
= MAP_ACTIVE
| ((cis_width
) ? MAP_16BIT
: 0);
181 card_offset
= addr
& ~(s
->map_size
-1);
183 sys
= set_cis_map(s
, card_offset
, flags
);
185 memset(ptr
, 0xff, len
);
188 end
= sys
+ s
->map_size
;
189 sys
= sys
+ (addr
& (s
->map_size
-1));
190 for ( ; len
> 0; len
--, buf
++, sys
+= inc
) {
195 card_offset
+= s
->map_size
;
199 cs_dbg(s
, 3, " %#2.2x %#2.2x %#2.2x %#2.2x ...\n",
200 *(u_char
*)(ptr
+0), *(u_char
*)(ptr
+1),
201 *(u_char
*)(ptr
+2), *(u_char
*)(ptr
+3));
205 void write_cis_mem(struct pcmcia_socket
*s
, int attr
, u_int addr
,
206 u_int len
, void *ptr
)
208 void __iomem
*sys
, *end
;
209 unsigned char *buf
= ptr
;
211 cs_dbg(s
, 3, "write_cis_mem(%d, %#x, %u)\n", attr
, addr
, len
);
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
) {
219 flags
= ICTRL0_AUTOINC
;
222 sys
= set_cis_map(s
, 0, MAP_ACTIVE
| ((cis_width
) ? MAP_16BIT
: 0));
224 return; /* FIXME: Error */
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
);
234 u_int inc
= 1, card_offset
, flags
;
236 flags
= MAP_ACTIVE
| ((cis_width
) ? MAP_16BIT
: 0);
237 if (attr
& IS_ATTR
) {
243 card_offset
= addr
& ~(s
->map_size
-1);
245 sys
= set_cis_map(s
, card_offset
, flags
);
247 return; /* FIXME: error */
249 end
= sys
+ s
->map_size
;
250 sys
= sys
+ (addr
& (s
->map_size
-1));
251 for ( ; len
> 0; len
--, buf
++, sys
+= inc
) {
256 card_offset
+= s
->map_size
;
262 /*======================================================================
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.
268 ======================================================================*/
270 static void read_cis_cache(struct pcmcia_socket
*s
, int attr
, u_int addr
,
271 u_int len
, void *ptr
)
273 struct cis_cache_entry
*cis
;
277 if (s
->fake_cis_len
> addr
+len
)
278 memcpy(ptr
, s
->fake_cis
+addr
, len
);
280 memset(ptr
, 0xff, len
);
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
);
291 #ifdef CONFIG_CARDBUS
292 if (s
->state
& SOCKET_CARDBUS
)
293 ret
= read_cb_mem(s
, attr
, addr
, len
, ptr
);
296 ret
= read_cis_mem(s
, attr
, addr
, len
, ptr
);
299 /* Copy data into the cache */
300 cis
= kmalloc(sizeof(struct cis_cache_entry
) + len
, GFP_KERNEL
);
305 memcpy(cis
->cache
, ptr
, len
);
306 list_add(&cis
->node
, &s
->cis_cache
);
312 remove_cis_cache(struct pcmcia_socket
*s
, int attr
, u_int addr
, u_int len
)
314 struct cis_cache_entry
*cis
;
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
);
324 void destroy_cis_cache(struct pcmcia_socket
*s
)
326 struct list_head
*l
, *n
;
328 list_for_each_safe(l
, n
, &s
->cis_cache
) {
329 struct cis_cache_entry
*cis
= list_entry(l
, struct cis_cache_entry
, node
);
331 list_del(&cis
->node
);
336 /*======================================================================
338 This verifies if the CIS of a card matches what is in the CIS
341 ======================================================================*/
343 int verify_cis_cache(struct pcmcia_socket
*s
)
345 struct cis_cache_entry
*cis
;
348 buf
= kmalloc(256, GFP_KERNEL
);
351 list_for_each_entry(cis
, &s
->cis_cache
, node
) {
356 #ifdef CONFIG_CARDBUS
357 if (s
->state
& SOCKET_CARDBUS
)
358 read_cb_mem(s
, cis
->attr
, cis
->addr
, len
, buf
);
361 read_cis_mem(s
, cis
->attr
, cis
->addr
, len
, buf
);
363 if (memcmp(buf
, cis
->cache
, len
) != 0) {
372 /*======================================================================
374 For really bad cards, we provide a facility for uploading a
377 ======================================================================*/
379 int pcmcia_replace_cis(client_handle_t handle
, cisdump_t
*cis
)
381 struct pcmcia_socket
*s
;
382 if (CHECK_HANDLE(handle
))
383 return CS_BAD_HANDLE
;
385 if (s
->fake_cis
!= NULL
) {
389 if (cis
->Length
> CISTPL_MAX_CIS_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
);
399 /*======================================================================
401 The high-level CIS tuple services
403 ======================================================================*/
405 typedef struct tuple_flags
{
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)
417 int pcmcia_get_next_tuple(client_handle_t handle
, tuple_t
*tuple
);
419 int pcmcia_get_first_tuple(client_handle_t handle
, tuple_t
*tuple
)
421 struct pcmcia_socket
*s
;
422 if (CHECK_HANDLE(handle
))
423 return CS_BAD_HANDLE
;
425 if (!(s
->state
& SOCKET_PRESENT
))
427 tuple
->TupleLink
= tuple
->Flags
= 0;
428 #ifdef CONFIG_CARDBUS
429 if (s
->state
& SOCKET_CARDBUS
) {
430 struct pci_dev
*dev
= s
->cb_dev
;
432 pci_bus_read_config_dword(dev
->subordinate
, 0, PCI_CARDBUS_CIS
, &ptr
);
433 tuple
->CISOffset
= ptr
& ~7;
434 SPACE(tuple
->Flags
) = (ptr
& 7);
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;
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
;
451 tuple
->CISOffset
= tuple
->TupleLink
= 0;
452 tuple
->DesiredTuple
= req
;
454 return pcmcia_get_next_tuple(handle
, tuple
);
457 static int follow_link(struct pcmcia_socket
*s
, tuple_t
*tuple
)
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;
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))
485 remove_cis_cache(s
, SPACE(tuple
->Flags
), ofs
, 5);
486 /* Then, we try the wrong spot... */
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))
493 remove_cis_cache(s
, SPACE(tuple
->Flags
), ofs
, 5);
497 int pcmcia_get_next_tuple(client_handle_t handle
, tuple_t
*tuple
)
499 struct pcmcia_socket
*s
;
503 if (CHECK_HANDLE(handle
))
504 return CS_BAD_HANDLE
;
506 if (!(s
->state
& SOCKET_PRESENT
))
509 link
[1] = tuple
->TupleLink
;
510 ofs
= tuple
->CISOffset
+ tuple
->TupleLink
;
511 attr
= SPACE(tuple
->Flags
);
513 for (i
= 0; i
< MAX_TUPLES
; i
++) {
514 if (link
[1] == 0xff) {
515 link
[0] = CISTPL_END
;
517 read_cis_cache(s
, attr
, ofs
, 2, link
);
518 if (link
[0] == CISTPL_NULL
) {
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
);
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
)) {
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
);
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
);
549 case CISTPL_INDIRECT
:
550 HAS_LINK(tuple
->Flags
) = 1;
551 LINK_SPACE(tuple
->Flags
) = IS_ATTR
| IS_INDIRECT
;
552 tuple
->LinkOffset
= 0;
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
;
562 /* Follow exactly one of the links */
563 MFC_FN(tuple
->Flags
) = 1;
564 tuple
->LinkOffset
+= handle
->Function
* 5;
568 HAS_LINK(tuple
->Flags
) = 0;
571 if ((tuple
->Attributes
& TUPLE_RETURN_LINK
) &&
572 (tuple
->DesiredTuple
== RETURN_FIRST_TUPLE
))
575 if (tuple
->DesiredTuple
== RETURN_FIRST_TUPLE
)
578 if (link
[0] == tuple
->DesiredTuple
)
582 if (i
== MAX_TUPLES
) {
583 cs_dbg(s
, 1, "cs: overrun in pcmcia_get_next_tuple\n");
584 return CS_NO_MORE_ITEMS
;
587 tuple
->TupleCode
= link
[0];
588 tuple
->TupleLink
= link
[1];
589 tuple
->CISOffset
= ofs
+ 2;
593 /*====================================================================*/
595 #define _MIN(a, b) (((a) < (b)) ? (a) : (b))
597 int pcmcia_get_tuple_data(client_handle_t handle
, tuple_t
*tuple
)
599 struct pcmcia_socket
*s
;
602 if (CHECK_HANDLE(handle
))
603 return CS_BAD_HANDLE
;
607 if (tuple
->TupleLink
< tuple
->TupleOffset
)
608 return CS_NO_MORE_ITEMS
;
609 len
= tuple
->TupleLink
- tuple
->TupleOffset
;
610 tuple
->TupleDataLen
= tuple
->TupleLink
;
613 read_cis_cache(s
, SPACE(tuple
->Flags
),
614 tuple
->CISOffset
+ tuple
->TupleOffset
,
615 _MIN(len
, tuple
->TupleDataMax
), tuple
->TupleData
);
619 /*======================================================================
621 Parsing routines for individual tuples
623 ======================================================================*/
625 static int parse_device(tuple_t
*tuple
, cistpl_device_t
*device
)
631 p
= (u_char
*)tuple
->TupleData
;
632 q
= p
+ tuple
->TupleDataLen
;
635 for (i
= 0; i
< CISTPL_MAX_DEVICES
; i
++) {
637 if (*p
== 0xff) break;
638 device
->dev
[i
].type
= (*p
>> 4);
639 device
->dev
[i
].wp
= (*p
& 0x08) ? 1 : 0;
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;
647 if (++p
== q
) return CS_BAD_TUPLE
;
648 device
->dev
[i
].speed
= SPEED_CVT(*p
);
650 if (++p
== q
) return CS_BAD_TUPLE
;
656 if (++p
== q
) return CS_BAD_TUPLE
;
657 if (*p
== 0xff) break;
659 if (scale
== 7) return CS_BAD_TUPLE
;
660 device
->dev
[i
].size
= ((*p
>> 3) + 1) * (512 << (scale
*2));
668 /*====================================================================*/
670 static int parse_checksum(tuple_t
*tuple
, cistpl_checksum_t
*csum
)
673 if (tuple
->TupleDataLen
< 5)
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));
682 /*====================================================================*/
684 static int parse_longlink(tuple_t
*tuple
, cistpl_longlink_t
*link
)
686 if (tuple
->TupleDataLen
< 4)
688 link
->addr
= le32_to_cpu(*(u_int
*)tuple
->TupleData
);
692 /*====================================================================*/
694 static int parse_longlink_mfc(tuple_t
*tuple
,
695 cistpl_longlink_mfc_t
*link
)
700 p
= (u_char
*)tuple
->TupleData
;
703 if (tuple
->TupleDataLen
<= link
->nfn
*5)
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;
712 /*====================================================================*/
714 static int parse_strings(u_char
*p
, u_char
*q
, int max
,
715 char *s
, u_char
*ofs
, u_char
*found
)
719 if (p
== q
) return CS_BAD_TUPLE
;
721 for (i
= 0; i
< max
; i
++) {
722 if (*p
== 0xff) break;
726 s
[j
++] = (*p
== 0xff) ? '\0' : *p
;
727 if ((*p
== '\0') || (*p
== 0xff)) break;
728 if (++p
== q
) return CS_BAD_TUPLE
;
730 if ((*p
== 0xff) || (++p
== q
)) break;
736 return (ns
== max
) ? CS_SUCCESS
: CS_BAD_TUPLE
;
740 /*====================================================================*/
742 static int parse_vers_1(tuple_t
*tuple
, cistpl_vers_1_t
*vers_1
)
746 p
= (u_char
*)tuple
->TupleData
;
747 q
= p
+ tuple
->TupleDataLen
;
749 vers_1
->major
= *p
; p
++;
750 vers_1
->minor
= *p
; p
++;
751 if (p
>= q
) return CS_BAD_TUPLE
;
753 return parse_strings(p
, q
, CISTPL_VERS_1_MAX_PROD_STRINGS
,
754 vers_1
->str
, vers_1
->ofs
, &vers_1
->ns
);
757 /*====================================================================*/
759 static int parse_altstr(tuple_t
*tuple
, cistpl_altstr_t
*altstr
)
763 p
= (u_char
*)tuple
->TupleData
;
764 q
= p
+ tuple
->TupleDataLen
;
766 return parse_strings(p
, q
, CISTPL_MAX_ALTSTR_STRINGS
,
767 altstr
->str
, altstr
->ofs
, &altstr
->ns
);
770 /*====================================================================*/
772 static int parse_jedec(tuple_t
*tuple
, cistpl_jedec_t
*jedec
)
777 p
= (u_char
*)tuple
->TupleData
;
778 q
= p
+ tuple
->TupleDataLen
;
780 for (nid
= 0; nid
< CISTPL_MAX_DEVICES
; nid
++) {
782 jedec
->id
[nid
].mfr
= p
[0];
783 jedec
->id
[nid
].info
= p
[1];
790 /*====================================================================*/
792 static int parse_manfid(tuple_t
*tuple
, cistpl_manfid_t
*m
)
795 if (tuple
->TupleDataLen
< 4)
797 p
= (u_short
*)tuple
->TupleData
;
798 m
->manf
= le16_to_cpu(p
[0]);
799 m
->card
= le16_to_cpu(p
[1]);
803 /*====================================================================*/
805 static int parse_funcid(tuple_t
*tuple
, cistpl_funcid_t
*f
)
808 if (tuple
->TupleDataLen
< 2)
810 p
= (u_char
*)tuple
->TupleData
;
816 /*====================================================================*/
818 static int parse_funce(tuple_t
*tuple
, cistpl_funce_t
*f
)
822 if (tuple
->TupleDataLen
< 1)
824 p
= (u_char
*)tuple
->TupleData
;
826 for (i
= 1; i
< tuple
->TupleDataLen
; i
++)
831 /*====================================================================*/
833 static int parse_config(tuple_t
*tuple
, cistpl_config_t
*config
)
838 p
= (u_char
*)tuple
->TupleData
;
840 rmsz
= (*p
& 0x3c) >> 2;
841 if (tuple
->TupleDataLen
< rasz
+rmsz
+4)
843 config
->last_idx
= *(++p
);
846 for (i
= 0; i
<= rasz
; i
++)
847 config
->base
+= p
[i
] << (8*i
);
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);
857 /*======================================================================
859 The following routines are all used to parse the nightmarish
860 config table entries.
862 ======================================================================*/
864 static u_char
*parse_power(u_char
*p
, u_char
*q
,
870 if (p
== q
) return NULL
;
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
);
880 if (++p
== q
) return NULL
;
881 if ((*p
& 0x7f) < 100)
882 pwr
->param
[i
] += (*p
& 0x7f) * scale
/ 100;
884 pwr
->flags
|= CISTPL_POWER_HIGHZ_OK
;
888 pwr
->flags
|= CISTPL_POWER_HIGHZ_REQ
;
897 /*====================================================================*/
899 static u_char
*parse_timing(u_char
*p
, u_char
*q
,
900 cistpl_timing_t
*timing
)
904 if (p
== q
) return NULL
;
906 if ((scale
& 3) != 3) {
907 if (++p
== q
) return NULL
;
908 timing
->wait
= SPEED_CVT(*p
);
909 timing
->waitscale
= exponent
[scale
& 3];
913 if ((scale
& 7) != 7) {
914 if (++p
== q
) return NULL
;
915 timing
->ready
= SPEED_CVT(*p
);
916 timing
->rdyscale
= exponent
[scale
& 7];
921 if (++p
== q
) return NULL
;
922 timing
->reserved
= SPEED_CVT(*p
);
923 timing
->rsvscale
= exponent
[scale
];
925 timing
->reserved
= 0;
930 /*====================================================================*/
932 static u_char
*parse_io(u_char
*p
, u_char
*q
, cistpl_io_t
*io
)
936 if (p
== q
) return NULL
;
942 io
->win
[0].len
= (1 << (io
->flags
& CISTPL_IO_LINES_MASK
));
946 if (++p
== q
) return NULL
;
947 io
->nwin
= (*p
& 0x0f) + 1;
948 bsz
= (*p
& 0x30) >> 4;
950 lsz
= (*p
& 0xc0) >> 6;
954 for (i
= 0; i
< io
->nwin
; i
++) {
957 for (j
= 0; j
< bsz
; j
++, p
++) {
958 if (p
== q
) return NULL
;
959 io
->win
[i
].base
+= *p
<< (j
*8);
961 for (j
= 0; j
< lsz
; j
++, p
++) {
962 if (p
== q
) return NULL
;
963 io
->win
[i
].len
+= *p
<< (j
*8);
969 /*====================================================================*/
971 static u_char
*parse_mem(u_char
*p
, u_char
*q
, cistpl_mem_t
*mem
)
973 int i
, j
, asz
, lsz
, has_ha
;
976 if (p
== q
) return NULL
;
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
;
984 for (i
= 0; i
< mem
->nwin
; i
++) {
986 for (j
= 0; j
< lsz
; j
++, p
++) {
987 if (p
== q
) return NULL
;
990 for (j
= 0; j
< asz
; j
++, p
++) {
991 if (p
== q
) return NULL
;
995 for (j
= 0; j
< asz
; j
++, p
++) {
996 if (p
== q
) return NULL
;
999 mem
->win
[i
].len
= len
<< 8;
1000 mem
->win
[i
].card_addr
= ca
<< 8;
1001 mem
->win
[i
].host_addr
= ha
<< 8;
1006 /*====================================================================*/
1008 static u_char
*parse_irq(u_char
*p
, u_char
*q
, cistpl_irq_t
*irq
)
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];
1020 /*====================================================================*/
1022 static int parse_cftable_entry(tuple_t
*tuple
,
1023 cistpl_cftable_entry_t
*entry
)
1025 u_char
*p
, *q
, features
;
1027 p
= tuple
->TupleData
;
1028 q
= p
+ tuple
->TupleDataLen
;
1029 entry
->index
= *p
& 0x3f;
1032 entry
->flags
|= CISTPL_CFTABLE_DEFAULT
;
1034 if (++p
== q
) return CS_BAD_TUPLE
;
1036 entry
->flags
|= CISTPL_CFTABLE_BVDS
;
1038 entry
->flags
|= CISTPL_CFTABLE_WP
;
1040 entry
->flags
|= CISTPL_CFTABLE_RDYBSY
;
1042 entry
->flags
|= CISTPL_CFTABLE_MWAIT
;
1043 entry
->interface
= *p
& 0x0f;
1045 entry
->interface
= 0;
1047 /* Process optional features */
1048 if (++p
== q
) return CS_BAD_TUPLE
;
1052 if ((features
& 3) > 0) {
1053 p
= parse_power(p
, q
, &entry
->vcc
);
1054 if (p
== NULL
) return CS_BAD_TUPLE
;
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
;
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
;
1066 entry
->vpp2
.present
= 0;
1068 /* Timing options */
1069 if (features
& 0x04) {
1070 p
= parse_timing(p
, q
, &entry
->timing
);
1071 if (p
== NULL
) return CS_BAD_TUPLE
;
1073 entry
->timing
.wait
= 0;
1074 entry
->timing
.ready
= 0;
1075 entry
->timing
.reserved
= 0;
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
;
1085 /* Interrupt options */
1086 if (features
& 0x10) {
1087 p
= parse_irq(p
, q
, &entry
->irq
);
1088 if (p
== NULL
) return CS_BAD_TUPLE
;
1090 entry
->irq
.IRQInfo1
= 0;
1092 switch (features
& 0x60) {
1094 entry
->mem
.nwin
= 0;
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;
1102 if (p
> q
) return CS_BAD_TUPLE
;
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;
1111 if (p
> q
) return CS_BAD_TUPLE
;
1114 p
= parse_mem(p
, q
, &entry
->mem
);
1115 if (p
== NULL
) return CS_BAD_TUPLE
;
1120 if (features
& 0x80) {
1121 if (p
== q
) return CS_BAD_TUPLE
;
1122 entry
->flags
|= (*p
<< 8);
1124 if (++p
== q
) return CS_BAD_TUPLE
;
1128 entry
->subtuples
= q
-p
;
1133 /*====================================================================*/
1135 #ifdef CONFIG_CARDBUS
1137 static int parse_bar(tuple_t
*tuple
, cistpl_bar_t
*bar
)
1140 if (tuple
->TupleDataLen
< 6)
1141 return CS_BAD_TUPLE
;
1142 p
= (u_char
*)tuple
->TupleData
;
1145 bar
->size
= le32_to_cpu(*(u_int
*)p
);
1149 static int parse_config_cb(tuple_t
*tuple
, cistpl_config_t
*config
)
1153 p
= (u_char
*)tuple
->TupleData
;
1154 if ((*p
!= 3) || (tuple
->TupleDataLen
< 6))
1155 return CS_BAD_TUPLE
;
1156 config
->last_idx
= *(++p
);
1158 config
->base
= le32_to_cpu(*(u_int
*)p
);
1159 config
->subtuples
= tuple
->TupleDataLen
- 6;
1163 static int parse_cftable_entry_cb(tuple_t
*tuple
,
1164 cistpl_cftable_entry_cb_t
*entry
)
1166 u_char
*p
, *q
, features
;
1168 p
= tuple
->TupleData
;
1169 q
= p
+ tuple
->TupleDataLen
;
1170 entry
->index
= *p
& 0x3f;
1173 entry
->flags
|= CISTPL_CFTABLE_DEFAULT
;
1175 /* Process optional features */
1176 if (++p
== q
) return CS_BAD_TUPLE
;
1180 if ((features
& 3) > 0) {
1181 p
= parse_power(p
, q
, &entry
->vcc
);
1182 if (p
== NULL
) return CS_BAD_TUPLE
;
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
;
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
;
1194 entry
->vpp2
.present
= 0;
1196 /* I/O window options */
1197 if (features
& 0x08) {
1198 if (p
== q
) return CS_BAD_TUPLE
;
1199 entry
->io
= *p
; p
++;
1203 /* Interrupt options */
1204 if (features
& 0x10) {
1205 p
= parse_irq(p
, q
, &entry
->irq
);
1206 if (p
== NULL
) return CS_BAD_TUPLE
;
1208 entry
->irq
.IRQInfo1
= 0;
1210 if (features
& 0x20) {
1211 if (p
== q
) return CS_BAD_TUPLE
;
1212 entry
->mem
= *p
; p
++;
1217 if (features
& 0x80) {
1218 if (p
== q
) return CS_BAD_TUPLE
;
1219 entry
->flags
|= (*p
<< 8);
1221 if (++p
== q
) return CS_BAD_TUPLE
;
1222 entry
->flags
|= (*p
<< 16);
1225 if (++p
== q
) return CS_BAD_TUPLE
;
1229 entry
->subtuples
= q
-p
;
1236 /*====================================================================*/
1238 static int parse_device_geo(tuple_t
*tuple
, cistpl_device_geo_t
*geo
)
1243 p
= (u_char
*)tuple
->TupleData
;
1244 q
= p
+ tuple
->TupleDataLen
;
1246 for (n
= 0; n
< CISTPL_MAX_DEVICES
; n
++) {
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);
1260 /*====================================================================*/
1262 static int parse_vers_2(tuple_t
*tuple
, cistpl_vers_2_t
*v2
)
1266 if (tuple
->TupleDataLen
< 10)
1267 return CS_BAD_TUPLE
;
1269 p
= tuple
->TupleData
;
1270 q
= p
+ tuple
->TupleDataLen
;
1274 v2
->dindex
= le16_to_cpu(*(u_short
*)(p
+2));
1279 return parse_strings(p
, q
, 2, v2
->str
, &v2
->vendor
, NULL
);
1282 /*====================================================================*/
1284 static int parse_org(tuple_t
*tuple
, cistpl_org_t
*org
)
1289 p
= tuple
->TupleData
;
1290 q
= p
+ tuple
->TupleDataLen
;
1291 if (p
== q
) return CS_BAD_TUPLE
;
1293 if (++p
== q
) return CS_BAD_TUPLE
;
1294 for (i
= 0; i
< 30; i
++) {
1296 if (*p
== '\0') break;
1297 if (++p
== q
) return CS_BAD_TUPLE
;
1302 /*====================================================================*/
1304 static int parse_format(tuple_t
*tuple
, cistpl_format_t
*fmt
)
1308 if (tuple
->TupleDataLen
< 10)
1309 return CS_BAD_TUPLE
;
1311 p
= tuple
->TupleData
;
1315 fmt
->offset
= le32_to_cpu(*(u_int
*)(p
+2));
1316 fmt
->length
= le32_to_cpu(*(u_int
*)(p
+6));
1321 /*====================================================================*/
1323 int pcmcia_parse_tuple(client_handle_t handle
, tuple_t
*tuple
, cisparse_t
*parse
)
1325 int ret
= CS_SUCCESS
;
1327 if (tuple
->TupleDataLen
> tuple
->TupleDataMax
)
1328 return CS_BAD_TUPLE
;
1329 switch (tuple
->TupleCode
) {
1331 case CISTPL_DEVICE_A
:
1332 ret
= parse_device(tuple
, &parse
->device
);
1334 #ifdef CONFIG_CARDBUS
1336 ret
= parse_bar(tuple
, &parse
->bar
);
1338 case CISTPL_CONFIG_CB
:
1339 ret
= parse_config_cb(tuple
, &parse
->config
);
1341 case CISTPL_CFTABLE_ENTRY_CB
:
1342 ret
= parse_cftable_entry_cb(tuple
, &parse
->cftable_entry_cb
);
1345 case CISTPL_CHECKSUM
:
1346 ret
= parse_checksum(tuple
, &parse
->checksum
);
1348 case CISTPL_LONGLINK_A
:
1349 case CISTPL_LONGLINK_C
:
1350 ret
= parse_longlink(tuple
, &parse
->longlink
);
1352 case CISTPL_LONGLINK_MFC
:
1353 ret
= parse_longlink_mfc(tuple
, &parse
->longlink_mfc
);
1356 ret
= parse_vers_1(tuple
, &parse
->version_1
);
1359 ret
= parse_altstr(tuple
, &parse
->altstr
);
1361 case CISTPL_JEDEC_A
:
1362 case CISTPL_JEDEC_C
:
1363 ret
= parse_jedec(tuple
, &parse
->jedec
);
1366 ret
= parse_manfid(tuple
, &parse
->manfid
);
1369 ret
= parse_funcid(tuple
, &parse
->funcid
);
1372 ret
= parse_funce(tuple
, &parse
->funce
);
1375 ret
= parse_config(tuple
, &parse
->config
);
1377 case CISTPL_CFTABLE_ENTRY
:
1378 ret
= parse_cftable_entry(tuple
, &parse
->cftable_entry
);
1380 case CISTPL_DEVICE_GEO
:
1381 case CISTPL_DEVICE_GEO_A
:
1382 ret
= parse_device_geo(tuple
, &parse
->device_geo
);
1385 ret
= parse_vers_2(tuple
, &parse
->vers_2
);
1388 ret
= parse_org(tuple
, &parse
->org
);
1391 case CISTPL_FORMAT_A
:
1392 ret
= parse_format(tuple
, &parse
->format
);
1394 case CISTPL_NO_LINK
:
1395 case CISTPL_LINKTARGET
:
1399 ret
= CS_UNSUPPORTED_FUNCTION
;
1405 /*======================================================================
1407 This is used internally by Card Services to look up CIS stuff.
1409 ======================================================================*/
1411 int read_tuple(client_handle_t handle
, cisdata_t code
, void *parse
)
1417 buf
= kmalloc(256, GFP_KERNEL
);
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
);
1435 /*======================================================================
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.
1443 ======================================================================*/
1445 int pcmcia_validate_cis(client_handle_t handle
, cisinfo_t
*info
)
1449 int ret
, reserved
, dev_ok
= 0, ident_ok
= 0;
1451 if (CHECK_HANDLE(handle
))
1452 return CS_BAD_HANDLE
;
1453 tuple
= kmalloc(sizeof(*tuple
), GFP_KERNEL
);
1455 return CS_OUT_OF_RESOURCE
;
1456 p
= kmalloc(sizeof(*p
), GFP_KERNEL
);
1459 return CS_OUT_OF_RESOURCE
;
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
)
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
))
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
))
1484 if (!dev_ok
&& !ident_ok
)
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)))
1495 if ((info
->Chains
== MAX_TUPLES
) || (reserved
> 5) ||
1496 ((!dev_ok
|| !ident_ok
) && (info
->Chains
> 10)))