aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2009-11-13 20:28:05 -0500
committerArnd Bergmann <arnd@arndb.de>2009-12-10 16:55:37 -0500
commit637e8a60a7aaf4ef7d46cfdf83bcfac9cf6f0fbd (patch)
tree5d50aaa8bcdf0b5f9af5c24ff6adcdb9d482cd9c
parent3695669cd4f5fb6d569fd4243312c1b4a05bd5ce (diff)
usbdevfs: move compat_ioctl handling to devio.c
Half the compat_ioctl handling is in devio.c, the other half is in fs/compat_ioctl.c. This moves everything into one place for consistency. As a positive side-effect, push down the BKL into the ioctl methods. Signed-off-by: Arnd Bergmann <arnd@arndb.de> Acked-by: Greg Kroah-Hartman <gregkh@suse.de> Cc: Alan Stern <stern@rowland.harvard.edu> Cc: Oliver Neukum <oliver@neukum.org> Cc: Alon Bar-Lev <alon.barlev@gmail.com> Cc: David Vrabel <david.vrabel@csr.com> Cc: linux-usb@vger.kernel.org
-rw-r--r--drivers/usb/core/devio.c110
-rw-r--r--fs/compat_ioctl.c112
-rw-r--r--include/linux/usbdevice_fs.h26
3 files changed, 125 insertions, 123 deletions
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index 181f78c84105..6e8bcdfd23b4 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -1388,6 +1388,46 @@ static int proc_reapurbnonblock(struct dev_state *ps, void __user *arg)
1388} 1388}
1389 1389
1390#ifdef CONFIG_COMPAT 1390#ifdef CONFIG_COMPAT
1391static int proc_control_compat(struct dev_state *ps,
1392 struct usbdevfs_ctrltransfer32 __user *p32)
1393{
1394 struct usbdevfs_ctrltransfer __user *p;
1395 __u32 udata;
1396 p = compat_alloc_user_space(sizeof(*p));
1397 if (copy_in_user(p, p32, (sizeof(*p32) - sizeof(compat_caddr_t))) ||
1398 get_user(udata, &p32->data) ||
1399 put_user(compat_ptr(udata), &p->data))
1400 return -EFAULT;
1401 return proc_control(ps, p);
1402}
1403
1404static int proc_bulk_compat(struct dev_state *ps,
1405 struct usbdevfs_bulktransfer32 __user *p32)
1406{
1407 struct usbdevfs_bulktransfer __user *p;
1408 compat_uint_t n;
1409 compat_caddr_t addr;
1410
1411 p = compat_alloc_user_space(sizeof(*p));
1412
1413 if (get_user(n, &p32->ep) || put_user(n, &p->ep) ||
1414 get_user(n, &p32->len) || put_user(n, &p->len) ||
1415 get_user(n, &p32->timeout) || put_user(n, &p->timeout) ||
1416 get_user(addr, &p32->data) || put_user(compat_ptr(addr), &p->data))
1417 return -EFAULT;
1418
1419 return proc_bulk(ps, p);
1420}
1421static int proc_disconnectsignal_compat(struct dev_state *ps, void __user *arg)
1422{
1423 struct usbdevfs_disconnectsignal32 ds;
1424
1425 if (copy_from_user(&ds, arg, sizeof(ds)))
1426 return -EFAULT;
1427 ps->discsignr = ds.signr;
1428 ps->disccontext = compat_ptr(ds.context);
1429 return 0;
1430}
1391 1431
1392static int get_urb32(struct usbdevfs_urb *kurb, 1432static int get_urb32(struct usbdevfs_urb *kurb,
1393 struct usbdevfs_urb32 __user *uurb) 1433 struct usbdevfs_urb32 __user *uurb)
@@ -1482,6 +1522,7 @@ static int proc_reapurbnonblock_compat(struct dev_state *ps, void __user *arg)
1482 return processcompl_compat(as, (void __user * __user *)arg); 1522 return processcompl_compat(as, (void __user * __user *)arg);
1483} 1523}
1484 1524
1525
1485#endif 1526#endif
1486 1527
1487static int proc_disconnectsignal(struct dev_state *ps, void __user *arg) 1528static int proc_disconnectsignal(struct dev_state *ps, void __user *arg)
@@ -1648,12 +1689,12 @@ static int proc_release_port(struct dev_state *ps, void __user *arg)
1648 * are assuming that somehow the configuration has been prevented from 1689 * are assuming that somehow the configuration has been prevented from
1649 * changing. But there's no mechanism to ensure that... 1690 * changing. But there's no mechanism to ensure that...
1650 */ 1691 */
1651static int usbdev_ioctl(struct inode *inode, struct file *file, 1692static long usbdev_do_ioctl(struct file *file, unsigned int cmd,
1652 unsigned int cmd, unsigned long arg) 1693 void __user *p)
1653{ 1694{
1654 struct dev_state *ps = file->private_data; 1695 struct dev_state *ps = file->private_data;
1696 struct inode *inode = file->f_path.dentry->d_inode;
1655 struct usb_device *dev = ps->dev; 1697 struct usb_device *dev = ps->dev;
1656 void __user *p = (void __user *)arg;
1657 int ret = -ENOTTY; 1698 int ret = -ENOTTY;
1658 1699
1659 if (!(file->f_mode & FMODE_WRITE)) 1700 if (!(file->f_mode & FMODE_WRITE))
@@ -1726,6 +1767,24 @@ static int usbdev_ioctl(struct inode *inode, struct file *file,
1726 break; 1767 break;
1727 1768
1728#ifdef CONFIG_COMPAT 1769#ifdef CONFIG_COMPAT
1770 case USBDEVFS_CONTROL32:
1771 snoop(&dev->dev, "%s: CONTROL32\n", __func__);
1772 ret = proc_control_compat(ps, p);
1773 if (ret >= 0)
1774 inode->i_mtime = CURRENT_TIME;
1775 break;
1776
1777 case USBDEVFS_BULK32:
1778 snoop(&dev->dev, "%s: BULK32\n", __func__);
1779 ret = proc_bulk_compat(ps, p);
1780 if (ret >= 0)
1781 inode->i_mtime = CURRENT_TIME;
1782 break;
1783
1784 case USBDEVFS_DISCSIGNAL32:
1785 snoop(&dev->dev, "%s: DISCSIGNAL32\n", __func__);
1786 ret = proc_disconnectsignal_compat(ps, p);
1787 break;
1729 1788
1730 case USBDEVFS_SUBMITURB32: 1789 case USBDEVFS_SUBMITURB32:
1731 snoop(&dev->dev, "%s: SUBMITURB32\n", __func__); 1790 snoop(&dev->dev, "%s: SUBMITURB32\n", __func__);
@@ -1745,7 +1804,7 @@ static int usbdev_ioctl(struct inode *inode, struct file *file,
1745 break; 1804 break;
1746 1805
1747 case USBDEVFS_IOCTL32: 1806 case USBDEVFS_IOCTL32:
1748 snoop(&dev->dev, "%s: IOCTL\n", __func__); 1807 snoop(&dev->dev, "%s: IOCTL32\n", __func__);
1749 ret = proc_ioctl_compat(ps, ptr_to_compat(p)); 1808 ret = proc_ioctl_compat(ps, ptr_to_compat(p));
1750 break; 1809 break;
1751#endif 1810#endif
@@ -1801,6 +1860,32 @@ static int usbdev_ioctl(struct inode *inode, struct file *file,
1801 return ret; 1860 return ret;
1802} 1861}
1803 1862
1863static long usbdev_ioctl(struct file *file, unsigned int cmd,
1864 unsigned long arg)
1865{
1866 int ret;
1867
1868 lock_kernel();
1869 ret = usbdev_do_ioctl(file, cmd, (void __user *)arg);
1870 unlock_kernel();
1871
1872 return ret;
1873}
1874
1875#ifdef CONFIG_COMPAT
1876static long usbdev_compat_ioctl(struct file *file, unsigned int cmd,
1877 unsigned long arg)
1878{
1879 int ret;
1880
1881 lock_kernel();
1882 ret = usbdev_do_ioctl(file, cmd, compat_ptr(arg));
1883 unlock_kernel();
1884
1885 return ret;
1886}
1887#endif
1888
1804/* No kernel lock - fine */ 1889/* No kernel lock - fine */
1805static unsigned int usbdev_poll(struct file *file, 1890static unsigned int usbdev_poll(struct file *file,
1806 struct poll_table_struct *wait) 1891 struct poll_table_struct *wait)
@@ -1817,13 +1902,16 @@ static unsigned int usbdev_poll(struct file *file,
1817} 1902}
1818 1903
1819const struct file_operations usbdev_file_operations = { 1904const struct file_operations usbdev_file_operations = {
1820 .owner = THIS_MODULE, 1905 .owner = THIS_MODULE,
1821 .llseek = usbdev_lseek, 1906 .llseek = usbdev_lseek,
1822 .read = usbdev_read, 1907 .read = usbdev_read,
1823 .poll = usbdev_poll, 1908 .poll = usbdev_poll,
1824 .ioctl = usbdev_ioctl, 1909 .unlocked_ioctl = usbdev_ioctl,
1825 .open = usbdev_open, 1910#ifdef CONFIG_COMPAT
1826 .release = usbdev_release, 1911 .compat_ioctl = usbdev_compat_ioctl,
1912#endif
1913 .open = usbdev_open,
1914 .release = usbdev_release,
1827}; 1915};
1828 1916
1829static void usbdev_remove(struct usb_device *udev) 1917static void usbdev_remove(struct usb_device *udev)
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index 598763fd207f..278020d2449c 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -742,94 +742,6 @@ static int serial_struct_ioctl(unsigned fd, unsigned cmd,
742 return err; 742 return err;
743} 743}
744 744
745struct usbdevfs_ctrltransfer32 {
746 u8 bRequestType;
747 u8 bRequest;
748 u16 wValue;
749 u16 wIndex;
750 u16 wLength;
751 u32 timeout; /* in milliseconds */
752 compat_caddr_t data;
753};
754
755#define USBDEVFS_CONTROL32 _IOWR('U', 0, struct usbdevfs_ctrltransfer32)
756
757static int do_usbdevfs_control(unsigned int fd, unsigned int cmd,
758 struct usbdevfs_ctrltransfer32 __user *p32)
759{
760 struct usbdevfs_ctrltransfer __user *p;
761 __u32 udata;
762 p = compat_alloc_user_space(sizeof(*p));
763 if (copy_in_user(p, p32, (sizeof(*p32) - sizeof(compat_caddr_t))) ||
764 get_user(udata, &p32->data) ||
765 put_user(compat_ptr(udata), &p->data))
766 return -EFAULT;
767 return sys_ioctl(fd, USBDEVFS_CONTROL, (unsigned long)p);
768}
769
770
771struct usbdevfs_bulktransfer32 {
772 compat_uint_t ep;
773 compat_uint_t len;
774 compat_uint_t timeout; /* in milliseconds */
775 compat_caddr_t data;
776};
777
778#define USBDEVFS_BULK32 _IOWR('U', 2, struct usbdevfs_bulktransfer32)
779
780static int do_usbdevfs_bulk(unsigned int fd, unsigned int cmd,
781 struct usbdevfs_bulktransfer32 __user *p32)
782{
783 struct usbdevfs_bulktransfer __user *p;
784 compat_uint_t n;
785 compat_caddr_t addr;
786
787 p = compat_alloc_user_space(sizeof(*p));
788
789 if (get_user(n, &p32->ep) || put_user(n, &p->ep) ||
790 get_user(n, &p32->len) || put_user(n, &p->len) ||
791 get_user(n, &p32->timeout) || put_user(n, &p->timeout) ||
792 get_user(addr, &p32->data) || put_user(compat_ptr(addr), &p->data))
793 return -EFAULT;
794
795 return sys_ioctl(fd, USBDEVFS_BULK, (unsigned long)p);
796}
797
798
799/*
800 * USBDEVFS_SUBMITURB, USBDEVFS_REAPURB and USBDEVFS_REAPURBNDELAY
801 * are handled in usbdevfs core. -Christopher Li
802 */
803
804struct usbdevfs_disconnectsignal32 {
805 compat_int_t signr;
806 compat_caddr_t context;
807};
808
809#define USBDEVFS_DISCSIGNAL32 _IOR('U', 14, struct usbdevfs_disconnectsignal32)
810
811static int do_usbdevfs_discsignal(unsigned int fd, unsigned int cmd,
812 struct usbdevfs_disconnectsignal32 __user *udis)
813{
814 struct usbdevfs_disconnectsignal kdis;
815 mm_segment_t old_fs;
816 u32 uctx;
817 int err;
818
819 if (get_user(kdis.signr, &udis->signr) ||
820 __get_user(uctx, &udis->context))
821 return -EFAULT;
822
823 kdis.context = compat_ptr(uctx);
824
825 old_fs = get_fs();
826 set_fs(KERNEL_DS);
827 err = sys_ioctl(fd, USBDEVFS_DISCSIGNAL, (unsigned long) &kdis);
828 set_fs(old_fs);
829
830 return err;
831}
832
833/* 745/*
834 * I2C layer ioctls 746 * I2C layer ioctls
835 */ 747 */
@@ -1471,21 +1383,6 @@ COMPATIBLE_IOCTL(PCIIOC_CONTROLLER)
1471COMPATIBLE_IOCTL(PCIIOC_MMAP_IS_IO) 1383COMPATIBLE_IOCTL(PCIIOC_MMAP_IS_IO)
1472COMPATIBLE_IOCTL(PCIIOC_MMAP_IS_MEM) 1384COMPATIBLE_IOCTL(PCIIOC_MMAP_IS_MEM)
1473COMPATIBLE_IOCTL(PCIIOC_WRITE_COMBINE) 1385COMPATIBLE_IOCTL(PCIIOC_WRITE_COMBINE)
1474/* USB */
1475COMPATIBLE_IOCTL(USBDEVFS_RESETEP)
1476COMPATIBLE_IOCTL(USBDEVFS_SETINTERFACE)
1477COMPATIBLE_IOCTL(USBDEVFS_SETCONFIGURATION)
1478COMPATIBLE_IOCTL(USBDEVFS_GETDRIVER)
1479COMPATIBLE_IOCTL(USBDEVFS_DISCARDURB)
1480COMPATIBLE_IOCTL(USBDEVFS_CLAIMINTERFACE)
1481COMPATIBLE_IOCTL(USBDEVFS_RELEASEINTERFACE)
1482COMPATIBLE_IOCTL(USBDEVFS_CONNECTINFO)
1483COMPATIBLE_IOCTL(USBDEVFS_HUB_PORTINFO)
1484COMPATIBLE_IOCTL(USBDEVFS_RESET)
1485COMPATIBLE_IOCTL(USBDEVFS_SUBMITURB32)
1486COMPATIBLE_IOCTL(USBDEVFS_REAPURB32)
1487COMPATIBLE_IOCTL(USBDEVFS_REAPURBNDELAY32)
1488COMPATIBLE_IOCTL(USBDEVFS_CLEAR_HALT)
1489/* NBD */ 1386/* NBD */
1490COMPATIBLE_IOCTL(NBD_DO_IT) 1387COMPATIBLE_IOCTL(NBD_DO_IT)
1491COMPATIBLE_IOCTL(NBD_CLEAR_SOCK) 1388COMPATIBLE_IOCTL(NBD_CLEAR_SOCK)
@@ -1604,8 +1501,6 @@ COMPATIBLE_IOCTL(TIOCSLTC)
1604COMPATIBLE_IOCTL(TIOCSTART) 1501COMPATIBLE_IOCTL(TIOCSTART)
1605COMPATIBLE_IOCTL(TIOCSTOP) 1502COMPATIBLE_IOCTL(TIOCSTOP)
1606#endif 1503#endif
1607/* Usbdevfs */
1608COMPATIBLE_IOCTL(USBDEVFS_IOCTL32)
1609 1504
1610/* fat 'r' ioctls. These are handled by fat with ->compat_ioctl, 1505/* fat 'r' ioctls. These are handled by fat with ->compat_ioctl,
1611 but we don't want warnings on other file systems. So declare 1506 but we don't want warnings on other file systems. So declare
@@ -1677,13 +1572,6 @@ static long do_ioctl_trans(int fd, unsigned int cmd,
1677 case TIOCGSERIAL: 1572 case TIOCGSERIAL:
1678 case TIOCSSERIAL: 1573 case TIOCSSERIAL:
1679 return serial_struct_ioctl(fd, cmd, argp); 1574 return serial_struct_ioctl(fd, cmd, argp);
1680 /* Usbdevfs */
1681 case USBDEVFS_CONTROL32:
1682 return do_usbdevfs_control(fd, cmd, argp);
1683 case USBDEVFS_BULK32:
1684 return do_usbdevfs_bulk(fd, cmd, argp);
1685 case USBDEVFS_DISCSIGNAL32:
1686 return do_usbdevfs_discsignal(fd, cmd, argp);
1687 /* i2c */ 1575 /* i2c */
1688 case I2C_FUNCS: 1576 case I2C_FUNCS:
1689 return w_long(fd, cmd, argp); 1577 return w_long(fd, cmd, argp);
diff --git a/include/linux/usbdevice_fs.h b/include/linux/usbdevice_fs.h
index b2a7d8ba6ee3..15591d2ea400 100644
--- a/include/linux/usbdevice_fs.h
+++ b/include/linux/usbdevice_fs.h
@@ -128,6 +128,29 @@ struct usbdevfs_hub_portinfo {
128#ifdef __KERNEL__ 128#ifdef __KERNEL__
129#ifdef CONFIG_COMPAT 129#ifdef CONFIG_COMPAT
130#include <linux/compat.h> 130#include <linux/compat.h>
131
132struct usbdevfs_ctrltransfer32 {
133 u8 bRequestType;
134 u8 bRequest;
135 u16 wValue;
136 u16 wIndex;
137 u16 wLength;
138 u32 timeout; /* in milliseconds */
139 compat_caddr_t data;
140};
141
142struct usbdevfs_bulktransfer32 {
143 compat_uint_t ep;
144 compat_uint_t len;
145 compat_uint_t timeout; /* in milliseconds */
146 compat_caddr_t data;
147};
148
149struct usbdevfs_disconnectsignal32 {
150 compat_int_t signr;
151 compat_caddr_t context;
152};
153
131struct usbdevfs_urb32 { 154struct usbdevfs_urb32 {
132 unsigned char type; 155 unsigned char type;
133 unsigned char endpoint; 156 unsigned char endpoint;
@@ -153,7 +176,9 @@ struct usbdevfs_ioctl32 {
153#endif /* __KERNEL__ */ 176#endif /* __KERNEL__ */
154 177
155#define USBDEVFS_CONTROL _IOWR('U', 0, struct usbdevfs_ctrltransfer) 178#define USBDEVFS_CONTROL _IOWR('U', 0, struct usbdevfs_ctrltransfer)
179#define USBDEVFS_CONTROL32 _IOWR('U', 0, struct usbdevfs_ctrltransfer32)
156#define USBDEVFS_BULK _IOWR('U', 2, struct usbdevfs_bulktransfer) 180#define USBDEVFS_BULK _IOWR('U', 2, struct usbdevfs_bulktransfer)
181#define USBDEVFS_BULK32 _IOWR('U', 2, struct usbdevfs_bulktransfer32)
157#define USBDEVFS_RESETEP _IOR('U', 3, unsigned int) 182#define USBDEVFS_RESETEP _IOR('U', 3, unsigned int)
158#define USBDEVFS_SETINTERFACE _IOR('U', 4, struct usbdevfs_setinterface) 183#define USBDEVFS_SETINTERFACE _IOR('U', 4, struct usbdevfs_setinterface)
159#define USBDEVFS_SETCONFIGURATION _IOR('U', 5, unsigned int) 184#define USBDEVFS_SETCONFIGURATION _IOR('U', 5, unsigned int)
@@ -166,6 +191,7 @@ struct usbdevfs_ioctl32 {
166#define USBDEVFS_REAPURBNDELAY _IOW('U', 13, void *) 191#define USBDEVFS_REAPURBNDELAY _IOW('U', 13, void *)
167#define USBDEVFS_REAPURBNDELAY32 _IOW('U', 13, __u32) 192#define USBDEVFS_REAPURBNDELAY32 _IOW('U', 13, __u32)
168#define USBDEVFS_DISCSIGNAL _IOR('U', 14, struct usbdevfs_disconnectsignal) 193#define USBDEVFS_DISCSIGNAL _IOR('U', 14, struct usbdevfs_disconnectsignal)
194#define USBDEVFS_DISCSIGNAL32 _IOR('U', 14, struct usbdevfs_disconnectsignal32)
169#define USBDEVFS_CLAIMINTERFACE _IOR('U', 15, unsigned int) 195#define USBDEVFS_CLAIMINTERFACE _IOR('U', 15, unsigned int)
170#define USBDEVFS_RELEASEINTERFACE _IOR('U', 16, unsigned int) 196#define USBDEVFS_RELEASEINTERFACE _IOR('U', 16, unsigned int)
171#define USBDEVFS_CONNECTINFO _IOW('U', 17, struct usbdevfs_connectinfo) 197#define USBDEVFS_CONNECTINFO _IOW('U', 17, struct usbdevfs_connectinfo)