/*
 * /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 <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 = kzalloc(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");
		kfree(tmpbuf);
		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 = kzalloc(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 = kzalloc(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 = kzalloc(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);
}
