/*
 * 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 <asm/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

/*====================================================================*/

/* Parameters that can be set with 'insmod' */

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

void release_cis_mem(struct pcmcia_socket *s)
{
    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;
    }
}
EXPORT_SYMBOL(release_cis_mem);

/*
 * Map the card memory at "card_offset" into virtual space.
 * If flags & MAP_ATTRIB, map the attribute space, otherwise
 * map the memory space.
 */
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;
}

/*======================================================================

    Low-level functions to read and write CIS memory.  I think the
    write routine is only useful for writing one-byte registers.
    
======================================================================*/

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

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;
    
    cs_dbg(s, 3, "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) {
	    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;

	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) {
		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;
	}
    }
    cs_dbg(s, 3, "  %#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;
}
EXPORT_SYMBOL(pcmcia_read_cis_mem);


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;
    
    cs_dbg(s, 3, "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)
		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)
		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;
	}
    }
}
EXPORT_SYMBOL(pcmcia_write_cis_mem);


/*======================================================================

    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 void read_cis_cache(struct pcmcia_socket *s, int attr, u_int addr,
			   size_t len, void *ptr)
{
    struct cis_cache_entry *cis;
    int ret;

    if (s->fake_cis) {
	if (s->fake_cis_len >= addr+len)
	    memcpy(ptr, s->fake_cis+addr, len);
	else
	    memset(ptr, 0xff, len);
	return;
    }

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

#ifdef CONFIG_CARDBUS
    if (s->state & SOCKET_CARDBUS)
	ret = read_cb_mem(s, attr, addr, len, ptr);
    else
#endif
	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);
		}
	}
}

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

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

void destroy_cis_cache(struct pcmcia_socket *s)
{
	struct list_head *l, *n;

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

		list_del(&cis->node);
		kfree(cis);
	}

	/*
	 * If there was a fake CIS, destroy that as well.
	 */
	kfree(s->fake_cis);
	s->fake_cis = NULL;
}
EXPORT_SYMBOL(destroy_cis_cache);

/*======================================================================

    This verifies if the CIS of a card matches what is in the CIS
    cache.
    
======================================================================*/

int verify_cis_cache(struct pcmcia_socket *s)
{
	struct cis_cache_entry *cis;
	char *buf;

	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;
#ifdef CONFIG_CARDBUS
		if (s->state & SOCKET_CARDBUS)
			read_cb_mem(s, cis->attr, cis->addr, len, buf);
		else
#endif
			pcmcia_read_cis_mem(s, cis->attr, cis->addr, len, buf);

		if (memcmp(buf, cis->cache, len) != 0) {
			kfree(buf);
			return -1;
		}
	}
	kfree(buf);
	return 0;
}

/*======================================================================

    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;
	}
	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");
		return -ENOMEM;
	}
	s->fake_cis_len = len;
	memcpy(s->fake_cis, data, len);
	return 0;
}
EXPORT_SYMBOL(pcmcia_replace_cis);

/*======================================================================

    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_next_tuple(struct pcmcia_socket *s, unsigned int func, tuple_t *tuple);

int pccard_get_first_tuple(struct pcmcia_socket *s, unsigned int function, tuple_t *tuple)
{
    if (!s)
	return -EINVAL;
    if (!(s->state & SOCKET_PRESENT))
	return -ENODEV;
    tuple->TupleLink = tuple->Flags = 0;
#ifdef CONFIG_CARDBUS
    if (s->state & SOCKET_CARDBUS) {
	struct pci_dev *dev = s->cb_dev;
	u_int ptr;
	pci_bus_read_config_dword(dev->subordinate, 0, PCI_CARDBUS_CIS, &ptr);
	tuple->CISOffset = ptr & ~7;
	SPACE(tuple->Flags) = (ptr & 7);
    } else
#endif
    {
	/* Assume presence of a LONGLINK_C to address 0 */
	tuple->CISOffset = tuple->LinkOffset = 0;
	SPACE(tuple->Flags) = HAS_LINK(tuple->Flags) = 1;
    }
    if (!(s->state & SOCKET_CARDBUS) && (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);
}
EXPORT_SYMBOL(pccard_get_first_tuple);

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

    if (MFC_FN(tuple->Flags)) {
	/* Get indirect link from the MFC tuple */
	read_cis_cache(s, LINK_SPACE(tuple->Flags),
		       tuple->LinkOffset, 5, link);
	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 (!(s->state & SOCKET_CARDBUS) && 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... */
	read_cis_cache(s, SPACE(tuple->Flags), ofs, 5, link);
	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;
    }
    read_cis_cache(s, SPACE(tuple->Flags), ofs, 5, link);
    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;

    if (!s)
	return -EINVAL;
    if (!(s->state & SOCKET_PRESENT))
	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 {
	    read_cis_cache(s, attr, ofs, 2, link);
	    if (link[0] == CISTPL_NULL) {
		ofs++; continue;
	    }
	}
	
	/* End of chain?  Follow long link if possible */
	if (link[0] == CISTPL_END) {
	    if ((ofs = follow_link(s, tuple)) < 0)
		return -ENOSPC;
	    attr = SPACE(tuple->Flags);
	    read_cis_cache(s, attr, ofs, 2, link);
	}

	/* 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;
		read_cis_cache(s, attr, ofs+2, 4, &tuple->LinkOffset);
		break;
	    case CISTPL_LONGLINK_C:
		HAS_LINK(tuple->Flags) = 1;
		LINK_SPACE(tuple->Flags) = attr & ~IS_ATTR;
		read_cis_cache(s, attr, ofs+2, 4, &tuple->LinkOffset);
		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 */
		    read_cis_cache(s, attr, ofs+2, 1, &tmp);
		    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) {
	cs_dbg(s, 1, "cs: overrun in pcmcia_get_next_tuple\n");
	return -ENOSPC;
    }
    
    tuple->TupleCode = link[0];
    tuple->TupleLink = link[1];
    tuple->CISOffset = ofs + 2;
    return 0;
}
EXPORT_SYMBOL(pccard_get_next_tuple);

/*====================================================================*/

#define _MIN(a, b)		(((a) < (b)) ? (a) : (b))

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

    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;
    read_cis_cache(s, SPACE(tuple->Flags),
		   tuple->CISOffset + tuple->TupleOffset,
		   _MIN(len, tuple->TupleDataMax), tuple->TupleData);
    return 0;
}
EXPORT_SYMBOL(pccard_get_tuple_data);


/*======================================================================

    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;
    } else {
	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;
}

/*====================================================================*/

#ifdef CONFIG_CARDBUS

static int parse_bar(tuple_t *tuple, cistpl_bar_t *bar)
{
    u_char *p;
    if (tuple->TupleDataLen < 6)
	return -EINVAL;
    p = (u_char *)tuple->TupleData;
    bar->attr = *p;
    p += 2;
    bar->size = get_unaligned_le32(p);
    return 0;
}

static int parse_config_cb(tuple_t *tuple, cistpl_config_t *config)
{
    u_char *p;
    
    p = (u_char *)tuple->TupleData;
    if ((*p != 3) || (tuple->TupleDataLen < 6))
	return -EINVAL;
    config->last_idx = *(++p);
    p++;
    config->base = get_unaligned_le32(p);
    config->subtuples = tuple->TupleDataLen - 6;
    return 0;
}

static int parse_cftable_entry_cb(tuple_t *tuple,
				  cistpl_cftable_entry_cb_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;

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

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

    if (features & 0x20) {
	if (p == q)
		return -EINVAL;
	entry->mem = *p; p++;
    } else
	entry->mem = 0;

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

    entry->subtuples = q-p;
    
    return 0;
}

#endif

/*====================================================================*/

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;
#ifdef CONFIG_CARDBUS
    case CISTPL_BAR:
	ret = parse_bar(tuple, &parse->bar);
	break;
    case CISTPL_CONFIG_CB:
	ret = parse_config_cb(tuple, &parse->config);
	break;
    case CISTPL_CFTABLE_ENTRY_CB:
	ret = parse_cftable_entry_cb(tuple, &parse->cftable_entry_cb);
	break;
#endif
    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)
	    __cs_dbg(0, "parse_tuple failed %d\n", ret);
    return ret;
}
EXPORT_SYMBOL(pcmcia_parse_tuple);

/*======================================================================

    This is used internally by Card Services to look up CIS stuff.
    
======================================================================*/

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 = 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;
}
EXPORT_SYMBOL(pccard_read_tuple);

/*======================================================================

    This tries to determine if a card has a sensible CIS.  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.
    
======================================================================*/

int pccard_validate_cis(struct pcmcia_socket *s, unsigned int function, 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;

    tuple = kmalloc(sizeof(*tuple), GFP_KERNEL);
    if (tuple == NULL) {
	    dev_printk(KERN_WARNING, &s->dev, "no memory to validate CIS\n");
	    return -ENOMEM;
    }
    p = kmalloc(sizeof(*p), GFP_KERNEL);
    if (p == NULL) {
	    kfree(tuple);
	    dev_printk(KERN_WARNING, &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, function, 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, function, CISTPL_CFTABLE_ENTRY, p) == 0) ||
	(pccard_read_tuple(s, function, CISTPL_CFTABLE_ENTRY_CB, p) == 0))
	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, function, CISTPL_MANFID, p) == 0) ||
	(pccard_read_tuple(s, function, CISTPL_VERS_1, p) == 0) ||
	(pccard_read_tuple(s, function, 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, function, 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;

done:
    if (info)
	    *info = count;
    kfree(tuple);
    kfree(p);
    return 0;
}
EXPORT_SYMBOL(pccard_validate_cis);
