/*
 * 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
 *
 * must be called with ops_mutex held
 */
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);

	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);
			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);
				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;
		}
	}
	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. Must be called
 * with ops_mutex held.
 */
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);

	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");
			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");
				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;
		}
	}
}


/**
 * 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;
		}
	}

	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);
			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;
	}
	mutex_lock(&s->ops_mutex);
	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);
			mutex_unlock(&s->ops_mutex);
			return -1;
		}
	}
	kfree(buf);
	mutex_unlock(&s->ops_mutex);
	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_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;

	if (s->functions) {
		WARN_ON(1);
		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 file *filp, 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 = 1;

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

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

		if (!(s->state & SOCKET_PRESENT))
			return -ENODEV;
		if (!s->functions && 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 file *filp, 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,
};
