cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

cistpl.c (35934B)


      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 <pcmcia/ds.h>
     32#include "cs_internal.h"
     33
     34static const u_char mantissa[] = {
     35    10, 12, 13, 15, 20, 25, 30, 35,
     36    40, 45, 50, 55, 60, 70, 80, 90
     37};
     38
     39static const u_int exponent[] = {
     40    1, 10, 100, 1000, 10000, 100000, 1000000, 10000000
     41};
     42
     43/* Convert an extended speed byte to a time in nanoseconds */
     44#define SPEED_CVT(v) \
     45    (mantissa[(((v)>>3)&15)-1] * exponent[(v)&7] / 10)
     46/* Convert a power byte to a current in 0.1 microamps */
     47#define POWER_CVT(v) \
     48    (mantissa[((v)>>3)&15] * exponent[(v)&7] / 10)
     49#define POWER_SCALE(v)		(exponent[(v)&7])
     50
     51/* Upper limit on reasonable # of tuples */
     52#define MAX_TUPLES		200
     53
     54/* Bits in IRQInfo1 field */
     55#define IRQ_INFO2_VALID		0x10
     56
     57/* 16-bit CIS? */
     58static int cis_width;
     59module_param(cis_width, int, 0444);
     60
     61void release_cis_mem(struct pcmcia_socket *s)
     62{
     63	mutex_lock(&s->ops_mutex);
     64	if (s->cis_mem.flags & MAP_ACTIVE) {
     65		s->cis_mem.flags &= ~MAP_ACTIVE;
     66		s->ops->set_mem_map(s, &s->cis_mem);
     67		if (s->cis_mem.res) {
     68			release_resource(s->cis_mem.res);
     69			kfree(s->cis_mem.res);
     70			s->cis_mem.res = NULL;
     71		}
     72		iounmap(s->cis_virt);
     73		s->cis_virt = NULL;
     74	}
     75	mutex_unlock(&s->ops_mutex);
     76}
     77
     78/*
     79 * set_cis_map() - map the card memory at "card_offset" into virtual space.
     80 *
     81 * If flags & MAP_ATTRIB, map the attribute space, otherwise
     82 * map the memory space.
     83 *
     84 * Must be called with ops_mutex held.
     85 */
     86static void __iomem *set_cis_map(struct pcmcia_socket *s,
     87				unsigned int card_offset, unsigned int flags)
     88{
     89	pccard_mem_map *mem = &s->cis_mem;
     90	int ret;
     91
     92	if (!(s->features & SS_CAP_STATIC_MAP) && (mem->res == NULL)) {
     93		mem->res = pcmcia_find_mem_region(0, s->map_size,
     94						s->map_size, 0, s);
     95		if (mem->res == NULL) {
     96			dev_notice(&s->dev, "cs: unable to map card memory!\n");
     97			return NULL;
     98		}
     99		s->cis_virt = NULL;
    100	}
    101
    102	if (!(s->features & SS_CAP_STATIC_MAP) && (!s->cis_virt))
    103		s->cis_virt = ioremap(mem->res->start, s->map_size);
    104
    105	mem->card_start = card_offset;
    106	mem->flags = flags;
    107
    108	ret = s->ops->set_mem_map(s, mem);
    109	if (ret) {
    110		iounmap(s->cis_virt);
    111		s->cis_virt = NULL;
    112		return NULL;
    113	}
    114
    115	if (s->features & SS_CAP_STATIC_MAP) {
    116		if (s->cis_virt)
    117			iounmap(s->cis_virt);
    118		s->cis_virt = ioremap(mem->static_start, s->map_size);
    119	}
    120
    121	return s->cis_virt;
    122}
    123
    124
    125/* Bits in attr field */
    126#define IS_ATTR		1
    127#define IS_INDIRECT	8
    128
    129/*
    130 * pcmcia_read_cis_mem() - low-level function to read CIS memory
    131 *
    132 * must be called with ops_mutex held
    133 */
    134int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
    135		 u_int len, void *ptr)
    136{
    137	void __iomem *sys, *end;
    138	unsigned char *buf = ptr;
    139
    140	dev_dbg(&s->dev, "pcmcia_read_cis_mem(%d, %#x, %u)\n", attr, addr, len);
    141
    142	if (attr & IS_INDIRECT) {
    143		/* Indirect accesses use a bunch of special registers at fixed
    144		   locations in common memory */
    145		u_char flags = ICTRL0_COMMON|ICTRL0_AUTOINC|ICTRL0_BYTEGRAN;
    146		if (attr & IS_ATTR) {
    147			addr *= 2;
    148			flags = ICTRL0_AUTOINC;
    149		}
    150
    151		sys = set_cis_map(s, 0, MAP_ACTIVE |
    152				((cis_width) ? MAP_16BIT : 0));
    153		if (!sys) {
    154			dev_dbg(&s->dev, "could not map memory\n");
    155			memset(ptr, 0xff, len);
    156			return -1;
    157		}
    158
    159		writeb(flags, sys+CISREG_ICTRL0);
    160		writeb(addr & 0xff, sys+CISREG_IADDR0);
    161		writeb((addr>>8) & 0xff, sys+CISREG_IADDR1);
    162		writeb((addr>>16) & 0xff, sys+CISREG_IADDR2);
    163		writeb((addr>>24) & 0xff, sys+CISREG_IADDR3);
    164		for ( ; len > 0; len--, buf++)
    165			*buf = readb(sys+CISREG_IDATA0);
    166	} else {
    167		u_int inc = 1, card_offset, flags;
    168
    169		if (addr > CISTPL_MAX_CIS_SIZE) {
    170			dev_dbg(&s->dev,
    171				"attempt to read CIS mem at addr %#x", addr);
    172			memset(ptr, 0xff, len);
    173			return -1;
    174		}
    175
    176		flags = MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0);
    177		if (attr) {
    178			flags |= MAP_ATTRIB;
    179			inc++;
    180			addr *= 2;
    181		}
    182
    183		card_offset = addr & ~(s->map_size-1);
    184		while (len) {
    185			sys = set_cis_map(s, card_offset, flags);
    186			if (!sys) {
    187				dev_dbg(&s->dev, "could not map memory\n");
    188				memset(ptr, 0xff, len);
    189				return -1;
    190			}
    191			end = sys + s->map_size;
    192			sys = sys + (addr & (s->map_size-1));
    193			for ( ; len > 0; len--, buf++, sys += inc) {
    194				if (sys == end)
    195					break;
    196				*buf = readb(sys);
    197			}
    198			card_offset += s->map_size;
    199			addr = 0;
    200		}
    201	}
    202	dev_dbg(&s->dev, "  %#2.2x %#2.2x %#2.2x %#2.2x ...\n",
    203		*(u_char *)(ptr+0), *(u_char *)(ptr+1),
    204		*(u_char *)(ptr+2), *(u_char *)(ptr+3));
    205	return 0;
    206}
    207
    208
    209/*
    210 * pcmcia_write_cis_mem() - low-level function to write CIS memory
    211 *
    212 * Probably only useful for writing one-byte registers. Must be called
    213 * with ops_mutex held.
    214 */
    215int pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
    216		   u_int len, void *ptr)
    217{
    218	void __iomem *sys, *end;
    219	unsigned char *buf = ptr;
    220
    221	dev_dbg(&s->dev,
    222		"pcmcia_write_cis_mem(%d, %#x, %u)\n", attr, addr, len);
    223
    224	if (attr & IS_INDIRECT) {
    225		/* Indirect accesses use a bunch of special registers at fixed
    226		   locations in common memory */
    227		u_char flags = ICTRL0_COMMON|ICTRL0_AUTOINC|ICTRL0_BYTEGRAN;
    228		if (attr & IS_ATTR) {
    229			addr *= 2;
    230			flags = ICTRL0_AUTOINC;
    231		}
    232
    233		sys = set_cis_map(s, 0, MAP_ACTIVE |
    234				((cis_width) ? MAP_16BIT : 0));
    235		if (!sys) {
    236			dev_dbg(&s->dev, "could not map memory\n");
    237			return -EINVAL;
    238		}
    239
    240		writeb(flags, sys+CISREG_ICTRL0);
    241		writeb(addr & 0xff, sys+CISREG_IADDR0);
    242		writeb((addr>>8) & 0xff, sys+CISREG_IADDR1);
    243		writeb((addr>>16) & 0xff, sys+CISREG_IADDR2);
    244		writeb((addr>>24) & 0xff, sys+CISREG_IADDR3);
    245		for ( ; len > 0; len--, buf++)
    246			writeb(*buf, sys+CISREG_IDATA0);
    247	} else {
    248		u_int inc = 1, card_offset, flags;
    249
    250		flags = MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0);
    251		if (attr & IS_ATTR) {
    252			flags |= MAP_ATTRIB;
    253			inc++;
    254			addr *= 2;
    255		}
    256
    257		card_offset = addr & ~(s->map_size-1);
    258		while (len) {
    259			sys = set_cis_map(s, card_offset, flags);
    260			if (!sys) {
    261				dev_dbg(&s->dev, "could not map memory\n");
    262				return -EINVAL;
    263			}
    264
    265			end = sys + s->map_size;
    266			sys = sys + (addr & (s->map_size-1));
    267			for ( ; len > 0; len--, buf++, sys += inc) {
    268				if (sys == end)
    269					break;
    270				writeb(*buf, sys);
    271			}
    272			card_offset += s->map_size;
    273			addr = 0;
    274		}
    275	}
    276	return 0;
    277}
    278
    279
    280/*
    281 * read_cis_cache() - read CIS memory or its associated cache
    282 *
    283 * This is a wrapper around read_cis_mem, with the same interface,
    284 * but which caches information, for cards whose CIS may not be
    285 * readable all the time.
    286 */
    287static int read_cis_cache(struct pcmcia_socket *s, int attr, u_int addr,
    288			size_t len, void *ptr)
    289{
    290	struct cis_cache_entry *cis;
    291	int ret = 0;
    292
    293	if (s->state & SOCKET_CARDBUS)
    294		return -EINVAL;
    295
    296	mutex_lock(&s->ops_mutex);
    297	if (s->fake_cis) {
    298		if (s->fake_cis_len >= addr+len)
    299			memcpy(ptr, s->fake_cis+addr, len);
    300		else {
    301			memset(ptr, 0xff, len);
    302			ret = -EINVAL;
    303		}
    304		mutex_unlock(&s->ops_mutex);
    305		return ret;
    306	}
    307
    308	list_for_each_entry(cis, &s->cis_cache, node) {
    309		if (cis->addr == addr && cis->len == len && cis->attr == attr) {
    310			memcpy(ptr, cis->cache, len);
    311			mutex_unlock(&s->ops_mutex);
    312			return 0;
    313		}
    314	}
    315
    316	ret = pcmcia_read_cis_mem(s, attr, addr, len, ptr);
    317
    318	if (ret == 0) {
    319		/* Copy data into the cache */
    320		cis = kmalloc(sizeof(struct cis_cache_entry) + len, GFP_KERNEL);
    321		if (cis) {
    322			cis->addr = addr;
    323			cis->len = len;
    324			cis->attr = attr;
    325			memcpy(cis->cache, ptr, len);
    326			list_add(&cis->node, &s->cis_cache);
    327		}
    328	}
    329	mutex_unlock(&s->ops_mutex);
    330
    331	return ret;
    332}
    333
    334static void
    335remove_cis_cache(struct pcmcia_socket *s, int attr, u_int addr, u_int len)
    336{
    337	struct cis_cache_entry *cis;
    338
    339	mutex_lock(&s->ops_mutex);
    340	list_for_each_entry(cis, &s->cis_cache, node)
    341		if (cis->addr == addr && cis->len == len && cis->attr == attr) {
    342			list_del(&cis->node);
    343			kfree(cis);
    344			break;
    345		}
    346	mutex_unlock(&s->ops_mutex);
    347}
    348
    349/**
    350 * destroy_cis_cache() - destroy the CIS cache
    351 * @s:		pcmcia_socket for which CIS cache shall be destroyed
    352 *
    353 * This destroys the CIS cache but keeps any fake CIS alive. Must be
    354 * called with ops_mutex held.
    355 */
    356void destroy_cis_cache(struct pcmcia_socket *s)
    357{
    358	struct list_head *l, *n;
    359	struct cis_cache_entry *cis;
    360
    361	list_for_each_safe(l, n, &s->cis_cache) {
    362		cis = list_entry(l, struct cis_cache_entry, node);
    363		list_del(&cis->node);
    364		kfree(cis);
    365	}
    366}
    367
    368/*
    369 * verify_cis_cache() - does the CIS match what is in the CIS cache?
    370 */
    371int verify_cis_cache(struct pcmcia_socket *s)
    372{
    373	struct cis_cache_entry *cis;
    374	char *buf;
    375	int ret;
    376
    377	if (s->state & SOCKET_CARDBUS)
    378		return -EINVAL;
    379
    380	buf = kmalloc(256, GFP_KERNEL);
    381	if (buf == NULL) {
    382		dev_warn(&s->dev, "no memory for verifying CIS\n");
    383		return -ENOMEM;
    384	}
    385	mutex_lock(&s->ops_mutex);
    386	list_for_each_entry(cis, &s->cis_cache, node) {
    387		int len = cis->len;
    388
    389		if (len > 256)
    390			len = 256;
    391
    392		ret = pcmcia_read_cis_mem(s, cis->attr, cis->addr, len, buf);
    393		if (ret || memcmp(buf, cis->cache, len) != 0) {
    394			kfree(buf);
    395			mutex_unlock(&s->ops_mutex);
    396			return -1;
    397		}
    398	}
    399	kfree(buf);
    400	mutex_unlock(&s->ops_mutex);
    401	return 0;
    402}
    403
    404/*
    405 * pcmcia_replace_cis() - use a replacement CIS instead of the card's CIS
    406 *
    407 * For really bad cards, we provide a facility for uploading a
    408 * replacement CIS.
    409 */
    410int pcmcia_replace_cis(struct pcmcia_socket *s,
    411		       const u8 *data, const size_t len)
    412{
    413	if (len > CISTPL_MAX_CIS_SIZE) {
    414		dev_warn(&s->dev, "replacement CIS too big\n");
    415		return -EINVAL;
    416	}
    417	mutex_lock(&s->ops_mutex);
    418	kfree(s->fake_cis);
    419	s->fake_cis = kmalloc(len, GFP_KERNEL);
    420	if (s->fake_cis == NULL) {
    421		dev_warn(&s->dev, "no memory to replace CIS\n");
    422		mutex_unlock(&s->ops_mutex);
    423		return -ENOMEM;
    424	}
    425	s->fake_cis_len = len;
    426	memcpy(s->fake_cis, data, len);
    427	dev_info(&s->dev, "Using replacement CIS\n");
    428	mutex_unlock(&s->ops_mutex);
    429	return 0;
    430}
    431
    432/* The high-level CIS tuple services */
    433
    434struct tuple_flags {
    435	u_int		link_space:4;
    436	u_int		has_link:1;
    437	u_int		mfc_fn:3;
    438	u_int		space:4;
    439};
    440
    441#define LINK_SPACE(f)	(((struct tuple_flags *)(&(f)))->link_space)
    442#define HAS_LINK(f)	(((struct tuple_flags *)(&(f)))->has_link)
    443#define MFC_FN(f)	(((struct tuple_flags *)(&(f)))->mfc_fn)
    444#define SPACE(f)	(((struct tuple_flags *)(&(f)))->space)
    445
    446int pccard_get_first_tuple(struct pcmcia_socket *s, unsigned int function,
    447			tuple_t *tuple)
    448{
    449	if (!s)
    450		return -EINVAL;
    451
    452	if (!(s->state & SOCKET_PRESENT) || (s->state & SOCKET_CARDBUS))
    453		return -ENODEV;
    454	tuple->TupleLink = tuple->Flags = 0;
    455
    456	/* Assume presence of a LONGLINK_C to address 0 */
    457	tuple->CISOffset = tuple->LinkOffset = 0;
    458	SPACE(tuple->Flags) = HAS_LINK(tuple->Flags) = 1;
    459
    460	if ((s->functions > 1) && !(tuple->Attributes & TUPLE_RETURN_COMMON)) {
    461		cisdata_t req = tuple->DesiredTuple;
    462		tuple->DesiredTuple = CISTPL_LONGLINK_MFC;
    463		if (pccard_get_next_tuple(s, function, tuple) == 0) {
    464			tuple->DesiredTuple = CISTPL_LINKTARGET;
    465			if (pccard_get_next_tuple(s, function, tuple) != 0)
    466				return -ENOSPC;
    467		} else
    468			tuple->CISOffset = tuple->TupleLink = 0;
    469		tuple->DesiredTuple = req;
    470	}
    471	return pccard_get_next_tuple(s, function, tuple);
    472}
    473
    474static int follow_link(struct pcmcia_socket *s, tuple_t *tuple)
    475{
    476	u_char link[5];
    477	u_int ofs;
    478	int ret;
    479
    480	if (MFC_FN(tuple->Flags)) {
    481		/* Get indirect link from the MFC tuple */
    482		ret = read_cis_cache(s, LINK_SPACE(tuple->Flags),
    483				tuple->LinkOffset, 5, link);
    484		if (ret)
    485			return -1;
    486		ofs = get_unaligned_le32(link + 1);
    487		SPACE(tuple->Flags) = (link[0] == CISTPL_MFC_ATTR);
    488		/* Move to the next indirect link */
    489		tuple->LinkOffset += 5;
    490		MFC_FN(tuple->Flags)--;
    491	} else if (HAS_LINK(tuple->Flags)) {
    492		ofs = tuple->LinkOffset;
    493		SPACE(tuple->Flags) = LINK_SPACE(tuple->Flags);
    494		HAS_LINK(tuple->Flags) = 0;
    495	} else
    496		return -1;
    497
    498	if (SPACE(tuple->Flags)) {
    499		/* This is ugly, but a common CIS error is to code the long
    500		   link offset incorrectly, so we check the right spot... */
    501		ret = read_cis_cache(s, SPACE(tuple->Flags), ofs, 5, link);
    502		if (ret)
    503			return -1;
    504		if ((link[0] == CISTPL_LINKTARGET) && (link[1] >= 3) &&
    505			(strncmp(link+2, "CIS", 3) == 0))
    506			return ofs;
    507		remove_cis_cache(s, SPACE(tuple->Flags), ofs, 5);
    508		/* Then, we try the wrong spot... */
    509		ofs = ofs >> 1;
    510	}
    511	ret = read_cis_cache(s, SPACE(tuple->Flags), ofs, 5, link);
    512	if (ret)
    513		return -1;
    514	if ((link[0] == CISTPL_LINKTARGET) && (link[1] >= 3) &&
    515		(strncmp(link+2, "CIS", 3) == 0))
    516		return ofs;
    517	remove_cis_cache(s, SPACE(tuple->Flags), ofs, 5);
    518	return -1;
    519}
    520
    521int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function,
    522			tuple_t *tuple)
    523{
    524	u_char link[2], tmp;
    525	int ofs, i, attr;
    526	int ret;
    527
    528	if (!s)
    529		return -EINVAL;
    530	if (!(s->state & SOCKET_PRESENT) || (s->state & SOCKET_CARDBUS))
    531		return -ENODEV;
    532
    533	link[1] = tuple->TupleLink;
    534	ofs = tuple->CISOffset + tuple->TupleLink;
    535	attr = SPACE(tuple->Flags);
    536
    537	for (i = 0; i < MAX_TUPLES; i++) {
    538		if (link[1] == 0xff)
    539			link[0] = CISTPL_END;
    540		else {
    541			ret = read_cis_cache(s, attr, ofs, 2, link);
    542			if (ret)
    543				return -1;
    544			if (link[0] == CISTPL_NULL) {
    545				ofs++;
    546				continue;
    547			}
    548		}
    549
    550		/* End of chain?  Follow long link if possible */
    551		if (link[0] == CISTPL_END) {
    552			ofs = follow_link(s, tuple);
    553			if (ofs < 0)
    554				return -ENOSPC;
    555			attr = SPACE(tuple->Flags);
    556			ret = read_cis_cache(s, attr, ofs, 2, link);
    557			if (ret)
    558				return -1;
    559		}
    560
    561		/* Is this a link tuple?  Make a note of it */
    562		if ((link[0] == CISTPL_LONGLINK_A) ||
    563			(link[0] == CISTPL_LONGLINK_C) ||
    564			(link[0] == CISTPL_LONGLINK_MFC) ||
    565			(link[0] == CISTPL_LINKTARGET) ||
    566			(link[0] == CISTPL_INDIRECT) ||
    567			(link[0] == CISTPL_NO_LINK)) {
    568			switch (link[0]) {
    569			case CISTPL_LONGLINK_A:
    570				HAS_LINK(tuple->Flags) = 1;
    571				LINK_SPACE(tuple->Flags) = attr | IS_ATTR;
    572				ret = read_cis_cache(s, attr, ofs+2, 4,
    573						&tuple->LinkOffset);
    574				if (ret)
    575					return -1;
    576				break;
    577			case CISTPL_LONGLINK_C:
    578				HAS_LINK(tuple->Flags) = 1;
    579				LINK_SPACE(tuple->Flags) = attr & ~IS_ATTR;
    580				ret = read_cis_cache(s, attr, ofs+2, 4,
    581						&tuple->LinkOffset);
    582				if (ret)
    583					return -1;
    584				break;
    585			case CISTPL_INDIRECT:
    586				HAS_LINK(tuple->Flags) = 1;
    587				LINK_SPACE(tuple->Flags) = IS_ATTR |
    588					IS_INDIRECT;
    589				tuple->LinkOffset = 0;
    590				break;
    591			case CISTPL_LONGLINK_MFC:
    592				tuple->LinkOffset = ofs + 3;
    593				LINK_SPACE(tuple->Flags) = attr;
    594				if (function == BIND_FN_ALL) {
    595					/* Follow all the MFC links */
    596					ret = read_cis_cache(s, attr, ofs+2,
    597							1, &tmp);
    598					if (ret)
    599						return -1;
    600					MFC_FN(tuple->Flags) = tmp;
    601				} else {
    602					/* Follow exactly one of the links */
    603					MFC_FN(tuple->Flags) = 1;
    604					tuple->LinkOffset += function * 5;
    605				}
    606				break;
    607			case CISTPL_NO_LINK:
    608				HAS_LINK(tuple->Flags) = 0;
    609				break;
    610			}
    611			if ((tuple->Attributes & TUPLE_RETURN_LINK) &&
    612				(tuple->DesiredTuple == RETURN_FIRST_TUPLE))
    613				break;
    614		} else
    615			if (tuple->DesiredTuple == RETURN_FIRST_TUPLE)
    616				break;
    617
    618		if (link[0] == tuple->DesiredTuple)
    619			break;
    620		ofs += link[1] + 2;
    621	}
    622	if (i == MAX_TUPLES) {
    623		dev_dbg(&s->dev, "cs: overrun in pcmcia_get_next_tuple\n");
    624		return -ENOSPC;
    625	}
    626
    627	tuple->TupleCode = link[0];
    628	tuple->TupleLink = link[1];
    629	tuple->CISOffset = ofs + 2;
    630	return 0;
    631}
    632
    633int pccard_get_tuple_data(struct pcmcia_socket *s, tuple_t *tuple)
    634{
    635	u_int len;
    636	int ret;
    637
    638	if (!s)
    639		return -EINVAL;
    640
    641	if (tuple->TupleLink < tuple->TupleOffset)
    642		return -ENOSPC;
    643	len = tuple->TupleLink - tuple->TupleOffset;
    644	tuple->TupleDataLen = tuple->TupleLink;
    645	if (len == 0)
    646		return 0;
    647	ret = read_cis_cache(s, SPACE(tuple->Flags),
    648			tuple->CISOffset + tuple->TupleOffset,
    649			min(len, (u_int) tuple->TupleDataMax),
    650			tuple->TupleData);
    651	if (ret)
    652		return -1;
    653	return 0;
    654}
    655
    656
    657/* Parsing routines for individual tuples */
    658
    659static int parse_device(tuple_t *tuple, cistpl_device_t *device)
    660{
    661	int i;
    662	u_char scale;
    663	u_char *p, *q;
    664
    665	p = (u_char *)tuple->TupleData;
    666	q = p + tuple->TupleDataLen;
    667
    668	device->ndev = 0;
    669	for (i = 0; i < CISTPL_MAX_DEVICES; i++) {
    670
    671		if (*p == 0xff)
    672			break;
    673		device->dev[i].type = (*p >> 4);
    674		device->dev[i].wp = (*p & 0x08) ? 1 : 0;
    675		switch (*p & 0x07) {
    676		case 0:
    677			device->dev[i].speed = 0;
    678			break;
    679		case 1:
    680			device->dev[i].speed = 250;
    681			break;
    682		case 2:
    683			device->dev[i].speed = 200;
    684			break;
    685		case 3:
    686			device->dev[i].speed = 150;
    687			break;
    688		case 4:
    689			device->dev[i].speed = 100;
    690			break;
    691		case 7:
    692			if (++p == q)
    693				return -EINVAL;
    694			device->dev[i].speed = SPEED_CVT(*p);
    695			while (*p & 0x80)
    696				if (++p == q)
    697					return -EINVAL;
    698			break;
    699		default:
    700			return -EINVAL;
    701		}
    702
    703		if (++p == q)
    704			return -EINVAL;
    705		if (*p == 0xff)
    706			break;
    707		scale = *p & 7;
    708		if (scale == 7)
    709			return -EINVAL;
    710		device->dev[i].size = ((*p >> 3) + 1) * (512 << (scale*2));
    711		device->ndev++;
    712		if (++p == q)
    713			break;
    714	}
    715
    716	return 0;
    717}
    718
    719
    720static int parse_checksum(tuple_t *tuple, cistpl_checksum_t *csum)
    721{
    722	u_char *p;
    723	if (tuple->TupleDataLen < 5)
    724		return -EINVAL;
    725	p = (u_char *) tuple->TupleData;
    726	csum->addr = tuple->CISOffset + get_unaligned_le16(p) - 2;
    727	csum->len = get_unaligned_le16(p + 2);
    728	csum->sum = *(p + 4);
    729	return 0;
    730}
    731
    732
    733static int parse_longlink(tuple_t *tuple, cistpl_longlink_t *link)
    734{
    735	if (tuple->TupleDataLen < 4)
    736		return -EINVAL;
    737	link->addr = get_unaligned_le32(tuple->TupleData);
    738	return 0;
    739}
    740
    741
    742static int parse_longlink_mfc(tuple_t *tuple, cistpl_longlink_mfc_t *link)
    743{
    744	u_char *p;
    745	int i;
    746
    747	p = (u_char *)tuple->TupleData;
    748
    749	link->nfn = *p; p++;
    750	if (tuple->TupleDataLen <= link->nfn*5)
    751		return -EINVAL;
    752	for (i = 0; i < link->nfn; i++) {
    753		link->fn[i].space = *p; p++;
    754		link->fn[i].addr = get_unaligned_le32(p);
    755		p += 4;
    756	}
    757	return 0;
    758}
    759
    760
    761static int parse_strings(u_char *p, u_char *q, int max,
    762			 char *s, u_char *ofs, u_char *found)
    763{
    764	int i, j, ns;
    765
    766	if (p == q)
    767		return -EINVAL;
    768	ns = 0; j = 0;
    769	for (i = 0; i < max; i++) {
    770		if (*p == 0xff)
    771			break;
    772		ofs[i] = j;
    773		ns++;
    774		for (;;) {
    775			s[j++] = (*p == 0xff) ? '\0' : *p;
    776			if ((*p == '\0') || (*p == 0xff))
    777				break;
    778			if (++p == q)
    779				return -EINVAL;
    780		}
    781		if ((*p == 0xff) || (++p == q))
    782			break;
    783	}
    784	if (found) {
    785		*found = ns;
    786		return 0;
    787	}
    788
    789	return (ns == max) ? 0 : -EINVAL;
    790}
    791
    792
    793static int parse_vers_1(tuple_t *tuple, cistpl_vers_1_t *vers_1)
    794{
    795	u_char *p, *q;
    796
    797	p = (u_char *)tuple->TupleData;
    798	q = p + tuple->TupleDataLen;
    799
    800	vers_1->major = *p; p++;
    801	vers_1->minor = *p; p++;
    802	if (p >= q)
    803		return -EINVAL;
    804
    805	return parse_strings(p, q, CISTPL_VERS_1_MAX_PROD_STRINGS,
    806			vers_1->str, vers_1->ofs, &vers_1->ns);
    807}
    808
    809
    810static int parse_altstr(tuple_t *tuple, cistpl_altstr_t *altstr)
    811{
    812	u_char *p, *q;
    813
    814	p = (u_char *)tuple->TupleData;
    815	q = p + tuple->TupleDataLen;
    816
    817	return parse_strings(p, q, CISTPL_MAX_ALTSTR_STRINGS,
    818			altstr->str, altstr->ofs, &altstr->ns);
    819}
    820
    821
    822static int parse_jedec(tuple_t *tuple, cistpl_jedec_t *jedec)
    823{
    824	u_char *p, *q;
    825	int nid;
    826
    827	p = (u_char *)tuple->TupleData;
    828	q = p + tuple->TupleDataLen;
    829
    830	for (nid = 0; nid < CISTPL_MAX_DEVICES; nid++) {
    831		if (p > q-2)
    832			break;
    833		jedec->id[nid].mfr = p[0];
    834		jedec->id[nid].info = p[1];
    835		p += 2;
    836	}
    837	jedec->nid = nid;
    838	return 0;
    839}
    840
    841
    842static int parse_manfid(tuple_t *tuple, cistpl_manfid_t *m)
    843{
    844	if (tuple->TupleDataLen < 4)
    845		return -EINVAL;
    846	m->manf = get_unaligned_le16(tuple->TupleData);
    847	m->card = get_unaligned_le16(tuple->TupleData + 2);
    848	return 0;
    849}
    850
    851
    852static int parse_funcid(tuple_t *tuple, cistpl_funcid_t *f)
    853{
    854	u_char *p;
    855	if (tuple->TupleDataLen < 2)
    856		return -EINVAL;
    857	p = (u_char *)tuple->TupleData;
    858	f->func = p[0];
    859	f->sysinit = p[1];
    860	return 0;
    861}
    862
    863
    864static int parse_funce(tuple_t *tuple, cistpl_funce_t *f)
    865{
    866	u_char *p;
    867	int i;
    868	if (tuple->TupleDataLen < 1)
    869		return -EINVAL;
    870	p = (u_char *)tuple->TupleData;
    871	f->type = p[0];
    872	for (i = 1; i < tuple->TupleDataLen; i++)
    873		f->data[i-1] = p[i];
    874	return 0;
    875}
    876
    877
    878static int parse_config(tuple_t *tuple, cistpl_config_t *config)
    879{
    880	int rasz, rmsz, i;
    881	u_char *p;
    882
    883	p = (u_char *)tuple->TupleData;
    884	rasz = *p & 0x03;
    885	rmsz = (*p & 0x3c) >> 2;
    886	if (tuple->TupleDataLen < rasz+rmsz+4)
    887		return -EINVAL;
    888	config->last_idx = *(++p);
    889	p++;
    890	config->base = 0;
    891	for (i = 0; i <= rasz; i++)
    892		config->base += p[i] << (8*i);
    893	p += rasz+1;
    894	for (i = 0; i < 4; i++)
    895		config->rmask[i] = 0;
    896	for (i = 0; i <= rmsz; i++)
    897		config->rmask[i>>2] += p[i] << (8*(i%4));
    898	config->subtuples = tuple->TupleDataLen - (rasz+rmsz+4);
    899	return 0;
    900}
    901
    902/* The following routines are all used to parse the nightmarish
    903 * config table entries.
    904 */
    905
    906static u_char *parse_power(u_char *p, u_char *q, cistpl_power_t *pwr)
    907{
    908	int i;
    909	u_int scale;
    910
    911	if (p == q)
    912		return NULL;
    913	pwr->present = *p;
    914	pwr->flags = 0;
    915	p++;
    916	for (i = 0; i < 7; i++)
    917		if (pwr->present & (1<<i)) {
    918			if (p == q)
    919				return NULL;
    920			pwr->param[i] = POWER_CVT(*p);
    921			scale = POWER_SCALE(*p);
    922			while (*p & 0x80) {
    923				if (++p == q)
    924					return NULL;
    925				if ((*p & 0x7f) < 100)
    926					pwr->param[i] +=
    927						(*p & 0x7f) * scale / 100;
    928				else if (*p == 0x7d)
    929					pwr->flags |= CISTPL_POWER_HIGHZ_OK;
    930				else if (*p == 0x7e)
    931					pwr->param[i] = 0;
    932				else if (*p == 0x7f)
    933					pwr->flags |= CISTPL_POWER_HIGHZ_REQ;
    934				else
    935					return NULL;
    936			}
    937			p++;
    938		}
    939	return p;
    940}
    941
    942
    943static u_char *parse_timing(u_char *p, u_char *q, cistpl_timing_t *timing)
    944{
    945	u_char scale;
    946
    947	if (p == q)
    948		return NULL;
    949	scale = *p;
    950	if ((scale & 3) != 3) {
    951		if (++p == q)
    952			return NULL;
    953		timing->wait = SPEED_CVT(*p);
    954		timing->waitscale = exponent[scale & 3];
    955	} else
    956		timing->wait = 0;
    957	scale >>= 2;
    958	if ((scale & 7) != 7) {
    959		if (++p == q)
    960			return NULL;
    961		timing->ready = SPEED_CVT(*p);
    962		timing->rdyscale = exponent[scale & 7];
    963	} else
    964		timing->ready = 0;
    965	scale >>= 3;
    966	if (scale != 7) {
    967		if (++p == q)
    968			return NULL;
    969		timing->reserved = SPEED_CVT(*p);
    970		timing->rsvscale = exponent[scale];
    971	} else
    972		timing->reserved = 0;
    973	p++;
    974	return p;
    975}
    976
    977
    978static u_char *parse_io(u_char *p, u_char *q, cistpl_io_t *io)
    979{
    980	int i, j, bsz, lsz;
    981
    982	if (p == q)
    983		return NULL;
    984	io->flags = *p;
    985
    986	if (!(*p & 0x80)) {
    987		io->nwin = 1;
    988		io->win[0].base = 0;
    989		io->win[0].len = (1 << (io->flags & CISTPL_IO_LINES_MASK));
    990		return p+1;
    991	}
    992
    993	if (++p == q)
    994		return NULL;
    995	io->nwin = (*p & 0x0f) + 1;
    996	bsz = (*p & 0x30) >> 4;
    997	if (bsz == 3)
    998		bsz++;
    999	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
   1022static 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
   1063static 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
   1078static 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
   1202static 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
   1226static 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
   1247static 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
   1270static 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
   1288int 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}
   1360EXPORT_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 */
   1376int 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
   1448done:
   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
   1473static 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
   1542static 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
   1573static 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
   1605const 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};