Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+89 -59
+89 -26
drivers/char/lp.c
··· 127 127 #include <linux/wait.h> 128 128 #include <linux/jiffies.h> 129 129 #include <linux/smp_lock.h> 130 + #include <linux/compat.h> 130 131 131 132 #include <linux/parport.h> 132 133 #undef LP_STATS ··· 572 571 return 0; 573 572 } 574 573 575 - static int lp_ioctl(struct inode *inode, struct file *file, 576 - unsigned int cmd, unsigned long arg) 574 + static int lp_do_ioctl(unsigned int minor, unsigned int cmd, 575 + unsigned long arg, void __user *argp) 577 576 { 578 - unsigned int minor = iminor(inode); 579 577 int status; 580 578 int retval = 0; 581 - void __user *argp = (void __user *)arg; 582 579 583 580 #ifdef LP_DEBUG 584 581 printk(KERN_DEBUG "lp%d ioctl, cmd: 0x%x, arg: 0x%lx\n", minor, cmd, arg); ··· 586 587 if ((LP_F(minor) & LP_EXIST) == 0) 587 588 return -ENODEV; 588 589 switch ( cmd ) { 589 - struct timeval par_timeout; 590 - long to_jiffies; 591 - 592 590 case LPTIME: 593 591 LP_TIME(minor) = arg * HZ/100; 594 592 break; ··· 648 652 return -EFAULT; 649 653 break; 650 654 651 - case LPSETTIMEOUT: 652 - if (copy_from_user (&par_timeout, argp, 653 - sizeof (struct timeval))) { 654 - return -EFAULT; 655 - } 656 - /* Convert to jiffies, place in lp_table */ 657 - if ((par_timeout.tv_sec < 0) || 658 - (par_timeout.tv_usec < 0)) { 659 - return -EINVAL; 660 - } 661 - to_jiffies = DIV_ROUND_UP(par_timeout.tv_usec, 1000000/HZ); 662 - to_jiffies += par_timeout.tv_sec * (long) HZ; 663 - if (to_jiffies <= 0) { 664 - return -EINVAL; 665 - } 666 - lp_table[minor].timeout = to_jiffies; 667 - break; 668 - 669 655 default: 670 656 retval = -EINVAL; 671 657 } 672 658 return retval; 673 659 } 674 660 661 + static int lp_set_timeout(unsigned int minor, struct timeval *par_timeout) 662 + { 663 + long to_jiffies; 664 + 665 + /* Convert to jiffies, place in lp_table */ 666 + if ((par_timeout->tv_sec < 0) || 667 + (par_timeout->tv_usec < 0)) { 668 + return -EINVAL; 669 + } 670 + to_jiffies = DIV_ROUND_UP(par_timeout->tv_usec, 1000000/HZ); 671 + to_jiffies += par_timeout->tv_sec * (long) HZ; 672 + if (to_jiffies <= 0) { 673 + return -EINVAL; 674 + } 675 + lp_table[minor].timeout = to_jiffies; 676 + return 0; 677 + } 678 + 679 + static long lp_ioctl(struct file *file, unsigned int cmd, 680 + unsigned long arg) 681 + { 682 + unsigned int minor; 683 + struct timeval par_timeout; 684 + int ret; 685 + 686 + minor = iminor(file->f_path.dentry->d_inode); 687 + lock_kernel(); 688 + switch (cmd) { 689 + case LPSETTIMEOUT: 690 + if (copy_from_user(&par_timeout, (void __user *)arg, 691 + sizeof (struct timeval))) { 692 + ret = -EFAULT; 693 + break; 694 + } 695 + ret = lp_set_timeout(minor, &par_timeout); 696 + break; 697 + default: 698 + ret = lp_do_ioctl(minor, cmd, arg, (void __user *)arg); 699 + break; 700 + } 701 + unlock_kernel(); 702 + 703 + return ret; 704 + } 705 + 706 + #ifdef CONFIG_COMPAT 707 + static long lp_compat_ioctl(struct file *file, unsigned int cmd, 708 + unsigned long arg) 709 + { 710 + unsigned int minor; 711 + struct timeval par_timeout; 712 + struct compat_timeval __user *tc; 713 + int ret; 714 + 715 + minor = iminor(file->f_path.dentry->d_inode); 716 + lock_kernel(); 717 + switch (cmd) { 718 + case LPSETTIMEOUT: 719 + tc = compat_ptr(arg); 720 + if (get_user(par_timeout.tv_sec, &tc->tv_sec) || 721 + get_user(par_timeout.tv_usec, &tc->tv_usec)) { 722 + ret = -EFAULT; 723 + break; 724 + } 725 + ret = lp_set_timeout(minor, &par_timeout); 726 + break; 727 + #ifdef LP_STATS 728 + case LPGETSTATS: 729 + /* FIXME: add an implementation if you set LP_STATS */ 730 + ret = -EINVAL; 731 + break; 732 + #endif 733 + default: 734 + ret = lp_do_ioctl(minor, cmd, arg, compat_ptr(arg)); 735 + break; 736 + } 737 + unlock_kernel(); 738 + 739 + return ret; 740 + } 741 + #endif 742 + 675 743 static const struct file_operations lp_fops = { 676 744 .owner = THIS_MODULE, 677 745 .write = lp_write, 678 - .ioctl = lp_ioctl, 746 + .unlocked_ioctl = lp_ioctl, 747 + #ifdef CONFIG_COMPAT 748 + .compat_ioctl = lp_compat_ioctl, 749 + #endif 679 750 .open = lp_open, 680 751 .release = lp_release, 681 752 #ifdef CONFIG_PARPORT_1284
-33
fs/compat_ioctl.c
··· 953 953 return -ENOIOCTLCMD; 954 954 } 955 955 956 - static int 957 - lp_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 956 /* on ia32 l_start is on a 32-bit boundary */ 971 957 #if defined(CONFIG_IA64) || defined(CONFIG_X86_64) 972 958 struct space_resv_32 { ··· 1198 1212 /* PPPOX */ 1199 1213 COMPATIBLE_IOCTL(PPPOEIOCSFWD) 1200 1214 COMPATIBLE_IOCTL(PPPOEIOCDFWD) 1201 - /* LP */ 1202 - COMPATIBLE_IOCTL(LPGETSTATUS) 1203 1215 /* ppdev */ 1204 1216 COMPATIBLE_IOCTL(PPSETMODE) 1205 1217 COMPATIBLE_IOCTL(PPRSTATUS) ··· 1607 1623 /* Usbdevfs */ 1608 1624 COMPATIBLE_IOCTL(USBDEVFS_IOCTL32) 1609 1625 1610 - /* parport */ 1611 - COMPATIBLE_IOCTL(LPTIME) 1612 - COMPATIBLE_IOCTL(LPCHAR) 1613 - COMPATIBLE_IOCTL(LPABORTOPEN) 1614 - COMPATIBLE_IOCTL(LPCAREFUL) 1615 - COMPATIBLE_IOCTL(LPWAIT) 1616 - COMPATIBLE_IOCTL(LPSETIRQ) 1617 - COMPATIBLE_IOCTL(LPGETSTATUS) 1618 - COMPATIBLE_IOCTL(LPGETSTATUS) 1619 - COMPATIBLE_IOCTL(LPRESET) 1620 - /*LPGETSTATS not implemented, but no kernels seem to compile it in anyways*/ 1621 - COMPATIBLE_IOCTL(LPGETFLAGS) 1622 - 1623 1626 /* fat 'r' ioctls. These are handled by fat with ->compat_ioctl, 1624 1627 but we don't want warnings on other file systems. So declare 1625 1628 them as compatible here. */ ··· 1705 1734 return do_video_stillpicture(fd, cmd, argp); 1706 1735 case VIDEO_SET_SPU_PALETTE: 1707 1736 return do_video_set_spu_palette(fd, cmd, argp); 1708 - 1709 - /* lp */ 1710 - case LPSETTIMEOUT: 1711 - return lp_timeout_trans(fd, cmd, argp); 1712 1737 } 1713 1738 1714 1739 /*