/*
 * cistpl.c -- 16-bit PCMCIA Card Information Structure parser
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * The initial developer of the original code is David A. Hinds
 * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
 * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
 *
 * (C) 1999		David A. Hinds
 */

#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/major.h>
#include <linux/errno.h>
#include <linux/timer.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/pci.h>
#include <linux/ioport.h>
#include <linux/io.h>
#include <asm/byteorder.h>
#include <asm/unaligned.h>

#include <pcmcia/cs_types.h>
#include <pcmcia/ss.h>
#include <pcmcia/cs.h>
#include <pcmcia/cisreg.h>
#include <pcmcia/cistpl.h>
#include "cs_internal.h"

static const u_char mantissa[] = {
    10, 12, 13, 15, 20, 25, 30, 35,
    40, 45, 50, 55, 60, 70, 80, 90
};

static const u_int exponent[] = {
    1, 10, 100, 1000, 10000, 100000, 1000000, 10000000
};

/* Convert an extended speed byte to a time in nanoseconds */
#define SPEED_CVT(v) \
    (mantissa[(((v)>>3)&15)-1] * exponent[(v)&7] / 10)
/* Convert a power byte to a current in 0.1 microamps */
#define POWER_CVT(v) \
    (mantissa[((v)>>3)&15] * exponent[(v)&7] / 10)
#define POWER_SCALE(v)		(exponent[(v)&7])

/* Upper limit on reasonable # of tuples */
#define MAX_TUPLES		200

/* 16-bit CIS? */
static int cis_width;
module_param(cis_width, int, 0444);

void release_cis_mem(struct pcmcia_socket *s)
{
	mutex_lock(&s->ops_mutex);
	if (s->cis_mem.flags & MAP_ACTIVE) {
		s->cis_mem.flags &= ~MAP_ACTIVE;
		s->ops->set_mem_map(s, &s->cis_mem);
		if (s->cis_mem.res) {
			release_resource(s->cis_mem.res);
			kfree(s->cis_mem.res);
			s->cis_mem.res = NULL;
		}
		iounmap(s->cis_virt);
		s->cis_virt = NULL;
	}
	mutex_unlock(&s->ops_mutex);
}

/**
 * set_cis_map() - map the card memory at "card_offset" into virtual space.
 *
 * If flags & MAP_ATTRIB, map the attribute space, otherwise
 * map the memory space.
 *
 * Must be called with ops_mutex held.
 */
static void __iomem *set_cis_map(struct pcmcia_socket *s,
				unsigned int card_offset, unsigned int flags)
{
	pccard_mem_map *mem = &s->cis_mem;
	int ret;

	if (!(s->features & SS_CAP_STATIC_MAP) && (mem->res == NULL)) {
		mem->res = pcmcia_find_mem_region(0, s->map_size,
						s->map_size, 0, s);
		if (mem->res == NULL) {
			dev_printk(KERN_NOTICE, &s->dev,
				   "cs: unable to map card memory!\n");
			return NULL;
		}
		s->cis_virt = NULL;
	}

	if (!(s->features & SS_CAP_STATIC_MAP) && (!s->cis_virt))
		s->cis_virt = ioremap(mem->res->start, s->map_size);

	mem->card_start = card_offset;
	mem->flags = flags;

	ret = s->ops->set_mem_map(s, mem);
	if (ret) {
		iounmap(s->cis_virt);
		s->cis_virt = NULL;
		return NULL;
	}

	if (s->features & SS_CAP_STATIC_MAP) {
		if (s->cis_virt)
			iounmap(s->cis_virt);
		s->cis_virt = ioremap(mem->static_start, s->map_size);
	}

	return s->cis_virt;
}


/* Bits in attr field */
#define IS_ATTR		1
#define IS_INDIRECT	8

/**
 * pcmcia_read_cis_mem() - low-level function to read CIS memory
 */
int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
		 u_int len, void *ptr)
{
	void __iomem *sys, *end;
	unsigned char *buf = ptr;

	dev_dbg(&s->dev, "pcmcia_read_cis_mem(%d, %#x, %u)\n", attr, addr, len);

	mutex_lock(&s->ops_mutex);
	if (attr & IS_INDIRECT) {
		/* Indirect accesses use a bunch of special registers at fixed
		   locations in common memory */
		u_char flags = ICTRL0_COMMON|ICTRL0_AUTOINC|ICTRL0_BYTEGRAN;
		if (attr & IS_ATTR) {
			addr *= 2;
			flags = ICTRL0_AUTOINC;
		}

		sys = set_cis_map(s, 0, MAP_ACTIVE |
				((cis_width) ? MAP_16BIT : 0));
		if (!sys) {
			dev_dbg(&s->dev, "could not map memory\n");
			memset(ptr, 0xff, len);
			mutex_unlock(&s->ops_mutex);
			return -1;
		}

		writeb(flags, sys+CISREG_ICTRL0);
		writeb(addr & 0xff, sys+CISREG_IADDR0);
		writeb((addr>>8) & 0xff, sys+CISREG_IADDR1);
		writeb((addr>>16) & 0xff, sys+CISREG_IADDR2);
		writeb((addr>>24) & 0xff, sys+CISREG_IADDR3);
		for ( ; len > 0; len--, buf++)
			*buf = readb(sys+CISREG_IDATA0);
	} else {
		u_int inc = 1, card_offset, flags;

		if (addr > CISTPL_MAX_CIS_SIZE)
			dev_dbg(&s->dev,
				"attempt to read CIS mem at addr %#x", addr);

		flags = MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0);
		if (attr) {
			flags |= MAP_ATTRIB;
			inc++;
			addr *= 2;
		}

		card_offset = addr & ~(s->map_size-1);
		while (len) {
			sys = set_cis_map(s, card_offset, flags);
			if (!sys) {
				dev_dbg(&s->dev, "could not map memory\n");
				memset(ptr, 0xff, len);
				mutex_unlock(&s->ops_mutex);
				return -1;
			}
			end = sys + s->map_size;
			sys = sys + (addr & (s->map_size-1));
			for ( ; len > 0; len--, buf++, sys += inc) {
				if (sys == end)
					break;
				*buf = readb(sys);
			}
			card_offset += s->map_size;
			addr = 0;
		}
	}
	mutex_unlock(&s->ops_mutex);
	dev_dbg(&s->dev, "  %#2.2x %#2.2x %#2.2x %#2.2x ...\n",
		*(u_char *)(ptr+0), *(u_char *)(ptr+1),
		*(u_char *)(ptr+2), *(u_char *)(ptr+3));
	return 0;
}


/**
 * pcmcia_write_cis_mem() - low-level function to write CIS memory
 *
 * Probably only useful for writing one-byte registers.
 */
void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
		   u_int len, void *ptr)
{
	void __iomem *sys, *end;
	unsigned char *buf = ptr;

	dev_dbg(&s->dev,
		"pcmcia_write_cis_mem(%d, %#x, %u)\n", attr, addr, len);

	mutex_lock(&s->ops_mutex);
	if (attr & IS_INDIRECT) {
		/* Indirect accesses use a bunch of special registers at fixed
		   locations in common memory */
		u_char flags = ICTRL0_COMMON|ICTRL0_AUTOINC|ICTRL0_BYTEGRAN;
		if (attr & IS_ATTR) {
			addr *= 2;
			flags = ICTRL0_AUTOINC;
		}

		sys = set_cis_map(s, 0, MAP_ACTIVE |
				((cis_width) ? MAP_16BIT : 0));
		if (!sys) {
			dev_dbg(&s->dev, "could not map memory\n");
			mutex_unlock(&s->ops_mutex);
			return; /* FIXME: Error */
		}

		writeb(flags, sys+CISREG_ICTRL0);
		writeb(addr & 0xff, sys+CISREG_IADDR0);
		writeb((addr>>8) & 0xff, sys+CISREG_IADDR1);
		writeb((addr>>16) & 0xff, sys+CISREG_IADDR2);
		writeb((addr>>24) & 0xff, sys+CISREG_IADDR3);
		for ( ; len > 0; len--, buf++)
			writeb(*buf, sys+CISREG_IDATA0);
	} else {
		u_int inc = 1, card_offset, flags;

		flags = MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0);
		if (attr & IS_ATTR) {
			flags |= MAP_ATTRIB;
			inc++;
			addr *= 2;
		}

		card_offset = addr & ~(s->map_size-1);
		while (len) {
			sys = set_cis_map(s, card_offset, flags);
			if (!sys) {
				dev_dbg(&s->dev, "could not map memory\n");
				mutex_unlock(&s->ops_mutex);
				return; /* FIXME: error */
			}

			end = sys + s->map_size;
			sys = sys + (addr & (s->map_size-1));
			for ( ; len > 0; len--, buf++, sys += inc) {
				if (sys == end)
					break;
				writeb(*buf, sys);
			}
			card_offset += s->map_size;
			addr = 0;
		}
	}
	mutex_unlock(&s->ops_mutex);
}


/**
 * read_cis_cache() - read CIS memory or its associated cache
 *
 * This is a wrapper around read_cis_mem, with the same interface,
 * but which caches information, for cards whose CIS may not be
 * readable all the time.
 */
static int read_cis_cache(struct pcmcia_socket *s, int attr, u_int addr,
			size_t len, void *ptr)
{
	struct cis_cache_entry *cis;
	int ret = 0;

	if (s->state & SOCKET_CARDBUS)
		return -EINVAL;

	mutex_lock(&s->ops_mutex);
	if (s->fake_cis) {
		if (s->fake_cis_len >= addr+len)
			memcpy(ptr, s->fake_cis+addr, len);
		else {
			memset(ptr, 0xff, len);
			ret = -EINVAL;
		}
		mutex_unlock(&s->ops_mutex);
		return ret;
	}

	list_for_each_entry(cis, &s->cis_cache, node) {
		if (cis->addr == addr && cis->len == len && cis->attr == attr) {
			memcpy(ptr, cis->cache, len);
			mutex_unlock(&s->ops_mutex);
			return 0;
		}
	}
	mutex_unlock(&s->ops_mutex);

	ret = pcmcia_read_cis_mem(s, attr, addr, len, ptr);

	if (ret == 0) {
		/* Copy data into the cache */
		cis = kmalloc(sizeof(struct cis_cache_entry) + len, GFP_KERNEL);
		if (cis) {
			cis->addr = addr;
			cis->len = len;
			cis->attr = attr;
			memcpy(cis->cache, ptr, len);
			mutex_lock(&s->ops_mutex);
			list_add(&cis->node, &s->cis_cache);
			mutex_unlock(&s->ops_mutex);
		}
	}
	return ret;
}

static void
remove_cis_cache(struct pcmcia_socket *s, int attr, u_int addr, u_int len)
{
	struct cis_cache_entry *cis;

	mutex_lock(&s->ops_mutex);
	list_for_each_entry(cis, &s->cis_cache, node)
		if (cis->addr == addr && cis->len == len && cis->attr == attr) {
			list_del(&cis->node);
			kfree(cis);
			break;
		}
	mutex_unlock(&s->ops_mutex);
}

/**
 * destroy_cis_cache() - destroy the CIS cache
 * @s:		pcmcia_socket for which CIS cache shall be destroyed
 *
 * This destroys the CIS cache but keeps any fake CIS alive. Must be
 * called with ops_mutex held.
 */
void destroy_cis_cache(struct pcmcia_socket *s)
{
	struct list_head *l, *n;
	struct cis_cache_entry *cis;

	list_for_each_safe(l, n, &s->cis_cache) {
		cis = list_entry(l, struct cis_cache_entry, node);
		list_del(&cis->node);
		kfree(cis);
	}
}

/**
 * verify_cis_cache() - does the CIS match what is in the CIS cache?
 */
int verify_cis_cache(struct pcmcia_socket *s)
{
	struct cis_cache_entry *cis;
	char *buf;
	int ret;

	if (s->state & SOCKET_CARDBUS)
		return -EINVAL;

	buf = kmalloc(256, GFP_KERNEL);
	if (buf == NULL) {
		dev_printk(KERN_WARNING, &s->dev,
			   "no memory for verifying CIS\n");
		return -ENOMEM;
	}
	list_for_each_entry(cis, &s->cis_cache, node) {
		int len = cis->len;

		if (len > 256)
			len = 256;

		ret = pcmcia_read_cis_mem(s, cis->attr, cis->addr, len, buf);
		if (ret || memcmp(buf, cis->cache, len) != 0) {
			kfree(buf);
			return -1;
		}
	}
	kfree(buf);
	return 0;
}

/**
 * pcmcia_replace_cis() - use a replacement CIS instead of the card's CIS
 *
 * For really bad cards, we provide a facility for uploading a
 * replacement CIS.
 */
int pcmcia_replace_cis(struct pcmcia_socket *s,
		       const u8 *data, const size_t len)
{
	if (len > CISTPL_MAX_CIS_SIZE) {
		dev_printk(KERN_WARNING, &s->dev, "replacement CIS too big\n");
		return -EINVAL;
	}
	mutex_lock(&s->ops_mutex);
	kfree(s->fake_cis);
	s->fake_cis = kmalloc(len, GFP_KERNEL);
	if (s->fake_cis == NULL) {
		dev_printk(KERN_WARNING, &s->dev, "no memory to replace CIS\n");
		mutex_unlock(&s->ops_mutex);
		return -ENOMEM;
	}
	s->fake_cis_len = len;
	memcpy(s->fake_cis, data, len);
	dev_info(&s->dev, "Using replacement CIS\n");
	mutex_unlock(&s->ops_mutex);
	return 0;
}

/* The high-level CIS tuple services */

typedef struct tuple_flags {
	u_int		link_space:4;
	u_int		has_link:1;
	u_int		mfc_fn:3;
	u_int		space:4;
} tuple_flags;

#define LINK_SPACE(f)	(((tuple_flags *)(&(f)))->link_space)
#define HAS_LINK(f)	(((tuple_flags *)(&(f)))->has_link)
#define MFC_FN(f)	(((tuple_flags *)(&(f)))->mfc_fn)
#define SPACE(f)	(((tuple_flags *)(&(f)))->space)

int pccard_get_first_tuple(struct pcmcia_socket *s, unsigned int function,
			tuple_t *tuple)
{
	if (!s)
		return -EINVAL;

	if (!(s->state & SOCKET_PRESENT) || (s->state & SOCKET_CARDBUS))
		return -ENODEV;
	tuple->TupleLink = tuple->Flags = 0;

	/* Assume presence of a LONGLINK_C to address 0 */
	tuple->CISOffset = tuple->LinkOffset = 0;
	SPACE(tuple->Flags) = HAS_LINK(tuple->Flags) = 1;

	if ((s->functions > 1) && !(tuple->Attributes & TUPLE_RETURN_COMMON)) {
		cisdata_t req = tuple->DesiredTuple;
		tuple->DesiredTuple = CISTPL_LONGLINK_MFC;
		if (pccard_get_next_tuple(s, function, tuple) == 0) {
			tuple->DesiredTuple = CISTPL_LINKTARGET;
			if (pccard_get_next_tuple(s, function, tuple) != 0)
				return -ENOSPC;
		} else
			tuple->CISOffset = tuple->TupleLink = 0;
		tuple->DesiredTuple = req;
	}
	return pccard_get_next_tuple(s, function, tuple);
}

static int follow_link(struct pcmcia_socket *s, tuple_t *tuple)
{
	u_char link[5];
	u_int ofs;
	int ret;

	if (MFC_FN(tuple->Flags)) {
		/* Get indirect link from the MFC tuple */
		ret = read_cis_cache(s, LINK_SPACE(tuple->Flags),
				tuple->LinkOffset, 5, link);
		if (ret)
			return -1;
		ofs = get_unaligned_le32(link + 1);
		SPACE(tuple->Flags) = (link[0] == CISTPL_MFC_ATTR);
		/* Move to the next indirect link */
		tuple->LinkOffset += 5;
		MFC_FN(tuple->Flags)--;
	} else if (HAS_LINK(tuple->Flags)) {
		ofs = tuple->LinkOffset;
		SPACE(tuple->Flags) = LINK_SPACE(tuple->Flags);
		HAS_LINK(tuple->Flags) = 0;
	} else
		return -1;

	if (SPACE(tuple->Flags)) {
		/* This is ugly, but a common CIS error is to code the long
		   link offset incorrectly, so we check the right spot... */
		ret = read_cis_cache(s, SPACE(tuple->Flags), ofs, 5, link);
		if (ret)
			return -1;
		if ((link[0] == CISTPL_LINKTARGET) && (link[1] >= 3) &&
			(strncmp(link+2, "CIS", 3) == 0))
			return ofs;
		remove_cis_cache(s, SPACE(tuple->Flags), ofs, 5);
		/* Then, we try the wrong spot... */
		ofs = ofs >> 1;
	}
	ret = read_cis_cache(s, SPACE(tuple->Flags), ofs, 5, link);
	if (ret)
		return -1;
	if ((link[0] == CISTPL_LINKTARGET) && (link[1] >= 3) &&
		(strncmp(link+2, "CIS", 3) == 0))
		return ofs;
	remove_cis_cache(s, SPACE(tuple->Flags), ofs, 5);
	return -1;
}

int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function,
			tuple_t *tuple)
{
	u_char link[2], tmp;
	int ofs, i, attr;
	int ret;

	if (!s)
		return -EINVAL;
	if (!(s->state & SOCKET_PRESENT) || (s->state & SOCKET_CARDBUS))
		return -ENODEV;

	link[1] = tuple->TupleLink;
	ofs = tuple->CISOffset + tuple->TupleLink;
	attr = SPACE(tuple->Flags);

	for (i = 0; i < MAX_TUPLES; i++) {
		if (link[1] == 0xff)
			link[0] = CISTPL_END;
		else {
			ret = read_cis_cache(s, attr, ofs, 2, link);
			if (ret)
				return -1;
			if (link[0] == CISTPL_NULL) {
				ofs++;
				continue;
			}
		}

		/* End of chain?  Follow long link if possible */
		if (link[0] == CISTPL_END) {
			ofs = follow_link(s, tuple);
			if (ofs < 0)
				return -ENOSPC;
			attr = SPACE(tuple->Flags);
			ret = read_cis_cache(s, attr, ofs, 2, link);
			if (ret)
				return -1;
		}

		/* Is this a link tuple?  Make a note of it */
		if ((link[0] == CISTPL_LONGLINK_A) ||
			(link[0] == CISTPL_LONGLINK_C) ||
			(link[0] == CISTPL_LONGLINK_MFC) ||
			(link[0] == CISTPL_LINKTARGET) ||
			(link[0] == CISTPL_INDIRECT) ||
			(link[0] == CISTPL_NO_LINK)) {
			switch (link[0]) {
			case CISTPL_LONGLINK_A:
				HAS_LINK(tuple->Flags) = 1;
				LINK_SPACE(tuple->Flags) = attr | IS_ATTR;
				ret = read_cis_cache(s, attr, ofs+2, 4,
						&tuple->LinkOffset);
				if (ret)
					return -1;
				break;
			case CISTPL_LONGLINK_C:
				HAS_LINK(tuple->Flags) = 1;
				LINK_SPACE(tuple->Flags) = attr & ~IS_ATTR;
				ret = read_cis_cache(s, attr, ofs+2, 4,
						&tuple->LinkOffset);
				if (ret)
					return -1;
				break;
			case CISTPL_INDIRECT:
				HAS_LINK(tuple->Flags) = 1;
				LINK_SPACE(tuple->Flags) = IS_ATTR |
					IS_INDIRECT;
				tuple->LinkOffset = 0;
				break;
			case CISTPL_LONGLINK_MFC:
				tuple->LinkOffset = ofs + 3;
				LINK_SPACE(tuple->Flags) = attr;
				if (function == BIND_FN_ALL) {
					/* Follow all the MFC links */
					ret = read_cis_cache(s, attr, ofs+2,
							1, &tmp);
					if (ret)
						return -1;
					MFC_FN(tuple->Flags) = tmp;
				} else {
					/* Follow exactly one of the links */
					MFC_FN(tuple->Flags) = 1;
					tuple->LinkOffset += function * 5;
				}
				break;
			case CISTPL_NO_LINK:
				HAS_LINK(tuple->Flags) = 0;
				break;
			}
			if ((tuple->Attributes & TUPLE_RETURN_LINK) &&
				(tuple->DesiredTuple == RETURN_FIRST_TUPLE))
				break;
		} else
			if (tuple->DesiredTuple == RETURN_FIRST_TUPLE)
				break;

		if (link[0] == tuple->DesiredTuple)
			break;
		ofs += link[1] + 2;
	}
	if (i == MAX_TUPLES) {
		dev_dbg(&s->dev, "cs: overrun in pcmcia_get_next_tuple\n");
		return -ENOSPC;
	}

	tuple->TupleCode = link[0];
	tuple->TupleLink = link[1];
	tuple->CISOffset = ofs + 2;
	return 0;
}

int pccard_get_tuple_data(struct pcmcia_socket *s, tuple_t *tuple)
{
	u_int len;
	int ret;

	if (!s)
		return -EINVAL;

	if (tuple->TupleLink < tuple->TupleOffset)
		return -ENOSPC;
	len = tuple->TupleLink - tuple->TupleOffset;
	tuple->TupleDataLen = tuple->TupleLink;
	if (len == 0)
		return 0;
	ret = read_cis_cache(s, SPACE(tuple->Flags),
			tuple->CISOffset + tuple->TupleOffset,
			min(len, (u_int) tuple->TupleDataMax),
			tuple->TupleData);
	if (ret)
		return -1;
	return 0;
}


/* Parsing routines for individual tuples */

static int parse_device(tuple_t *tuple, cistpl_device_t *device)
{
	int i;
	u_char scale;
	u_char *p, *q;

	p = (u_char *)tuple->TupleData;
	q = p + tuple->TupleDataLen;

	device->ndev = 0;
	for (i = 0; i < CISTPL_MAX_DEVICES; i++) {

		if (*p == 0xff)
			break;
		device->dev[i].type = (*p >> 4);
		device->dev[i].wp = (*p & 0x08) ? 1 : 0;
		switch (*p & 0x07) {
		case 0:
			device->dev[i].speed = 0;
			break;
		case 1:
			device->dev[i].speed = 250;
			break;
		case 2:
			device->dev[i].speed = 200;
			break;
		case 3:
			device->dev[i].speed = 150;
			break;
		case 4:
			device->dev[i].speed = 100;
			break;
		case 7:
			if (++p == q)
				return -EINVAL;
			device->dev[i].speed = SPEED_CVT(*p);
			while (*p & 0x80)
				if (++p == q)
					return -EINVAL;
			break;
		default:
			return -EINVAL;
		}

		if (++p == q)
			return -EINVAL;
		if (*p == 0xff)
			break;
		scale = *p & 7;
		if (scale == 7)
			return -EINVAL;
		device->dev[i].size = ((*p >> 3) + 1) * (512 << (scale*2));
		device->ndev++;
		if (++p == q)
			break;
	}

	return 0;
}


static int parse_checksum(tuple_t *tuple, cistpl_checksum_t *csum)
{
	u_char *p;
	if (tuple->TupleDataLen < 5)
		return -EINVAL;
	p = (u_char *) tuple->TupleData;
	csum->addr = tuple->CISOffset + get_unaligned_le16(p) - 2;
	csum->len = get_unaligned_le16(p + 2);
	csum->sum = *(p + 4);
	return 0;
}


static int parse_longlink(tuple_t *tuple, cistpl_longlink_t *link)
{
	if (tuple->TupleDataLen < 4)
		return -EINVAL;
	link->addr = get_unaligned_le32(tuple->TupleData);
	return 0;
}


static int parse_longlink_mfc(tuple_t *tuple, cistpl_longlink_mfc_t *link)
{
	u_char *p;
	int i;

	p = (u_char *)tuple->TupleData;

	link->nfn = *p; p++;
	if (tuple->TupleDataLen <= link->nfn*5)
		return -EINVAL;
	for (i = 0; i < link->nfn; i++) {
		link->fn[i].space = *p; p++;
		link->fn[i].addr = get_unaligned_le32(p);
		p += 4;
	}
	return 0;
}


static int parse_strings(u_char *p, u_char *q, int max,
			 char *s, u_char *ofs, u_char *found)
{
	int i, j, ns;

	if (p == q)
		return -EINVAL;
	ns = 0; j = 0;
	for (i = 0; i < max; i++) {
		if (*p == 0xff)
			break;
		ofs[i] = j;
		ns++;
		for (;;) {
			s[j++] = (*p == 0xff) ? '\0' : *p;
			if ((*p == '\0') || (*p == 0xff))
				break;
			if (++p == q)
				return -EINVAL;
		}
		if ((*p == 0xff) || (++p == q))
			break;
	}
	if (found) {
		*found = ns;
		return 0;
	}

	return (ns == max) ? 0 : -EINVAL;
}


static int parse_vers_1(tuple_t *tuple, cistpl_vers_1_t *vers_1)
{
	u_char *p, *q;

	p = (u_char *)tuple->TupleData;
	q = p + tuple->TupleDataLen;

	vers_1->major = *p; p++;
	vers_1->minor = *p; p++;
	if (p >= q)
		return -EINVAL;

	return parse_strings(p, q, CISTPL_VERS_1_MAX_PROD_STRINGS,
			vers_1->str, vers_1->ofs, &vers_1->ns);
}


static int parse_altstr(tuple_t *tuple, cistpl_altstr_t *altstr)
{
	u_char *p, *q;

	p = (u_char *)tuple->TupleData;
	q = p + tuple->TupleDataLen;

	return parse_strings(p, q, CISTPL_MAX_ALTSTR_STRINGS,
			altstr->str, altstr->ofs, &altstr->ns);
}


static int parse_jedec(tuple_t *tuple, cistpl_jedec_t *jedec)
{
	u_char *p, *q;
	int nid;

	p = (u_char *)tuple->TupleData;
	q = p + tuple->TupleDataLen;

	for (nid = 0; nid < CISTPL_MAX_DEVICES; nid++) {
		if (p > q-2)
			break;
		jedec->id[nid].mfr = p[0];
		jedec->id[nid].info = p[1];
		p += 2;
	}
	jedec->nid = nid;
	return 0;
}


static int parse_manfid(tuple_t *tuple, cistpl_manfid_t *m)
{
	if (tuple->TupleDataLen < 4)
		return -EINVAL;
	m->manf = get_unaligned_le16(tuple->TupleData);
	m->card = get_unaligned_le16(tuple->TupleData + 2);
	return 0;
}


static int parse_funcid(tuple_t *tuple, cistpl_funcid_t *f)
{
	u_char *p;
	if (tuple->TupleDataLen < 2)
		return -EINVAL;
	p = (u_char *)tuple->TupleData;
	f->func = p[0];
	f->sysinit = p[1];
	return 0;
}


static int parse_funce(tuple_t *tuple, cistpl_funce_t *f)
{
	u_char *p;
	int i;
	if (tuple->TupleDataLen < 1)
		return -EINVAL;
	p = (u_char *)tuple->TupleData;
	f->type = p[0];
	for (i = 1; i < tuple->TupleDataLen; i++)
		f->data[i-1] = p[i];
	return 0;
}


static int parse_config(tuple_t *tuple, cistpl_config_t *config)
{
	int rasz, rmsz, i;
	u_char *p;

	p = (u_char *)tuple->TupleData;
	rasz = *p & 0x03;
	rmsz = (*p & 0x3c) >> 2;
	if (tuple->TupleDataLen < rasz+rmsz+4)
		return -EINVAL;
	config->last_idx = *(++p);
	p++;
	config->base = 0;
	for (i = 0; i <= rasz; i++)
		config->base += p[i] << (8*i);
	p += rasz+1;
	for (i = 0; i < 4; i++)
		config->rmask[i] = 0;
	for (i = 0; i <= rmsz; i++)
		config->rmask[i>>2] += p[i] << (8*(i%4));
	config->subtuples = tuple->TupleDataLen - (rasz+rmsz+4);
	return 0;
}

/* The following routines are all used to parse the nightmarish
 * config table entries.
 */

static u_char *parse_power(u_char *p, u_char *q, cistpl_power_t *pwr)
{
	int i;
	u_int scale;

	if (p == q)
		return NULL;
	pwr->present = *p;
	pwr->flags = 0;
	p++;
	for (i = 0; i < 7; i++)
		if (pwr->present & (1<<i)) {
			if (p == q)
				return NULL;
			pwr->param[i] = POWER_CVT(*p);
			scale = POWER_SCALE(*p);
			while (*p & 0x80) {
				if (++p == q)
					return NULL;
				if ((*p & 0x7f) < 100)
					pwr->param[i] +=
						(*p & 0x7f) * scale / 100;
				else if (*p == 0x7d)
					pwr->flags |= CISTPL_POWER_HIGHZ_OK;
				else if (*p == 0x7e)
					pwr->param[i] = 0;
				else if (*p == 0x7f)
					pwr->flags |= CISTPL_POWER_HIGHZ_REQ;
				else
					return NULL;
			}
			p++;
		}
	return p;
}


static u_char *parse_timing(u_char *p, u_char *q, cistpl_timing_t *timing)
{
	u_char scale;

	if (p == q)
		return NULL;
	scale = *p;
	if ((scale & 3) != 3) {
		if (++p == q)
			return NULL;
		timing->wait = SPEED_CVT(*p);
		timing->waitscale = exponent[scale & 3];
	} else
		timing->wait = 0;
	scale >>= 2;
	if ((scale & 7) != 7) {
		if (++p == q)
			return NULL;
		timing->ready = SPEED_CVT(*p);
		timing->rdyscale = exponent[scale & 7];
	} else
		timing->ready = 0;
	scale >>= 3;
	if (scale != 7) {
		if (++p == q)
			return NULL;
		timing->reserved = SPEED_CVT(*p);
		timing->rsvscale = exponent[scale];
	} else
		timing->reserved = 0;
	p++;
	return p;
}


static u_char *parse_io(u_char *p, u_char *q, cistpl_io_t *io)
{
	int i, j, bsz, lsz;

	if (p == q)
		return NULL;
	io->flags = *p;

	if (!(*p & 0x80)) {
		io->nwin = 1;
		io->win[0].base = 0;
		io->win[0].len = (1 << (io->flags & CISTPL_IO_LINES_MASK));
		return p+1;
	}

	if (++p == q)
		return NULL;
	io->nwin = (*p & 0x0f) + 1;
	bsz = (*p & 0x30) >> 4;
	if (bsz == 3)
		bsz++;
	lsz = (*p & 0xc0) >> 6;
	if (lsz == 3)
		lsz++;
	p++;

	for (i = 0; i < io->nwin; i++) {
		io->win[i].base = 0;
		io->win[i].len = 1;
		for (j = 0; j < bsz; j++, p++) {
			if (p == q)
				return NULL;
			io->win[i].base += *p << (j*8);
		}
		for (j = 0; j < lsz; j++, p++) {
			if (p == q)
				return NULL;
			io->win[i].len += *p << (j*8);
		}
	}
	return p;
}


static u_char *parse_mem(u_char *p, u_char *q, cistpl_mem_t *mem)
{
	int i, j, asz, lsz, has_ha;
	u_int len, ca, ha;

	if (p == q)
		return NULL;

	mem->nwin = (*p & 0x07) + 1;
	lsz = (*p & 0x18) >> 3;
	asz = (*p & 0x60) >> 5;
	has_ha = (*p & 0x80);
	if (++p == q)
		return NULL;

	for (i = 0; i < mem->nwin; i++) {
		len = ca = ha = 0;
		for (j = 0; j < lsz; j++, p++) {
			if (p == q)
				return NULL;
			len += *p << (j*8);
		}
		for (j = 0; j < asz; j++, p++) {
			if (p == q)
				return NULL;
			ca += *p << (j*8);
		}
		if (has_ha)
			for (j = 0; j < asz; j++, p++) {
				if (p == q)
					return NULL;
				ha += *p << (j*8);
			}
		mem->win[i].len = len << 8;
		mem->win[i].card_addr = ca << 8;
		mem->win[i].host_addr = ha << 8;
	}
	return p;
}


static u_char *parse_irq(u_char *p, u_char *q, cistpl_irq_t *irq)
{
	if (p == q)
		return NULL;
	irq->IRQInfo1 = *p; p++;
	if (irq->IRQInfo1 & IRQ_INFO2_VALID) {
		if (p+2 > q)
			return NULL;
		irq->IRQInfo2 = (p[1]<<8) + p[0];
		p += 2;
	}
	return p;
}


static int parse_cftable_entry(tuple_t *tuple,
			       cistpl_cftable_entry_t *entry)
{
	u_char *p, *q, features;

	p = tuple->TupleData;
	q = p + tuple->TupleDataLen;
	entry->index = *p & 0x3f;
	entry->flags = 0;
	if (*p & 0x40)
		entry->flags |= CISTPL_CFTABLE_DEFAULT;
	if (*p & 0x80) {
		if (++p == q)
			return -EINVAL;
		if (*p & 0x10)
			entry->flags |= CISTPL_CFTABLE_BVDS;
		if (*p & 0x20)
			entry->flags |= CISTPL_CFTABLE_WP;
		if (*p & 0x40)
			entry->flags |= CISTPL_CFTABLE_RDYBSY;
		if (*p & 0x80)
			entry->flags |= CISTPL_CFTABLE_MWAIT;
		entry->interface = *p & 0x0f;
	} else
		entry->interface = 0;

	/* Process optional features */
	if (++p == q)
		return -EINVAL;
	features = *p; p++;

	/* Power options */
	if ((features & 3) > 0) {
		p = parse_power(p, q, &entry->vcc);
		if (p == NULL)
			return -EINVAL;
	} else
		entry->vcc.present = 0;
	if ((features & 3) > 1) {
		p = parse_power(p, q, &entry->vpp1);
		if (p == NULL)
			return -EINVAL;
	} else
		entry->vpp1.present = 0;
	if ((features & 3) > 2) {
		p = parse_power(p, q, &entry->vpp2);
		if (p == NULL)
			return -EINVAL;
	} else
		entry->vpp2.present = 0;

	/* Timing options */
	if (features & 0x04) {
		p = parse_timing(p, q, &entry->timing);
		if (p == NULL)
			return -EINVAL;
	} else {
		entry->timing.wait = 0;
		entry->timing.ready = 0;
		entry->timing.reserved = 0;
	}

	/* I/O window options */
	if (features & 0x08) {
		p = parse_io(p, q, &entry->io);
		if (p == NULL)
			return -EINVAL;
	} else
		entry->io.nwin = 0;

	/* Interrupt options */
	if (features & 0x10) {
		p = parse_irq(p, q, &entry->irq);
		if (p == NULL)
			return -EINVAL;
	} else
		entry->irq.IRQInfo1 = 0;

	switch (features & 0x60) {
	case 0x00:
		entry->mem.nwin = 0;
		break;
	case 0x20:
		entry->mem.nwin = 1;
		entry->mem.win[0].len = get_unaligned_le16(p) << 8;
		entry->mem.win[0].card_addr = 0;
		entry->mem.win[0].host_addr = 0;
		p += 2;
		if (p > q)
			return -EINVAL;
		break;
	case 0x40:
		entry->mem.nwin = 1;
		entry->mem.win[0].len = get_unaligned_le16(p) << 8;
		entry->mem.win[0].card_addr = get_unaligned_le16(p + 2) << 8;
		entry->mem.win[0].host_addr = 0;
		p += 4;
		if (p > q)
			return -EINVAL;
		break;
	case 0x60:
		p = parse_mem(p, q, &entry->mem);
		if (p == NULL)
			return -EINVAL;
		break;
	}

	/* Misc features */
	if (features & 0x80) {
		if (p == q)
			return -EINVAL;
		entry->flags |= (*p << 8);
		while (*p & 0x80)
			if (++p == q)
				return -EINVAL;
		p++;
	}

	entry->subtuples = q-p;

	return 0;
}


static int parse_device_geo(tuple_t *tuple, cistpl_device_geo_t *geo)
{
	u_char *p, *q;
	int n;

	p = (u_char *)tuple->TupleData;
	q = p + tuple->TupleDataLen;

	for (n = 0; n < CISTPL_MAX_DEVICES; n++) {
		if (p > q-6)
			break;
		geo->geo[n].buswidth = p[0];
		geo->geo[n].erase_block = 1 << (p[1]-1);
		geo->geo[n].read_block  = 1 << (p[2]-1);
		geo->geo[n].write_block = 1 << (p[3]-1);
		geo->geo[n].partition   = 1 << (p[4]-1);
		geo->geo[n].interleave  = 1 << (p[5]-1);
		p += 6;
	}
	geo->ngeo = n;
	return 0;
}


static int parse_vers_2(tuple_t *tuple, cistpl_vers_2_t *v2)
{
	u_char *p, *q;

	if (tuple->TupleDataLen < 10)
		return -EINVAL;

	p = tuple->TupleData;
	q = p + tuple->TupleDataLen;

	v2->vers = p[0];
	v2->comply = p[1];
	v2->dindex = get_unaligned_le16(p + 2);
	v2->vspec8 = p[6];
	v2->vspec9 = p[7];
	v2->nhdr = p[8];
	p += 9;
	return parse_strings(p, q, 2, v2->str, &v2->vendor, NULL);
}


static int parse_org(tuple_t *tuple, cistpl_org_t *org)
{
	u_char *p, *q;
	int i;

	p = tuple->TupleData;
	q = p + tuple->TupleDataLen;
	if (p == q)
		return -EINVAL;
	org->data_org = *p;
	if (++p == q)
		return -EINVAL;
	for (i = 0; i < 30; i++) {
		org->desc[i] = *p;
		if (*p == '\0')
			break;
		if (++p == q)
			return -EINVAL;
	}
	return 0;
}


static int parse_format(tuple_t *tuple, cistpl_format_t *fmt)
{
	u_char *p;

	if (tuple->TupleDataLen < 10)
		return -EINVAL;

	p = tuple->TupleData;

	fmt->type = p[0];
	fmt->edc = p[1];
	fmt->offset = get_unaligned_le32(p + 2);
	fmt->length = get_unaligned_le32(p + 6);

	return 0;
}


int pcmcia_parse_tuple(tuple_t *tuple, cisparse_t *parse)
{
	int ret = 0;

	if (tuple->TupleDataLen > tuple->TupleDataMax)
		return -EINVAL;
	switch (tuple->TupleCode) {
	case CISTPL_DEVICE:
	case CISTPL_DEVICE_A:
		ret = parse_device(tuple, &parse->device);
		break;
	case CISTPL_CHECKSUM:
		ret = parse_checksum(tuple, &parse->checksum);
		break;
	case CISTPL_LONGLINK_A:
	case CISTPL_LONGLINK_C:
		ret = parse_longlink(tuple, &parse->longlink);
		break;
	case CISTPL_LONGLINK_MFC:
		ret = parse_longlink_mfc(tuple, &parse->longlink_mfc);
		break;
	case CISTPL_VERS_1:
		ret = parse_vers_1(tuple, &parse->version_1);
		break;
	case CISTPL_ALTSTR:
		ret = parse_altstr(tuple, &parse->altstr);
		break;
	case CISTPL_JEDEC_A:
	case CISTPL_JEDEC_C:
		ret = parse_jedec(tuple, &parse->jedec);
		break;
	case CISTPL_MANFID:
		ret = parse_manfid(tuple, &parse->manfid);
		break;
	case CISTPL_FUNCID:
		ret = parse_funcid(tuple, &parse->funcid);
		break;
	case CISTPL_FUNCE:
		ret = parse_funce(tuple, &parse->funce);
		break;
	case CISTPL_CONFIG:
		ret = parse_config(tuple, &parse->config);
		break;
	case CISTPL_CFTABLE_ENTRY:
		ret = parse_cftable_entry(tuple, &parse->cftable_entry);
		break;
	case CISTPL_DEVICE_GEO:
	case CISTPL_DEVICE_GEO_A:
		ret = parse_device_geo(tuple, &parse->device_geo);
		break;
	case CISTPL_VERS_2:
		ret = parse_vers_2(tuple, &parse->vers_2);
		break;
	case CISTPL_ORG:
		ret = parse_org(tuple, &parse->org);
		break;
	case CISTPL_FORMAT:
	case CISTPL_FORMAT_A:
		ret = parse_format(tuple, &parse->format);
		break;
	case CISTPL_NO_LINK:
	case CISTPL_LINKTARGET:
		ret = 0;
		break;
	default:
		ret = -EINVAL;
		break;
	}
	if (ret)
		pr_debug("parse_tuple failed %d\n", ret);
	return ret;
}
EXPORT_SYMBOL(pcmcia_parse_tuple);


/**
 * pccard_read_tuple() - internal CIS tuple access
 * @s:		the struct pcmcia_socket where the card is inserted
 * @function:	the device function we loop for
 * @code:	which CIS code shall we look for?
 * @parse:	buffer where the tuple shall be parsed (or NULL, if no parse)
 *
 * pccard_read_tuple() reads out one tuple and attempts to parse it
 */
int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function,
		cisdata_t code, void *parse)
{
	tuple_t tuple;
	cisdata_t *buf;
	int ret;

	buf = kmalloc(256, GFP_KERNEL);
	if (buf == NULL) {
		dev_printk(KERN_WARNING, &s->dev, "no memory to read tuple\n");
		return -ENOMEM;
	}
	tuple.DesiredTuple = code;
	tuple.Attributes = 0;
	if (function == BIND_FN_ALL)
		tuple.Attributes = TUPLE_RETURN_COMMON;
	ret = pccard_get_first_tuple(s, function, &tuple);
	if (ret != 0)
		goto done;
	tuple.TupleData = buf;
	tuple.TupleOffset = 0;
	tuple.TupleDataMax = 255;
	ret = pccard_get_tuple_data(s, &tuple);
	if (ret != 0)
		goto done;
	ret = pcmcia_parse_tuple(&tuple, parse);
done:
	kfree(buf);
	return ret;
}


/**
 * pccard_loop_tuple() - loop over tuples in the CIS
 * @s:		the struct pcmcia_socket where the card is inserted
 * @function:	the device function we loop for
 * @code:	which CIS code shall we look for?
 * @parse:	buffer where the tuple shall be parsed (or NULL, if no parse)
 * @priv_data:	private data to be passed to the loop_tuple function.
 * @loop_tuple:	function to call for each CIS entry of type @function. IT
 *		gets passed the raw tuple, the paresed tuple (if @parse is
 *		set) and @priv_data.
 *
 * pccard_loop_tuple() loops over all CIS entries of type @function, and
 * calls the @loop_tuple function for each entry. If the call to @loop_tuple
 * returns 0, the loop exits. Returns 0 on success or errorcode otherwise.
 */
int pccard_loop_tuple(struct pcmcia_socket *s, unsigned int function,
		      cisdata_t code, cisparse_t *parse, void *priv_data,
		      int (*loop_tuple) (tuple_t *tuple,
					 cisparse_t *parse,
					 void *priv_data))
{
	tuple_t tuple;
	cisdata_t *buf;
	int ret;

	buf = kzalloc(256, GFP_KERNEL);
	if (buf == NULL) {
		dev_printk(KERN_WARNING, &s->dev, "no memory to read tuple\n");
		return -ENOMEM;
	}

	tuple.TupleData = buf;
	tuple.TupleDataMax = 255;
	tuple.TupleOffset = 0;
	tuple.DesiredTuple = code;
	tuple.Attributes = 0;

	ret = pccard_get_first_tuple(s, function, &tuple);
	while (!ret) {
		if (pccard_get_tuple_data(s, &tuple))
			goto next_entry;

		if (parse)
			if (pcmcia_parse_tuple(&tuple, parse))
				goto next_entry;

		ret = loop_tuple(&tuple, parse, priv_data);
		if (!ret)
			break;

next_entry:
		ret = pccard_get_next_tuple(s, function, &tuple);
	}

	kfree(buf);
	return ret;
}


/**
 * pccard_validate_cis() - check whether card has a sensible CIS
 * @s:		the struct pcmcia_socket we are to check
 * @info:	returns the number of tuples in the (valid) CIS, or 0
 *
 * This tries to determine if a card has a sensible CIS.  In @info, it
 * returns the number of tuples in the CIS, or 0 if the CIS looks bad. The
 * checks include making sure several critical tuples are present and
 * valid; seeing if the total number of tuples is reasonable; and
 * looking for tuples that use reserved codes.
 *
 * The function returns 0 on success.
 */
int pccard_validate_cis(struct pcmcia_socket *s, unsigned int *info)
{
	tuple_t *tuple;
	cisparse_t *p;
	unsigned int count = 0;
	int ret, reserved, dev_ok = 0, ident_ok = 0;

	if (!s)
		return -EINVAL;

	/* We do not want to validate the CIS cache... */
	mutex_lock(&s->ops_mutex);
	destroy_cis_cache(s);
	mutex_unlock(&s->ops_mutex);

	tuple = kmalloc(sizeof(*tuple), GFP_KERNEL);
	if (tuple == NULL) {
		dev_warn(&s->dev, "no memory to validate CIS\n");
		return -ENOMEM;
	}
	p = kmalloc(sizeof(*p), GFP_KERNEL);
	if (p == NULL) {
		kfree(tuple);
		dev_warn(&s->dev, "no memory to validate CIS\n");
		return -ENOMEM;
	}

	count = reserved = 0;
	tuple->DesiredTuple = RETURN_FIRST_TUPLE;
	tuple->Attributes = TUPLE_RETURN_COMMON;
	ret = pccard_get_first_tuple(s, BIND_FN_ALL, tuple);
	if (ret != 0)
		goto done;

	/* First tuple should be DEVICE; we should really have either that
	   or a CFTABLE_ENTRY of some sort */
	if ((tuple->TupleCode == CISTPL_DEVICE) ||
	    (!pccard_read_tuple(s, BIND_FN_ALL, CISTPL_CFTABLE_ENTRY, p)) ||
	    (!pccard_read_tuple(s, BIND_FN_ALL, CISTPL_CFTABLE_ENTRY_CB, p)))
		dev_ok++;

	/* All cards should have a MANFID tuple, and/or a VERS_1 or VERS_2
	   tuple, for card identification.  Certain old D-Link and Linksys
	   cards have only a broken VERS_2 tuple; hence the bogus test. */
	if ((pccard_read_tuple(s, BIND_FN_ALL, CISTPL_MANFID, p) == 0) ||
	    (pccard_read_tuple(s, BIND_FN_ALL, CISTPL_VERS_1, p) == 0) ||
	    (pccard_read_tuple(s, BIND_FN_ALL, CISTPL_VERS_2, p) != -ENOSPC))
		ident_ok++;

	if (!dev_ok && !ident_ok)
		goto done;

	for (count = 1; count < MAX_TUPLES; count++) {
		ret = pccard_get_next_tuple(s, BIND_FN_ALL, tuple);
		if (ret != 0)
			break;
		if (((tuple->TupleCode > 0x23) && (tuple->TupleCode < 0x40)) ||
		    ((tuple->TupleCode > 0x47) && (tuple->TupleCode < 0x80)) ||
		    ((tuple->TupleCode > 0x90) && (tuple->TupleCode < 0xff)))
			reserved++;
	}
	if ((count == MAX_TUPLES) || (reserved > 5) ||
		((!dev_ok || !ident_ok) && (count > 10)))
		count = 0;

	ret = 0;

done:
	/* invalidate CIS cache on failure */
	if (!dev_ok || !ident_ok || !count) {
		mutex_lock(&s->ops_mutex);
		destroy_cis_cache(s);
		mutex_unlock(&s->ops_mutex);
		ret = -EIO;
	}

	if (info)
		*info = count;
	kfree(tuple);
	kfree(p);
	return ret;
}


#define to_socket(_dev) container_of(_dev, struct pcmcia_socket, dev)

static ssize_t pccard_extract_cis(struct pcmcia_socket *s, char *buf,
				  loff_t off, size_t count)
{
	tuple_t tuple;
	int status, i;
	loff_t pointer = 0;
	ssize_t ret = 0;
	u_char *tuplebuffer;
	u_char *tempbuffer;

	tuplebuffer = kmalloc(sizeof(u_char) * 256, GFP_KERNEL);
	if (!tuplebuffer)
		return -ENOMEM;

	tempbuffer = kmalloc(sizeof(u_char) * 258, GFP_KERNEL);
	if (!tempbuffer) {
		ret = -ENOMEM;
		goto free_tuple;
	}

	memset(&tuple, 0, sizeof(tuple_t));

	tuple.Attributes = TUPLE_RETURN_LINK | TUPLE_RETURN_COMMON;
	tuple.DesiredTuple = RETURN_FIRST_TUPLE;
	tuple.TupleOffset = 0;

	status = pccard_get_first_tuple(s, BIND_FN_ALL, &tuple);
	while (!status) {
		tuple.TupleData = tuplebuffer;
		tuple.TupleDataMax = 255;
		memset(tuplebuffer, 0, sizeof(u_char) * 255);

		status = pccard_get_tuple_data(s, &tuple);
		if (status)
			break;

		if (off < (pointer + 2 + tuple.TupleDataLen)) {
			tempbuffer[0] = tuple.TupleCode & 0xff;
			tempbuffer[1] = tuple.TupleLink & 0xff;
			for (i = 0; i < tuple.TupleDataLen; i++)
				tempbuffer[i + 2] = tuplebuffer[i] & 0xff;

			for (i = 0; i < (2 + tuple.TupleDataLen); i++) {
				if (((i + pointer) >= off) &&
				    (i + pointer) < (off + count)) {
					buf[ret] = tempbuffer[i];
					ret++;
				}
			}
		}

		pointer += 2 + tuple.TupleDataLen;

		if (pointer >= (off + count))
			break;

		if (tuple.TupleCode == CISTPL_END)
			break;
		status = pccard_get_next_tuple(s, BIND_FN_ALL, &tuple);
	}

	kfree(tempbuffer);
 free_tuple:
	kfree(tuplebuffer);

	return ret;
}


static ssize_t pccard_show_cis(struct kobject *kobj,
			       struct bin_attribute *bin_attr,
			       char *buf, loff_t off, size_t count)
{
	unsigned int size = 0x200;

	if (off >= size)
		count = 0;
	else {
		struct pcmcia_socket *s;
		unsigned int chains;

		if (off + count > size)
			count = size - off;

		s = to_socket(container_of(kobj, struct device, kobj));

		if (!(s->state & SOCKET_PRESENT))
			return -ENODEV;
		if (pccard_validate_cis(s, &chains))
			return -EIO;
		if (!chains)
			return -ENODATA;

		count = pccard_extract_cis(s, buf, off, count);
	}

	return count;
}


static ssize_t pccard_store_cis(struct kobject *kobj,
				struct bin_attribute *bin_attr,
				char *buf, loff_t off, size_t count)
{
	struct pcmcia_socket *s;
	int error;

	s = to_socket(container_of(kobj, struct device, kobj));

	if (off)
		return -EINVAL;

	if (count >= CISTPL_MAX_CIS_SIZE)
		return -EINVAL;

	if (!(s->state & SOCKET_PRESENT))
		return -ENODEV;

	error = pcmcia_replace_cis(s, buf, count);
	if (error)
		return -EIO;

	pcmcia_parse_uevents(s, PCMCIA_UEVENT_REQUERY);

	return count;
}


struct bin_attribute pccard_cis_attr = {
	.attr = { .name = "cis", .mode = S_IRUGO | S_IWUSR },
	.size = 0x200,
	.read = pccard_show_cis,
	.write = pccard_store_cis,
};
