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