/*
 * 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/mutex.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 <linux/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");
MODULE_ALIAS_MISCDEV(SUN_OPENPROM_MINOR);

/* 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 DEFINE_MUTEX(openprom_mutex);
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->phandle;

	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->phandle;
		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->phandle;
	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 long openprom_sunos_ioctl(struct file * file,
				 unsigned int cmd, unsigned long arg,
				 struct device_node *dp)
{
	DATA *data = file->private_data;
	struct openpromio *opp = NULL;
	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;

	mutex_lock(&openprom_mutex);

	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);
	mutex_unlock(&openprom_mutex);

	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 char * copyin_string(char __user *user, size_t len)
{
	if ((ssize_t)len < 0 || (ssize_t)(len + 1) < 0)
		return ERR_PTR(-EINVAL);

	return memdup_user_nul(user, len);
}

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

	str = copyin_string(op.op_name, op.op_namelen);
	if (IS_ERR(str))
		return PTR_ERR(str);

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

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

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

	str = copyin_string(op.op_name, op.op_namelen);
	if (IS_ERR(str))
		return PTR_ERR(str);

	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;

	str = copyin_string(op.op_name, op.op_namelen);
	if (IS_ERR(str))
		return PTR_ERR(str);

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

	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->phandle;
	if (copy_to_user(argp, &nd, sizeof(phandle)))
		return -EFAULT;

	return 0;
}

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

	mutex_lock(&openprom_mutex);
	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));

		err = 0;
		if (copy_to_user(argp, &options_node->phandle, sizeof(phandle)))
			err = -EFAULT;
		break;

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

	default:
		err = -EINVAL;
		break;
	}
	mutex_unlock(&openprom_mutex);

	return err;
}


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

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

	case OPROMSETOPT:
	case OPROMSETOPT2:
		if ((file->f_mode & FMODE_WRITE) == 0)
			return -EPERM;
		return openprom_sunos_ioctl(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(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(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(file,cmd,arg);

	case OPIOCSET:
		if ((file->f_mode & FMODE_WRITE) == 0)
			return -EBADF;
		return openprom_bsd_ioctl(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, 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;

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

	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,
	.unlocked_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);
