aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2009-11-13 19:33:13 -0500
committerArnd Bergmann <arnd@arndb.de>2009-12-10 16:55:36 -0500
commit3695669cd4f5fb6d569fd4243312c1b4a05bd5ce (patch)
tree0e74dafb6f26ac2bbd9d0dcea019798380b55aeb
parent43c6e7b97f9ea0f4dec430dbafb6afa6ac711eb1 (diff)
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>
-rw-r--r--drivers/char/lp.c115
-rw-r--r--fs/compat_ioctl.c33
2 files changed, 89 insertions, 59 deletions
diff --git a/drivers/char/lp.c b/drivers/char/lp.c
index e444c2dba160..938a3a273886 100644
--- a/drivers/char/lp.c
+++ b/drivers/char/lp.c
@@ -127,6 +127,7 @@
127#include <linux/wait.h> 127#include <linux/wait.h>
128#include <linux/jiffies.h> 128#include <linux/jiffies.h>
129#include <linux/smp_lock.h> 129#include <linux/smp_lock.h>
130#include <linux/compat.h>
130 131
131#include <linux/parport.h> 132#include <linux/parport.h>
132#undef LP_STATS 133#undef LP_STATS
@@ -571,13 +572,11 @@ static int lp_release(struct inode * inode, struct file * file)
571 return 0; 572 return 0;
572} 573}
573 574
574static int lp_ioctl(struct inode *inode, struct file *file, 575static int lp_do_ioctl(unsigned int minor, unsigned int cmd,
575 unsigned int cmd, unsigned long arg) 576 unsigned long arg, void __user *argp)
576{ 577{
577 unsigned int minor = iminor(inode);
578 int status; 578 int status;
579 int retval = 0; 579 int retval = 0;
580 void __user *argp = (void __user *)arg;
581 580
582#ifdef LP_DEBUG 581#ifdef LP_DEBUG
583 printk(KERN_DEBUG "lp%d ioctl, cmd: 0x%x, arg: 0x%lx\n", minor, cmd, arg); 582 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,
587 if ((LP_F(minor) & LP_EXIST) == 0) 586 if ((LP_F(minor) & LP_EXIST) == 0)
588 return -ENODEV; 587 return -ENODEV;
589 switch ( cmd ) { 588 switch ( cmd ) {
590 struct timeval par_timeout;
591 long to_jiffies;
592
593 case LPTIME: 589 case LPTIME:
594 LP_TIME(minor) = arg * HZ/100; 590 LP_TIME(minor) = arg * HZ/100;
595 break; 591 break;
@@ -652,34 +648,101 @@ static int lp_ioctl(struct inode *inode, struct file *file,
652 return -EFAULT; 648 return -EFAULT;
653 break; 649 break;
654 650
655 case LPSETTIMEOUT:
656 if (copy_from_user (&par_timeout, argp,
657 sizeof (struct timeval))) {
658 return -EFAULT;
659 }
660 /* Convert to jiffies, place in lp_table */
661 if ((par_timeout.tv_sec < 0) ||
662 (par_timeout.tv_usec < 0)) {
663 return -EINVAL;
664 }
665 to_jiffies = DIV_ROUND_UP(par_timeout.tv_usec, 1000000/HZ);
666 to_jiffies += par_timeout.tv_sec * (long) HZ;
667 if (to_jiffies <= 0) {
668 return -EINVAL;
669 }
670 lp_table[minor].timeout = to_jiffies;
671 break;
672
673 default: 651 default:
674 retval = -EINVAL; 652 retval = -EINVAL;
675 } 653 }
676 return retval; 654 return retval;
677} 655}
678 656
657static int lp_set_timeout(unsigned int minor, struct timeval *par_timeout)
658{
659 long to_jiffies;
660
661 /* Convert to jiffies, place in lp_table */
662 if ((par_timeout->tv_sec < 0) ||
663 (par_timeout->tv_usec < 0)) {
664 return -EINVAL;
665 }
666 to_jiffies = DIV_ROUND_UP(par_timeout->tv_usec, 1000000/HZ);
667 to_jiffies += par_timeout->tv_sec * (long) HZ;
668 if (to_jiffies <= 0) {
669 return -EINVAL;
670 }
671 lp_table[minor].timeout = to_jiffies;
672 return 0;
673}
674
675static long lp_ioctl(struct file *file, unsigned int cmd,
676 unsigned long arg)
677{
678 unsigned int minor;
679 struct timeval par_timeout;
680 int ret;
681
682 minor = iminor(file->f_path.dentry->d_inode);
683 lock_kernel();
684 switch (cmd) {
685 case LPSETTIMEOUT:
686 if (copy_from_user(&par_timeout, (void __user *)arg,
687 sizeof (struct timeval))) {
688 ret = -EFAULT;
689 break;
690 }
691 ret = lp_set_timeout(minor, &par_timeout);
692 break;
693 default:
694 ret = lp_do_ioctl(minor, cmd, arg, (void __user *)arg);
695 break;
696 }
697 unlock_kernel();
698
699 return ret;
700}
701
702#ifdef CONFIG_COMPAT
703static long lp_compat_ioctl(struct file *file, unsigned int cmd,
704 unsigned long arg)
705{
706 unsigned int minor;
707 struct timeval par_timeout;
708 struct compat_timeval __user *tc;
709 int ret;
710
711 minor = iminor(file->f_path.dentry->d_inode);
712 lock_kernel();
713 switch (cmd) {
714 case LPSETTIMEOUT:
715 tc = compat_ptr(arg);
716 if (get_user(par_timeout.tv_sec, &tc->tv_sec) ||
717 get_user(par_timeout.tv_usec, &tc->tv_usec)) {
718 ret = -EFAULT;
719 break;
720 }
721 ret = lp_set_timeout(minor, &par_timeout);
722 break;
723#ifdef LP_STATS
724 case LPGETSTATS:
725 /* FIXME: add an implementation if you set LP_STATS */
726 ret = -EINVAL;
727 break;
728#endif
729 default:
730 ret = lp_do_ioctl(minor, cmd, arg, compat_ptr(arg));
731 break;
732 }
733 unlock_kernel();
734
735 return ret;
736}
737#endif
738
679static const struct file_operations lp_fops = { 739static const struct file_operations lp_fops = {
680 .owner = THIS_MODULE, 740 .owner = THIS_MODULE,
681 .write = lp_write, 741 .write = lp_write,
682 .ioctl = lp_ioctl, 742 .unlocked_ioctl = lp_ioctl,
743#ifdef CONFIG_COMPAT
744 .compat_ioctl = lp_compat_ioctl,
745#endif
683 .open = lp_open, 746 .open = lp_open,
684 .release = lp_release, 747 .release = lp_release,
685#ifdef CONFIG_PARPORT_1284 748#ifdef CONFIG_PARPORT_1284
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index ae1f1e699ad7..598763fd207f 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -953,20 +953,6 @@ static int rtc_ioctl(unsigned fd, unsigned cmd, void __user *argp)
953 return -ENOIOCTLCMD; 953 return -ENOIOCTLCMD;
954} 954}
955 955
956static int
957lp_timeout_trans(unsigned int fd, unsigned int cmd,
958 struct compat_timeval __user *tc)
959{
960 struct timeval __user *tn = compat_alloc_user_space(sizeof(struct timeval));
961 struct timeval ts;
962 if (get_user(ts.tv_sec, &tc->tv_sec) ||
963 get_user(ts.tv_usec, &tc->tv_usec) ||
964 put_user(ts.tv_sec, &tn->tv_sec) ||
965 put_user(ts.tv_usec, &tn->tv_usec))
966 return -EFAULT;
967 return sys_ioctl(fd, cmd, (unsigned long)tn);
968}
969
970/* on ia32 l_start is on a 32-bit boundary */ 956/* on ia32 l_start is on a 32-bit boundary */
971#if defined(CONFIG_IA64) || defined(CONFIG_X86_64) 957#if defined(CONFIG_IA64) || defined(CONFIG_X86_64)
972struct space_resv_32 { 958struct space_resv_32 {
@@ -1212,8 +1198,6 @@ COMPATIBLE_IOCTL(PPPIOCGCHAN)
1212/* PPPOX */ 1198/* PPPOX */
1213COMPATIBLE_IOCTL(PPPOEIOCSFWD) 1199COMPATIBLE_IOCTL(PPPOEIOCSFWD)
1214COMPATIBLE_IOCTL(PPPOEIOCDFWD) 1200COMPATIBLE_IOCTL(PPPOEIOCDFWD)
1215/* LP */
1216COMPATIBLE_IOCTL(LPGETSTATUS)
1217/* ppdev */ 1201/* ppdev */
1218COMPATIBLE_IOCTL(PPSETMODE) 1202COMPATIBLE_IOCTL(PPSETMODE)
1219COMPATIBLE_IOCTL(PPRSTATUS) 1203COMPATIBLE_IOCTL(PPRSTATUS)
@@ -1623,19 +1607,6 @@ COMPATIBLE_IOCTL(TIOCSTOP)
1623/* Usbdevfs */ 1607/* Usbdevfs */
1624COMPATIBLE_IOCTL(USBDEVFS_IOCTL32) 1608COMPATIBLE_IOCTL(USBDEVFS_IOCTL32)
1625 1609
1626/* parport */
1627COMPATIBLE_IOCTL(LPTIME)
1628COMPATIBLE_IOCTL(LPCHAR)
1629COMPATIBLE_IOCTL(LPABORTOPEN)
1630COMPATIBLE_IOCTL(LPCAREFUL)
1631COMPATIBLE_IOCTL(LPWAIT)
1632COMPATIBLE_IOCTL(LPSETIRQ)
1633COMPATIBLE_IOCTL(LPGETSTATUS)
1634COMPATIBLE_IOCTL(LPGETSTATUS)
1635COMPATIBLE_IOCTL(LPRESET)
1636/*LPGETSTATS not implemented, but no kernels seem to compile it in anyways*/
1637COMPATIBLE_IOCTL(LPGETFLAGS)
1638
1639/* fat 'r' ioctls. These are handled by fat with ->compat_ioctl, 1610/* fat 'r' ioctls. These are handled by fat with ->compat_ioctl,
1640 but we don't want warnings on other file systems. So declare 1611 but we don't want warnings on other file systems. So declare
1641 them as compatible here. */ 1612 them as compatible here. */
@@ -1734,10 +1705,6 @@ static long do_ioctl_trans(int fd, unsigned int cmd,
1734 return do_video_stillpicture(fd, cmd, argp); 1705 return do_video_stillpicture(fd, cmd, argp);
1735 case VIDEO_SET_SPU_PALETTE: 1706 case VIDEO_SET_SPU_PALETTE:
1736 return do_video_set_spu_palette(fd, cmd, argp); 1707 return do_video_set_spu_palette(fd, cmd, argp);
1737
1738 /* lp */
1739 case LPSETTIMEOUT:
1740 return lp_timeout_trans(fd, cmd, argp);
1741 } 1708 }
1742 1709
1743 /* 1710 /*