aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/pcmcia/cardbus.c2
-rw-r--r--drivers/pcmcia/cistpl.c1908
-rw-r--r--drivers/pcmcia/rsrc_mgr.c3
3 files changed, 942 insertions, 971 deletions
diff --git a/drivers/pcmcia/cardbus.c b/drivers/pcmcia/cardbus.c
index ac0686efbf75..e6ab2a47d8cb 100644
--- a/drivers/pcmcia/cardbus.c
+++ b/drivers/pcmcia/cardbus.c
@@ -71,7 +71,7 @@ int __ref cb_alloc(struct pcmcia_socket *s)
71 unsigned int max, pass; 71 unsigned int max, pass;
72 72
73 s->functions = pci_scan_slot(bus, PCI_DEVFN(0, 0)); 73 s->functions = pci_scan_slot(bus, PCI_DEVFN(0, 0));
74 pci_fixup_cardbus(bus); 74 pci_fixup_cardbus(bus);
75 75
76 max = bus->secondary; 76 max = bus->secondary;
77 for (pass = 0; pass < 2; pass++) 77 for (pass = 0; pass < 2; pass++)
diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c
index 2f3622dd4b69..f230f6543bff 100644
--- a/drivers/pcmcia/cistpl.c
+++ b/drivers/pcmcia/cistpl.c
@@ -54,46 +54,44 @@ static const u_int exponent[] = {
54/* Upper limit on reasonable # of tuples */ 54/* Upper limit on reasonable # of tuples */
55#define MAX_TUPLES 200 55#define MAX_TUPLES 200
56 56
57/*====================================================================*/
58
59/* Parameters that can be set with 'insmod' */
60
61/* 16-bit CIS? */ 57/* 16-bit CIS? */
62static int cis_width; 58static int cis_width;
63module_param(cis_width, int, 0444); 59module_param(cis_width, int, 0444);
64 60
65void release_cis_mem(struct pcmcia_socket *s) 61void release_cis_mem(struct pcmcia_socket *s)
66{ 62{
67 mutex_lock(&s->ops_mutex); 63 mutex_lock(&s->ops_mutex);
68 if (s->cis_mem.flags & MAP_ACTIVE) { 64 if (s->cis_mem.flags & MAP_ACTIVE) {
69 s->cis_mem.flags &= ~MAP_ACTIVE; 65 s->cis_mem.flags &= ~MAP_ACTIVE;
70 s->ops->set_mem_map(s, &s->cis_mem); 66 s->ops->set_mem_map(s, &s->cis_mem);
71 if (s->cis_mem.res) { 67 if (s->cis_mem.res) {
72 release_resource(s->cis_mem.res); 68 release_resource(s->cis_mem.res);
73 kfree(s->cis_mem.res); 69 kfree(s->cis_mem.res);
74 s->cis_mem.res = NULL; 70 s->cis_mem.res = NULL;
71 }
72 iounmap(s->cis_virt);
73 s->cis_virt = NULL;
75 } 74 }
76 iounmap(s->cis_virt); 75 mutex_unlock(&s->ops_mutex);
77 s->cis_virt = NULL;
78 }
79 mutex_unlock(&s->ops_mutex);
80} 76}
81 77
82/* 78/**
83 * Map the card memory at "card_offset" into virtual space. 79 * set_cis_map() - map the card memory at "card_offset" into virtual space.
80 *
84 * If flags & MAP_ATTRIB, map the attribute space, otherwise 81 * If flags & MAP_ATTRIB, map the attribute space, otherwise
85 * map the memory space. 82 * map the memory space.
86 * 83 *
87 * Must be called with ops_mutex held. 84 * Must be called with ops_mutex held.
88 */ 85 */
89static void __iomem * 86static void __iomem *set_cis_map(struct pcmcia_socket *s,
90set_cis_map(struct pcmcia_socket *s, unsigned int card_offset, unsigned int flags) 87 unsigned int card_offset, unsigned int flags)
91{ 88{
92 pccard_mem_map *mem = &s->cis_mem; 89 pccard_mem_map *mem = &s->cis_mem;
93 int ret; 90 int ret;
94 91
95 if (!(s->features & SS_CAP_STATIC_MAP) && (mem->res == NULL)) { 92 if (!(s->features & SS_CAP_STATIC_MAP) && (mem->res == NULL)) {
96 mem->res = pcmcia_find_mem_region(0, s->map_size, s->map_size, 0, s); 93 mem->res = pcmcia_find_mem_region(0, s->map_size,
94 s->map_size, 0, s);
97 if (mem->res == NULL) { 95 if (mem->res == NULL) {
98 dev_printk(KERN_NOTICE, &s->dev, 96 dev_printk(KERN_NOTICE, &s->dev,
99 "cs: unable to map card memory!\n"); 97 "cs: unable to map card memory!\n");
@@ -124,165 +122,170 @@ set_cis_map(struct pcmcia_socket *s, unsigned int card_offset, unsigned int flag
124 return s->cis_virt; 122 return s->cis_virt;
125} 123}
126 124
127/*======================================================================
128
129 Low-level functions to read and write CIS memory. I think the
130 write routine is only useful for writing one-byte registers.
131
132======================================================================*/
133 125
134/* Bits in attr field */ 126/* Bits in attr field */
135#define IS_ATTR 1 127#define IS_ATTR 1
136#define IS_INDIRECT 8 128#define IS_INDIRECT 8
137 129
130/**
131 * pcmcia_read_cis_mem() - low-level function to read CIS memory
132 */
138int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, 133int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
139 u_int len, void *ptr) 134 u_int len, void *ptr)
140{ 135{
141 void __iomem *sys, *end; 136 void __iomem *sys, *end;
142 unsigned char *buf = ptr; 137 unsigned char *buf = ptr;
143
144 dev_dbg(&s->dev, "pcmcia_read_cis_mem(%d, %#x, %u)\n", attr, addr, len);
145
146 mutex_lock(&s->ops_mutex);
147 if (attr & IS_INDIRECT) {
148 /* Indirect accesses use a bunch of special registers at fixed
149 locations in common memory */
150 u_char flags = ICTRL0_COMMON|ICTRL0_AUTOINC|ICTRL0_BYTEGRAN;
151 if (attr & IS_ATTR) {
152 addr *= 2;
153 flags = ICTRL0_AUTOINC;
154 }
155 138
156 sys = set_cis_map(s, 0, MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0)); 139 dev_dbg(&s->dev, "pcmcia_read_cis_mem(%d, %#x, %u)\n", attr, addr, len);
157 if (!sys) {
158 dev_dbg(&s->dev, "could not map memory\n");
159 memset(ptr, 0xff, len);
160 mutex_unlock(&s->ops_mutex);
161 return -1;
162 }
163 140
164 writeb(flags, sys+CISREG_ICTRL0); 141 mutex_lock(&s->ops_mutex);
165 writeb(addr & 0xff, sys+CISREG_IADDR0); 142 if (attr & IS_INDIRECT) {
166 writeb((addr>>8) & 0xff, sys+CISREG_IADDR1); 143 /* Indirect accesses use a bunch of special registers at fixed
167 writeb((addr>>16) & 0xff, sys+CISREG_IADDR2); 144 locations in common memory */
168 writeb((addr>>24) & 0xff, sys+CISREG_IADDR3); 145 u_char flags = ICTRL0_COMMON|ICTRL0_AUTOINC|ICTRL0_BYTEGRAN;
169 for ( ; len > 0; len--, buf++) 146 if (attr & IS_ATTR) {
170 *buf = readb(sys+CISREG_IDATA0); 147 addr *= 2;
171 } else { 148 flags = ICTRL0_AUTOINC;
172 u_int inc = 1, card_offset, flags; 149 }
173
174 if (addr > CISTPL_MAX_CIS_SIZE)
175 dev_dbg(&s->dev, "attempt to read CIS mem at addr %#x", addr);
176
177 flags = MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0);
178 if (attr) {
179 flags |= MAP_ATTRIB;
180 inc++;
181 addr *= 2;
182 }
183 150
184 card_offset = addr & ~(s->map_size-1); 151 sys = set_cis_map(s, 0, MAP_ACTIVE |
185 while (len) { 152 ((cis_width) ? MAP_16BIT : 0));
186 sys = set_cis_map(s, card_offset, flags); 153 if (!sys) {
187 if (!sys) { 154 dev_dbg(&s->dev, "could not map memory\n");
188 dev_dbg(&s->dev, "could not map memory\n"); 155 memset(ptr, 0xff, len);
189 memset(ptr, 0xff, len); 156 mutex_unlock(&s->ops_mutex);
190 mutex_unlock(&s->ops_mutex); 157 return -1;
191 return -1; 158 }
192 } 159
193 end = sys + s->map_size; 160 writeb(flags, sys+CISREG_ICTRL0);
194 sys = sys + (addr & (s->map_size-1)); 161 writeb(addr & 0xff, sys+CISREG_IADDR0);
195 for ( ; len > 0; len--, buf++, sys += inc) { 162 writeb((addr>>8) & 0xff, sys+CISREG_IADDR1);
196 if (sys == end) 163 writeb((addr>>16) & 0xff, sys+CISREG_IADDR2);
197 break; 164 writeb((addr>>24) & 0xff, sys+CISREG_IADDR3);
198 *buf = readb(sys); 165 for ( ; len > 0; len--, buf++)
199 } 166 *buf = readb(sys+CISREG_IDATA0);
200 card_offset += s->map_size; 167 } else {
201 addr = 0; 168 u_int inc = 1, card_offset, flags;
169
170 if (addr > CISTPL_MAX_CIS_SIZE)
171 dev_dbg(&s->dev,
172 "attempt to read CIS mem at addr %#x", addr);
173
174 flags = MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0);
175 if (attr) {
176 flags |= MAP_ATTRIB;
177 inc++;
178 addr *= 2;
179 }
180
181 card_offset = addr & ~(s->map_size-1);
182 while (len) {
183 sys = set_cis_map(s, card_offset, flags);
184 if (!sys) {
185 dev_dbg(&s->dev, "could not map memory\n");
186 memset(ptr, 0xff, len);
187 mutex_unlock(&s->ops_mutex);
188 return -1;
189 }
190 end = sys + s->map_size;
191 sys = sys + (addr & (s->map_size-1));
192 for ( ; len > 0; len--, buf++, sys += inc) {
193 if (sys == end)
194 break;
195 *buf = readb(sys);
196 }
197 card_offset += s->map_size;
198 addr = 0;
199 }
202 } 200 }
203 } 201 mutex_unlock(&s->ops_mutex);
204 mutex_unlock(&s->ops_mutex); 202 dev_dbg(&s->dev, " %#2.2x %#2.2x %#2.2x %#2.2x ...\n",
205 dev_dbg(&s->dev, " %#2.2x %#2.2x %#2.2x %#2.2x ...\n", 203 *(u_char *)(ptr+0), *(u_char *)(ptr+1),
206 *(u_char *)(ptr+0), *(u_char *)(ptr+1), 204 *(u_char *)(ptr+2), *(u_char *)(ptr+3));
207 *(u_char *)(ptr+2), *(u_char *)(ptr+3)); 205 return 0;
208 return 0;
209} 206}
210 207
211 208
209/**
210 * pcmcia_write_cis_mem() - low-level function to write CIS memory
211 *
212 * Probably only useful for writing one-byte registers.
213 */
212void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, 214void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
213 u_int len, void *ptr) 215 u_int len, void *ptr)
214{ 216{
215 void __iomem *sys, *end; 217 void __iomem *sys, *end;
216 unsigned char *buf = ptr; 218 unsigned char *buf = ptr;
217
218 dev_dbg(&s->dev, "pcmcia_write_cis_mem(%d, %#x, %u)\n", attr, addr, len);
219
220 mutex_lock(&s->ops_mutex);
221 if (attr & IS_INDIRECT) {
222 /* Indirect accesses use a bunch of special registers at fixed
223 locations in common memory */
224 u_char flags = ICTRL0_COMMON|ICTRL0_AUTOINC|ICTRL0_BYTEGRAN;
225 if (attr & IS_ATTR) {
226 addr *= 2;
227 flags = ICTRL0_AUTOINC;
228 }
229 219
230 sys = set_cis_map(s, 0, MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0)); 220 dev_dbg(&s->dev,
231 if (!sys) { 221 "pcmcia_write_cis_mem(%d, %#x, %u)\n", attr, addr, len);
232 dev_dbg(&s->dev, "could not map memory\n");
233 mutex_unlock(&s->ops_mutex);
234 return; /* FIXME: Error */
235 }
236 222
237 writeb(flags, sys+CISREG_ICTRL0); 223 mutex_lock(&s->ops_mutex);
238 writeb(addr & 0xff, sys+CISREG_IADDR0); 224 if (attr & IS_INDIRECT) {
239 writeb((addr>>8) & 0xff, sys+CISREG_IADDR1); 225 /* Indirect accesses use a bunch of special registers at fixed
240 writeb((addr>>16) & 0xff, sys+CISREG_IADDR2); 226 locations in common memory */
241 writeb((addr>>24) & 0xff, sys+CISREG_IADDR3); 227 u_char flags = ICTRL0_COMMON|ICTRL0_AUTOINC|ICTRL0_BYTEGRAN;
242 for ( ; len > 0; len--, buf++) 228 if (attr & IS_ATTR) {
243 writeb(*buf, sys+CISREG_IDATA0); 229 addr *= 2;
244 } else { 230 flags = ICTRL0_AUTOINC;
245 u_int inc = 1, card_offset, flags; 231 }
246
247 flags = MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0);
248 if (attr & IS_ATTR) {
249 flags |= MAP_ATTRIB;
250 inc++;
251 addr *= 2;
252 }
253 232
254 card_offset = addr & ~(s->map_size-1); 233 sys = set_cis_map(s, 0, MAP_ACTIVE |
255 while (len) { 234 ((cis_width) ? MAP_16BIT : 0));
256 sys = set_cis_map(s, card_offset, flags); 235 if (!sys) {
257 if (!sys) { 236 dev_dbg(&s->dev, "could not map memory\n");
258 dev_dbg(&s->dev, "could not map memory\n"); 237 mutex_unlock(&s->ops_mutex);
259 mutex_unlock(&s->ops_mutex); 238 return; /* FIXME: Error */
260 return; /* FIXME: error */ 239 }
261 } 240
262 241 writeb(flags, sys+CISREG_ICTRL0);
263 end = sys + s->map_size; 242 writeb(addr & 0xff, sys+CISREG_IADDR0);
264 sys = sys + (addr & (s->map_size-1)); 243 writeb((addr>>8) & 0xff, sys+CISREG_IADDR1);
265 for ( ; len > 0; len--, buf++, sys += inc) { 244 writeb((addr>>16) & 0xff, sys+CISREG_IADDR2);
266 if (sys == end) 245 writeb((addr>>24) & 0xff, sys+CISREG_IADDR3);
267 break; 246 for ( ; len > 0; len--, buf++)
268 writeb(*buf, sys); 247 writeb(*buf, sys+CISREG_IDATA0);
269 } 248 } else {
270 card_offset += s->map_size; 249 u_int inc = 1, card_offset, flags;
271 addr = 0;
272 }
273 }
274 mutex_unlock(&s->ops_mutex);
275}
276 250
251 flags = MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0);
252 if (attr & IS_ATTR) {
253 flags |= MAP_ATTRIB;
254 inc++;
255 addr *= 2;
256 }
277 257
278/*====================================================================== 258 card_offset = addr & ~(s->map_size-1);
259 while (len) {
260 sys = set_cis_map(s, card_offset, flags);
261 if (!sys) {
262 dev_dbg(&s->dev, "could not map memory\n");
263 mutex_unlock(&s->ops_mutex);
264 return; /* FIXME: error */
265 }
279 266
280 This is a wrapper around read_cis_mem, with the same interface, 267 end = sys + s->map_size;
281 but which caches information, for cards whose CIS may not be 268 sys = sys + (addr & (s->map_size-1));
282 readable all the time. 269 for ( ; len > 0; len--, buf++, sys += inc) {
270 if (sys == end)
271 break;
272 writeb(*buf, sys);
273 }
274 card_offset += s->map_size;
275 addr = 0;
276 }
277 }
278 mutex_unlock(&s->ops_mutex);
279}
283 280
284======================================================================*/
285 281
282/**
283 * read_cis_cache() - read CIS memory or its associated cache
284 *
285 * This is a wrapper around read_cis_mem, with the same interface,
286 * but which caches information, for cards whose CIS may not be
287 * readable all the time.
288 */
286static int read_cis_cache(struct pcmcia_socket *s, int attr, u_int addr, 289static int read_cis_cache(struct pcmcia_socket *s, int attr, u_int addr,
287 size_t len, void *ptr) 290 size_t len, void *ptr)
288{ 291{
@@ -353,7 +356,6 @@ remove_cis_cache(struct pcmcia_socket *s, int attr, u_int addr, u_int len)
353 * This destroys the CIS cache but keeps any fake CIS alive. Must be 356 * This destroys the CIS cache but keeps any fake CIS alive. Must be
354 * called with ops_mutex held. 357 * called with ops_mutex held.
355 */ 358 */
356
357void destroy_cis_cache(struct pcmcia_socket *s) 359void destroy_cis_cache(struct pcmcia_socket *s)
358{ 360{
359 struct list_head *l, *n; 361 struct list_head *l, *n;
@@ -366,13 +368,9 @@ void destroy_cis_cache(struct pcmcia_socket *s)
366 } 368 }
367} 369}
368 370
369/*====================================================================== 371/**
370 372 * verify_cis_cache() - does the CIS match what is in the CIS cache?
371 This verifies if the CIS of a card matches what is in the CIS 373 */
372 cache.
373
374======================================================================*/
375
376int verify_cis_cache(struct pcmcia_socket *s) 374int verify_cis_cache(struct pcmcia_socket *s)
377{ 375{
378 struct cis_cache_entry *cis; 376 struct cis_cache_entry *cis;
@@ -404,13 +402,12 @@ int verify_cis_cache(struct pcmcia_socket *s)
404 return 0; 402 return 0;
405} 403}
406 404
407/*====================================================================== 405/**
408 406 * pcmcia_replace_cis() - use a replacement CIS instead of the card's CIS
409 For really bad cards, we provide a facility for uploading a 407 *
410 replacement CIS. 408 * For really bad cards, we provide a facility for uploading a
411 409 * replacement CIS.
412======================================================================*/ 410 */
413
414int pcmcia_replace_cis(struct pcmcia_socket *s, 411int pcmcia_replace_cis(struct pcmcia_socket *s,
415 const u8 *data, const size_t len) 412 const u8 *data, const size_t len)
416{ 413{
@@ -433,17 +430,13 @@ int pcmcia_replace_cis(struct pcmcia_socket *s,
433 return 0; 430 return 0;
434} 431}
435 432
436/*====================================================================== 433/* The high-level CIS tuple services */
437
438 The high-level CIS tuple services
439
440======================================================================*/
441 434
442typedef struct tuple_flags { 435typedef struct tuple_flags {
443 u_int link_space:4; 436 u_int link_space:4;
444 u_int has_link:1; 437 u_int has_link:1;
445 u_int mfc_fn:3; 438 u_int mfc_fn:3;
446 u_int space:4; 439 u_int space:4;
447} tuple_flags; 440} tuple_flags;
448 441
449#define LINK_SPACE(f) (((tuple_flags *)(&(f)))->link_space) 442#define LINK_SPACE(f) (((tuple_flags *)(&(f)))->link_space)
@@ -451,982 +444,961 @@ typedef struct tuple_flags {
451#define MFC_FN(f) (((tuple_flags *)(&(f)))->mfc_fn) 444#define MFC_FN(f) (((tuple_flags *)(&(f)))->mfc_fn)
452#define SPACE(f) (((tuple_flags *)(&(f)))->space) 445#define SPACE(f) (((tuple_flags *)(&(f)))->space)
453 446
454int pccard_get_first_tuple(struct pcmcia_socket *s, unsigned int function, tuple_t *tuple) 447int pccard_get_first_tuple(struct pcmcia_socket *s, unsigned int function,
448 tuple_t *tuple)
455{ 449{
456 if (!s) 450 if (!s)
457 return -EINVAL; 451 return -EINVAL;
458 452
459 if (!(s->state & SOCKET_PRESENT) || (s->state & SOCKET_CARDBUS)) 453 if (!(s->state & SOCKET_PRESENT) || (s->state & SOCKET_CARDBUS))
460 return -ENODEV; 454 return -ENODEV;
461 tuple->TupleLink = tuple->Flags = 0; 455 tuple->TupleLink = tuple->Flags = 0;
462 456
463 /* Assume presence of a LONGLINK_C to address 0 */ 457 /* Assume presence of a LONGLINK_C to address 0 */
464 tuple->CISOffset = tuple->LinkOffset = 0; 458 tuple->CISOffset = tuple->LinkOffset = 0;
465 SPACE(tuple->Flags) = HAS_LINK(tuple->Flags) = 1; 459 SPACE(tuple->Flags) = HAS_LINK(tuple->Flags) = 1;
466 460
467 if ((s->functions > 1) && !(tuple->Attributes & TUPLE_RETURN_COMMON)) { 461 if ((s->functions > 1) && !(tuple->Attributes & TUPLE_RETURN_COMMON)) {
468 cisdata_t req = tuple->DesiredTuple; 462 cisdata_t req = tuple->DesiredTuple;
469 tuple->DesiredTuple = CISTPL_LONGLINK_MFC; 463 tuple->DesiredTuple = CISTPL_LONGLINK_MFC;
470 if (pccard_get_next_tuple(s, function, tuple) == 0) { 464 if (pccard_get_next_tuple(s, function, tuple) == 0) {
471 tuple->DesiredTuple = CISTPL_LINKTARGET; 465 tuple->DesiredTuple = CISTPL_LINKTARGET;
472 if (pccard_get_next_tuple(s, function, tuple) != 0) 466 if (pccard_get_next_tuple(s, function, tuple) != 0)
473 return -ENOSPC; 467 return -ENOSPC;
474 } else 468 } else
475 tuple->CISOffset = tuple->TupleLink = 0; 469 tuple->CISOffset = tuple->TupleLink = 0;
476 tuple->DesiredTuple = req; 470 tuple->DesiredTuple = req;
477 } 471 }
478 return pccard_get_next_tuple(s, function, tuple); 472 return pccard_get_next_tuple(s, function, tuple);
479} 473}
480 474
481static int follow_link(struct pcmcia_socket *s, tuple_t *tuple) 475static int follow_link(struct pcmcia_socket *s, tuple_t *tuple)
482{ 476{
483 u_char link[5]; 477 u_char link[5];
484 u_int ofs; 478 u_int ofs;
485 int ret; 479 int ret;
486 480
487 if (MFC_FN(tuple->Flags)) { 481 if (MFC_FN(tuple->Flags)) {
488 /* Get indirect link from the MFC tuple */ 482 /* Get indirect link from the MFC tuple */
489 ret = read_cis_cache(s, LINK_SPACE(tuple->Flags), 483 ret = read_cis_cache(s, LINK_SPACE(tuple->Flags),
490 tuple->LinkOffset, 5, link); 484 tuple->LinkOffset, 5, link);
491 if (ret) 485 if (ret)
486 return -1;
487 ofs = get_unaligned_le32(link + 1);
488 SPACE(tuple->Flags) = (link[0] == CISTPL_MFC_ATTR);
489 /* Move to the next indirect link */
490 tuple->LinkOffset += 5;
491 MFC_FN(tuple->Flags)--;
492 } else if (HAS_LINK(tuple->Flags)) {
493 ofs = tuple->LinkOffset;
494 SPACE(tuple->Flags) = LINK_SPACE(tuple->Flags);
495 HAS_LINK(tuple->Flags) = 0;
496 } else
492 return -1; 497 return -1;
493 ofs = get_unaligned_le32(link + 1); 498
494 SPACE(tuple->Flags) = (link[0] == CISTPL_MFC_ATTR); 499 if (SPACE(tuple->Flags)) {
495 /* Move to the next indirect link */ 500 /* This is ugly, but a common CIS error is to code the long
496 tuple->LinkOffset += 5; 501 link offset incorrectly, so we check the right spot... */
497 MFC_FN(tuple->Flags)--; 502 ret = read_cis_cache(s, SPACE(tuple->Flags), ofs, 5, link);
498 } else if (HAS_LINK(tuple->Flags)) { 503 if (ret)
499 ofs = tuple->LinkOffset; 504 return -1;
500 SPACE(tuple->Flags) = LINK_SPACE(tuple->Flags); 505 if ((link[0] == CISTPL_LINKTARGET) && (link[1] >= 3) &&
501 HAS_LINK(tuple->Flags) = 0; 506 (strncmp(link+2, "CIS", 3) == 0))
502 } else { 507 return ofs;
503 return -1; 508 remove_cis_cache(s, SPACE(tuple->Flags), ofs, 5);
504 } 509 /* Then, we try the wrong spot... */
505 if (SPACE(tuple->Flags)) { 510 ofs = ofs >> 1;
506 /* This is ugly, but a common CIS error is to code the long 511 }
507 link offset incorrectly, so we check the right spot... */
508 ret = read_cis_cache(s, SPACE(tuple->Flags), ofs, 5, link); 512 ret = read_cis_cache(s, SPACE(tuple->Flags), ofs, 5, link);
509 if (ret) 513 if (ret)
510 return -1; 514 return -1;
511 if ((link[0] == CISTPL_LINKTARGET) && (link[1] >= 3) && 515 if ((link[0] == CISTPL_LINKTARGET) && (link[1] >= 3) &&
512 (strncmp(link+2, "CIS", 3) == 0)) 516 (strncmp(link+2, "CIS", 3) == 0))
513 return ofs; 517 return ofs;
514 remove_cis_cache(s, SPACE(tuple->Flags), ofs, 5); 518 remove_cis_cache(s, SPACE(tuple->Flags), ofs, 5);
515 /* Then, we try the wrong spot... */ 519 return -1;
516 ofs = ofs >> 1;
517 }
518 ret = read_cis_cache(s, SPACE(tuple->Flags), ofs, 5, link);
519 if (ret)
520 return -1;
521 if ((link[0] == CISTPL_LINKTARGET) && (link[1] >= 3) &&
522 (strncmp(link+2, "CIS", 3) == 0))
523 return ofs;
524 remove_cis_cache(s, SPACE(tuple->Flags), ofs, 5);
525 return -1;
526} 520}
527 521
528int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, tuple_t *tuple) 522int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function,
523 tuple_t *tuple)
529{ 524{
530 u_char link[2], tmp; 525 u_char link[2], tmp;
531 int ofs, i, attr; 526 int ofs, i, attr;
532 int ret; 527 int ret;
533
534 if (!s)
535 return -EINVAL;
536 if (!(s->state & SOCKET_PRESENT) || (s->state & SOCKET_CARDBUS))
537 return -ENODEV;
538
539 link[1] = tuple->TupleLink;
540 ofs = tuple->CISOffset + tuple->TupleLink;
541 attr = SPACE(tuple->Flags);
542
543 for (i = 0; i < MAX_TUPLES; i++) {
544 if (link[1] == 0xff) {
545 link[0] = CISTPL_END;
546 } else {
547 ret = read_cis_cache(s, attr, ofs, 2, link);
548 if (ret)
549 return -1;
550 if (link[0] == CISTPL_NULL) {
551 ofs++; continue;
552 }
553 }
554 528
555 /* End of chain? Follow long link if possible */ 529 if (!s)
556 if (link[0] == CISTPL_END) { 530 return -EINVAL;
557 ofs = follow_link(s, tuple); 531 if (!(s->state & SOCKET_PRESENT) || (s->state & SOCKET_CARDBUS))
558 if (ofs < 0) 532 return -ENODEV;
559 return -ENOSPC;
560 attr = SPACE(tuple->Flags);
561 ret = read_cis_cache(s, attr, ofs, 2, link);
562 if (ret)
563 return -1;
564 }
565 533
566 /* Is this a link tuple? Make a note of it */ 534 link[1] = tuple->TupleLink;
567 if ((link[0] == CISTPL_LONGLINK_A) || 535 ofs = tuple->CISOffset + tuple->TupleLink;
568 (link[0] == CISTPL_LONGLINK_C) || 536 attr = SPACE(tuple->Flags);
569 (link[0] == CISTPL_LONGLINK_MFC) || 537
570 (link[0] == CISTPL_LINKTARGET) || 538 for (i = 0; i < MAX_TUPLES; i++) {
571 (link[0] == CISTPL_INDIRECT) || 539 if (link[1] == 0xff)
572 (link[0] == CISTPL_NO_LINK)) { 540 link[0] = CISTPL_END;
573 switch (link[0]) { 541 else {
574 case CISTPL_LONGLINK_A: 542 ret = read_cis_cache(s, attr, ofs, 2, link);
575 HAS_LINK(tuple->Flags) = 1; 543 if (ret)
576 LINK_SPACE(tuple->Flags) = attr | IS_ATTR; 544 return -1;
577 ret = read_cis_cache(s, attr, ofs+2, 4, &tuple->LinkOffset); 545 if (link[0] == CISTPL_NULL) {
578 if (ret) 546 ofs++;
579 return -1; 547 continue;
580 break; 548 }
581 case CISTPL_LONGLINK_C:
582 HAS_LINK(tuple->Flags) = 1;
583 LINK_SPACE(tuple->Flags) = attr & ~IS_ATTR;
584 ret = read_cis_cache(s, attr, ofs+2, 4, &tuple->LinkOffset);
585 if (ret)
586 return -1;
587 break;
588 case CISTPL_INDIRECT:
589 HAS_LINK(tuple->Flags) = 1;
590 LINK_SPACE(tuple->Flags) = IS_ATTR | IS_INDIRECT;
591 tuple->LinkOffset = 0;
592 break;
593 case CISTPL_LONGLINK_MFC:
594 tuple->LinkOffset = ofs + 3;
595 LINK_SPACE(tuple->Flags) = attr;
596 if (function == BIND_FN_ALL) {
597 /* Follow all the MFC links */
598 ret = read_cis_cache(s, attr, ofs+2, 1, &tmp);
599 if (ret)
600 return -1;
601 MFC_FN(tuple->Flags) = tmp;
602 } else {
603 /* Follow exactly one of the links */
604 MFC_FN(tuple->Flags) = 1;
605 tuple->LinkOffset += function * 5;
606 } 549 }
607 break;
608 case CISTPL_NO_LINK:
609 HAS_LINK(tuple->Flags) = 0;
610 break;
611 }
612 if ((tuple->Attributes & TUPLE_RETURN_LINK) &&
613 (tuple->DesiredTuple == RETURN_FIRST_TUPLE))
614 break;
615 } else
616 if (tuple->DesiredTuple == RETURN_FIRST_TUPLE)
617 break;
618 550
619 if (link[0] == tuple->DesiredTuple) 551 /* End of chain? Follow long link if possible */
620 break; 552 if (link[0] == CISTPL_END) {
621 ofs += link[1] + 2; 553 ofs = follow_link(s, tuple);
622 } 554 if (ofs < 0)
623 if (i == MAX_TUPLES) { 555 return -ENOSPC;
624 dev_dbg(&s->dev, "cs: overrun in pcmcia_get_next_tuple\n"); 556 attr = SPACE(tuple->Flags);
625 return -ENOSPC; 557 ret = read_cis_cache(s, attr, ofs, 2, link);
626 } 558 if (ret)
627 559 return -1;
628 tuple->TupleCode = link[0]; 560 }
629 tuple->TupleLink = link[1];
630 tuple->CISOffset = ofs + 2;
631 return 0;
632}
633 561
634/*====================================================================*/ 562 /* Is this a link tuple? Make a note of it */
563 if ((link[0] == CISTPL_LONGLINK_A) ||
564 (link[0] == CISTPL_LONGLINK_C) ||
565 (link[0] == CISTPL_LONGLINK_MFC) ||
566 (link[0] == CISTPL_LINKTARGET) ||
567 (link[0] == CISTPL_INDIRECT) ||
568 (link[0] == CISTPL_NO_LINK)) {
569 switch (link[0]) {
570 case CISTPL_LONGLINK_A:
571 HAS_LINK(tuple->Flags) = 1;
572 LINK_SPACE(tuple->Flags) = attr | IS_ATTR;
573 ret = read_cis_cache(s, attr, ofs+2, 4,
574 &tuple->LinkOffset);
575 if (ret)
576 return -1;
577 break;
578 case CISTPL_LONGLINK_C:
579 HAS_LINK(tuple->Flags) = 1;
580 LINK_SPACE(tuple->Flags) = attr & ~IS_ATTR;
581 ret = read_cis_cache(s, attr, ofs+2, 4,
582 &tuple->LinkOffset);
583 if (ret)
584 return -1;
585 break;
586 case CISTPL_INDIRECT:
587 HAS_LINK(tuple->Flags) = 1;
588 LINK_SPACE(tuple->Flags) = IS_ATTR |
589 IS_INDIRECT;
590 tuple->LinkOffset = 0;
591 break;
592 case CISTPL_LONGLINK_MFC:
593 tuple->LinkOffset = ofs + 3;
594 LINK_SPACE(tuple->Flags) = attr;
595 if (function == BIND_FN_ALL) {
596 /* Follow all the MFC links */
597 ret = read_cis_cache(s, attr, ofs+2,
598 1, &tmp);
599 if (ret)
600 return -1;
601 MFC_FN(tuple->Flags) = tmp;
602 } else {
603 /* Follow exactly one of the links */
604 MFC_FN(tuple->Flags) = 1;
605 tuple->LinkOffset += function * 5;
606 }
607 break;
608 case CISTPL_NO_LINK:
609 HAS_LINK(tuple->Flags) = 0;
610 break;
611 }
612 if ((tuple->Attributes & TUPLE_RETURN_LINK) &&
613 (tuple->DesiredTuple == RETURN_FIRST_TUPLE))
614 break;
615 } else
616 if (tuple->DesiredTuple == RETURN_FIRST_TUPLE)
617 break;
618
619 if (link[0] == tuple->DesiredTuple)
620 break;
621 ofs += link[1] + 2;
622 }
623 if (i == MAX_TUPLES) {
624 dev_dbg(&s->dev, "cs: overrun in pcmcia_get_next_tuple\n");
625 return -ENOSPC;
626 }
635 627
636#define _MIN(a, b) (((a) < (b)) ? (a) : (b)) 628 tuple->TupleCode = link[0];
629 tuple->TupleLink = link[1];
630 tuple->CISOffset = ofs + 2;
631 return 0;
632}
637 633
638int pccard_get_tuple_data(struct pcmcia_socket *s, tuple_t *tuple) 634int pccard_get_tuple_data(struct pcmcia_socket *s, tuple_t *tuple)
639{ 635{
640 u_int len; 636 u_int len;
641 int ret; 637 int ret;
642 638
643 if (!s) 639 if (!s)
644 return -EINVAL; 640 return -EINVAL;
645 641
646 if (tuple->TupleLink < tuple->TupleOffset) 642 if (tuple->TupleLink < tuple->TupleOffset)
647 return -ENOSPC; 643 return -ENOSPC;
648 len = tuple->TupleLink - tuple->TupleOffset; 644 len = tuple->TupleLink - tuple->TupleOffset;
649 tuple->TupleDataLen = tuple->TupleLink; 645 tuple->TupleDataLen = tuple->TupleLink;
650 if (len == 0) 646 if (len == 0)
647 return 0;
648 ret = read_cis_cache(s, SPACE(tuple->Flags),
649 tuple->CISOffset + tuple->TupleOffset,
650 min(len, (u_int) tuple->TupleDataMax),
651 tuple->TupleData);
652 if (ret)
653 return -1;
651 return 0; 654 return 0;
652 ret = read_cis_cache(s, SPACE(tuple->Flags),
653 tuple->CISOffset + tuple->TupleOffset,
654 _MIN(len, tuple->TupleDataMax), tuple->TupleData);
655 if (ret)
656 return -1;
657 return 0;
658} 655}
659 656
660 657
661/*====================================================================== 658/* Parsing routines for individual tuples */
662
663 Parsing routines for individual tuples
664
665======================================================================*/
666 659
667static int parse_device(tuple_t *tuple, cistpl_device_t *device) 660static int parse_device(tuple_t *tuple, cistpl_device_t *device)
668{ 661{
669 int i; 662 int i;
670 u_char scale; 663 u_char scale;
671 u_char *p, *q; 664 u_char *p, *q;
672 665
673 p = (u_char *)tuple->TupleData; 666 p = (u_char *)tuple->TupleData;
674 q = p + tuple->TupleDataLen; 667 q = p + tuple->TupleDataLen;
675 668
676 device->ndev = 0; 669 device->ndev = 0;
677 for (i = 0; i < CISTPL_MAX_DEVICES; i++) { 670 for (i = 0; i < CISTPL_MAX_DEVICES; i++) {
678 671
679 if (*p == 0xff) 672 if (*p == 0xff)
680 break; 673 break;
681 device->dev[i].type = (*p >> 4); 674 device->dev[i].type = (*p >> 4);
682 device->dev[i].wp = (*p & 0x08) ? 1 : 0; 675 device->dev[i].wp = (*p & 0x08) ? 1 : 0;
683 switch (*p & 0x07) { 676 switch (*p & 0x07) {
684 case 0: 677 case 0:
685 device->dev[i].speed = 0; 678 device->dev[i].speed = 0;
686 break; 679 break;
687 case 1: 680 case 1:
688 device->dev[i].speed = 250; 681 device->dev[i].speed = 250;
689 break; 682 break;
690 case 2: 683 case 2:
691 device->dev[i].speed = 200; 684 device->dev[i].speed = 200;
692 break; 685 break;
693 case 3: 686 case 3:
694 device->dev[i].speed = 150; 687 device->dev[i].speed = 150;
695 break; 688 break;
696 case 4: 689 case 4:
697 device->dev[i].speed = 100; 690 device->dev[i].speed = 100;
698 break; 691 break;
699 case 7: 692 case 7:
700 if (++p == q)
701 return -EINVAL;
702 device->dev[i].speed = SPEED_CVT(*p);
703 while (*p & 0x80)
704 if (++p == q) 693 if (++p == q)
705 return -EINVAL; 694 return -EINVAL;
706 break; 695 device->dev[i].speed = SPEED_CVT(*p);
707 default: 696 while (*p & 0x80)
708 return -EINVAL; 697 if (++p == q)
709 } 698 return -EINVAL;
699 break;
700 default:
701 return -EINVAL;
702 }
710 703
711 if (++p == q) 704 if (++p == q)
712 return -EINVAL; 705 return -EINVAL;
713 if (*p == 0xff) 706 if (*p == 0xff)
714 break; 707 break;
715 scale = *p & 7; 708 scale = *p & 7;
716 if (scale == 7) 709 if (scale == 7)
717 return -EINVAL; 710 return -EINVAL;
718 device->dev[i].size = ((*p >> 3) + 1) * (512 << (scale*2)); 711 device->dev[i].size = ((*p >> 3) + 1) * (512 << (scale*2));
719 device->ndev++; 712 device->ndev++;
720 if (++p == q) 713 if (++p == q)
721 break; 714 break;
722 } 715 }
723 716
724 return 0; 717 return 0;
725} 718}
726 719
727/*====================================================================*/
728 720
729static int parse_checksum(tuple_t *tuple, cistpl_checksum_t *csum) 721static int parse_checksum(tuple_t *tuple, cistpl_checksum_t *csum)
730{ 722{
731 u_char *p; 723 u_char *p;
732 if (tuple->TupleDataLen < 5) 724 if (tuple->TupleDataLen < 5)
733 return -EINVAL; 725 return -EINVAL;
734 p = (u_char *) tuple->TupleData; 726 p = (u_char *) tuple->TupleData;
735 csum->addr = tuple->CISOffset + get_unaligned_le16(p) - 2; 727 csum->addr = tuple->CISOffset + get_unaligned_le16(p) - 2;
736 csum->len = get_unaligned_le16(p + 2); 728 csum->len = get_unaligned_le16(p + 2);
737 csum->sum = *(p + 4); 729 csum->sum = *(p + 4);
738 return 0; 730 return 0;
739} 731}
740 732
741/*====================================================================*/
742 733
743static int parse_longlink(tuple_t *tuple, cistpl_longlink_t *link) 734static int parse_longlink(tuple_t *tuple, cistpl_longlink_t *link)
744{ 735{
745 if (tuple->TupleDataLen < 4) 736 if (tuple->TupleDataLen < 4)
746 return -EINVAL; 737 return -EINVAL;
747 link->addr = get_unaligned_le32(tuple->TupleData); 738 link->addr = get_unaligned_le32(tuple->TupleData);
748 return 0; 739 return 0;
749} 740}
750 741
751/*====================================================================*/
752 742
753static int parse_longlink_mfc(tuple_t *tuple, 743static int parse_longlink_mfc(tuple_t *tuple, cistpl_longlink_mfc_t *link)
754 cistpl_longlink_mfc_t *link)
755{ 744{
756 u_char *p; 745 u_char *p;
757 int i; 746 int i;
758 747
759 p = (u_char *)tuple->TupleData; 748 p = (u_char *)tuple->TupleData;
760 749
761 link->nfn = *p; p++; 750 link->nfn = *p; p++;
762 if (tuple->TupleDataLen <= link->nfn*5) 751 if (tuple->TupleDataLen <= link->nfn*5)
763 return -EINVAL; 752 return -EINVAL;
764 for (i = 0; i < link->nfn; i++) { 753 for (i = 0; i < link->nfn; i++) {
765 link->fn[i].space = *p; p++; 754 link->fn[i].space = *p; p++;
766 link->fn[i].addr = get_unaligned_le32(p); 755 link->fn[i].addr = get_unaligned_le32(p);
767 p += 4; 756 p += 4;
768 } 757 }
769 return 0; 758 return 0;
770} 759}
771 760
772/*====================================================================*/
773 761
774static int parse_strings(u_char *p, u_char *q, int max, 762static int parse_strings(u_char *p, u_char *q, int max,
775 char *s, u_char *ofs, u_char *found) 763 char *s, u_char *ofs, u_char *found)
776{ 764{
777 int i, j, ns; 765 int i, j, ns;
778 766
779 if (p == q) 767 if (p == q)
780 return -EINVAL; 768 return -EINVAL;
781 ns = 0; j = 0; 769 ns = 0; j = 0;
782 for (i = 0; i < max; i++) { 770 for (i = 0; i < max; i++) {
783 if (*p == 0xff) 771 if (*p == 0xff)
784 break; 772 break;
785 ofs[i] = j; 773 ofs[i] = j;
786 ns++; 774 ns++;
787 for (;;) { 775 for (;;) {
788 s[j++] = (*p == 0xff) ? '\0' : *p; 776 s[j++] = (*p == 0xff) ? '\0' : *p;
789 if ((*p == '\0') || (*p == 0xff)) 777 if ((*p == '\0') || (*p == 0xff))
790 break; 778 break;
791 if (++p == q) 779 if (++p == q)
792 return -EINVAL; 780 return -EINVAL;
781 }
782 if ((*p == 0xff) || (++p == q))
783 break;
793 } 784 }
794 if ((*p == 0xff) || (++p == q)) 785 if (found) {
795 break; 786 *found = ns;
796 } 787 return 0;
797 if (found) { 788 }
798 *found = ns; 789
799 return 0;
800 } else {
801 return (ns == max) ? 0 : -EINVAL; 790 return (ns == max) ? 0 : -EINVAL;
802 }
803} 791}
804 792
805/*====================================================================*/
806 793
807static int parse_vers_1(tuple_t *tuple, cistpl_vers_1_t *vers_1) 794static int parse_vers_1(tuple_t *tuple, cistpl_vers_1_t *vers_1)
808{ 795{
809 u_char *p, *q; 796 u_char *p, *q;
810 797
811 p = (u_char *)tuple->TupleData; 798 p = (u_char *)tuple->TupleData;
812 q = p + tuple->TupleDataLen; 799 q = p + tuple->TupleDataLen;
813 800
814 vers_1->major = *p; p++; 801 vers_1->major = *p; p++;
815 vers_1->minor = *p; p++; 802 vers_1->minor = *p; p++;
816 if (p >= q) 803 if (p >= q)
817 return -EINVAL; 804 return -EINVAL;
818 805
819 return parse_strings(p, q, CISTPL_VERS_1_MAX_PROD_STRINGS, 806 return parse_strings(p, q, CISTPL_VERS_1_MAX_PROD_STRINGS,
820 vers_1->str, vers_1->ofs, &vers_1->ns); 807 vers_1->str, vers_1->ofs, &vers_1->ns);
821} 808}
822 809
823/*====================================================================*/
824 810
825static int parse_altstr(tuple_t *tuple, cistpl_altstr_t *altstr) 811static int parse_altstr(tuple_t *tuple, cistpl_altstr_t *altstr)
826{ 812{
827 u_char *p, *q; 813 u_char *p, *q;
828 814
829 p = (u_char *)tuple->TupleData; 815 p = (u_char *)tuple->TupleData;
830 q = p + tuple->TupleDataLen; 816 q = p + tuple->TupleDataLen;
831 817
832 return parse_strings(p, q, CISTPL_MAX_ALTSTR_STRINGS, 818 return parse_strings(p, q, CISTPL_MAX_ALTSTR_STRINGS,
833 altstr->str, altstr->ofs, &altstr->ns); 819 altstr->str, altstr->ofs, &altstr->ns);
834} 820}
835 821
836/*====================================================================*/
837 822
838static int parse_jedec(tuple_t *tuple, cistpl_jedec_t *jedec) 823static int parse_jedec(tuple_t *tuple, cistpl_jedec_t *jedec)
839{ 824{
840 u_char *p, *q; 825 u_char *p, *q;
841 int nid; 826 int nid;
842 827
843 p = (u_char *)tuple->TupleData; 828 p = (u_char *)tuple->TupleData;
844 q = p + tuple->TupleDataLen; 829 q = p + tuple->TupleDataLen;
845 830
846 for (nid = 0; nid < CISTPL_MAX_DEVICES; nid++) { 831 for (nid = 0; nid < CISTPL_MAX_DEVICES; nid++) {
847 if (p > q-2) 832 if (p > q-2)
848 break; 833 break;
849 jedec->id[nid].mfr = p[0]; 834 jedec->id[nid].mfr = p[0];
850 jedec->id[nid].info = p[1]; 835 jedec->id[nid].info = p[1];
851 p += 2; 836 p += 2;
852 } 837 }
853 jedec->nid = nid; 838 jedec->nid = nid;
854 return 0; 839 return 0;
855} 840}
856 841
857/*====================================================================*/
858 842
859static int parse_manfid(tuple_t *tuple, cistpl_manfid_t *m) 843static int parse_manfid(tuple_t *tuple, cistpl_manfid_t *m)
860{ 844{
861 if (tuple->TupleDataLen < 4) 845 if (tuple->TupleDataLen < 4)
862 return -EINVAL; 846 return -EINVAL;
863 m->manf = get_unaligned_le16(tuple->TupleData); 847 m->manf = get_unaligned_le16(tuple->TupleData);
864 m->card = get_unaligned_le16(tuple->TupleData + 2); 848 m->card = get_unaligned_le16(tuple->TupleData + 2);
865 return 0; 849 return 0;
866} 850}
867 851
868/*====================================================================*/
869 852
870static int parse_funcid(tuple_t *tuple, cistpl_funcid_t *f) 853static int parse_funcid(tuple_t *tuple, cistpl_funcid_t *f)
871{ 854{
872 u_char *p; 855 u_char *p;
873 if (tuple->TupleDataLen < 2) 856 if (tuple->TupleDataLen < 2)
874 return -EINVAL; 857 return -EINVAL;
875 p = (u_char *)tuple->TupleData; 858 p = (u_char *)tuple->TupleData;
876 f->func = p[0]; 859 f->func = p[0];
877 f->sysinit = p[1]; 860 f->sysinit = p[1];
878 return 0; 861 return 0;
879} 862}
880 863
881/*====================================================================*/
882 864
883static int parse_funce(tuple_t *tuple, cistpl_funce_t *f) 865static int parse_funce(tuple_t *tuple, cistpl_funce_t *f)
884{ 866{
885 u_char *p; 867 u_char *p;
886 int i; 868 int i;
887 if (tuple->TupleDataLen < 1) 869 if (tuple->TupleDataLen < 1)
888 return -EINVAL; 870 return -EINVAL;
889 p = (u_char *)tuple->TupleData; 871 p = (u_char *)tuple->TupleData;
890 f->type = p[0]; 872 f->type = p[0];
891 for (i = 1; i < tuple->TupleDataLen; i++) 873 for (i = 1; i < tuple->TupleDataLen; i++)
892 f->data[i-1] = p[i]; 874 f->data[i-1] = p[i];
893 return 0; 875 return 0;
894} 876}
895 877
896/*====================================================================*/
897 878
898static int parse_config(tuple_t *tuple, cistpl_config_t *config) 879static int parse_config(tuple_t *tuple, cistpl_config_t *config)
899{ 880{
900 int rasz, rmsz, i; 881 int rasz, rmsz, i;
901 u_char *p; 882 u_char *p;
902 883
903 p = (u_char *)tuple->TupleData; 884 p = (u_char *)tuple->TupleData;
904 rasz = *p & 0x03; 885 rasz = *p & 0x03;
905 rmsz = (*p & 0x3c) >> 2; 886 rmsz = (*p & 0x3c) >> 2;
906 if (tuple->TupleDataLen < rasz+rmsz+4) 887 if (tuple->TupleDataLen < rasz+rmsz+4)
907 return -EINVAL; 888 return -EINVAL;
908 config->last_idx = *(++p); 889 config->last_idx = *(++p);
909 p++; 890 p++;
910 config->base = 0; 891 config->base = 0;
911 for (i = 0; i <= rasz; i++) 892 for (i = 0; i <= rasz; i++)
912 config->base += p[i] << (8*i); 893 config->base += p[i] << (8*i);
913 p += rasz+1; 894 p += rasz+1;
914 for (i = 0; i < 4; i++) 895 for (i = 0; i < 4; i++)
915 config->rmask[i] = 0; 896 config->rmask[i] = 0;
916 for (i = 0; i <= rmsz; i++) 897 for (i = 0; i <= rmsz; i++)
917 config->rmask[i>>2] += p[i] << (8*(i%4)); 898 config->rmask[i>>2] += p[i] << (8*(i%4));
918 config->subtuples = tuple->TupleDataLen - (rasz+rmsz+4); 899 config->subtuples = tuple->TupleDataLen - (rasz+rmsz+4);
919 return 0; 900 return 0;
920} 901}
921 902
922/*====================================================================== 903/* The following routines are all used to parse the nightmarish
904 * config table entries.
905 */
906
907static u_char *parse_power(u_char *p, u_char *q, cistpl_power_t *pwr)
908{
909 int i;
910 u_int scale;
923 911
924 The following routines are all used to parse the nightmarish 912 if (p == q)
925 config table entries. 913 return NULL;
914 pwr->present = *p;
915 pwr->flags = 0;
916 p++;
917 for (i = 0; i < 7; i++)
918 if (pwr->present & (1<<i)) {
919 if (p == q)
920 return NULL;
921 pwr->param[i] = POWER_CVT(*p);
922 scale = POWER_SCALE(*p);
923 while (*p & 0x80) {
924 if (++p == q)
925 return NULL;
926 if ((*p & 0x7f) < 100)
927 pwr->param[i] +=
928 (*p & 0x7f) * scale / 100;
929 else if (*p == 0x7d)
930 pwr->flags |= CISTPL_POWER_HIGHZ_OK;
931 else if (*p == 0x7e)
932 pwr->param[i] = 0;
933 else if (*p == 0x7f)
934 pwr->flags |= CISTPL_POWER_HIGHZ_REQ;
935 else
936 return NULL;
937 }
938 p++;
939 }
940 return p;
941}
926 942
927======================================================================*/
928 943
929static u_char *parse_power(u_char *p, u_char *q, 944static u_char *parse_timing(u_char *p, u_char *q, cistpl_timing_t *timing)
930 cistpl_power_t *pwr)
931{ 945{
932 int i; 946 u_char scale;
933 u_int scale; 947
934 948 if (p == q)
935 if (p == q) 949 return NULL;
936 return NULL; 950 scale = *p;
937 pwr->present = *p; 951 if ((scale & 3) != 3) {
938 pwr->flags = 0;
939 p++;
940 for (i = 0; i < 7; i++)
941 if (pwr->present & (1<<i)) {
942 if (p == q)
943 return NULL;
944 pwr->param[i] = POWER_CVT(*p);
945 scale = POWER_SCALE(*p);
946 while (*p & 0x80) {
947 if (++p == q) 952 if (++p == q)
948 return NULL; 953 return NULL;
949 if ((*p & 0x7f) < 100) 954 timing->wait = SPEED_CVT(*p);
950 pwr->param[i] += (*p & 0x7f) * scale / 100; 955 timing->waitscale = exponent[scale & 3];
951 else if (*p == 0x7d) 956 } else
952 pwr->flags |= CISTPL_POWER_HIGHZ_OK; 957 timing->wait = 0;
953 else if (*p == 0x7e) 958 scale >>= 2;
954 pwr->param[i] = 0; 959 if ((scale & 7) != 7) {
955 else if (*p == 0x7f) 960 if (++p == q)
956 pwr->flags |= CISTPL_POWER_HIGHZ_REQ; 961 return NULL;
957 else 962 timing->ready = SPEED_CVT(*p);
958 return NULL; 963 timing->rdyscale = exponent[scale & 7];
959 } 964 } else
960 p++; 965 timing->ready = 0;
961 } 966 scale >>= 3;
962 return p; 967 if (scale != 7) {
968 if (++p == q)
969 return NULL;
970 timing->reserved = SPEED_CVT(*p);
971 timing->rsvscale = exponent[scale];
972 } else
973 timing->reserved = 0;
974 p++;
975 return p;
963} 976}
964 977
965/*====================================================================*/
966 978
967static u_char *parse_timing(u_char *p, u_char *q, 979static u_char *parse_io(u_char *p, u_char *q, cistpl_io_t *io)
968 cistpl_timing_t *timing)
969{ 980{
970 u_char scale; 981 int i, j, bsz, lsz;
971 982
972 if (p == q) 983 if (p == q)
973 return NULL;
974 scale = *p;
975 if ((scale & 3) != 3) {
976 if (++p == q)
977 return NULL;
978 timing->wait = SPEED_CVT(*p);
979 timing->waitscale = exponent[scale & 3];
980 } else
981 timing->wait = 0;
982 scale >>= 2;
983 if ((scale & 7) != 7) {
984 if (++p == q)
985 return NULL; 984 return NULL;
986 timing->ready = SPEED_CVT(*p); 985 io->flags = *p;
987 timing->rdyscale = exponent[scale & 7]; 986
988 } else 987 if (!(*p & 0x80)) {
989 timing->ready = 0; 988 io->nwin = 1;
990 scale >>= 3; 989 io->win[0].base = 0;
991 if (scale != 7) { 990 io->win[0].len = (1 << (io->flags & CISTPL_IO_LINES_MASK));
991 return p+1;
992 }
993
992 if (++p == q) 994 if (++p == q)
993 return NULL; 995 return NULL;
994 timing->reserved = SPEED_CVT(*p); 996 io->nwin = (*p & 0x0f) + 1;
995 timing->rsvscale = exponent[scale]; 997 bsz = (*p & 0x30) >> 4;
996 } else 998 if (bsz == 3)
997 timing->reserved = 0; 999 bsz++;
998 p++; 1000 lsz = (*p & 0xc0) >> 6;
999 return p; 1001 if (lsz == 3)
1000} 1002 lsz++;
1001 1003 p++;
1002/*====================================================================*/
1003 1004
1004static u_char *parse_io(u_char *p, u_char *q, cistpl_io_t *io) 1005 for (i = 0; i < io->nwin; i++) {
1005{ 1006 io->win[i].base = 0;
1006 int i, j, bsz, lsz; 1007 io->win[i].len = 1;
1007 1008 for (j = 0; j < bsz; j++, p++) {
1008 if (p == q) 1009 if (p == q)
1009 return NULL; 1010 return NULL;
1010 io->flags = *p; 1011 io->win[i].base += *p << (j*8);
1011 1012 }
1012 if (!(*p & 0x80)) { 1013 for (j = 0; j < lsz; j++, p++) {
1013 io->nwin = 1; 1014 if (p == q)
1014 io->win[0].base = 0; 1015 return NULL;
1015 io->win[0].len = (1 << (io->flags & CISTPL_IO_LINES_MASK)); 1016 io->win[i].len += *p << (j*8);
1016 return p+1; 1017 }
1017 }
1018
1019 if (++p == q)
1020 return NULL;
1021 io->nwin = (*p & 0x0f) + 1;
1022 bsz = (*p & 0x30) >> 4;
1023 if (bsz == 3)
1024 bsz++;
1025 lsz = (*p & 0xc0) >> 6;
1026 if (lsz == 3)
1027 lsz++;
1028 p++;
1029
1030 for (i = 0; i < io->nwin; i++) {
1031 io->win[i].base = 0;
1032 io->win[i].len = 1;
1033 for (j = 0; j < bsz; j++, p++) {
1034 if (p == q)
1035 return NULL;
1036 io->win[i].base += *p << (j*8);
1037 }
1038 for (j = 0; j < lsz; j++, p++) {
1039 if (p == q)
1040 return NULL;
1041 io->win[i].len += *p << (j*8);
1042 } 1018 }
1043 } 1019 return p;
1044 return p;
1045} 1020}
1046 1021
1047/*====================================================================*/
1048 1022
1049static u_char *parse_mem(u_char *p, u_char *q, cistpl_mem_t *mem) 1023static u_char *parse_mem(u_char *p, u_char *q, cistpl_mem_t *mem)
1050{ 1024{
1051 int i, j, asz, lsz, has_ha; 1025 int i, j, asz, lsz, has_ha;
1052 u_int len, ca, ha; 1026 u_int len, ca, ha;
1053 1027
1054 if (p == q) 1028 if (p == q)
1055 return NULL; 1029 return NULL;
1056 1030
1057 mem->nwin = (*p & 0x07) + 1; 1031 mem->nwin = (*p & 0x07) + 1;
1058 lsz = (*p & 0x18) >> 3; 1032 lsz = (*p & 0x18) >> 3;
1059 asz = (*p & 0x60) >> 5; 1033 asz = (*p & 0x60) >> 5;
1060 has_ha = (*p & 0x80); 1034 has_ha = (*p & 0x80);
1061 if (++p == q) 1035 if (++p == q)
1062 return NULL; 1036 return NULL;
1063 1037
1064 for (i = 0; i < mem->nwin; i++) { 1038 for (i = 0; i < mem->nwin; i++) {
1065 len = ca = ha = 0; 1039 len = ca = ha = 0;
1066 for (j = 0; j < lsz; j++, p++) { 1040 for (j = 0; j < lsz; j++, p++) {
1067 if (p == q) 1041 if (p == q)
1068 return NULL; 1042 return NULL;
1069 len += *p << (j*8); 1043 len += *p << (j*8);
1070 } 1044 }
1071 for (j = 0; j < asz; j++, p++) { 1045 for (j = 0; j < asz; j++, p++) {
1072 if (p == q) 1046 if (p == q)
1073 return NULL; 1047 return NULL;
1074 ca += *p << (j*8); 1048 ca += *p << (j*8);
1049 }
1050 if (has_ha)
1051 for (j = 0; j < asz; j++, p++) {
1052 if (p == q)
1053 return NULL;
1054 ha += *p << (j*8);
1055 }
1056 mem->win[i].len = len << 8;
1057 mem->win[i].card_addr = ca << 8;
1058 mem->win[i].host_addr = ha << 8;
1075 } 1059 }
1076 if (has_ha) 1060 return p;
1077 for (j = 0; j < asz; j++, p++) {
1078 if (p == q)
1079 return NULL;
1080 ha += *p << (j*8);
1081 }
1082 mem->win[i].len = len << 8;
1083 mem->win[i].card_addr = ca << 8;
1084 mem->win[i].host_addr = ha << 8;
1085 }
1086 return p;
1087} 1061}
1088 1062
1089/*====================================================================*/
1090 1063
1091static u_char *parse_irq(u_char *p, u_char *q, cistpl_irq_t *irq) 1064static u_char *parse_irq(u_char *p, u_char *q, cistpl_irq_t *irq)
1092{ 1065{
1093 if (p == q) 1066 if (p == q)
1094 return NULL;
1095 irq->IRQInfo1 = *p; p++;
1096 if (irq->IRQInfo1 & IRQ_INFO2_VALID) {
1097 if (p+2 > q)
1098 return NULL; 1067 return NULL;
1099 irq->IRQInfo2 = (p[1]<<8) + p[0]; 1068 irq->IRQInfo1 = *p; p++;
1100 p += 2; 1069 if (irq->IRQInfo1 & IRQ_INFO2_VALID) {
1101 } 1070 if (p+2 > q)
1102 return p; 1071 return NULL;
1072 irq->IRQInfo2 = (p[1]<<8) + p[0];
1073 p += 2;
1074 }
1075 return p;
1103} 1076}
1104 1077
1105/*====================================================================*/
1106 1078
1107static int parse_cftable_entry(tuple_t *tuple, 1079static int parse_cftable_entry(tuple_t *tuple,
1108 cistpl_cftable_entry_t *entry) 1080 cistpl_cftable_entry_t *entry)
1109{ 1081{
1110 u_char *p, *q, features; 1082 u_char *p, *q, features;
1111 1083
1112 p = tuple->TupleData; 1084 p = tuple->TupleData;
1113 q = p + tuple->TupleDataLen; 1085 q = p + tuple->TupleDataLen;
1114 entry->index = *p & 0x3f; 1086 entry->index = *p & 0x3f;
1115 entry->flags = 0; 1087 entry->flags = 0;
1116 if (*p & 0x40)
1117 entry->flags |= CISTPL_CFTABLE_DEFAULT;
1118 if (*p & 0x80) {
1119 if (++p == q)
1120 return -EINVAL;
1121 if (*p & 0x10)
1122 entry->flags |= CISTPL_CFTABLE_BVDS;
1123 if (*p & 0x20)
1124 entry->flags |= CISTPL_CFTABLE_WP;
1125 if (*p & 0x40) 1088 if (*p & 0x40)
1126 entry->flags |= CISTPL_CFTABLE_RDYBSY; 1089 entry->flags |= CISTPL_CFTABLE_DEFAULT;
1127 if (*p & 0x80) 1090 if (*p & 0x80) {
1128 entry->flags |= CISTPL_CFTABLE_MWAIT; 1091 if (++p == q)
1129 entry->interface = *p & 0x0f; 1092 return -EINVAL;
1130 } else 1093 if (*p & 0x10)
1131 entry->interface = 0; 1094 entry->flags |= CISTPL_CFTABLE_BVDS;
1132 1095 if (*p & 0x20)
1133 /* Process optional features */ 1096 entry->flags |= CISTPL_CFTABLE_WP;
1134 if (++p == q) 1097 if (*p & 0x40)
1135 return -EINVAL; 1098 entry->flags |= CISTPL_CFTABLE_RDYBSY;
1136 features = *p; p++; 1099 if (*p & 0x80)
1137 1100 entry->flags |= CISTPL_CFTABLE_MWAIT;
1138 /* Power options */ 1101 entry->interface = *p & 0x0f;
1139 if ((features & 3) > 0) { 1102 } else
1140 p = parse_power(p, q, &entry->vcc); 1103 entry->interface = 0;
1141 if (p == NULL)
1142 return -EINVAL;
1143 } else
1144 entry->vcc.present = 0;
1145 if ((features & 3) > 1) {
1146 p = parse_power(p, q, &entry->vpp1);
1147 if (p == NULL)
1148 return -EINVAL;
1149 } else
1150 entry->vpp1.present = 0;
1151 if ((features & 3) > 2) {
1152 p = parse_power(p, q, &entry->vpp2);
1153 if (p == NULL)
1154 return -EINVAL;
1155 } else
1156 entry->vpp2.present = 0;
1157 1104
1158 /* Timing options */ 1105 /* Process optional features */
1159 if (features & 0x04) { 1106 if (++p == q)
1160 p = parse_timing(p, q, &entry->timing);
1161 if (p == NULL)
1162 return -EINVAL;
1163 } else {
1164 entry->timing.wait = 0;
1165 entry->timing.ready = 0;
1166 entry->timing.reserved = 0;
1167 }
1168
1169 /* I/O window options */
1170 if (features & 0x08) {
1171 p = parse_io(p, q, &entry->io);
1172 if (p == NULL)
1173 return -EINVAL; 1107 return -EINVAL;
1174 } else 1108 features = *p; p++;
1175 entry->io.nwin = 0;
1176 1109
1177 /* Interrupt options */ 1110 /* Power options */
1178 if (features & 0x10) { 1111 if ((features & 3) > 0) {
1179 p = parse_irq(p, q, &entry->irq); 1112 p = parse_power(p, q, &entry->vcc);
1180 if (p == NULL) 1113 if (p == NULL)
1181 return -EINVAL; 1114 return -EINVAL;
1182 } else 1115 } else
1183 entry->irq.IRQInfo1 = 0; 1116 entry->vcc.present = 0;
1184 1117 if ((features & 3) > 1) {
1185 switch (features & 0x60) { 1118 p = parse_power(p, q, &entry->vpp1);
1186 case 0x00: 1119 if (p == NULL)
1187 entry->mem.nwin = 0; 1120 return -EINVAL;
1188 break; 1121 } else
1189 case 0x20: 1122 entry->vpp1.present = 0;
1190 entry->mem.nwin = 1; 1123 if ((features & 3) > 2) {
1191 entry->mem.win[0].len = get_unaligned_le16(p) << 8; 1124 p = parse_power(p, q, &entry->vpp2);
1192 entry->mem.win[0].card_addr = 0; 1125 if (p == NULL)
1193 entry->mem.win[0].host_addr = 0; 1126 return -EINVAL;
1194 p += 2; 1127 } else
1195 if (p > q) 1128 entry->vpp2.present = 0;
1196 return -EINVAL;
1197 break;
1198 case 0x40:
1199 entry->mem.nwin = 1;
1200 entry->mem.win[0].len = get_unaligned_le16(p) << 8;
1201 entry->mem.win[0].card_addr = get_unaligned_le16(p + 2) << 8;
1202 entry->mem.win[0].host_addr = 0;
1203 p += 4;
1204 if (p > q)
1205 return -EINVAL;
1206 break;
1207 case 0x60:
1208 p = parse_mem(p, q, &entry->mem);
1209 if (p == NULL)
1210 return -EINVAL;
1211 break;
1212 }
1213 1129
1214 /* Misc features */ 1130 /* Timing options */
1215 if (features & 0x80) { 1131 if (features & 0x04) {
1216 if (p == q) 1132 p = parse_timing(p, q, &entry->timing);
1217 return -EINVAL; 1133 if (p == NULL)
1218 entry->flags |= (*p << 8); 1134 return -EINVAL;
1219 while (*p & 0x80) 1135 } else {
1220 if (++p == q) 1136 entry->timing.wait = 0;
1221 return -EINVAL; 1137 entry->timing.ready = 0;
1222 p++; 1138 entry->timing.reserved = 0;
1223 } 1139 }
1224 1140
1225 entry->subtuples = q-p; 1141 /* I/O window options */
1142 if (features & 0x08) {
1143 p = parse_io(p, q, &entry->io);
1144 if (p == NULL)
1145 return -EINVAL;
1146 } else
1147 entry->io.nwin = 0;
1148
1149 /* Interrupt options */
1150 if (features & 0x10) {
1151 p = parse_irq(p, q, &entry->irq);
1152 if (p == NULL)
1153 return -EINVAL;
1154 } else
1155 entry->irq.IRQInfo1 = 0;
1156
1157 switch (features & 0x60) {
1158 case 0x00:
1159 entry->mem.nwin = 0;
1160 break;
1161 case 0x20:
1162 entry->mem.nwin = 1;
1163 entry->mem.win[0].len = get_unaligned_le16(p) << 8;
1164 entry->mem.win[0].card_addr = 0;
1165 entry->mem.win[0].host_addr = 0;
1166 p += 2;
1167 if (p > q)
1168 return -EINVAL;
1169 break;
1170 case 0x40:
1171 entry->mem.nwin = 1;
1172 entry->mem.win[0].len = get_unaligned_le16(p) << 8;
1173 entry->mem.win[0].card_addr = get_unaligned_le16(p + 2) << 8;
1174 entry->mem.win[0].host_addr = 0;
1175 p += 4;
1176 if (p > q)
1177 return -EINVAL;
1178 break;
1179 case 0x60:
1180 p = parse_mem(p, q, &entry->mem);
1181 if (p == NULL)
1182 return -EINVAL;
1183 break;
1184 }
1185
1186 /* Misc features */
1187 if (features & 0x80) {
1188 if (p == q)
1189 return -EINVAL;
1190 entry->flags |= (*p << 8);
1191 while (*p & 0x80)
1192 if (++p == q)
1193 return -EINVAL;
1194 p++;
1195 }
1196
1197 entry->subtuples = q-p;
1226 1198
1227 return 0; 1199 return 0;
1228} 1200}
1229 1201
1230/*====================================================================*/
1231 1202
1232static int parse_device_geo(tuple_t *tuple, cistpl_device_geo_t *geo) 1203static int parse_device_geo(tuple_t *tuple, cistpl_device_geo_t *geo)
1233{ 1204{
1234 u_char *p, *q; 1205 u_char *p, *q;
1235 int n; 1206 int n;
1236 1207
1237 p = (u_char *)tuple->TupleData; 1208 p = (u_char *)tuple->TupleData;
1238 q = p + tuple->TupleDataLen; 1209 q = p + tuple->TupleDataLen;
1239 1210
1240 for (n = 0; n < CISTPL_MAX_DEVICES; n++) { 1211 for (n = 0; n < CISTPL_MAX_DEVICES; n++) {
1241 if (p > q-6) 1212 if (p > q-6)
1242 break; 1213 break;
1243 geo->geo[n].buswidth = p[0]; 1214 geo->geo[n].buswidth = p[0];
1244 geo->geo[n].erase_block = 1 << (p[1]-1); 1215 geo->geo[n].erase_block = 1 << (p[1]-1);
1245 geo->geo[n].read_block = 1 << (p[2]-1); 1216 geo->geo[n].read_block = 1 << (p[2]-1);
1246 geo->geo[n].write_block = 1 << (p[3]-1); 1217 geo->geo[n].write_block = 1 << (p[3]-1);
1247 geo->geo[n].partition = 1 << (p[4]-1); 1218 geo->geo[n].partition = 1 << (p[4]-1);
1248 geo->geo[n].interleave = 1 << (p[5]-1); 1219 geo->geo[n].interleave = 1 << (p[5]-1);
1249 p += 6; 1220 p += 6;
1250 } 1221 }
1251 geo->ngeo = n; 1222 geo->ngeo = n;
1252 return 0; 1223 return 0;
1253} 1224}
1254 1225
1255/*====================================================================*/
1256 1226
1257static int parse_vers_2(tuple_t *tuple, cistpl_vers_2_t *v2) 1227static int parse_vers_2(tuple_t *tuple, cistpl_vers_2_t *v2)
1258{ 1228{
1259 u_char *p, *q; 1229 u_char *p, *q;
1260 1230
1261 if (tuple->TupleDataLen < 10) 1231 if (tuple->TupleDataLen < 10)
1262 return -EINVAL; 1232 return -EINVAL;
1263 1233
1264 p = tuple->TupleData; 1234 p = tuple->TupleData;
1265 q = p + tuple->TupleDataLen; 1235 q = p + tuple->TupleDataLen;
1266 1236
1267 v2->vers = p[0]; 1237 v2->vers = p[0];
1268 v2->comply = p[1]; 1238 v2->comply = p[1];
1269 v2->dindex = get_unaligned_le16(p + 2); 1239 v2->dindex = get_unaligned_le16(p + 2);
1270 v2->vspec8 = p[6]; 1240 v2->vspec8 = p[6];
1271 v2->vspec9 = p[7]; 1241 v2->vspec9 = p[7];
1272 v2->nhdr = p[8]; 1242 v2->nhdr = p[8];
1273 p += 9; 1243 p += 9;
1274 return parse_strings(p, q, 2, v2->str, &v2->vendor, NULL); 1244 return parse_strings(p, q, 2, v2->str, &v2->vendor, NULL);
1275} 1245}
1276 1246
1277/*====================================================================*/
1278 1247
1279static int parse_org(tuple_t *tuple, cistpl_org_t *org) 1248static int parse_org(tuple_t *tuple, cistpl_org_t *org)
1280{ 1249{
1281 u_char *p, *q; 1250 u_char *p, *q;
1282 int i; 1251 int i;
1283 1252
1284 p = tuple->TupleData; 1253 p = tuple->TupleData;
1285 q = p + tuple->TupleDataLen; 1254 q = p + tuple->TupleDataLen;
1286 if (p == q) 1255 if (p == q)
1287 return -EINVAL; 1256 return -EINVAL;
1288 org->data_org = *p; 1257 org->data_org = *p;
1289 if (++p == q)
1290 return -EINVAL;
1291 for (i = 0; i < 30; i++) {
1292 org->desc[i] = *p;
1293 if (*p == '\0')
1294 break;
1295 if (++p == q) 1258 if (++p == q)
1296 return -EINVAL; 1259 return -EINVAL;
1297 } 1260 for (i = 0; i < 30; i++) {
1298 return 0; 1261 org->desc[i] = *p;
1262 if (*p == '\0')
1263 break;
1264 if (++p == q)
1265 return -EINVAL;
1266 }
1267 return 0;
1299} 1268}
1300 1269
1301/*====================================================================*/
1302 1270
1303static int parse_format(tuple_t *tuple, cistpl_format_t *fmt) 1271static int parse_format(tuple_t *tuple, cistpl_format_t *fmt)
1304{ 1272{
1305 u_char *p; 1273 u_char *p;
1306 1274
1307 if (tuple->TupleDataLen < 10) 1275 if (tuple->TupleDataLen < 10)
1308 return -EINVAL; 1276 return -EINVAL;
1309 1277
1310 p = tuple->TupleData; 1278 p = tuple->TupleData;
1311 1279
1312 fmt->type = p[0]; 1280 fmt->type = p[0];
1313 fmt->edc = p[1]; 1281 fmt->edc = p[1];
1314 fmt->offset = get_unaligned_le32(p + 2); 1282 fmt->offset = get_unaligned_le32(p + 2);
1315 fmt->length = get_unaligned_le32(p + 6); 1283 fmt->length = get_unaligned_le32(p + 6);
1316 1284
1317 return 0; 1285 return 0;
1318} 1286}
1319 1287
1320/*====================================================================*/
1321 1288
1322int pcmcia_parse_tuple(tuple_t *tuple, cisparse_t *parse) 1289int pcmcia_parse_tuple(tuple_t *tuple, cisparse_t *parse)
1323{ 1290{
1324 int ret = 0; 1291 int ret = 0;
1325 1292
1326 if (tuple->TupleDataLen > tuple->TupleDataMax) 1293 if (tuple->TupleDataLen > tuple->TupleDataMax)
1327 return -EINVAL; 1294 return -EINVAL;
1328 switch (tuple->TupleCode) { 1295 switch (tuple->TupleCode) {
1329 case CISTPL_DEVICE: 1296 case CISTPL_DEVICE:
1330 case CISTPL_DEVICE_A: 1297 case CISTPL_DEVICE_A:
1331 ret = parse_device(tuple, &parse->device); 1298 ret = parse_device(tuple, &parse->device);
1332 break; 1299 break;
1333 case CISTPL_CHECKSUM: 1300 case CISTPL_CHECKSUM:
1334 ret = parse_checksum(tuple, &parse->checksum); 1301 ret = parse_checksum(tuple, &parse->checksum);
1335 break; 1302 break;
1336 case CISTPL_LONGLINK_A: 1303 case CISTPL_LONGLINK_A:
1337 case CISTPL_LONGLINK_C: 1304 case CISTPL_LONGLINK_C:
1338 ret = parse_longlink(tuple, &parse->longlink); 1305 ret = parse_longlink(tuple, &parse->longlink);
1339 break; 1306 break;
1340 case CISTPL_LONGLINK_MFC: 1307 case CISTPL_LONGLINK_MFC:
1341 ret = parse_longlink_mfc(tuple, &parse->longlink_mfc); 1308 ret = parse_longlink_mfc(tuple, &parse->longlink_mfc);
1342 break; 1309 break;
1343 case CISTPL_VERS_1: 1310 case CISTPL_VERS_1:
1344 ret = parse_vers_1(tuple, &parse->version_1); 1311 ret = parse_vers_1(tuple, &parse->version_1);
1345 break; 1312 break;
1346 case CISTPL_ALTSTR: 1313 case CISTPL_ALTSTR:
1347 ret = parse_altstr(tuple, &parse->altstr); 1314 ret = parse_altstr(tuple, &parse->altstr);
1348 break; 1315 break;
1349 case CISTPL_JEDEC_A: 1316 case CISTPL_JEDEC_A:
1350 case CISTPL_JEDEC_C: 1317 case CISTPL_JEDEC_C:
1351 ret = parse_jedec(tuple, &parse->jedec); 1318 ret = parse_jedec(tuple, &parse->jedec);
1352 break; 1319 break;
1353 case CISTPL_MANFID: 1320 case CISTPL_MANFID:
1354 ret = parse_manfid(tuple, &parse->manfid); 1321 ret = parse_manfid(tuple, &parse->manfid);
1355 break; 1322 break;
1356 case CISTPL_FUNCID: 1323 case CISTPL_FUNCID:
1357 ret = parse_funcid(tuple, &parse->funcid); 1324 ret = parse_funcid(tuple, &parse->funcid);
1358 break; 1325 break;
1359 case CISTPL_FUNCE: 1326 case CISTPL_FUNCE:
1360 ret = parse_funce(tuple, &parse->funce); 1327 ret = parse_funce(tuple, &parse->funce);
1361 break; 1328 break;
1362 case CISTPL_CONFIG: 1329 case CISTPL_CONFIG:
1363 ret = parse_config(tuple, &parse->config); 1330 ret = parse_config(tuple, &parse->config);
1364 break; 1331 break;
1365 case CISTPL_CFTABLE_ENTRY: 1332 case CISTPL_CFTABLE_ENTRY:
1366 ret = parse_cftable_entry(tuple, &parse->cftable_entry); 1333 ret = parse_cftable_entry(tuple, &parse->cftable_entry);
1367 break; 1334 break;
1368 case CISTPL_DEVICE_GEO: 1335 case CISTPL_DEVICE_GEO:
1369 case CISTPL_DEVICE_GEO_A: 1336 case CISTPL_DEVICE_GEO_A:
1370 ret = parse_device_geo(tuple, &parse->device_geo); 1337 ret = parse_device_geo(tuple, &parse->device_geo);
1371 break; 1338 break;
1372 case CISTPL_VERS_2: 1339 case CISTPL_VERS_2:
1373 ret = parse_vers_2(tuple, &parse->vers_2); 1340 ret = parse_vers_2(tuple, &parse->vers_2);
1374 break; 1341 break;
1375 case CISTPL_ORG: 1342 case CISTPL_ORG:
1376 ret = parse_org(tuple, &parse->org); 1343 ret = parse_org(tuple, &parse->org);
1377 break; 1344 break;
1378 case CISTPL_FORMAT: 1345 case CISTPL_FORMAT:
1379 case CISTPL_FORMAT_A: 1346 case CISTPL_FORMAT_A:
1380 ret = parse_format(tuple, &parse->format); 1347 ret = parse_format(tuple, &parse->format);
1381 break; 1348 break;
1382 case CISTPL_NO_LINK: 1349 case CISTPL_NO_LINK:
1383 case CISTPL_LINKTARGET: 1350 case CISTPL_LINKTARGET:
1384 ret = 0; 1351 ret = 0;
1385 break; 1352 break;
1386 default: 1353 default:
1387 ret = -EINVAL; 1354 ret = -EINVAL;
1388 break; 1355 break;
1389 } 1356 }
1390 if (ret) 1357 if (ret)
1391 pr_debug("parse_tuple failed %d\n", ret); 1358 pr_debug("parse_tuple failed %d\n", ret);
1392 return ret; 1359 return ret;
1393} 1360}
1394EXPORT_SYMBOL(pcmcia_parse_tuple); 1361EXPORT_SYMBOL(pcmcia_parse_tuple);
1395 1362
1396/*======================================================================
1397 1363
1398 This is used internally by Card Services to look up CIS stuff. 1364/**
1399 1365 * pccard_read_tuple() - internal CIS tuple access
1400======================================================================*/ 1366 * @s: the struct pcmcia_socket where the card is inserted
1401 1367 * @function: the device function we loop for
1402int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function, cisdata_t code, void *parse) 1368 * @code: which CIS code shall we look for?
1369 * @parse: buffer where the tuple shall be parsed (or NULL, if no parse)
1370 *
1371 * pccard_read_tuple() reads out one tuple and attempts to parse it
1372 */
1373int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function,
1374 cisdata_t code, void *parse)
1403{ 1375{
1404 tuple_t tuple; 1376 tuple_t tuple;
1405 cisdata_t *buf; 1377 cisdata_t *buf;
1406 int ret; 1378 int ret;
1407 1379
1408 buf = kmalloc(256, GFP_KERNEL); 1380 buf = kmalloc(256, GFP_KERNEL);
1409 if (buf == NULL) { 1381 if (buf == NULL) {
1410 dev_printk(KERN_WARNING, &s->dev, "no memory to read tuple\n"); 1382 dev_printk(KERN_WARNING, &s->dev, "no memory to read tuple\n");
1411 return -ENOMEM; 1383 return -ENOMEM;
1412 } 1384 }
1413 tuple.DesiredTuple = code; 1385 tuple.DesiredTuple = code;
1414 tuple.Attributes = 0; 1386 tuple.Attributes = 0;
1415 if (function == BIND_FN_ALL) 1387 if (function == BIND_FN_ALL)
1416 tuple.Attributes = TUPLE_RETURN_COMMON; 1388 tuple.Attributes = TUPLE_RETURN_COMMON;
1417 ret = pccard_get_first_tuple(s, function, &tuple); 1389 ret = pccard_get_first_tuple(s, function, &tuple);
1418 if (ret != 0) 1390 if (ret != 0)
1419 goto done; 1391 goto done;
1420 tuple.TupleData = buf; 1392 tuple.TupleData = buf;
1421 tuple.TupleOffset = 0; 1393 tuple.TupleOffset = 0;
1422 tuple.TupleDataMax = 255; 1394 tuple.TupleDataMax = 255;
1423 ret = pccard_get_tuple_data(s, &tuple); 1395 ret = pccard_get_tuple_data(s, &tuple);
1424 if (ret != 0) 1396 if (ret != 0)
1425 goto done; 1397 goto done;
1426 ret = pcmcia_parse_tuple(&tuple, parse); 1398 ret = pcmcia_parse_tuple(&tuple, parse);
1427done: 1399done:
1428 kfree(buf); 1400 kfree(buf);
1429 return ret; 1401 return ret;
1430} 1402}
1431 1403
1432 1404
diff --git a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c
index e6f7d410aed6..452c83b512c4 100644
--- a/drivers/pcmcia/rsrc_mgr.c
+++ b/drivers/pcmcia/rsrc_mgr.c
@@ -79,9 +79,8 @@ static resource_size_t pcmcia_align(void *align_data,
79 79
80#ifdef CONFIG_X86 80#ifdef CONFIG_X86
81 if (res->flags & IORESOURCE_IO) { 81 if (res->flags & IORESOURCE_IO) {
82 if (start & 0x300) { 82 if (start & 0x300)
83 start = (start + 0x3ff) & ~0x3ff; 83 start = (start + 0x3ff) & ~0x3ff;
84 }
85 } 84 }
86#endif 85#endif
87 86