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