Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3695669c authored by Arnd Bergmann's avatar Arnd Bergmann
Browse files

lp: move compat_ioctl handling into lp.c



Handling for LPSETTIMEOUT can easily be done in lp_ioctl, which
is the only user. As a positive side-effect, push the BKL
into the ioctl methods.

Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
Acked-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 43c6e7b9
Loading
Loading
Loading
Loading
+89 −26
Original line number Diff line number Diff line
@@ -127,6 +127,7 @@
#include <linux/wait.h>
#include <linux/jiffies.h>
#include <linux/smp_lock.h>
#include <linux/compat.h>

#include <linux/parport.h>
#undef LP_STATS
@@ -571,13 +572,11 @@ static int lp_release(struct inode * inode, struct file * file)
	return 0;
}

static int lp_ioctl(struct inode *inode, struct file *file,
		    unsigned int cmd, unsigned long arg)
static int lp_do_ioctl(unsigned int minor, unsigned int cmd,
	unsigned long arg, void __user *argp)
{
	unsigned int minor = iminor(inode);
	int status;
	int retval = 0;
	void __user *argp = (void __user *)arg;

#ifdef LP_DEBUG
	printk(KERN_DEBUG "lp%d ioctl, cmd: 0x%x, arg: 0x%lx\n", minor, cmd, arg);
@@ -587,9 +586,6 @@ static int lp_ioctl(struct inode *inode, struct file *file,
	if ((LP_F(minor) & LP_EXIST) == 0)
		return -ENODEV;
	switch ( cmd ) {
		struct timeval par_timeout;
		long to_jiffies;

		case LPTIME:
			LP_TIME(minor) = arg * HZ/100;
			break;
@@ -652,34 +648,101 @@ static int lp_ioctl(struct inode *inode, struct file *file,
				return -EFAULT;
			break;

		case LPSETTIMEOUT:
			if (copy_from_user (&par_timeout, argp,
					    sizeof (struct timeval))) {
				return -EFAULT;
		default:
			retval = -EINVAL;
	}
	return retval;
}

static int lp_set_timeout(unsigned int minor, struct timeval *par_timeout)
{
	long to_jiffies;

	/* Convert to jiffies, place in lp_table */
			if ((par_timeout.tv_sec < 0) ||
			    (par_timeout.tv_usec < 0)) {
	if ((par_timeout->tv_sec < 0) ||
	    (par_timeout->tv_usec < 0)) {
		return -EINVAL;
	}
			to_jiffies = DIV_ROUND_UP(par_timeout.tv_usec, 1000000/HZ);
			to_jiffies += par_timeout.tv_sec * (long) HZ;
	to_jiffies = DIV_ROUND_UP(par_timeout->tv_usec, 1000000/HZ);
	to_jiffies += par_timeout->tv_sec * (long) HZ;
	if (to_jiffies <= 0) {
		return -EINVAL;
	}
	lp_table[minor].timeout = to_jiffies;
	return 0;
}

static long lp_ioctl(struct file *file, unsigned int cmd,
			unsigned long arg)
{
	unsigned int minor;
	struct timeval par_timeout;
	int ret;

	minor = iminor(file->f_path.dentry->d_inode);
	lock_kernel();
	switch (cmd) {
	case LPSETTIMEOUT:
		if (copy_from_user(&par_timeout, (void __user *)arg,
					sizeof (struct timeval))) {
			ret = -EFAULT;
			break;
		}
		ret = lp_set_timeout(minor, &par_timeout);
		break;
	default:
		ret = lp_do_ioctl(minor, cmd, arg, (void __user *)arg);
		break;
	}
	unlock_kernel();

	return ret;
}

#ifdef CONFIG_COMPAT
static long lp_compat_ioctl(struct file *file, unsigned int cmd,
			unsigned long arg)
{
	unsigned int minor;
	struct timeval par_timeout;
	struct compat_timeval __user *tc;
	int ret;

	minor = iminor(file->f_path.dentry->d_inode);
	lock_kernel();
	switch (cmd) {
	case LPSETTIMEOUT:
		tc = compat_ptr(arg);
		if (get_user(par_timeout.tv_sec, &tc->tv_sec) ||
		    get_user(par_timeout.tv_usec, &tc->tv_usec)) {
			ret = -EFAULT;
			break;
		}
		ret = lp_set_timeout(minor, &par_timeout);
		break;
#ifdef LP_STATS
	case LPGETSTATS:
		/* FIXME: add an implementation if you set LP_STATS */
		ret = -EINVAL;
		break;
#endif
	default:
			retval = -EINVAL;
		ret = lp_do_ioctl(minor, cmd, arg, compat_ptr(arg));
		break;
	}
	return retval;
	unlock_kernel();

	return ret;
}
#endif

static const struct file_operations lp_fops = {
	.owner		= THIS_MODULE,
	.write		= lp_write,
	.ioctl		= lp_ioctl,
	.unlocked_ioctl	= lp_ioctl,
#ifdef CONFIG_COMPAT
	.compat_ioctl	= lp_compat_ioctl,
#endif
	.open		= lp_open,
	.release	= lp_release,
#ifdef CONFIG_PARPORT_1284
+0 −33
Original line number Diff line number Diff line
@@ -953,20 +953,6 @@ static int rtc_ioctl(unsigned fd, unsigned cmd, void __user *argp)
	return -ENOIOCTLCMD;
}

static int
lp_timeout_trans(unsigned int fd, unsigned int cmd,
			struct compat_timeval __user *tc)
{
	struct timeval __user *tn = compat_alloc_user_space(sizeof(struct timeval));
	struct timeval ts;
	if (get_user(ts.tv_sec, &tc->tv_sec) ||
	    get_user(ts.tv_usec, &tc->tv_usec) ||
	    put_user(ts.tv_sec, &tn->tv_sec) ||
	    put_user(ts.tv_usec, &tn->tv_usec))
		return -EFAULT;
	return sys_ioctl(fd, cmd, (unsigned long)tn);
}

/* on ia32 l_start is on a 32-bit boundary */
#if defined(CONFIG_IA64) || defined(CONFIG_X86_64)
struct space_resv_32 {
@@ -1212,8 +1198,6 @@ COMPATIBLE_IOCTL(PPPIOCGCHAN)
/* PPPOX */
COMPATIBLE_IOCTL(PPPOEIOCSFWD)
COMPATIBLE_IOCTL(PPPOEIOCDFWD)
/* LP */
COMPATIBLE_IOCTL(LPGETSTATUS)
/* ppdev */
COMPATIBLE_IOCTL(PPSETMODE)
COMPATIBLE_IOCTL(PPRSTATUS)
@@ -1623,19 +1607,6 @@ COMPATIBLE_IOCTL(TIOCSTOP)
/* Usbdevfs */
COMPATIBLE_IOCTL(USBDEVFS_IOCTL32)

/* parport */
COMPATIBLE_IOCTL(LPTIME)
COMPATIBLE_IOCTL(LPCHAR)
COMPATIBLE_IOCTL(LPABORTOPEN)
COMPATIBLE_IOCTL(LPCAREFUL)
COMPATIBLE_IOCTL(LPWAIT)
COMPATIBLE_IOCTL(LPSETIRQ)
COMPATIBLE_IOCTL(LPGETSTATUS)
COMPATIBLE_IOCTL(LPGETSTATUS)
COMPATIBLE_IOCTL(LPRESET)
/*LPGETSTATS not implemented, but no kernels seem to compile it in anyways*/
COMPATIBLE_IOCTL(LPGETFLAGS)

/* fat 'r' ioctls. These are handled by fat with ->compat_ioctl,
   but we don't want warnings on other file systems. So declare
   them as compatible here. */
@@ -1734,10 +1705,6 @@ static long do_ioctl_trans(int fd, unsigned int cmd,
		return do_video_stillpicture(fd, cmd, argp);
	case VIDEO_SET_SPU_PALETTE:
		return do_video_set_spu_palette(fd, cmd, argp);

	/* lp */
	case LPSETTIMEOUT:
		return lp_timeout_trans(fd, cmd, argp);
	}

	/*