Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * cistpl.c -- 16-bit PCMCIA Card Information Structure parser
0004  *
0005  * The initial developer of the original code is David A. Hinds
0006  * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
0007  * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
0008  *
0009  * (C) 1999     David A. Hinds
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 /* Convert an extended speed byte to a time in nanoseconds */
0044 #define SPEED_CVT(v) \
0045     (mantissa[(((v)>>3)&15)-1] * exponent[(v)&7] / 10)
0046 /* Convert a power byte to a current in 0.1 microamps */
0047 #define POWER_CVT(v) \
0048     (mantissa[((v)>>3)&15] * exponent[(v)&7] / 10)
0049 #define POWER_SCALE(v)      (exponent[(v)&7])
0050 
0051 /* Upper limit on reasonable # of tuples */
0052 #define MAX_TUPLES      200
0053 
0054 /* Bits in IRQInfo1 field */
0055 #define IRQ_INFO2_VALID     0x10
0056 
0057 /* 16-bit CIS? */
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  * set_cis_map() - map the card memory at "card_offset" into virtual space.
0080  *
0081  * If flags & MAP_ATTRIB, map the attribute space, otherwise
0082  * map the memory space.
0083  *
0084  * Must be called with ops_mutex held.
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 /* Bits in attr field */
0126 #define IS_ATTR     1
0127 #define IS_INDIRECT 8
0128 
0129 /*
0130  * pcmcia_read_cis_mem() - low-level function to read CIS memory
0131  *
0132  * must be called with ops_mutex held
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         /* Indirect accesses use a bunch of special registers at fixed
0144            locations in common memory */
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  * pcmcia_write_cis_mem() - low-level function to write CIS memory
0211  *
0212  * Probably only useful for writing one-byte registers. Must be called
0213  * with ops_mutex held.
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         /* Indirect accesses use a bunch of special registers at fixed
0226            locations in common memory */
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  * read_cis_cache() - read CIS memory or its associated cache
0282  *
0283  * This is a wrapper around read_cis_mem, with the same interface,
0284  * but which caches information, for cards whose CIS may not be
0285  * readable all the time.
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         /* Copy data into the cache */
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  * destroy_cis_cache() - destroy the CIS cache
0351  * @s:      pcmcia_socket for which CIS cache shall be destroyed
0352  *
0353  * This destroys the CIS cache but keeps any fake CIS alive. Must be
0354  * called with ops_mutex held.
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  * verify_cis_cache() - does the CIS match what is in the CIS cache?
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  * pcmcia_replace_cis() - use a replacement CIS instead of the card's CIS
0406  *
0407  * For really bad cards, we provide a facility for uploading a
0408  * replacement CIS.
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 /* The high-level CIS tuple services */
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     /* Assume presence of a LONGLINK_C to address 0 */
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         /* Get indirect link from the MFC tuple */
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         /* Move to the next indirect link */
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         /* This is ugly, but a common CIS error is to code the long
0500            link offset incorrectly, so we check the right spot... */
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         /* Then, we try the wrong spot... */
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         /* End of chain?  Follow long link if possible */
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         /* Is this a link tuple?  Make a note of it */
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                     /* Follow all the MFC links */
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                     /* Follow exactly one of the links */
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 /* Parsing routines for individual tuples */
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 /* The following routines are all used to parse the nightmarish
0903  * config table entries.
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     /* Process optional features */
1105     if (++p == q)
1106         return -EINVAL;
1107     features = *p; p++;
1108 
1109     /* Power options */
1110     if ((features & 3) > 0) {
1111         p = parse_power(p, q, &entry->vcc);
1112         if (p == NULL)
1113             return -EINVAL;
1114     } else
1115         entry->vcc.present = 0;
1116     if ((features & 3) > 1) {
1117         p = parse_power(p, q, &entry->vpp1);
1118         if (p == NULL)
1119             return -EINVAL;
1120     } else
1121         entry->vpp1.present = 0;
1122     if ((features & 3) > 2) {
1123         p = parse_power(p, q, &entry->vpp2);
1124         if (p == NULL)
1125             return -EINVAL;
1126     } else
1127         entry->vpp2.present = 0;
1128 
1129     /* Timing options */
1130     if (features & 0x04) {
1131         p = parse_timing(p, q, &entry->timing);
1132         if (p == NULL)
1133             return -EINVAL;
1134     } else {
1135         entry->timing.wait = 0;
1136         entry->timing.ready = 0;
1137         entry->timing.reserved = 0;
1138     }
1139 
1140     /* I/O window options */
1141     if (features & 0x08) {
1142         p = parse_io(p, q, &entry->io);
1143         if (p == NULL)
1144             return -EINVAL;
1145     } else
1146         entry->io.nwin = 0;
1147 
1148     /* Interrupt options */
1149     if (features & 0x10) {
1150         p = parse_irq(p, q, &entry->irq);
1151         if (p == NULL)
1152             return -EINVAL;
1153     } else
1154         entry->irq.IRQInfo1 = 0;
1155 
1156     switch (features & 0x60) {
1157     case 0x00:
1158         entry->mem.nwin = 0;
1159         break;
1160     case 0x20:
1161         entry->mem.nwin = 1;
1162         entry->mem.win[0].len = get_unaligned_le16(p) << 8;
1163         entry->mem.win[0].card_addr = 0;
1164         entry->mem.win[0].host_addr = 0;
1165         p += 2;
1166         if (p > q)
1167             return -EINVAL;
1168         break;
1169     case 0x40:
1170         entry->mem.nwin = 1;
1171         entry->mem.win[0].len = get_unaligned_le16(p) << 8;
1172         entry->mem.win[0].card_addr = get_unaligned_le16(p + 2) << 8;
1173         entry->mem.win[0].host_addr = 0;
1174         p += 4;
1175         if (p > q)
1176             return -EINVAL;
1177         break;
1178     case 0x60:
1179         p = parse_mem(p, q, &entry->mem);
1180         if (p == NULL)
1181             return -EINVAL;
1182         break;
1183     }
1184 
1185     /* Misc features */
1186     if (features & 0x80) {
1187         if (p == q)
1188             return -EINVAL;
1189         entry->flags |= (*p << 8);
1190         while (*p & 0x80)
1191             if (++p == q)
1192                 return -EINVAL;
1193         p++;
1194     }
1195 
1196     entry->subtuples = q-p;
1197 
1198     return 0;
1199 }
1200 
1201 
1202 static int parse_device_geo(tuple_t *tuple, cistpl_device_geo_t *geo)
1203 {
1204     u_char *p, *q;
1205     int n;
1206 
1207     p = (u_char *)tuple->TupleData;
1208     q = p + tuple->TupleDataLen;
1209 
1210     for (n = 0; n < CISTPL_MAX_DEVICES; n++) {
1211         if (p > q-6)
1212             break;
1213         geo->geo[n].buswidth = p[0];
1214         geo->geo[n].erase_block = 1 << (p[1]-1);
1215         geo->geo[n].read_block  = 1 << (p[2]-1);
1216         geo->geo[n].write_block = 1 << (p[3]-1);
1217         geo->geo[n].partition   = 1 << (p[4]-1);
1218         geo->geo[n].interleave  = 1 << (p[5]-1);
1219         p += 6;
1220     }
1221     geo->ngeo = n;
1222     return 0;
1223 }
1224 
1225 
1226 static int parse_vers_2(tuple_t *tuple, cistpl_vers_2_t *v2)
1227 {
1228     u_char *p, *q;
1229 
1230     if (tuple->TupleDataLen < 10)
1231         return -EINVAL;
1232 
1233     p = tuple->TupleData;
1234     q = p + tuple->TupleDataLen;
1235 
1236     v2->vers = p[0];
1237     v2->comply = p[1];
1238     v2->dindex = get_unaligned_le16(p + 2);
1239     v2->vspec8 = p[6];
1240     v2->vspec9 = p[7];
1241     v2->nhdr = p[8];
1242     p += 9;
1243     return parse_strings(p, q, 2, v2->str, &v2->vendor, NULL);
1244 }
1245 
1246 
1247 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  * pccard_validate_cis() - check whether card has a sensible CIS
1365  * @s:      the struct pcmcia_socket we are to check
1366  * @info:   returns the number of tuples in the (valid) CIS, or 0
1367  *
1368  * This tries to determine if a card has a sensible CIS.  In @info, it
1369  * returns the number of tuples in the CIS, or 0 if the CIS looks bad. The
1370  * checks include making sure several critical tuples are present and
1371  * valid; seeing if the total number of tuples is reasonable; and
1372  * looking for tuples that use reserved codes.
1373  *
1374  * The function returns 0 on success.
1375  */
1376 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     /* We do not want to validate the CIS cache... */
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     /* First tuple should be DEVICE; we should really have either that
1416        or a CFTABLE_ENTRY of some sort */
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     /* All cards should have a MANFID tuple, and/or a VERS_1 or VERS_2
1423        tuple, for card identification.  Certain old D-Link and Linksys
1424        cards have only a broken VERS_2 tuple; hence the bogus test. */
1425     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     /* invalidate CIS cache on failure */
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         /* We differentiate between dev_ok, ident_ok and count
1455            failures to allow for an override for anonymous cards
1456            in ds.c */
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 };