/*
 * /proc/bus/pnp interface for Plug and Play devices
 *
 * Written by David Hinds, dahinds@users.sourceforge.net
 * Modified by Thomas Hood
 *
 * The .../devices and .../<node> and .../boot/<node> files are
 * utilized by the lspnp and setpnp utilities, supplied with the
 * pcmcia-cs package.
 *     http://pcmcia-cs.sourceforge.net
 *
 * The .../escd file is utilized by the lsescd utility written by
 * Gunther Mayer.
 *     http://home.t-online.de/home/gunther.mayer/lsescd
 *
 * The .../legacy_device_resources file is not used yet.
 *
 * The other files are human-readable.
 */

//#include <pcmcia/config.h>
//#include <pcmcia/k_compat.h>

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/proc_fs.h>
#include <linux/pnpbios.h>
#include <linux/init.h>

#include <asm/uaccess.h>

#include "pnpbios.h"

static struct proc_dir_entry *proc_pnp = NULL;
static struct proc_dir_entry *proc_pnp_boot = NULL;

static int proc_read_pnpconfig(char *buf, char **start, off_t pos,
                               int count, int *eof, void *data)
{
	struct pnp_isa_config_struc pnps;

	if (pnp_bios_isapnp_config(&pnps))
		return -EIO;
	return snprintf(buf, count,
		"structure_revision %d\n"
		"number_of_CSNs %d\n"
		"ISA_read_data_port 0x%x\n",
		pnps.revision,
		pnps.no_csns,
		pnps.isa_rd_data_port
	);
}

static int proc_read_escdinfo(char *buf, char **start, off_t pos,
                              int count, int *eof, void *data)
{
	struct escd_info_struc escd;

	if (pnp_bios_escd_info(&escd))
		return -EIO;
	return snprintf(buf, count,
		"min_ESCD_write_size %d\n"
		"ESCD_size %d\n"
		"NVRAM_base 0x%x\n",
		escd.min_escd_write_size,
		escd.escd_size,
		escd.nv_storage_base
	);
}

#define MAX_SANE_ESCD_SIZE (32*1024)
static int proc_read_escd(char *buf, char **start, off_t pos,
                          int count, int *eof, void *data)
{
	struct escd_info_struc escd;
	char *tmpbuf;
	int escd_size, escd_left_to_read, n;

	if (pnp_bios_escd_info(&escd))
		return -EIO;

	/* sanity check */
	if (escd.escd_size > MAX_SANE_ESCD_SIZE) {
		printk(KERN_ERR "PnPBIOS: proc_read_escd: ESCD size reported by BIOS escd_info call is too great\n");
		return -EFBIG;
	}

	tmpbuf = kcalloc(1, escd.escd_size, GFP_KERNEL);
	if (!tmpbuf) return -ENOMEM;

	if (pnp_bios_read_escd(tmpbuf, escd.nv_storage_base)) {
		kfree(tmpbuf);
		return -EIO;
	}

	escd_size = (unsigned char)(tmpbuf[0]) + (unsigned char)(tmpbuf[1])*256;

	/* sanity check */
	if (escd_size > MAX_SANE_ESCD_SIZE) {
		printk(KERN_ERR "PnPBIOS: proc_read_escd: ESCD size reported by BIOS read_escd call is too great\n");
		return -EFBIG;
	}

	escd_left_to_read = escd_size - pos;
	if (escd_left_to_read < 0) escd_left_to_read = 0;
	if (escd_left_to_read == 0) *eof = 1;
	n = min(count,escd_left_to_read);
	memcpy(buf, tmpbuf + pos, n);
	kfree(tmpbuf);
	*start = buf;
	return n;
}

static int proc_read_legacyres(char *buf, char **start, off_t pos,
                               int count, int *eof, void *data)
{
	/* Assume that the following won't overflow the buffer */
	if (pnp_bios_get_stat_res(buf)) 
		return -EIO;

	return count;  // FIXME: Return actual length
}

static int proc_read_devices(char *buf, char **start, off_t pos,
                             int count, int *eof, void *data)
{
	struct pnp_bios_node *node;
	u8 nodenum;
	char *p = buf;

	if (pos >= 0xff)
		return 0;

	node = kcalloc(1, node_info.max_node_size, GFP_KERNEL);
	if (!node) return -ENOMEM;

	for (nodenum=pos; nodenum<0xff; ) {
		u8 thisnodenum = nodenum;
		/* 26 = the number of characters per line sprintf'ed */
		if ((p - buf + 26) > count)
			break;
		if (pnp_bios_get_dev_node(&nodenum, PNPMODE_DYNAMIC, node))
			break;
		p += sprintf(p, "%02x\t%08x\t%02x:%02x:%02x\t%04x\n",
			     node->handle, node->eisa_id,
			     node->type_code[0], node->type_code[1],
			     node->type_code[2], node->flags);
		if (nodenum <= thisnodenum) {
			printk(KERN_ERR "%s Node number 0x%x is out of sequence following node 0x%x. Aborting.\n", "PnPBIOS: proc_read_devices:", (unsigned int)nodenum, (unsigned int)thisnodenum);
			*eof = 1;
			break;
		}
	}
	kfree(node);
	if (nodenum == 0xff)
		*eof = 1;
	*start = (char *)((off_t)nodenum - pos);
	return p - buf;
}

static int proc_read_node(char *buf, char **start, off_t pos,
                          int count, int *eof, void *data)
{
	struct pnp_bios_node *node;
	int boot = (long)data >> 8;
	u8 nodenum = (long)data;
	int len;

	node = kcalloc(1, node_info.max_node_size, GFP_KERNEL);
	if (!node) return -ENOMEM;
	if (pnp_bios_get_dev_node(&nodenum, boot, node)) {
		kfree(node);
		return -EIO;
	}
	len = node->size - sizeof(struct pnp_bios_node);
	memcpy(buf, node->data, len);
	kfree(node);
	return len;
}

static int proc_write_node(struct file *file, const char __user *buf,
                           unsigned long count, void *data)
{
	struct pnp_bios_node *node;
	int boot = (long)data >> 8;
	u8 nodenum = (long)data;
	int ret = count;

	node = kcalloc(1, node_info.max_node_size, GFP_KERNEL);
	if (!node)
		return -ENOMEM;
	if (pnp_bios_get_dev_node(&nodenum, boot, node)) {
		ret = -EIO;
		goto out;
	}
	if (count != node->size - sizeof(struct pnp_bios_node)) {
		ret = -EINVAL;
		goto out;
	}
	if (copy_from_user(node->data, buf, count)) {
		ret = -EFAULT;
		goto out;
	}
	if (pnp_bios_set_dev_node(node->handle, boot, node) != 0) {
		ret = -EINVAL;
		goto out;
	}
	ret = count;
out:
	kfree(node);
	return ret;
}

int pnpbios_interface_attach_device(struct pnp_bios_node * node)
{
	char name[3];
	struct proc_dir_entry *ent;

	sprintf(name, "%02x", node->handle);

	if (!proc_pnp)
		return -EIO;
	if ( !pnpbios_dont_use_current_config ) {
		ent = create_proc_entry(name, 0, proc_pnp);
		if (ent) {
			ent->read_proc = proc_read_node;
			ent->write_proc = proc_write_node;
			ent->data = (void *)(long)(node->handle);
		}
	}

	if (!proc_pnp_boot)
		return -EIO;
	ent = create_proc_entry(name, 0, proc_pnp_boot);
	if (ent) {
		ent->read_proc = proc_read_node;
		ent->write_proc = proc_write_node;
		ent->data = (void *)(long)(node->handle+0x100);
		return 0;
	}

	return -EIO;
}

/*
 * When this is called, pnpbios functions are assumed to
 * work and the pnpbios_dont_use_current_config flag
 * should already have been set to the appropriate value
 */
int __init pnpbios_proc_init( void )
{
	proc_pnp = proc_mkdir("pnp", proc_bus);
	if (!proc_pnp)
		return -EIO;
	proc_pnp_boot = proc_mkdir("boot", proc_pnp);
	if (!proc_pnp_boot)
		return -EIO;
	create_proc_read_entry("devices", 0, proc_pnp, proc_read_devices, NULL);
	create_proc_read_entry("configuration_info", 0, proc_pnp, proc_read_pnpconfig, NULL);
	create_proc_read_entry("escd_info", 0, proc_pnp, proc_read_escdinfo, NULL);
	create_proc_read_entry("escd", S_IRUSR, proc_pnp, proc_read_escd, NULL);
	create_proc_read_entry("legacy_device_resources", 0, proc_pnp, proc_read_legacyres, NULL);

	return 0;
}

void __exit pnpbios_proc_exit(void)
{
	int i;
	char name[3];

	if (!proc_pnp)
		return;

	for (i=0; i<0xff; i++) {
		sprintf(name, "%02x", i);
		if ( !pnpbios_dont_use_current_config )
			remove_proc_entry(name, proc_pnp);
		remove_proc_entry(name, proc_pnp_boot);
	}
	remove_proc_entry("legacy_device_resources", proc_pnp);
	remove_proc_entry("escd", proc_pnp);
	remove_proc_entry("escd_info", proc_pnp);
	remove_proc_entry("configuration_info", proc_pnp);
	remove_proc_entry("devices", proc_pnp);
	remove_proc_entry("boot", proc_pnp);
	remove_proc_entry("pnp", proc_bus);

	return;
}
