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