0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <linux/module.h>
0013 #include <linux/moduleparam.h>
0014 #include <linux/kernel.h>
0015 #include <linux/string.h>
0016 #include <linux/major.h>
0017 #include <linux/errno.h>
0018 #include <linux/timer.h>
0019 #include <linux/slab.h>
0020 #include <linux/mm.h>
0021 #include <linux/pci.h>
0022 #include <linux/ioport.h>
0023 #include <linux/io.h>
0024 #include <linux/security.h>
0025 #include <asm/byteorder.h>
0026 #include <asm/unaligned.h>
0027
0028 #include <pcmcia/ss.h>
0029 #include <pcmcia/cisreg.h>
0030 #include <pcmcia/cistpl.h>
0031 #include <pcmcia/ds.h>
0032 #include "cs_internal.h"
0033
0034 static const u_char mantissa[] = {
0035 10, 12, 13, 15, 20, 25, 30, 35,
0036 40, 45, 50, 55, 60, 70, 80, 90
0037 };
0038
0039 static const u_int exponent[] = {
0040 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000
0041 };
0042
0043
0044 #define SPEED_CVT(v) \
0045 (mantissa[(((v)>>3)&15)-1] * exponent[(v)&7] / 10)
0046
0047 #define POWER_CVT(v) \
0048 (mantissa[((v)>>3)&15] * exponent[(v)&7] / 10)
0049 #define POWER_SCALE(v) (exponent[(v)&7])
0050
0051
0052 #define MAX_TUPLES 200
0053
0054
0055 #define IRQ_INFO2_VALID 0x10
0056
0057
0058 static int cis_width;
0059 module_param(cis_width, int, 0444);
0060
0061 void release_cis_mem(struct pcmcia_socket *s)
0062 {
0063 mutex_lock(&s->ops_mutex);
0064 if (s->cis_mem.flags & MAP_ACTIVE) {
0065 s->cis_mem.flags &= ~MAP_ACTIVE;
0066 s->ops->set_mem_map(s, &s->cis_mem);
0067 if (s->cis_mem.res) {
0068 release_resource(s->cis_mem.res);
0069 kfree(s->cis_mem.res);
0070 s->cis_mem.res = NULL;
0071 }
0072 iounmap(s->cis_virt);
0073 s->cis_virt = NULL;
0074 }
0075 mutex_unlock(&s->ops_mutex);
0076 }
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086 static void __iomem *set_cis_map(struct pcmcia_socket *s,
0087 unsigned int card_offset, unsigned int flags)
0088 {
0089 pccard_mem_map *mem = &s->cis_mem;
0090 int ret;
0091
0092 if (!(s->features & SS_CAP_STATIC_MAP) && (mem->res == NULL)) {
0093 mem->res = pcmcia_find_mem_region(0, s->map_size,
0094 s->map_size, 0, s);
0095 if (mem->res == NULL) {
0096 dev_notice(&s->dev, "cs: unable to map card memory!\n");
0097 return NULL;
0098 }
0099 s->cis_virt = NULL;
0100 }
0101
0102 if (!(s->features & SS_CAP_STATIC_MAP) && (!s->cis_virt))
0103 s->cis_virt = ioremap(mem->res->start, s->map_size);
0104
0105 mem->card_start = card_offset;
0106 mem->flags = flags;
0107
0108 ret = s->ops->set_mem_map(s, mem);
0109 if (ret) {
0110 iounmap(s->cis_virt);
0111 s->cis_virt = NULL;
0112 return NULL;
0113 }
0114
0115 if (s->features & SS_CAP_STATIC_MAP) {
0116 if (s->cis_virt)
0117 iounmap(s->cis_virt);
0118 s->cis_virt = ioremap(mem->static_start, s->map_size);
0119 }
0120
0121 return s->cis_virt;
0122 }
0123
0124
0125
0126 #define IS_ATTR 1
0127 #define IS_INDIRECT 8
0128
0129
0130
0131
0132
0133
0134 int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
0135 u_int len, void *ptr)
0136 {
0137 void __iomem *sys, *end;
0138 unsigned char *buf = ptr;
0139
0140 dev_dbg(&s->dev, "pcmcia_read_cis_mem(%d, %#x, %u)\n", attr, addr, len);
0141
0142 if (attr & IS_INDIRECT) {
0143
0144
0145 u_char flags = ICTRL0_COMMON|ICTRL0_AUTOINC|ICTRL0_BYTEGRAN;
0146 if (attr & IS_ATTR) {
0147 addr *= 2;
0148 flags = ICTRL0_AUTOINC;
0149 }
0150
0151 sys = set_cis_map(s, 0, MAP_ACTIVE |
0152 ((cis_width) ? MAP_16BIT : 0));
0153 if (!sys) {
0154 dev_dbg(&s->dev, "could not map memory\n");
0155 memset(ptr, 0xff, len);
0156 return -1;
0157 }
0158
0159 writeb(flags, sys+CISREG_ICTRL0);
0160 writeb(addr & 0xff, sys+CISREG_IADDR0);
0161 writeb((addr>>8) & 0xff, sys+CISREG_IADDR1);
0162 writeb((addr>>16) & 0xff, sys+CISREG_IADDR2);
0163 writeb((addr>>24) & 0xff, sys+CISREG_IADDR3);
0164 for ( ; len > 0; len--, buf++)
0165 *buf = readb(sys+CISREG_IDATA0);
0166 } else {
0167 u_int inc = 1, card_offset, flags;
0168
0169 if (addr > CISTPL_MAX_CIS_SIZE) {
0170 dev_dbg(&s->dev,
0171 "attempt to read CIS mem at addr %#x", addr);
0172 memset(ptr, 0xff, len);
0173 return -1;
0174 }
0175
0176 flags = MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0);
0177 if (attr) {
0178 flags |= MAP_ATTRIB;
0179 inc++;
0180 addr *= 2;
0181 }
0182
0183 card_offset = addr & ~(s->map_size-1);
0184 while (len) {
0185 sys = set_cis_map(s, card_offset, flags);
0186 if (!sys) {
0187 dev_dbg(&s->dev, "could not map memory\n");
0188 memset(ptr, 0xff, len);
0189 return -1;
0190 }
0191 end = sys + s->map_size;
0192 sys = sys + (addr & (s->map_size-1));
0193 for ( ; len > 0; len--, buf++, sys += inc) {
0194 if (sys == end)
0195 break;
0196 *buf = readb(sys);
0197 }
0198 card_offset += s->map_size;
0199 addr = 0;
0200 }
0201 }
0202 dev_dbg(&s->dev, " %#2.2x %#2.2x %#2.2x %#2.2x ...\n",
0203 *(u_char *)(ptr+0), *(u_char *)(ptr+1),
0204 *(u_char *)(ptr+2), *(u_char *)(ptr+3));
0205 return 0;
0206 }
0207
0208
0209
0210
0211
0212
0213
0214
0215 int pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
0216 u_int len, void *ptr)
0217 {
0218 void __iomem *sys, *end;
0219 unsigned char *buf = ptr;
0220
0221 dev_dbg(&s->dev,
0222 "pcmcia_write_cis_mem(%d, %#x, %u)\n", attr, addr, len);
0223
0224 if (attr & IS_INDIRECT) {
0225
0226
0227 u_char flags = ICTRL0_COMMON|ICTRL0_AUTOINC|ICTRL0_BYTEGRAN;
0228 if (attr & IS_ATTR) {
0229 addr *= 2;
0230 flags = ICTRL0_AUTOINC;
0231 }
0232
0233 sys = set_cis_map(s, 0, MAP_ACTIVE |
0234 ((cis_width) ? MAP_16BIT : 0));
0235 if (!sys) {
0236 dev_dbg(&s->dev, "could not map memory\n");
0237 return -EINVAL;
0238 }
0239
0240 writeb(flags, sys+CISREG_ICTRL0);
0241 writeb(addr & 0xff, sys+CISREG_IADDR0);
0242 writeb((addr>>8) & 0xff, sys+CISREG_IADDR1);
0243 writeb((addr>>16) & 0xff, sys+CISREG_IADDR2);
0244 writeb((addr>>24) & 0xff, sys+CISREG_IADDR3);
0245 for ( ; len > 0; len--, buf++)
0246 writeb(*buf, sys+CISREG_IDATA0);
0247 } else {
0248 u_int inc = 1, card_offset, flags;
0249
0250 flags = MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0);
0251 if (attr & IS_ATTR) {
0252 flags |= MAP_ATTRIB;
0253 inc++;
0254 addr *= 2;
0255 }
0256
0257 card_offset = addr & ~(s->map_size-1);
0258 while (len) {
0259 sys = set_cis_map(s, card_offset, flags);
0260 if (!sys) {
0261 dev_dbg(&s->dev, "could not map memory\n");
0262 return -EINVAL;
0263 }
0264
0265 end = sys + s->map_size;
0266 sys = sys + (addr & (s->map_size-1));
0267 for ( ; len > 0; len--, buf++, sys += inc) {
0268 if (sys == end)
0269 break;
0270 writeb(*buf, sys);
0271 }
0272 card_offset += s->map_size;
0273 addr = 0;
0274 }
0275 }
0276 return 0;
0277 }
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287 static int read_cis_cache(struct pcmcia_socket *s, int attr, u_int addr,
0288 size_t len, void *ptr)
0289 {
0290 struct cis_cache_entry *cis;
0291 int ret = 0;
0292
0293 if (s->state & SOCKET_CARDBUS)
0294 return -EINVAL;
0295
0296 mutex_lock(&s->ops_mutex);
0297 if (s->fake_cis) {
0298 if (s->fake_cis_len >= addr+len)
0299 memcpy(ptr, s->fake_cis+addr, len);
0300 else {
0301 memset(ptr, 0xff, len);
0302 ret = -EINVAL;
0303 }
0304 mutex_unlock(&s->ops_mutex);
0305 return ret;
0306 }
0307
0308 list_for_each_entry(cis, &s->cis_cache, node) {
0309 if (cis->addr == addr && cis->len == len && cis->attr == attr) {
0310 memcpy(ptr, cis->cache, len);
0311 mutex_unlock(&s->ops_mutex);
0312 return 0;
0313 }
0314 }
0315
0316 ret = pcmcia_read_cis_mem(s, attr, addr, len, ptr);
0317
0318 if (ret == 0) {
0319
0320 cis = kmalloc(sizeof(struct cis_cache_entry) + len, GFP_KERNEL);
0321 if (cis) {
0322 cis->addr = addr;
0323 cis->len = len;
0324 cis->attr = attr;
0325 memcpy(cis->cache, ptr, len);
0326 list_add(&cis->node, &s->cis_cache);
0327 }
0328 }
0329 mutex_unlock(&s->ops_mutex);
0330
0331 return ret;
0332 }
0333
0334 static void
0335 remove_cis_cache(struct pcmcia_socket *s, int attr, u_int addr, u_int len)
0336 {
0337 struct cis_cache_entry *cis;
0338
0339 mutex_lock(&s->ops_mutex);
0340 list_for_each_entry(cis, &s->cis_cache, node)
0341 if (cis->addr == addr && cis->len == len && cis->attr == attr) {
0342 list_del(&cis->node);
0343 kfree(cis);
0344 break;
0345 }
0346 mutex_unlock(&s->ops_mutex);
0347 }
0348
0349
0350
0351
0352
0353
0354
0355
0356 void destroy_cis_cache(struct pcmcia_socket *s)
0357 {
0358 struct list_head *l, *n;
0359 struct cis_cache_entry *cis;
0360
0361 list_for_each_safe(l, n, &s->cis_cache) {
0362 cis = list_entry(l, struct cis_cache_entry, node);
0363 list_del(&cis->node);
0364 kfree(cis);
0365 }
0366 }
0367
0368
0369
0370
0371 int verify_cis_cache(struct pcmcia_socket *s)
0372 {
0373 struct cis_cache_entry *cis;
0374 char *buf;
0375 int ret;
0376
0377 if (s->state & SOCKET_CARDBUS)
0378 return -EINVAL;
0379
0380 buf = kmalloc(256, GFP_KERNEL);
0381 if (buf == NULL) {
0382 dev_warn(&s->dev, "no memory for verifying CIS\n");
0383 return -ENOMEM;
0384 }
0385 mutex_lock(&s->ops_mutex);
0386 list_for_each_entry(cis, &s->cis_cache, node) {
0387 int len = cis->len;
0388
0389 if (len > 256)
0390 len = 256;
0391
0392 ret = pcmcia_read_cis_mem(s, cis->attr, cis->addr, len, buf);
0393 if (ret || memcmp(buf, cis->cache, len) != 0) {
0394 kfree(buf);
0395 mutex_unlock(&s->ops_mutex);
0396 return -1;
0397 }
0398 }
0399 kfree(buf);
0400 mutex_unlock(&s->ops_mutex);
0401 return 0;
0402 }
0403
0404
0405
0406
0407
0408
0409
0410 int pcmcia_replace_cis(struct pcmcia_socket *s,
0411 const u8 *data, const size_t len)
0412 {
0413 if (len > CISTPL_MAX_CIS_SIZE) {
0414 dev_warn(&s->dev, "replacement CIS too big\n");
0415 return -EINVAL;
0416 }
0417 mutex_lock(&s->ops_mutex);
0418 kfree(s->fake_cis);
0419 s->fake_cis = kmalloc(len, GFP_KERNEL);
0420 if (s->fake_cis == NULL) {
0421 dev_warn(&s->dev, "no memory to replace CIS\n");
0422 mutex_unlock(&s->ops_mutex);
0423 return -ENOMEM;
0424 }
0425 s->fake_cis_len = len;
0426 memcpy(s->fake_cis, data, len);
0427 dev_info(&s->dev, "Using replacement CIS\n");
0428 mutex_unlock(&s->ops_mutex);
0429 return 0;
0430 }
0431
0432
0433
0434 struct tuple_flags {
0435 u_int link_space:4;
0436 u_int has_link:1;
0437 u_int mfc_fn:3;
0438 u_int space:4;
0439 };
0440
0441 #define LINK_SPACE(f) (((struct tuple_flags *)(&(f)))->link_space)
0442 #define HAS_LINK(f) (((struct tuple_flags *)(&(f)))->has_link)
0443 #define MFC_FN(f) (((struct tuple_flags *)(&(f)))->mfc_fn)
0444 #define SPACE(f) (((struct tuple_flags *)(&(f)))->space)
0445
0446 int pccard_get_first_tuple(struct pcmcia_socket *s, unsigned int function,
0447 tuple_t *tuple)
0448 {
0449 if (!s)
0450 return -EINVAL;
0451
0452 if (!(s->state & SOCKET_PRESENT) || (s->state & SOCKET_CARDBUS))
0453 return -ENODEV;
0454 tuple->TupleLink = tuple->Flags = 0;
0455
0456
0457 tuple->CISOffset = tuple->LinkOffset = 0;
0458 SPACE(tuple->Flags) = HAS_LINK(tuple->Flags) = 1;
0459
0460 if ((s->functions > 1) && !(tuple->Attributes & TUPLE_RETURN_COMMON)) {
0461 cisdata_t req = tuple->DesiredTuple;
0462 tuple->DesiredTuple = CISTPL_LONGLINK_MFC;
0463 if (pccard_get_next_tuple(s, function, tuple) == 0) {
0464 tuple->DesiredTuple = CISTPL_LINKTARGET;
0465 if (pccard_get_next_tuple(s, function, tuple) != 0)
0466 return -ENOSPC;
0467 } else
0468 tuple->CISOffset = tuple->TupleLink = 0;
0469 tuple->DesiredTuple = req;
0470 }
0471 return pccard_get_next_tuple(s, function, tuple);
0472 }
0473
0474 static int follow_link(struct pcmcia_socket *s, tuple_t *tuple)
0475 {
0476 u_char link[5];
0477 u_int ofs;
0478 int ret;
0479
0480 if (MFC_FN(tuple->Flags)) {
0481
0482 ret = read_cis_cache(s, LINK_SPACE(tuple->Flags),
0483 tuple->LinkOffset, 5, link);
0484 if (ret)
0485 return -1;
0486 ofs = get_unaligned_le32(link + 1);
0487 SPACE(tuple->Flags) = (link[0] == CISTPL_MFC_ATTR);
0488
0489 tuple->LinkOffset += 5;
0490 MFC_FN(tuple->Flags)--;
0491 } else if (HAS_LINK(tuple->Flags)) {
0492 ofs = tuple->LinkOffset;
0493 SPACE(tuple->Flags) = LINK_SPACE(tuple->Flags);
0494 HAS_LINK(tuple->Flags) = 0;
0495 } else
0496 return -1;
0497
0498 if (SPACE(tuple->Flags)) {
0499
0500
0501 ret = read_cis_cache(s, SPACE(tuple->Flags), ofs, 5, link);
0502 if (ret)
0503 return -1;
0504 if ((link[0] == CISTPL_LINKTARGET) && (link[1] >= 3) &&
0505 (strncmp(link+2, "CIS", 3) == 0))
0506 return ofs;
0507 remove_cis_cache(s, SPACE(tuple->Flags), ofs, 5);
0508
0509 ofs = ofs >> 1;
0510 }
0511 ret = read_cis_cache(s, SPACE(tuple->Flags), ofs, 5, link);
0512 if (ret)
0513 return -1;
0514 if ((link[0] == CISTPL_LINKTARGET) && (link[1] >= 3) &&
0515 (strncmp(link+2, "CIS", 3) == 0))
0516 return ofs;
0517 remove_cis_cache(s, SPACE(tuple->Flags), ofs, 5);
0518 return -1;
0519 }
0520
0521 int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function,
0522 tuple_t *tuple)
0523 {
0524 u_char link[2], tmp;
0525 int ofs, i, attr;
0526 int ret;
0527
0528 if (!s)
0529 return -EINVAL;
0530 if (!(s->state & SOCKET_PRESENT) || (s->state & SOCKET_CARDBUS))
0531 return -ENODEV;
0532
0533 link[1] = tuple->TupleLink;
0534 ofs = tuple->CISOffset + tuple->TupleLink;
0535 attr = SPACE(tuple->Flags);
0536
0537 for (i = 0; i < MAX_TUPLES; i++) {
0538 if (link[1] == 0xff)
0539 link[0] = CISTPL_END;
0540 else {
0541 ret = read_cis_cache(s, attr, ofs, 2, link);
0542 if (ret)
0543 return -1;
0544 if (link[0] == CISTPL_NULL) {
0545 ofs++;
0546 continue;
0547 }
0548 }
0549
0550
0551 if (link[0] == CISTPL_END) {
0552 ofs = follow_link(s, tuple);
0553 if (ofs < 0)
0554 return -ENOSPC;
0555 attr = SPACE(tuple->Flags);
0556 ret = read_cis_cache(s, attr, ofs, 2, link);
0557 if (ret)
0558 return -1;
0559 }
0560
0561
0562 if ((link[0] == CISTPL_LONGLINK_A) ||
0563 (link[0] == CISTPL_LONGLINK_C) ||
0564 (link[0] == CISTPL_LONGLINK_MFC) ||
0565 (link[0] == CISTPL_LINKTARGET) ||
0566 (link[0] == CISTPL_INDIRECT) ||
0567 (link[0] == CISTPL_NO_LINK)) {
0568 switch (link[0]) {
0569 case CISTPL_LONGLINK_A:
0570 HAS_LINK(tuple->Flags) = 1;
0571 LINK_SPACE(tuple->Flags) = attr | IS_ATTR;
0572 ret = read_cis_cache(s, attr, ofs+2, 4,
0573 &tuple->LinkOffset);
0574 if (ret)
0575 return -1;
0576 break;
0577 case CISTPL_LONGLINK_C:
0578 HAS_LINK(tuple->Flags) = 1;
0579 LINK_SPACE(tuple->Flags) = attr & ~IS_ATTR;
0580 ret = read_cis_cache(s, attr, ofs+2, 4,
0581 &tuple->LinkOffset);
0582 if (ret)
0583 return -1;
0584 break;
0585 case CISTPL_INDIRECT:
0586 HAS_LINK(tuple->Flags) = 1;
0587 LINK_SPACE(tuple->Flags) = IS_ATTR |
0588 IS_INDIRECT;
0589 tuple->LinkOffset = 0;
0590 break;
0591 case CISTPL_LONGLINK_MFC:
0592 tuple->LinkOffset = ofs + 3;
0593 LINK_SPACE(tuple->Flags) = attr;
0594 if (function == BIND_FN_ALL) {
0595
0596 ret = read_cis_cache(s, attr, ofs+2,
0597 1, &tmp);
0598 if (ret)
0599 return -1;
0600 MFC_FN(tuple->Flags) = tmp;
0601 } else {
0602
0603 MFC_FN(tuple->Flags) = 1;
0604 tuple->LinkOffset += function * 5;
0605 }
0606 break;
0607 case CISTPL_NO_LINK:
0608 HAS_LINK(tuple->Flags) = 0;
0609 break;
0610 }
0611 if ((tuple->Attributes & TUPLE_RETURN_LINK) &&
0612 (tuple->DesiredTuple == RETURN_FIRST_TUPLE))
0613 break;
0614 } else
0615 if (tuple->DesiredTuple == RETURN_FIRST_TUPLE)
0616 break;
0617
0618 if (link[0] == tuple->DesiredTuple)
0619 break;
0620 ofs += link[1] + 2;
0621 }
0622 if (i == MAX_TUPLES) {
0623 dev_dbg(&s->dev, "cs: overrun in pcmcia_get_next_tuple\n");
0624 return -ENOSPC;
0625 }
0626
0627 tuple->TupleCode = link[0];
0628 tuple->TupleLink = link[1];
0629 tuple->CISOffset = ofs + 2;
0630 return 0;
0631 }
0632
0633 int pccard_get_tuple_data(struct pcmcia_socket *s, tuple_t *tuple)
0634 {
0635 u_int len;
0636 int ret;
0637
0638 if (!s)
0639 return -EINVAL;
0640
0641 if (tuple->TupleLink < tuple->TupleOffset)
0642 return -ENOSPC;
0643 len = tuple->TupleLink - tuple->TupleOffset;
0644 tuple->TupleDataLen = tuple->TupleLink;
0645 if (len == 0)
0646 return 0;
0647 ret = read_cis_cache(s, SPACE(tuple->Flags),
0648 tuple->CISOffset + tuple->TupleOffset,
0649 min(len, (u_int) tuple->TupleDataMax),
0650 tuple->TupleData);
0651 if (ret)
0652 return -1;
0653 return 0;
0654 }
0655
0656
0657
0658
0659 static int parse_device(tuple_t *tuple, cistpl_device_t *device)
0660 {
0661 int i;
0662 u_char scale;
0663 u_char *p, *q;
0664
0665 p = (u_char *)tuple->TupleData;
0666 q = p + tuple->TupleDataLen;
0667
0668 device->ndev = 0;
0669 for (i = 0; i < CISTPL_MAX_DEVICES; i++) {
0670
0671 if (*p == 0xff)
0672 break;
0673 device->dev[i].type = (*p >> 4);
0674 device->dev[i].wp = (*p & 0x08) ? 1 : 0;
0675 switch (*p & 0x07) {
0676 case 0:
0677 device->dev[i].speed = 0;
0678 break;
0679 case 1:
0680 device->dev[i].speed = 250;
0681 break;
0682 case 2:
0683 device->dev[i].speed = 200;
0684 break;
0685 case 3:
0686 device->dev[i].speed = 150;
0687 break;
0688 case 4:
0689 device->dev[i].speed = 100;
0690 break;
0691 case 7:
0692 if (++p == q)
0693 return -EINVAL;
0694 device->dev[i].speed = SPEED_CVT(*p);
0695 while (*p & 0x80)
0696 if (++p == q)
0697 return -EINVAL;
0698 break;
0699 default:
0700 return -EINVAL;
0701 }
0702
0703 if (++p == q)
0704 return -EINVAL;
0705 if (*p == 0xff)
0706 break;
0707 scale = *p & 7;
0708 if (scale == 7)
0709 return -EINVAL;
0710 device->dev[i].size = ((*p >> 3) + 1) * (512 << (scale*2));
0711 device->ndev++;
0712 if (++p == q)
0713 break;
0714 }
0715
0716 return 0;
0717 }
0718
0719
0720 static int parse_checksum(tuple_t *tuple, cistpl_checksum_t *csum)
0721 {
0722 u_char *p;
0723 if (tuple->TupleDataLen < 5)
0724 return -EINVAL;
0725 p = (u_char *) tuple->TupleData;
0726 csum->addr = tuple->CISOffset + get_unaligned_le16(p) - 2;
0727 csum->len = get_unaligned_le16(p + 2);
0728 csum->sum = *(p + 4);
0729 return 0;
0730 }
0731
0732
0733 static int parse_longlink(tuple_t *tuple, cistpl_longlink_t *link)
0734 {
0735 if (tuple->TupleDataLen < 4)
0736 return -EINVAL;
0737 link->addr = get_unaligned_le32(tuple->TupleData);
0738 return 0;
0739 }
0740
0741
0742 static int parse_longlink_mfc(tuple_t *tuple, cistpl_longlink_mfc_t *link)
0743 {
0744 u_char *p;
0745 int i;
0746
0747 p = (u_char *)tuple->TupleData;
0748
0749 link->nfn = *p; p++;
0750 if (tuple->TupleDataLen <= link->nfn*5)
0751 return -EINVAL;
0752 for (i = 0; i < link->nfn; i++) {
0753 link->fn[i].space = *p; p++;
0754 link->fn[i].addr = get_unaligned_le32(p);
0755 p += 4;
0756 }
0757 return 0;
0758 }
0759
0760
0761 static int parse_strings(u_char *p, u_char *q, int max,
0762 char *s, u_char *ofs, u_char *found)
0763 {
0764 int i, j, ns;
0765
0766 if (p == q)
0767 return -EINVAL;
0768 ns = 0; j = 0;
0769 for (i = 0; i < max; i++) {
0770 if (*p == 0xff)
0771 break;
0772 ofs[i] = j;
0773 ns++;
0774 for (;;) {
0775 s[j++] = (*p == 0xff) ? '\0' : *p;
0776 if ((*p == '\0') || (*p == 0xff))
0777 break;
0778 if (++p == q)
0779 return -EINVAL;
0780 }
0781 if ((*p == 0xff) || (++p == q))
0782 break;
0783 }
0784 if (found) {
0785 *found = ns;
0786 return 0;
0787 }
0788
0789 return (ns == max) ? 0 : -EINVAL;
0790 }
0791
0792
0793 static int parse_vers_1(tuple_t *tuple, cistpl_vers_1_t *vers_1)
0794 {
0795 u_char *p, *q;
0796
0797 p = (u_char *)tuple->TupleData;
0798 q = p + tuple->TupleDataLen;
0799
0800 vers_1->major = *p; p++;
0801 vers_1->minor = *p; p++;
0802 if (p >= q)
0803 return -EINVAL;
0804
0805 return parse_strings(p, q, CISTPL_VERS_1_MAX_PROD_STRINGS,
0806 vers_1->str, vers_1->ofs, &vers_1->ns);
0807 }
0808
0809
0810 static int parse_altstr(tuple_t *tuple, cistpl_altstr_t *altstr)
0811 {
0812 u_char *p, *q;
0813
0814 p = (u_char *)tuple->TupleData;
0815 q = p + tuple->TupleDataLen;
0816
0817 return parse_strings(p, q, CISTPL_MAX_ALTSTR_STRINGS,
0818 altstr->str, altstr->ofs, &altstr->ns);
0819 }
0820
0821
0822 static int parse_jedec(tuple_t *tuple, cistpl_jedec_t *jedec)
0823 {
0824 u_char *p, *q;
0825 int nid;
0826
0827 p = (u_char *)tuple->TupleData;
0828 q = p + tuple->TupleDataLen;
0829
0830 for (nid = 0; nid < CISTPL_MAX_DEVICES; nid++) {
0831 if (p > q-2)
0832 break;
0833 jedec->id[nid].mfr = p[0];
0834 jedec->id[nid].info = p[1];
0835 p += 2;
0836 }
0837 jedec->nid = nid;
0838 return 0;
0839 }
0840
0841
0842 static int parse_manfid(tuple_t *tuple, cistpl_manfid_t *m)
0843 {
0844 if (tuple->TupleDataLen < 4)
0845 return -EINVAL;
0846 m->manf = get_unaligned_le16(tuple->TupleData);
0847 m->card = get_unaligned_le16(tuple->TupleData + 2);
0848 return 0;
0849 }
0850
0851
0852 static int parse_funcid(tuple_t *tuple, cistpl_funcid_t *f)
0853 {
0854 u_char *p;
0855 if (tuple->TupleDataLen < 2)
0856 return -EINVAL;
0857 p = (u_char *)tuple->TupleData;
0858 f->func = p[0];
0859 f->sysinit = p[1];
0860 return 0;
0861 }
0862
0863
0864 static int parse_funce(tuple_t *tuple, cistpl_funce_t *f)
0865 {
0866 u_char *p;
0867 int i;
0868 if (tuple->TupleDataLen < 1)
0869 return -EINVAL;
0870 p = (u_char *)tuple->TupleData;
0871 f->type = p[0];
0872 for (i = 1; i < tuple->TupleDataLen; i++)
0873 f->data[i-1] = p[i];
0874 return 0;
0875 }
0876
0877
0878 static int parse_config(tuple_t *tuple, cistpl_config_t *config)
0879 {
0880 int rasz, rmsz, i;
0881 u_char *p;
0882
0883 p = (u_char *)tuple->TupleData;
0884 rasz = *p & 0x03;
0885 rmsz = (*p & 0x3c) >> 2;
0886 if (tuple->TupleDataLen < rasz+rmsz+4)
0887 return -EINVAL;
0888 config->last_idx = *(++p);
0889 p++;
0890 config->base = 0;
0891 for (i = 0; i <= rasz; i++)
0892 config->base += p[i] << (8*i);
0893 p += rasz+1;
0894 for (i = 0; i < 4; i++)
0895 config->rmask[i] = 0;
0896 for (i = 0; i <= rmsz; i++)
0897 config->rmask[i>>2] += p[i] << (8*(i%4));
0898 config->subtuples = tuple->TupleDataLen - (rasz+rmsz+4);
0899 return 0;
0900 }
0901
0902
0903
0904
0905
0906 static u_char *parse_power(u_char *p, u_char *q, cistpl_power_t *pwr)
0907 {
0908 int i;
0909 u_int scale;
0910
0911 if (p == q)
0912 return NULL;
0913 pwr->present = *p;
0914 pwr->flags = 0;
0915 p++;
0916 for (i = 0; i < 7; i++)
0917 if (pwr->present & (1<<i)) {
0918 if (p == q)
0919 return NULL;
0920 pwr->param[i] = POWER_CVT(*p);
0921 scale = POWER_SCALE(*p);
0922 while (*p & 0x80) {
0923 if (++p == q)
0924 return NULL;
0925 if ((*p & 0x7f) < 100)
0926 pwr->param[i] +=
0927 (*p & 0x7f) * scale / 100;
0928 else if (*p == 0x7d)
0929 pwr->flags |= CISTPL_POWER_HIGHZ_OK;
0930 else if (*p == 0x7e)
0931 pwr->param[i] = 0;
0932 else if (*p == 0x7f)
0933 pwr->flags |= CISTPL_POWER_HIGHZ_REQ;
0934 else
0935 return NULL;
0936 }
0937 p++;
0938 }
0939 return p;
0940 }
0941
0942
0943 static u_char *parse_timing(u_char *p, u_char *q, cistpl_timing_t *timing)
0944 {
0945 u_char scale;
0946
0947 if (p == q)
0948 return NULL;
0949 scale = *p;
0950 if ((scale & 3) != 3) {
0951 if (++p == q)
0952 return NULL;
0953 timing->wait = SPEED_CVT(*p);
0954 timing->waitscale = exponent[scale & 3];
0955 } else
0956 timing->wait = 0;
0957 scale >>= 2;
0958 if ((scale & 7) != 7) {
0959 if (++p == q)
0960 return NULL;
0961 timing->ready = SPEED_CVT(*p);
0962 timing->rdyscale = exponent[scale & 7];
0963 } else
0964 timing->ready = 0;
0965 scale >>= 3;
0966 if (scale != 7) {
0967 if (++p == q)
0968 return NULL;
0969 timing->reserved = SPEED_CVT(*p);
0970 timing->rsvscale = exponent[scale];
0971 } else
0972 timing->reserved = 0;
0973 p++;
0974 return p;
0975 }
0976
0977
0978 static u_char *parse_io(u_char *p, u_char *q, cistpl_io_t *io)
0979 {
0980 int i, j, bsz, lsz;
0981
0982 if (p == q)
0983 return NULL;
0984 io->flags = *p;
0985
0986 if (!(*p & 0x80)) {
0987 io->nwin = 1;
0988 io->win[0].base = 0;
0989 io->win[0].len = (1 << (io->flags & CISTPL_IO_LINES_MASK));
0990 return p+1;
0991 }
0992
0993 if (++p == q)
0994 return NULL;
0995 io->nwin = (*p & 0x0f) + 1;
0996 bsz = (*p & 0x30) >> 4;
0997 if (bsz == 3)
0998 bsz++;
0999 lsz = (*p & 0xc0) >> 6;
1000 if (lsz == 3)
1001 lsz++;
1002 p++;
1003
1004 for (i = 0; i < io->nwin; i++) {
1005 io->win[i].base = 0;
1006 io->win[i].len = 1;
1007 for (j = 0; j < bsz; j++, p++) {
1008 if (p == q)
1009 return NULL;
1010 io->win[i].base += *p << (j*8);
1011 }
1012 for (j = 0; j < lsz; j++, p++) {
1013 if (p == q)
1014 return NULL;
1015 io->win[i].len += *p << (j*8);
1016 }
1017 }
1018 return p;
1019 }
1020
1021
1022 static u_char *parse_mem(u_char *p, u_char *q, cistpl_mem_t *mem)
1023 {
1024 int i, j, asz, lsz, has_ha;
1025 u_int len, ca, ha;
1026
1027 if (p == q)
1028 return NULL;
1029
1030 mem->nwin = (*p & 0x07) + 1;
1031 lsz = (*p & 0x18) >> 3;
1032 asz = (*p & 0x60) >> 5;
1033 has_ha = (*p & 0x80);
1034 if (++p == q)
1035 return NULL;
1036
1037 for (i = 0; i < mem->nwin; i++) {
1038 len = ca = ha = 0;
1039 for (j = 0; j < lsz; j++, p++) {
1040 if (p == q)
1041 return NULL;
1042 len += *p << (j*8);
1043 }
1044 for (j = 0; j < asz; j++, p++) {
1045 if (p == q)
1046 return NULL;
1047 ca += *p << (j*8);
1048 }
1049 if (has_ha)
1050 for (j = 0; j < asz; j++, p++) {
1051 if (p == q)
1052 return NULL;
1053 ha += *p << (j*8);
1054 }
1055 mem->win[i].len = len << 8;
1056 mem->win[i].card_addr = ca << 8;
1057 mem->win[i].host_addr = ha << 8;
1058 }
1059 return p;
1060 }
1061
1062
1063 static u_char *parse_irq(u_char *p, u_char *q, cistpl_irq_t *irq)
1064 {
1065 if (p == q)
1066 return NULL;
1067 irq->IRQInfo1 = *p; p++;
1068 if (irq->IRQInfo1 & IRQ_INFO2_VALID) {
1069 if (p+2 > q)
1070 return NULL;
1071 irq->IRQInfo2 = (p[1]<<8) + p[0];
1072 p += 2;
1073 }
1074 return p;
1075 }
1076
1077
1078 static int parse_cftable_entry(tuple_t *tuple,
1079 cistpl_cftable_entry_t *entry)
1080 {
1081 u_char *p, *q, features;
1082
1083 p = tuple->TupleData;
1084 q = p + tuple->TupleDataLen;
1085 entry->index = *p & 0x3f;
1086 entry->flags = 0;
1087 if (*p & 0x40)
1088 entry->flags |= CISTPL_CFTABLE_DEFAULT;
1089 if (*p & 0x80) {
1090 if (++p == q)
1091 return -EINVAL;
1092 if (*p & 0x10)
1093 entry->flags |= CISTPL_CFTABLE_BVDS;
1094 if (*p & 0x20)
1095 entry->flags |= CISTPL_CFTABLE_WP;
1096 if (*p & 0x40)
1097 entry->flags |= CISTPL_CFTABLE_RDYBSY;
1098 if (*p & 0x80)
1099 entry->flags |= CISTPL_CFTABLE_MWAIT;
1100 entry->interface = *p & 0x0f;
1101 } else
1102 entry->interface = 0;
1103
1104
1105 if (++p == q)
1106 return -EINVAL;
1107 features = *p; p++;
1108
1109
1110 if ((features & 3) > 0) {
1111 p = parse_power(p, q, &entry->vcc);
1112 if (p == NULL)
1113 return -EINVAL;
1114 } else
1115 entry->vcc.present = 0;
1116 if ((features & 3) > 1) {
1117 p = parse_power(p, q, &entry->vpp1);
1118 if (p == NULL)
1119 return -EINVAL;
1120 } else
1121 entry->vpp1.present = 0;
1122 if ((features & 3) > 2) {
1123 p = parse_power(p, q, &entry->vpp2);
1124 if (p == NULL)
1125 return -EINVAL;
1126 } else
1127 entry->vpp2.present = 0;
1128
1129
1130 if (features & 0x04) {
1131 p = parse_timing(p, q, &entry->timing);
1132 if (p == NULL)
1133 return -EINVAL;
1134 } else {
1135 entry->timing.wait = 0;
1136 entry->timing.ready = 0;
1137 entry->timing.reserved = 0;
1138 }
1139
1140
1141 if (features & 0x08) {
1142 p = parse_io(p, q, &entry->io);
1143 if (p == NULL)
1144 return -EINVAL;
1145 } else
1146 entry->io.nwin = 0;
1147
1148
1149 if (features & 0x10) {
1150 p = parse_irq(p, q, &entry->irq);
1151 if (p == NULL)
1152 return -EINVAL;
1153 } else
1154 entry->irq.IRQInfo1 = 0;
1155
1156 switch (features & 0x60) {
1157 case 0x00:
1158 entry->mem.nwin = 0;
1159 break;
1160 case 0x20:
1161 entry->mem.nwin = 1;
1162 entry->mem.win[0].len = get_unaligned_le16(p) << 8;
1163 entry->mem.win[0].card_addr = 0;
1164 entry->mem.win[0].host_addr = 0;
1165 p += 2;
1166 if (p > q)
1167 return -EINVAL;
1168 break;
1169 case 0x40:
1170 entry->mem.nwin = 1;
1171 entry->mem.win[0].len = get_unaligned_le16(p) << 8;
1172 entry->mem.win[0].card_addr = get_unaligned_le16(p + 2) << 8;
1173 entry->mem.win[0].host_addr = 0;
1174 p += 4;
1175 if (p > q)
1176 return -EINVAL;
1177 break;
1178 case 0x60:
1179 p = parse_mem(p, q, &entry->mem);
1180 if (p == NULL)
1181 return -EINVAL;
1182 break;
1183 }
1184
1185
1186 if (features & 0x80) {
1187 if (p == q)
1188 return -EINVAL;
1189 entry->flags |= (*p << 8);
1190 while (*p & 0x80)
1191 if (++p == q)
1192 return -EINVAL;
1193 p++;
1194 }
1195
1196 entry->subtuples = q-p;
1197
1198 return 0;
1199 }
1200
1201
1202 static int parse_device_geo(tuple_t *tuple, cistpl_device_geo_t *geo)
1203 {
1204 u_char *p, *q;
1205 int n;
1206
1207 p = (u_char *)tuple->TupleData;
1208 q = p + tuple->TupleDataLen;
1209
1210 for (n = 0; n < CISTPL_MAX_DEVICES; n++) {
1211 if (p > q-6)
1212 break;
1213 geo->geo[n].buswidth = p[0];
1214 geo->geo[n].erase_block = 1 << (p[1]-1);
1215 geo->geo[n].read_block = 1 << (p[2]-1);
1216 geo->geo[n].write_block = 1 << (p[3]-1);
1217 geo->geo[n].partition = 1 << (p[4]-1);
1218 geo->geo[n].interleave = 1 << (p[5]-1);
1219 p += 6;
1220 }
1221 geo->ngeo = n;
1222 return 0;
1223 }
1224
1225
1226 static int parse_vers_2(tuple_t *tuple, cistpl_vers_2_t *v2)
1227 {
1228 u_char *p, *q;
1229
1230 if (tuple->TupleDataLen < 10)
1231 return -EINVAL;
1232
1233 p = tuple->TupleData;
1234 q = p + tuple->TupleDataLen;
1235
1236 v2->vers = p[0];
1237 v2->comply = p[1];
1238 v2->dindex = get_unaligned_le16(p + 2);
1239 v2->vspec8 = p[6];
1240 v2->vspec9 = p[7];
1241 v2->nhdr = p[8];
1242 p += 9;
1243 return parse_strings(p, q, 2, v2->str, &v2->vendor, NULL);
1244 }
1245
1246
1247 static int parse_org(tuple_t *tuple, cistpl_org_t *org)
1248 {
1249 u_char *p, *q;
1250 int i;
1251
1252 p = tuple->TupleData;
1253 q = p + tuple->TupleDataLen;
1254 if (p == q)
1255 return -EINVAL;
1256 org->data_org = *p;
1257 if (++p == q)
1258 return -EINVAL;
1259 for (i = 0; i < 30; i++) {
1260 org->desc[i] = *p;
1261 if (*p == '\0')
1262 break;
1263 if (++p == q)
1264 return -EINVAL;
1265 }
1266 return 0;
1267 }
1268
1269
1270 static int parse_format(tuple_t *tuple, cistpl_format_t *fmt)
1271 {
1272 u_char *p;
1273
1274 if (tuple->TupleDataLen < 10)
1275 return -EINVAL;
1276
1277 p = tuple->TupleData;
1278
1279 fmt->type = p[0];
1280 fmt->edc = p[1];
1281 fmt->offset = get_unaligned_le32(p + 2);
1282 fmt->length = get_unaligned_le32(p + 6);
1283
1284 return 0;
1285 }
1286
1287
1288 int pcmcia_parse_tuple(tuple_t *tuple, cisparse_t *parse)
1289 {
1290 int ret = 0;
1291
1292 if (tuple->TupleDataLen > tuple->TupleDataMax)
1293 return -EINVAL;
1294 switch (tuple->TupleCode) {
1295 case CISTPL_DEVICE:
1296 case CISTPL_DEVICE_A:
1297 ret = parse_device(tuple, &parse->device);
1298 break;
1299 case CISTPL_CHECKSUM:
1300 ret = parse_checksum(tuple, &parse->checksum);
1301 break;
1302 case CISTPL_LONGLINK_A:
1303 case CISTPL_LONGLINK_C:
1304 ret = parse_longlink(tuple, &parse->longlink);
1305 break;
1306 case CISTPL_LONGLINK_MFC:
1307 ret = parse_longlink_mfc(tuple, &parse->longlink_mfc);
1308 break;
1309 case CISTPL_VERS_1:
1310 ret = parse_vers_1(tuple, &parse->version_1);
1311 break;
1312 case CISTPL_ALTSTR:
1313 ret = parse_altstr(tuple, &parse->altstr);
1314 break;
1315 case CISTPL_JEDEC_A:
1316 case CISTPL_JEDEC_C:
1317 ret = parse_jedec(tuple, &parse->jedec);
1318 break;
1319 case CISTPL_MANFID:
1320 ret = parse_manfid(tuple, &parse->manfid);
1321 break;
1322 case CISTPL_FUNCID:
1323 ret = parse_funcid(tuple, &parse->funcid);
1324 break;
1325 case CISTPL_FUNCE:
1326 ret = parse_funce(tuple, &parse->funce);
1327 break;
1328 case CISTPL_CONFIG:
1329 ret = parse_config(tuple, &parse->config);
1330 break;
1331 case CISTPL_CFTABLE_ENTRY:
1332 ret = parse_cftable_entry(tuple, &parse->cftable_entry);
1333 break;
1334 case CISTPL_DEVICE_GEO:
1335 case CISTPL_DEVICE_GEO_A:
1336 ret = parse_device_geo(tuple, &parse->device_geo);
1337 break;
1338 case CISTPL_VERS_2:
1339 ret = parse_vers_2(tuple, &parse->vers_2);
1340 break;
1341 case CISTPL_ORG:
1342 ret = parse_org(tuple, &parse->org);
1343 break;
1344 case CISTPL_FORMAT:
1345 case CISTPL_FORMAT_A:
1346 ret = parse_format(tuple, &parse->format);
1347 break;
1348 case CISTPL_NO_LINK:
1349 case CISTPL_LINKTARGET:
1350 ret = 0;
1351 break;
1352 default:
1353 ret = -EINVAL;
1354 break;
1355 }
1356 if (ret)
1357 pr_debug("parse_tuple failed %d\n", ret);
1358 return ret;
1359 }
1360 EXPORT_SYMBOL(pcmcia_parse_tuple);
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376 int pccard_validate_cis(struct pcmcia_socket *s, unsigned int *info)
1377 {
1378 tuple_t *tuple;
1379 cisparse_t *p;
1380 unsigned int count = 0;
1381 int ret, reserved, dev_ok = 0, ident_ok = 0;
1382
1383 if (!s)
1384 return -EINVAL;
1385
1386 if (s->functions || !(s->state & SOCKET_PRESENT)) {
1387 WARN_ON(1);
1388 return -EINVAL;
1389 }
1390
1391
1392 mutex_lock(&s->ops_mutex);
1393 destroy_cis_cache(s);
1394 mutex_unlock(&s->ops_mutex);
1395
1396 tuple = kmalloc(sizeof(*tuple), GFP_KERNEL);
1397 if (tuple == NULL) {
1398 dev_warn(&s->dev, "no memory to validate CIS\n");
1399 return -ENOMEM;
1400 }
1401 p = kmalloc(sizeof(*p), GFP_KERNEL);
1402 if (p == NULL) {
1403 kfree(tuple);
1404 dev_warn(&s->dev, "no memory to validate CIS\n");
1405 return -ENOMEM;
1406 }
1407
1408 count = reserved = 0;
1409 tuple->DesiredTuple = RETURN_FIRST_TUPLE;
1410 tuple->Attributes = TUPLE_RETURN_COMMON;
1411 ret = pccard_get_first_tuple(s, BIND_FN_ALL, tuple);
1412 if (ret != 0)
1413 goto done;
1414
1415
1416
1417 if ((tuple->TupleCode == CISTPL_DEVICE) ||
1418 (!pccard_read_tuple(s, BIND_FN_ALL, CISTPL_CFTABLE_ENTRY, p)) ||
1419 (!pccard_read_tuple(s, BIND_FN_ALL, CISTPL_CFTABLE_ENTRY_CB, p)))
1420 dev_ok++;
1421
1422
1423
1424
1425 if ((pccard_read_tuple(s, BIND_FN_ALL, CISTPL_MANFID, p) == 0) ||
1426 (pccard_read_tuple(s, BIND_FN_ALL, CISTPL_VERS_1, p) == 0) ||
1427 (pccard_read_tuple(s, BIND_FN_ALL, CISTPL_VERS_2, p) != -ENOSPC))
1428 ident_ok++;
1429
1430 if (!dev_ok && !ident_ok)
1431 goto done;
1432
1433 for (count = 1; count < MAX_TUPLES; count++) {
1434 ret = pccard_get_next_tuple(s, BIND_FN_ALL, tuple);
1435 if (ret != 0)
1436 break;
1437 if (((tuple->TupleCode > 0x23) && (tuple->TupleCode < 0x40)) ||
1438 ((tuple->TupleCode > 0x47) && (tuple->TupleCode < 0x80)) ||
1439 ((tuple->TupleCode > 0x90) && (tuple->TupleCode < 0xff)))
1440 reserved++;
1441 }
1442 if ((count == MAX_TUPLES) || (reserved > 5) ||
1443 ((!dev_ok || !ident_ok) && (count > 10)))
1444 count = 0;
1445
1446 ret = 0;
1447
1448 done:
1449
1450 if (!dev_ok || !ident_ok || !count) {
1451 mutex_lock(&s->ops_mutex);
1452 destroy_cis_cache(s);
1453 mutex_unlock(&s->ops_mutex);
1454
1455
1456
1457 if (!dev_ok || !ident_ok)
1458 ret = -EIO;
1459 else
1460 ret = -EFAULT;
1461 }
1462
1463 if (info)
1464 *info = count;
1465 kfree(tuple);
1466 kfree(p);
1467 return ret;
1468 }
1469
1470
1471 #define to_socket(_dev) container_of(_dev, struct pcmcia_socket, dev)
1472
1473 static ssize_t pccard_extract_cis(struct pcmcia_socket *s, char *buf,
1474 loff_t off, size_t count)
1475 {
1476 tuple_t tuple;
1477 int status, i;
1478 loff_t pointer = 0;
1479 ssize_t ret = 0;
1480 u_char *tuplebuffer;
1481 u_char *tempbuffer;
1482
1483 tuplebuffer = kmalloc_array(256, sizeof(u_char), GFP_KERNEL);
1484 if (!tuplebuffer)
1485 return -ENOMEM;
1486
1487 tempbuffer = kmalloc_array(258, sizeof(u_char), GFP_KERNEL);
1488 if (!tempbuffer) {
1489 ret = -ENOMEM;
1490 goto free_tuple;
1491 }
1492
1493 memset(&tuple, 0, sizeof(tuple_t));
1494
1495 tuple.Attributes = TUPLE_RETURN_LINK | TUPLE_RETURN_COMMON;
1496 tuple.DesiredTuple = RETURN_FIRST_TUPLE;
1497 tuple.TupleOffset = 0;
1498
1499 status = pccard_get_first_tuple(s, BIND_FN_ALL, &tuple);
1500 while (!status) {
1501 tuple.TupleData = tuplebuffer;
1502 tuple.TupleDataMax = 255;
1503 memset(tuplebuffer, 0, sizeof(u_char) * 255);
1504
1505 status = pccard_get_tuple_data(s, &tuple);
1506 if (status)
1507 break;
1508
1509 if (off < (pointer + 2 + tuple.TupleDataLen)) {
1510 tempbuffer[0] = tuple.TupleCode & 0xff;
1511 tempbuffer[1] = tuple.TupleLink & 0xff;
1512 for (i = 0; i < tuple.TupleDataLen; i++)
1513 tempbuffer[i + 2] = tuplebuffer[i] & 0xff;
1514
1515 for (i = 0; i < (2 + tuple.TupleDataLen); i++) {
1516 if (((i + pointer) >= off) &&
1517 (i + pointer) < (off + count)) {
1518 buf[ret] = tempbuffer[i];
1519 ret++;
1520 }
1521 }
1522 }
1523
1524 pointer += 2 + tuple.TupleDataLen;
1525
1526 if (pointer >= (off + count))
1527 break;
1528
1529 if (tuple.TupleCode == CISTPL_END)
1530 break;
1531 status = pccard_get_next_tuple(s, BIND_FN_ALL, &tuple);
1532 }
1533
1534 kfree(tempbuffer);
1535 free_tuple:
1536 kfree(tuplebuffer);
1537
1538 return ret;
1539 }
1540
1541
1542 static ssize_t pccard_show_cis(struct file *filp, struct kobject *kobj,
1543 struct bin_attribute *bin_attr,
1544 char *buf, loff_t off, size_t count)
1545 {
1546 unsigned int size = 0x200;
1547
1548 if (off >= size)
1549 count = 0;
1550 else {
1551 struct pcmcia_socket *s;
1552 unsigned int chains = 1;
1553
1554 if (off + count > size)
1555 count = size - off;
1556
1557 s = to_socket(kobj_to_dev(kobj));
1558
1559 if (!(s->state & SOCKET_PRESENT))
1560 return -ENODEV;
1561 if (!s->functions && pccard_validate_cis(s, &chains))
1562 return -EIO;
1563 if (!chains)
1564 return -ENODATA;
1565
1566 count = pccard_extract_cis(s, buf, off, count);
1567 }
1568
1569 return count;
1570 }
1571
1572
1573 static ssize_t pccard_store_cis(struct file *filp, struct kobject *kobj,
1574 struct bin_attribute *bin_attr,
1575 char *buf, loff_t off, size_t count)
1576 {
1577 struct pcmcia_socket *s;
1578 int error;
1579
1580 error = security_locked_down(LOCKDOWN_PCMCIA_CIS);
1581 if (error)
1582 return error;
1583
1584 s = to_socket(kobj_to_dev(kobj));
1585
1586 if (off)
1587 return -EINVAL;
1588
1589 if (count >= CISTPL_MAX_CIS_SIZE)
1590 return -EINVAL;
1591
1592 if (!(s->state & SOCKET_PRESENT))
1593 return -ENODEV;
1594
1595 error = pcmcia_replace_cis(s, buf, count);
1596 if (error)
1597 return -EIO;
1598
1599 pcmcia_parse_uevents(s, PCMCIA_UEVENT_REQUERY);
1600
1601 return count;
1602 }
1603
1604
1605 const struct bin_attribute pccard_cis_attr = {
1606 .attr = { .name = "cis", .mode = S_IRUGO | S_IWUSR },
1607 .size = 0x200,
1608 .read = pccard_show_cis,
1609 .write = pccard_store_cis,
1610 };