/*
 * 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>
#include <asm/pbm.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)
{
	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 pcidev_cookie *pcp;
		pdev = pci_find_slot (((int *) op->oprom_array)[0],
				      ((int *) op->oprom_array)[1]);

		pcp = pdev->sysdata;
		if (pcp != NULL) {
			dp = pcp->prom_node;
			data->current_node = dp;
			*((int *)op->oprom_array) = dp->node;
			op->oprom_size = sizeof(int);
			err = copyout(argp, op, bufsize + sizeof(int));
		}
#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;
	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);
