/*
 * Linux/SPARC PROM Configuration Driver
 * Copyright (C) 1996 Thomas K. Dyas (tdyas@noc.rutgers.edu)
 * Copyright (C) 1996 Eddie C. Dost  (ecd@skynet.be)
 *
 * This character device driver allows user programs to access the
 * PROM device tree. It is compatible with the SunOS /dev/openprom
 * driver and the NetBSD /dev/openprom driver. The SunOS eeprom
 * utility works without any modifications.
 *
 * The driver uses a minor number under the misc device major. The
 * file read/write mode determines the type of access to the PROM.
 * Interrupts are disabled whenever the driver calls into the PROM for
 * sanity's sake.
 */

/* This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/miscdevice.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <asm/oplib.h>
#include <asm/prom.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/openpromio.h>
#ifdef CONFIG_PCI
#include <linux/pci.h>
#endif

MODULE_AUTHOR("Thomas K. Dyas (tdyas@noc.rutgers.edu) and Eddie C. Dost  (ecd@skynet.be)");
MODULE_DESCRIPTION("OPENPROM Configuration Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION("1.0");

/* Private data kept by the driver for each descriptor. */
typedef struct openprom_private_data
{
	struct device_node *current_node; /* Current node for SunOS ioctls. */
	struct device_node *lastnode; /* Last valid node used by BSD ioctls. */
} DATA;

/* ID of the PROM node containing all of the EEPROM options. */
static struct device_node *options_node;

/*
 * Copy an openpromio structure into kernel space from user space.
 * This routine does error checking to make sure that all memory
 * accesses are within bounds. A pointer to the allocated openpromio
 * structure will be placed in "*opp_p". Return value is the length
 * of the user supplied buffer.
 */
static int copyin(struct openpromio __user *info, struct openpromio **opp_p)
{
	unsigned int bufsize;

	if (!info || !opp_p)
		return -EFAULT;

	if (get_user(bufsize, &info->oprom_size))
		return -EFAULT;

	if (bufsize == 0)
		return -EINVAL;

	/* If the bufsize is too large, just limit it.
	 * Fix from Jason Rappleye.
	 */
	if (bufsize > OPROMMAXPARAM)
		bufsize = OPROMMAXPARAM;

	if (!(*opp_p = kzalloc(sizeof(int) + bufsize + 1, GFP_KERNEL)))
		return -ENOMEM;

	if (copy_from_user(&(*opp_p)->oprom_array,
			   &info->oprom_array, bufsize)) {
		kfree(*opp_p);
		return -EFAULT;
	}
	return bufsize;
}

static int getstrings(struct openpromio __user *info, struct openpromio **opp_p)
{
	int n, bufsize;
	char c;

	if (!info || !opp_p)
		return -EFAULT;

	if (!(*opp_p = kzalloc(sizeof(int) + OPROMMAXPARAM + 1, GFP_KERNEL)))
		return -ENOMEM;

	(*opp_p)->oprom_size = 0;

	n = bufsize = 0;
	while ((n < 2) && (bufsize < OPROMMAXPARAM)) {
		if (get_user(c, &info->oprom_array[bufsize])) {
			kfree(*opp_p);
			return -EFAULT;
		}
		if (c == '\0')
			n++;
		(*opp_p)->oprom_array[bufsize++] = c;
	}
	if (!n) {
		kfree(*opp_p);
		return -EINVAL;
	}
	return bufsize;
}

/*
 * Copy an openpromio structure in kernel space back to user space.
 */
static int copyout(void __user *info, struct openpromio *opp, int len)
{
	if (copy_to_user(info, opp, len))
		return -EFAULT;
	return 0;
}

static int opromgetprop(void __user *argp, struct device_node *dp, struct openpromio *op, int bufsize)
{
	const void *pval;
	int len;

	if (!dp ||
	    !(pval = of_get_property(dp, op->oprom_array, &len)) ||
	    len <= 0 || len > bufsize)
		return copyout(argp, op, sizeof(int));

	memcpy(op->oprom_array, pval, len);
	op->oprom_array[len] = '\0';
	op->oprom_size = len;

	return copyout(argp, op, sizeof(int) + bufsize);
}

static int opromnxtprop(void __user *argp, struct device_node *dp, struct openpromio *op, int bufsize)
{
	struct property *prop;
	int len;

	if (!dp)
		return copyout(argp, op, sizeof(int));
	if (op->oprom_array[0] == '\0') {
		prop = dp->properties;
		if (!prop)
			return copyout(argp, op, sizeof(int));
		len = strlen(prop->name);
	} else {
		prop = of_find_property(dp, op->oprom_array, NULL);

		if (!prop ||
		    !prop->next ||
		    (len = strlen(prop->next->name)) + 1 > bufsize)
			return copyout(argp, op, sizeof(int));

		prop = prop->next;
	}

	memcpy(op->oprom_array, prop->name, len);
	op->oprom_array[len] = '\0';
	op->oprom_size = ++len;

	return copyout(argp, op, sizeof(int) + bufsize);
}

static int opromsetopt(struct device_node *dp, struct openpromio *op, int bufsize)
{
	char *buf = op->oprom_array + strlen(op->oprom_array) + 1;
	int len = op->oprom_array + bufsize - buf;

	return of_set_property(options_node, op->oprom_array, buf, len);
}

static int opromnext(void __user *argp, unsigned int cmd, struct device_node *dp, struct openpromio *op, int bufsize, DATA *data)
{
	phandle ph;

	BUILD_BUG_ON(sizeof(phandle) != sizeof(int));

	if (bufsize < sizeof(phandle))
		return -EINVAL;

	ph = *((int *) op->oprom_array);
	if (ph) {
		dp = of_find_node_by_phandle(ph);
		if (!dp)
			return -EINVAL;

		switch (cmd) {
		case OPROMNEXT:
			dp = dp->sibling;
			break;

		case OPROMCHILD:
			dp = dp->child;
			break;

		case OPROMSETCUR:
		default:
			break;
		};
	} else {
		/* Sibling of node zero is the root node.  */
		if (cmd != OPROMNEXT)
			return -EINVAL;

		dp = of_find_node_by_path("/");
	}

	ph = 0;
	if (dp)
		ph = dp->node;

	data->current_node = dp;
	*((int *) op->oprom_array) = ph;
	op->oprom_size = sizeof(phandle);

	return copyout(argp, op, bufsize + sizeof(int));
}

static int oprompci2node(void __user *argp, struct device_node *dp, struct openpromio *op, int bufsize, DATA *data)
{
	int err = -EINVAL;

	if (bufsize >= 2*sizeof(int)) {
#ifdef CONFIG_PCI
		struct pci_dev *pdev;
		struct device_node *dp;

		pdev = pci_get_bus_and_slot (((int *) op->oprom_array)[0],
				      ((int *) op->oprom_array)[1]);

		dp = pci_device_to_OF_node(pdev);
		data->current_node = dp;
		*((int *)op->oprom_array) = dp->node;
		op->oprom_size = sizeof(int);
		err = copyout(argp, op, bufsize + sizeof(int));

		pci_dev_put(pdev);
#endif
	}

	return err;
}

static int oprompath2node(void __user *argp, struct device_node *dp, struct openpromio *op, int bufsize, DATA *data)
{
	phandle ph = 0;

	dp = of_find_node_by_path(op->oprom_array);
	if (dp)
		ph = dp->node;
	data->current_node = dp;
	*((int *)op->oprom_array) = ph;
	op->oprom_size = sizeof(int);

	return copyout(argp, op, bufsize + sizeof(int));
}

static int opromgetbootargs(void __user *argp, struct openpromio *op, int bufsize)
{
	char *buf = saved_command_line;
	int len = strlen(buf);

	if (len > bufsize)
		return -EINVAL;

	strcpy(op->oprom_array, buf);
	op->oprom_size = len;

	return copyout(argp, op, bufsize + sizeof(int));
}

/*
 *	SunOS and Solaris /dev/openprom ioctl calls.
 */
static int openprom_sunos_ioctl(struct inode * inode, struct file * file,
				unsigned int cmd, unsigned long arg,
				struct device_node *dp)
{
	DATA *data = file->private_data;
	struct openpromio *opp;
	int bufsize, error = 0;
	static int cnt;
	void __user *argp = (void __user *)arg;

	if (cmd == OPROMSETOPT)
		bufsize = getstrings(argp, &opp);
	else
		bufsize = copyin(argp, &opp);

	if (bufsize < 0)
		return bufsize;

	switch (cmd) {
	case OPROMGETOPT:
	case OPROMGETPROP:
		error = opromgetprop(argp, dp, opp, bufsize);
		break;

	case OPROMNXTOPT:
	case OPROMNXTPROP:
		error = opromnxtprop(argp, dp, opp, bufsize);
		break;

	case OPROMSETOPT:
	case OPROMSETOPT2:
		error = opromsetopt(dp, opp, bufsize);
		break;

	case OPROMNEXT:
	case OPROMCHILD:
	case OPROMSETCUR:
		error = opromnext(argp, cmd, dp, opp, bufsize, data);
		break;

	case OPROMPCI2NODE:
		error = oprompci2node(argp, dp, opp, bufsize, data);
		break;

	case OPROMPATH2NODE:
		error = oprompath2node(argp, dp, opp, bufsize, data);
		break;

	case OPROMGETBOOTARGS:
		error = opromgetbootargs(argp, opp, bufsize);
		break;

	case OPROMU2P:
	case OPROMGETCONS:
	case OPROMGETFBNAME:
		if (cnt++ < 10)
			printk(KERN_INFO "openprom_sunos_ioctl: unimplemented ioctl\n");
		error = -EINVAL;
		break;
	default:
		if (cnt++ < 10)
			printk(KERN_INFO "openprom_sunos_ioctl: cmd 0x%X, arg 0x%lX\n", cmd, arg);
		error = -EINVAL;
		break;
	}

	kfree(opp);
	return error;
}

static struct device_node *get_node(phandle n, DATA *data)
{
	struct device_node *dp = of_find_node_by_phandle(n);

	if (dp)
		data->lastnode = dp;

	return dp;
}

/* Copy in a whole string from userspace into kernelspace. */
static int copyin_string(char __user *user, size_t len, char **ptr)
{
	char *tmp;

	if ((ssize_t)len < 0 || (ssize_t)(len + 1) < 0)
		return -EINVAL;

	tmp = kmalloc(len + 1, GFP_KERNEL);
	if (!tmp)
		return -ENOMEM;

	if (copy_from_user(tmp, user, len)) {
		kfree(tmp);
		return -EFAULT;
	}

	tmp[len] = '\0';

	*ptr = tmp;

	return 0;
}

/*
 *	NetBSD /dev/openprom ioctl calls.
 */
static int opiocget(void __user *argp, DATA *data)
{
	struct opiocdesc op;
	struct device_node *dp;
	char *str;
	const void *pval;
	int err, len;

	if (copy_from_user(&op, argp, sizeof(op)))
		return -EFAULT;

	dp = get_node(op.op_nodeid, data);

	err = copyin_string(op.op_name, op.op_namelen, &str);
	if (err)
		return err;

	pval = of_get_property(dp, str, &len);
	err = 0;
	if (!pval || len > op.op_buflen) {
		err = -EINVAL;
	} else {
		op.op_buflen = len;
		if (copy_to_user(argp, &op, sizeof(op)) ||
		    copy_to_user(op.op_buf, pval, len))
			err = -EFAULT;
	}
	kfree(str);

	return err;
}

static int opiocnextprop(void __user *argp, DATA *data)
{
	struct opiocdesc op;
	struct device_node *dp;
	struct property *prop;
	char *str;
	int err, len;

	if (copy_from_user(&op, argp, sizeof(op)))
		return -EFAULT;

	dp = get_node(op.op_nodeid, data);
	if (!dp)
		return -EINVAL;

	err = copyin_string(op.op_name, op.op_namelen, &str);
	if (err)
		return err;

	if (str[0] == '\0') {
		prop = dp->properties;
	} else {
		prop = of_find_property(dp, str, NULL);
		if (prop)
			prop = prop->next;
	}
	kfree(str);

	if (!prop)
		len = 0;
	else
		len = prop->length;

	if (len > op.op_buflen)
		len = op.op_buflen;

	if (copy_to_user(argp, &op, sizeof(op)))
		return -EFAULT;

	if (len &&
	    copy_to_user(op.op_buf, prop->value, len))
		return -EFAULT;

	return 0;
}

static int opiocset(void __user *argp, DATA *data)
{
	struct opiocdesc op;
	struct device_node *dp;
	char *str, *tmp;
	int err;

	if (copy_from_user(&op, argp, sizeof(op)))
		return -EFAULT;

	dp = get_node(op.op_nodeid, data);
	if (!dp)
		return -EINVAL;

	err = copyin_string(op.op_name, op.op_namelen, &str);
	if (err)
		return err;

	err = copyin_string(op.op_buf, op.op_buflen, &tmp);
	if (err) {
		kfree(str);
		return err;
	}

	err = of_set_property(dp, str, tmp, op.op_buflen);

	kfree(str);
	kfree(tmp);

	return err;
}

static int opiocgetnext(unsigned int cmd, void __user *argp)
{
	struct device_node *dp;
	phandle nd;

	BUILD_BUG_ON(sizeof(phandle) != sizeof(int));

	if (copy_from_user(&nd, argp, sizeof(phandle)))
		return -EFAULT;

	if (nd == 0) {
		if (cmd != OPIOCGETNEXT)
			return -EINVAL;
		dp = of_find_node_by_path("/");
	} else {
		dp = of_find_node_by_phandle(nd);
		nd = 0;
		if (dp) {
			if (cmd == OPIOCGETNEXT)
				dp = dp->sibling;
			else
				dp = dp->child;
		}
	}
	if (dp)
		nd = dp->node;
	if (copy_to_user(argp, &nd, sizeof(phandle)))
		return -EFAULT;

	return 0;
}

static int openprom_bsd_ioctl(struct inode * inode, struct file * file,
			      unsigned int cmd, unsigned long arg)
{
	DATA *data = (DATA *) file->private_data;
	void __user *argp = (void __user *)arg;
	int err;

	switch (cmd) {
	case OPIOCGET:
		err = opiocget(argp, data);
		break;

	case OPIOCNEXTPROP:
		err = opiocnextprop(argp, data);
		break;

	case OPIOCSET:
		err = opiocset(argp, data);
		break;

	case OPIOCGETOPTNODE:
		BUILD_BUG_ON(sizeof(phandle) != sizeof(int));

		if (copy_to_user(argp, &options_node->node, sizeof(phandle)))
			return -EFAULT;

		return 0;

	case OPIOCGETNEXT:
	case OPIOCGETCHILD:
		err = opiocgetnext(cmd, argp);
		break;

	default:
		return -EINVAL;

	};

	return err;
}


/*
 *	Handoff control to the correct ioctl handler.
 */
static int openprom_ioctl(struct inode * inode, struct file * file,
			  unsigned int cmd, unsigned long arg)
{
	DATA *data = (DATA *) file->private_data;

	switch (cmd) {
	case OPROMGETOPT:
	case OPROMNXTOPT:
		if ((file->f_mode & FMODE_READ) == 0)
			return -EPERM;
		return openprom_sunos_ioctl(inode, file, cmd, arg,
					    options_node);

	case OPROMSETOPT:
	case OPROMSETOPT2:
		if ((file->f_mode & FMODE_WRITE) == 0)
			return -EPERM;
		return openprom_sunos_ioctl(inode, file, cmd, arg,
					    options_node);

	case OPROMNEXT:
	case OPROMCHILD:
	case OPROMGETPROP:
	case OPROMNXTPROP:
		if ((file->f_mode & FMODE_READ) == 0)
			return -EPERM;
		return openprom_sunos_ioctl(inode, file, cmd, arg,
					    data->current_node);

	case OPROMU2P:
	case OPROMGETCONS:
	case OPROMGETFBNAME:
	case OPROMGETBOOTARGS:
	case OPROMSETCUR:
	case OPROMPCI2NODE:
	case OPROMPATH2NODE:
		if ((file->f_mode & FMODE_READ) == 0)
			return -EPERM;
		return openprom_sunos_ioctl(inode, file, cmd, arg, NULL);

	case OPIOCGET:
	case OPIOCNEXTPROP:
	case OPIOCGETOPTNODE:
	case OPIOCGETNEXT:
	case OPIOCGETCHILD:
		if ((file->f_mode & FMODE_READ) == 0)
			return -EBADF;
		return openprom_bsd_ioctl(inode,file,cmd,arg);

	case OPIOCSET:
		if ((file->f_mode & FMODE_WRITE) == 0)
			return -EBADF;
		return openprom_bsd_ioctl(inode,file,cmd,arg);

	default:
		return -EINVAL;
	};
}

static long openprom_compat_ioctl(struct file *file, unsigned int cmd,
		unsigned long arg)
{
	long rval = -ENOTTY;

	/*
	 * SunOS/Solaris only, the NetBSD one's have embedded pointers in
	 * the arg which we'd need to clean up...
	 */
	switch (cmd) {
	case OPROMGETOPT:
	case OPROMSETOPT:
	case OPROMNXTOPT:
	case OPROMSETOPT2:
	case OPROMNEXT:
	case OPROMCHILD:
	case OPROMGETPROP:
	case OPROMNXTPROP:
	case OPROMU2P:
	case OPROMGETCONS:
	case OPROMGETFBNAME:
	case OPROMGETBOOTARGS:
	case OPROMSETCUR:
	case OPROMPCI2NODE:
	case OPROMPATH2NODE:
		rval = openprom_ioctl(file->f_path.dentry->d_inode, file, cmd, arg);
		break;
	}

	return rval;
}

static int openprom_open(struct inode * inode, struct file * file)
{
	DATA *data;

	data = kmalloc(sizeof(DATA), GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	data->current_node = of_find_node_by_path("/");
	data->lastnode = data->current_node;
	file->private_data = (void *) data;

	return 0;
}

static int openprom_release(struct inode * inode, struct file * file)
{
	kfree(file->private_data);
	return 0;
}

static const struct file_operations openprom_fops = {
	.owner =	THIS_MODULE,
	.llseek =	no_llseek,
	.ioctl =	openprom_ioctl,
	.compat_ioctl =	openprom_compat_ioctl,
	.open =		openprom_open,
	.release =	openprom_release,
};

static struct miscdevice openprom_dev = {
	.minor		= SUN_OPENPROM_MINOR,
	.name		= "openprom",
	.fops		= &openprom_fops,
};

static int __init openprom_init(void)
{
	struct device_node *dp;
	int err;

	err = misc_register(&openprom_dev);
	if (err)
		return err;

	dp = of_find_node_by_path("/");
	dp = dp->child;
	while (dp) {
		if (!strcmp(dp->name, "options"))
			break;
		dp = dp->sibling;
	}
	options_node = dp;

	if (!options_node) {
		misc_deregister(&openprom_dev);
		return -EIO;
	}

	return 0;
}

static void __exit openprom_cleanup(void)
{
	misc_deregister(&openprom_dev);
}

module_init(openprom_init);
module_exit(openprom_cleanup);
