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