/*
 * rsparser.c - parses and encodes pnpbios resource data streams
 *
 */

#include <linux/config.h>
#include <linux/ctype.h>
#include <linux/pnp.h>
#include <linux/pnpbios.h>

#ifdef CONFIG_PCI
#include <linux/pci.h>
#else
inline void pcibios_penalize_isa_irq(int irq, int active) {}
#endif /* CONFIG_PCI */

#include "pnpbios.h"

/* standard resource tags */
#define SMALL_TAG_PNPVERNO		0x01
#define SMALL_TAG_LOGDEVID		0x02
#define SMALL_TAG_COMPATDEVID		0x03
#define SMALL_TAG_IRQ			0x04
#define SMALL_TAG_DMA			0x05
#define SMALL_TAG_STARTDEP		0x06
#define SMALL_TAG_ENDDEP		0x07
#define SMALL_TAG_PORT			0x08
#define SMALL_TAG_FIXEDPORT		0x09
#define SMALL_TAG_VENDOR		0x0e
#define SMALL_TAG_END			0x0f
#define LARGE_TAG			0x80
#define LARGE_TAG_MEM			0x81
#define LARGE_TAG_ANSISTR		0x82
#define LARGE_TAG_UNICODESTR		0x83
#define LARGE_TAG_VENDOR		0x84
#define LARGE_TAG_MEM32			0x85
#define LARGE_TAG_FIXEDMEM32		0x86

/*
 * Resource Data Stream Format:
 *
 * Allocated Resources (required)
 * end tag ->
 * Resource Configuration Options (optional)
 * end tag ->
 * Compitable Device IDs (optional)
 * final end tag ->
 */

/*
 * Allocated Resources
 */

static void
pnpbios_parse_allocated_irqresource(struct pnp_resource_table * res, int irq)
{
	int i = 0;
	while (!(res->irq_resource[i].flags & IORESOURCE_UNSET) && i < PNP_MAX_IRQ) i++;
	if (i < PNP_MAX_IRQ) {
		res->irq_resource[i].flags = IORESOURCE_IRQ;  // Also clears _UNSET flag
		if (irq == -1) {
			res->irq_resource[i].flags |= IORESOURCE_DISABLED;
			return;
		}
		res->irq_resource[i].start =
		res->irq_resource[i].end = (unsigned long) irq;
		pcibios_penalize_isa_irq(irq, 1);
	}
}

static void
pnpbios_parse_allocated_dmaresource(struct pnp_resource_table * res, int dma)
{
	int i = 0;
	while (i < PNP_MAX_DMA &&
			!(res->dma_resource[i].flags & IORESOURCE_UNSET))
		i++;
	if (i < PNP_MAX_DMA) {
		res->dma_resource[i].flags = IORESOURCE_DMA;  // Also clears _UNSET flag
		if (dma == -1) {
			res->dma_resource[i].flags |= IORESOURCE_DISABLED;
			return;
		}
		res->dma_resource[i].start =
		res->dma_resource[i].end = (unsigned long) dma;
	}
}

static void
pnpbios_parse_allocated_ioresource(struct pnp_resource_table * res, int io, int len)
{
	int i = 0;
	while (!(res->port_resource[i].flags & IORESOURCE_UNSET) && i < PNP_MAX_PORT) i++;
	if (i < PNP_MAX_PORT) {
		res->port_resource[i].flags = IORESOURCE_IO;  // Also clears _UNSET flag
		if (len <= 0 || (io + len -1) >= 0x10003) {
			res->port_resource[i].flags |= IORESOURCE_DISABLED;
			return;
		}
		res->port_resource[i].start = (unsigned long) io;
		res->port_resource[i].end = (unsigned long)(io + len - 1);
	}
}

static void
pnpbios_parse_allocated_memresource(struct pnp_resource_table * res, int mem, int len)
{
	int i = 0;
	while (!(res->mem_resource[i].flags & IORESOURCE_UNSET) && i < PNP_MAX_MEM) i++;
	if (i < PNP_MAX_MEM) {
		res->mem_resource[i].flags = IORESOURCE_MEM;  // Also clears _UNSET flag
		if (len <= 0) {
			res->mem_resource[i].flags |= IORESOURCE_DISABLED;
			return;
		}
		res->mem_resource[i].start = (unsigned long) mem;
		res->mem_resource[i].end = (unsigned long)(mem + len - 1);
	}
}

static unsigned char *
pnpbios_parse_allocated_resource_data(unsigned char * p, unsigned char * end, struct pnp_resource_table * res)
{
	unsigned int len, tag;
	int io, size, mask, i;

	if (!p)
		return NULL;

	/* Blank the resource table values */
	pnp_init_resource_table(res);

	while ((char *)p < (char *)end) {

		/* determine the type of tag */
		if (p[0] & LARGE_TAG) { /* large tag */
			len = (p[2] << 8) | p[1];
			tag = p[0];
		} else { /* small tag */
			len = p[0] & 0x07;
			tag = ((p[0]>>3) & 0x0f);
		}

		switch (tag) {

		case LARGE_TAG_MEM:
			if (len != 9)
				goto len_err;
			io = *(short *) &p[4];
			size = *(short *) &p[10];
			pnpbios_parse_allocated_memresource(res, io, size);
			break;

		case LARGE_TAG_ANSISTR:
			/* ignore this for now */
			break;

		case LARGE_TAG_VENDOR:
			/* do nothing */
			break;

		case LARGE_TAG_MEM32:
			if (len != 17)
				goto len_err;
			io = *(int *) &p[4];
			size = *(int *) &p[16];
			pnpbios_parse_allocated_memresource(res, io, size);
			break;

		case LARGE_TAG_FIXEDMEM32:
			if (len != 9)
				goto len_err;
			io = *(int *) &p[4];
			size = *(int *) &p[8];
			pnpbios_parse_allocated_memresource(res, io, size);
			break;

		case SMALL_TAG_IRQ:
			if (len < 2 || len > 3)
				goto len_err;
			io = -1;
			mask= p[1] + p[2]*256;
			for (i=0;i<16;i++, mask=mask>>1)
				if(mask & 0x01) io=i;
			pnpbios_parse_allocated_irqresource(res, io);
			break;

		case SMALL_TAG_DMA:
			if (len != 2)
				goto len_err;
			io = -1;
			mask = p[1];
			for (i=0;i<8;i++, mask = mask>>1)
				if(mask & 0x01) io=i;
			pnpbios_parse_allocated_dmaresource(res, io);
			break;

		case SMALL_TAG_PORT:
			if (len != 7)
				goto len_err;
			io = p[2] + p[3] *256;
			size = p[7];
			pnpbios_parse_allocated_ioresource(res, io, size);
			break;

		case SMALL_TAG_VENDOR:
			/* do nothing */
			break;

		case SMALL_TAG_FIXEDPORT:
			if (len != 3)
				goto len_err;
			io = p[1] + p[2] * 256;
			size = p[3];
			pnpbios_parse_allocated_ioresource(res, io, size);
			break;

		case SMALL_TAG_END:
			p = p + 2;
        		return (unsigned char *)p;
			break;

		default: /* an unkown tag */
			len_err:
			printk(KERN_ERR "PnPBIOS: Unknown tag '0x%x', length '%d'.\n", tag, len);
			break;
		}

		/* continue to the next tag */
		if (p[0] & LARGE_TAG)
			p += len + 3;
		else
			p += len + 1;
	}

	printk(KERN_ERR "PnPBIOS: Resource structure does not contain an end tag.\n");

	return NULL;
}


/*
 * Resource Configuration Options
 */

static void
pnpbios_parse_mem_option(unsigned char *p, int size, struct pnp_option *option)
{
	struct pnp_mem * mem;
	mem = kcalloc(1, sizeof(struct pnp_mem), GFP_KERNEL);
	if (!mem)
		return;
	mem->min = ((p[5] << 8) | p[4]) << 8;
	mem->max = ((p[7] << 8) | p[6]) << 8;
	mem->align = (p[9] << 8) | p[8];
	mem->size = ((p[11] << 8) | p[10]) << 8;
	mem->flags = p[3];
	pnp_register_mem_resource(option,mem);
	return;
}

static void
pnpbios_parse_mem32_option(unsigned char *p, int size, struct pnp_option *option)
{
	struct pnp_mem * mem;
	mem = kcalloc(1, sizeof(struct pnp_mem), GFP_KERNEL);
	if (!mem)
		return;
	mem->min = (p[7] << 24) | (p[6] << 16) | (p[5] << 8) | p[4];
	mem->max = (p[11] << 24) | (p[10] << 16) | (p[9] << 8) | p[8];
	mem->align = (p[15] << 24) | (p[14] << 16) | (p[13] << 8) | p[12];
	mem->size = (p[19] << 24) | (p[18] << 16) | (p[17] << 8) | p[16];
	mem->flags = p[3];
	pnp_register_mem_resource(option,mem);
	return;
}

static void
pnpbios_parse_fixed_mem32_option(unsigned char *p, int size, struct pnp_option *option)
{
	struct pnp_mem * mem;
	mem = kcalloc(1, sizeof(struct pnp_mem), GFP_KERNEL);
	if (!mem)
		return;
	mem->min = mem->max = (p[7] << 24) | (p[6] << 16) | (p[5] << 8) | p[4];
	mem->size = (p[11] << 24) | (p[10] << 16) | (p[9] << 8) | p[8];
	mem->align = 0;
	mem->flags = p[3];
	pnp_register_mem_resource(option,mem);
	return;
}

static void
pnpbios_parse_irq_option(unsigned char *p, int size, struct pnp_option *option)
{
	struct pnp_irq * irq;
	unsigned long bits;

	irq = kcalloc(1, sizeof(struct pnp_irq), GFP_KERNEL);
	if (!irq)
		return;
	bits = (p[2] << 8) | p[1];
	bitmap_copy(irq->map, &bits, 16);
	if (size > 2)
		irq->flags = p[3];
	else
		irq->flags = IORESOURCE_IRQ_HIGHEDGE;
	pnp_register_irq_resource(option,irq);
	return;
}

static void
pnpbios_parse_dma_option(unsigned char *p, int size, struct pnp_option *option)
{
	struct pnp_dma * dma;
	dma = kcalloc(1, sizeof(struct pnp_dma), GFP_KERNEL);
	if (!dma)
		return;
	dma->map = p[1];
	dma->flags = p[2];
	pnp_register_dma_resource(option,dma);
	return;
}

static void
pnpbios_parse_port_option(unsigned char *p, int size, struct pnp_option *option)
{
	struct pnp_port * port;
	port = kcalloc(1, sizeof(struct pnp_port), GFP_KERNEL);
	if (!port)
		return;
	port->min = (p[3] << 8) | p[2];
	port->max = (p[5] << 8) | p[4];
	port->align = p[6];
	port->size = p[7];
	port->flags = p[1] ? PNP_PORT_FLAG_16BITADDR : 0;
	pnp_register_port_resource(option,port);
	return;
}

static void
pnpbios_parse_fixed_port_option(unsigned char *p, int size, struct pnp_option *option)
{
	struct pnp_port * port;
	port = kcalloc(1, sizeof(struct pnp_port), GFP_KERNEL);
	if (!port)
		return;
	port->min = port->max = (p[2] << 8) | p[1];
	port->size = p[3];
	port->align = 0;
	port->flags = PNP_PORT_FLAG_FIXED;
	pnp_register_port_resource(option,port);
	return;
}

static unsigned char *
pnpbios_parse_resource_option_data(unsigned char * p, unsigned char * end, struct pnp_dev *dev)
{
	unsigned int len, tag;
	int priority = 0;
	struct pnp_option *option, *option_independent;

	if (!p)
		return NULL;

	option_independent = option = pnp_register_independent_option(dev);
	if (!option)
		return NULL;

	while ((char *)p < (char *)end) {

		/* determine the type of tag */
		if (p[0] & LARGE_TAG) { /* large tag */
			len = (p[2] << 8) | p[1];
			tag = p[0];
		} else { /* small tag */
			len = p[0] & 0x07;
			tag = ((p[0]>>3) & 0x0f);
		}

		switch (tag) {

		case LARGE_TAG_MEM:
			if (len != 9)
				goto len_err;
			pnpbios_parse_mem_option(p, len, option);
			break;

		case LARGE_TAG_MEM32:
			if (len != 17)
				goto len_err;
			pnpbios_parse_mem32_option(p, len, option);
			break;

		case LARGE_TAG_FIXEDMEM32:
			if (len != 9)
				goto len_err;
			pnpbios_parse_fixed_mem32_option(p, len, option);
			break;

		case SMALL_TAG_IRQ:
			if (len < 2 || len > 3)
				goto len_err;
			pnpbios_parse_irq_option(p, len, option);
			break;

		case SMALL_TAG_DMA:
			if (len != 2)
				goto len_err;
			pnpbios_parse_dma_option(p, len, option);
			break;

		case SMALL_TAG_PORT:
			if (len != 7)
				goto len_err;
			pnpbios_parse_port_option(p, len, option);
			break;

		case SMALL_TAG_VENDOR:
			/* do nothing */
			break;

		case SMALL_TAG_FIXEDPORT:
			if (len != 3)
				goto len_err;
			pnpbios_parse_fixed_port_option(p, len, option);
			break;

		case SMALL_TAG_STARTDEP:
			if (len > 1)
				goto len_err;
			priority = 0x100 | PNP_RES_PRIORITY_ACCEPTABLE;
			if (len > 0)
				priority = 0x100 | p[1];
			option = pnp_register_dependent_option(dev, priority);
			if (!option)
				return NULL;
			break;

		case SMALL_TAG_ENDDEP:
			if (len != 0)
				goto len_err;
			if (option_independent == option)
				printk(KERN_WARNING "PnPBIOS: Missing SMALL_TAG_STARTDEP tag\n");
			option = option_independent;
			break;

		case SMALL_TAG_END:
			if (option_independent != option)
				printk(KERN_WARNING "PnPBIOS: Missing SMALL_TAG_ENDDEP tag\n");
			p = p + 2;
        		return (unsigned char *)p;
			break;

		default: /* an unkown tag */
			len_err:
			printk(KERN_ERR "PnPBIOS: Unknown tag '0x%x', length '%d'.\n", tag, len);
			break;
		}

		/* continue to the next tag */
		if (p[0] & LARGE_TAG)
			p += len + 3;
		else
			p += len + 1;
	}

	printk(KERN_ERR "PnPBIOS: Resource structure does not contain an end tag.\n");

	return NULL;
}


/*
 * Compatible Device IDs
 */

#define HEX(id,a) hex[((id)>>a) & 15]
#define CHAR(id,a) (0x40 + (((id)>>a) & 31))
//

void pnpid32_to_pnpid(u32 id, char *str)
{
	const char *hex = "0123456789abcdef";

	id = be32_to_cpu(id);
	str[0] = CHAR(id, 26);
	str[1] = CHAR(id, 21);
	str[2] = CHAR(id,16);
	str[3] = HEX(id, 12);
	str[4] = HEX(id, 8);
	str[5] = HEX(id, 4);
	str[6] = HEX(id, 0);
	str[7] = '\0';

	return;
}
//
#undef CHAR
#undef HEX

static unsigned char *
pnpbios_parse_compatible_ids(unsigned char *p, unsigned char *end, struct pnp_dev *dev)
{
	int len, tag;
	char id[8];
	struct pnp_id *dev_id;

	if (!p)
		return NULL;

	while ((char *)p < (char *)end) {

		/* determine the type of tag */
		if (p[0] & LARGE_TAG) { /* large tag */
			len = (p[2] << 8) | p[1];
			tag = p[0];
		} else { /* small tag */
			len = p[0] & 0x07;
			tag = ((p[0]>>3) & 0x0f);
		}

		switch (tag) {

		case LARGE_TAG_ANSISTR:
			strncpy(dev->name, p + 3, len >= PNP_NAME_LEN ? PNP_NAME_LEN - 2 : len);
			dev->name[len >= PNP_NAME_LEN ? PNP_NAME_LEN - 1 : len] = '\0';
			break;

		case SMALL_TAG_COMPATDEVID: /* compatible ID */
			if (len != 4)
				goto len_err;
			dev_id =  kcalloc(1, sizeof (struct pnp_id), GFP_KERNEL);
			if (!dev_id)
				return NULL;
			memset(dev_id, 0, sizeof(struct pnp_id));
			pnpid32_to_pnpid(p[1] | p[2] << 8 | p[3] << 16 | p[4] << 24,id);
			memcpy(&dev_id->id, id, 7);
			pnp_add_id(dev_id, dev);
			break;

		case SMALL_TAG_END:
			p = p + 2;
        		return (unsigned char *)p;
			break;

		default: /* an unkown tag */
			len_err:
			printk(KERN_ERR "PnPBIOS: Unknown tag '0x%x', length '%d'.\n", tag, len);
			break;
		}

		/* continue to the next tag */
		if (p[0] & LARGE_TAG)
			p += len + 3;
		else
			p += len + 1;
	}

	printk(KERN_ERR "PnPBIOS: Resource structure does not contain an end tag.\n");

	return NULL;
}


/*
 * Allocated Resource Encoding
 */

static void pnpbios_encode_mem(unsigned char *p, struct resource * res)
{
	unsigned long base = res->start;
	unsigned long len = res->end - res->start + 1;
	p[4] = (base >> 8) & 0xff;
	p[5] = ((base >> 8) >> 8) & 0xff;
	p[6] = (base >> 8) & 0xff;
	p[7] = ((base >> 8) >> 8) & 0xff;
	p[10] = (len >> 8) & 0xff;
	p[11] = ((len >> 8) >> 8) & 0xff;
	return;
}

static void pnpbios_encode_mem32(unsigned char *p, struct resource * res)
{
	unsigned long base = res->start;
	unsigned long len = res->end - res->start + 1;
	p[4] = base & 0xff;
	p[5] = (base >> 8) & 0xff;
	p[6] = (base >> 16) & 0xff;
	p[7] = (base >> 24) & 0xff;
	p[8] = base & 0xff;
	p[9] = (base >> 8) & 0xff;
	p[10] = (base >> 16) & 0xff;
	p[11] = (base >> 24) & 0xff;
	p[16] = len & 0xff;
	p[17] = (len >> 8) & 0xff;
	p[18] = (len >> 16) & 0xff;
	p[19] = (len >> 24) & 0xff;
	return;
}

static void pnpbios_encode_fixed_mem32(unsigned char *p, struct resource * res)
{	unsigned long base = res->start;
	unsigned long len = res->end - res->start + 1;
	p[4] = base & 0xff;
	p[5] = (base >> 8) & 0xff;
	p[6] = (base >> 16) & 0xff;
	p[7] = (base >> 24) & 0xff;
	p[8] = len & 0xff;
	p[9] = (len >> 8) & 0xff;
	p[10] = (len >> 16) & 0xff;
	p[11] = (len >> 24) & 0xff;
	return;
}

static void pnpbios_encode_irq(unsigned char *p, struct resource * res)
{
	unsigned long map = 0;
	map = 1 << res->start;
	p[1] = map & 0xff;
	p[2] = (map >> 8) & 0xff;
	return;
}

static void pnpbios_encode_dma(unsigned char *p, struct resource * res)
{
	unsigned long map = 0;
	map = 1 << res->start;
	p[1] = map & 0xff;
	return;
}

static void pnpbios_encode_port(unsigned char *p, struct resource * res)
{
	unsigned long base = res->start;
	unsigned long len = res->end - res->start + 1;
	p[2] = base & 0xff;
	p[3] = (base >> 8) & 0xff;
	p[4] = base & 0xff;
	p[5] = (base >> 8) & 0xff;
	p[7] = len & 0xff;
	return;
}

static void pnpbios_encode_fixed_port(unsigned char *p, struct resource * res)
{
	unsigned long base = res->start;
	unsigned long len = res->end - res->start + 1;
	p[1] = base & 0xff;
	p[2] = (base >> 8) & 0xff;
	p[3] = len & 0xff;
	return;
}

static unsigned char *
pnpbios_encode_allocated_resource_data(unsigned char * p, unsigned char * end, struct pnp_resource_table * res)
{
	unsigned int len, tag;
	int port = 0, irq = 0, dma = 0, mem = 0;

	if (!p)
		return NULL;

	while ((char *)p < (char *)end) {

		/* determine the type of tag */
		if (p[0] & LARGE_TAG) { /* large tag */
			len = (p[2] << 8) | p[1];
			tag = p[0];
		} else { /* small tag */
			len = p[0] & 0x07;
			tag = ((p[0]>>3) & 0x0f);
		}

		switch (tag) {

		case LARGE_TAG_MEM:
			if (len != 9)
				goto len_err;
			pnpbios_encode_mem(p, &res->mem_resource[mem]);
			mem++;
			break;

		case LARGE_TAG_MEM32:
			if (len != 17)
				goto len_err;
			pnpbios_encode_mem32(p, &res->mem_resource[mem]);
			mem++;
			break;

		case LARGE_TAG_FIXEDMEM32:
			if (len != 9)
				goto len_err;
			pnpbios_encode_fixed_mem32(p, &res->mem_resource[mem]);
			mem++;
			break;

		case SMALL_TAG_IRQ:
			if (len < 2 || len > 3)
				goto len_err;
			pnpbios_encode_irq(p, &res->irq_resource[irq]);
			irq++;
			break;

		case SMALL_TAG_DMA:
			if (len != 2)
				goto len_err;
			pnpbios_encode_dma(p, &res->dma_resource[dma]);
			dma++;
			break;

		case SMALL_TAG_PORT:
			if (len != 7)
				goto len_err;
			pnpbios_encode_port(p, &res->port_resource[port]);
			port++;
			break;

		case SMALL_TAG_VENDOR:
			/* do nothing */
			break;

		case SMALL_TAG_FIXEDPORT:
			if (len != 3)
				goto len_err;
			pnpbios_encode_fixed_port(p, &res->port_resource[port]);
			port++;
			break;

		case SMALL_TAG_END:
			p = p + 2;
        		return (unsigned char *)p;
			break;

		default: /* an unkown tag */
			len_err:
			printk(KERN_ERR "PnPBIOS: Unknown tag '0x%x', length '%d'.\n", tag, len);
			break;
		}

		/* continue to the next tag */
		if (p[0] & LARGE_TAG)
			p += len + 3;
		else
			p += len + 1;
	}

	printk(KERN_ERR "PnPBIOS: Resource structure does not contain an end tag.\n");

	return NULL;
}


/*
 * Core Parsing Functions
 */

int
pnpbios_parse_data_stream(struct pnp_dev *dev, struct pnp_bios_node * node)
{
	unsigned char * p = (char *)node->data;
	unsigned char * end = (char *)(node->data + node->size);
	p = pnpbios_parse_allocated_resource_data(p,end,&dev->res);
	if (!p)
		return -EIO;
	p = pnpbios_parse_resource_option_data(p,end,dev);
	if (!p)
		return -EIO;
	p = pnpbios_parse_compatible_ids(p,end,dev);
	if (!p)
		return -EIO;
	return 0;
}

int
pnpbios_read_resources_from_node(struct pnp_resource_table *res,
				 struct pnp_bios_node * node)
{
	unsigned char * p = (char *)node->data;
	unsigned char * end = (char *)(node->data + node->size);
	p = pnpbios_parse_allocated_resource_data(p,end,res);
	if (!p)
		return -EIO;
	return 0;
}

int
pnpbios_write_resources_to_node(struct pnp_resource_table *res,
				struct pnp_bios_node * node)
{
	unsigned char * p = (char *)node->data;
	unsigned char * end = (char *)(node->data + node->size);
	p = pnpbios_encode_allocated_resource_data(p,end,res);
	if (!p)
		return -EIO;
	return 0;
}
