mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-08 14:13:53 +00:00
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: Arnd Bergmann <arnd@arndb.de> Acked-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
43c6e7b97f
commit
3695669cd4
@ -127,6 +127,7 @@
|
|||||||
#include <linux/wait.h>
|
#include <linux/wait.h>
|
||||||
#include <linux/jiffies.h>
|
#include <linux/jiffies.h>
|
||||||
#include <linux/smp_lock.h>
|
#include <linux/smp_lock.h>
|
||||||
|
#include <linux/compat.h>
|
||||||
|
|
||||||
#include <linux/parport.h>
|
#include <linux/parport.h>
|
||||||
#undef LP_STATS
|
#undef LP_STATS
|
||||||
@ -571,13 +572,11 @@ static int lp_release(struct inode * inode, struct file * file)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int lp_ioctl(struct inode *inode, struct file *file,
|
static int lp_do_ioctl(unsigned int minor, unsigned int cmd,
|
||||||
unsigned int cmd, unsigned long arg)
|
unsigned long arg, void __user *argp)
|
||||||
{
|
{
|
||||||
unsigned int minor = iminor(inode);
|
|
||||||
int status;
|
int status;
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
void __user *argp = (void __user *)arg;
|
|
||||||
|
|
||||||
#ifdef LP_DEBUG
|
#ifdef LP_DEBUG
|
||||||
printk(KERN_DEBUG "lp%d ioctl, cmd: 0x%x, arg: 0x%lx\n", minor, cmd, arg);
|
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)
|
if ((LP_F(minor) & LP_EXIST) == 0)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
switch ( cmd ) {
|
switch ( cmd ) {
|
||||||
struct timeval par_timeout;
|
|
||||||
long to_jiffies;
|
|
||||||
|
|
||||||
case LPTIME:
|
case LPTIME:
|
||||||
LP_TIME(minor) = arg * HZ/100;
|
LP_TIME(minor) = arg * HZ/100;
|
||||||
break;
|
break;
|
||||||
@ -652,34 +648,101 @@ static int lp_ioctl(struct inode *inode, struct file *file,
|
|||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LPSETTIMEOUT:
|
|
||||||
if (copy_from_user (&par_timeout, argp,
|
|
||||||
sizeof (struct timeval))) {
|
|
||||||
return -EFAULT;
|
|
||||||
}
|
|
||||||
/* Convert to jiffies, place in lp_table */
|
|
||||||
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;
|
|
||||||
if (to_jiffies <= 0) {
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
lp_table[minor].timeout = to_jiffies;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
retval = -EINVAL;
|
retval = -EINVAL;
|
||||||
}
|
}
|
||||||
return retval;
|
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)) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
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:
|
||||||
|
ret = lp_do_ioctl(minor, cmd, arg, compat_ptr(arg));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
unlock_kernel();
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static const struct file_operations lp_fops = {
|
static const struct file_operations lp_fops = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.write = lp_write,
|
.write = lp_write,
|
||||||
.ioctl = lp_ioctl,
|
.unlocked_ioctl = lp_ioctl,
|
||||||
|
#ifdef CONFIG_COMPAT
|
||||||
|
.compat_ioctl = lp_compat_ioctl,
|
||||||
|
#endif
|
||||||
.open = lp_open,
|
.open = lp_open,
|
||||||
.release = lp_release,
|
.release = lp_release,
|
||||||
#ifdef CONFIG_PARPORT_1284
|
#ifdef CONFIG_PARPORT_1284
|
||||||
|
@ -953,20 +953,6 @@ static int rtc_ioctl(unsigned fd, unsigned cmd, void __user *argp)
|
|||||||
return -ENOIOCTLCMD;
|
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 */
|
/* on ia32 l_start is on a 32-bit boundary */
|
||||||
#if defined(CONFIG_IA64) || defined(CONFIG_X86_64)
|
#if defined(CONFIG_IA64) || defined(CONFIG_X86_64)
|
||||||
struct space_resv_32 {
|
struct space_resv_32 {
|
||||||
@ -1212,8 +1198,6 @@ COMPATIBLE_IOCTL(PPPIOCGCHAN)
|
|||||||
/* PPPOX */
|
/* PPPOX */
|
||||||
COMPATIBLE_IOCTL(PPPOEIOCSFWD)
|
COMPATIBLE_IOCTL(PPPOEIOCSFWD)
|
||||||
COMPATIBLE_IOCTL(PPPOEIOCDFWD)
|
COMPATIBLE_IOCTL(PPPOEIOCDFWD)
|
||||||
/* LP */
|
|
||||||
COMPATIBLE_IOCTL(LPGETSTATUS)
|
|
||||||
/* ppdev */
|
/* ppdev */
|
||||||
COMPATIBLE_IOCTL(PPSETMODE)
|
COMPATIBLE_IOCTL(PPSETMODE)
|
||||||
COMPATIBLE_IOCTL(PPRSTATUS)
|
COMPATIBLE_IOCTL(PPRSTATUS)
|
||||||
@ -1623,19 +1607,6 @@ COMPATIBLE_IOCTL(TIOCSTOP)
|
|||||||
/* Usbdevfs */
|
/* Usbdevfs */
|
||||||
COMPATIBLE_IOCTL(USBDEVFS_IOCTL32)
|
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,
|
/* fat 'r' ioctls. These are handled by fat with ->compat_ioctl,
|
||||||
but we don't want warnings on other file systems. So declare
|
but we don't want warnings on other file systems. So declare
|
||||||
them as compatible here. */
|
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);
|
return do_video_stillpicture(fd, cmd, argp);
|
||||||
case VIDEO_SET_SPU_PALETTE:
|
case VIDEO_SET_SPU_PALETTE:
|
||||||
return do_video_set_spu_palette(fd, cmd, argp);
|
return do_video_set_spu_palette(fd, cmd, argp);
|
||||||
|
|
||||||
/* lp */
|
|
||||||
case LPSETTIMEOUT:
|
|
||||||
return lp_timeout_trans(fd, cmd, argp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user