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