diff options
author | Arnd Bergmann <arnd@arndb.de> | 2009-11-13 20:28:05 -0500 |
---|---|---|
committer | Arnd Bergmann <arnd@arndb.de> | 2009-12-10 16:55:37 -0500 |
commit | 637e8a60a7aaf4ef7d46cfdf83bcfac9cf6f0fbd (patch) | |
tree | 5d50aaa8bcdf0b5f9af5c24ff6adcdb9d482cd9c /drivers | |
parent | 3695669cd4f5fb6d569fd4243312c1b4a05bd5ce (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
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/usb/core/devio.c | 110 |
1 files changed, 99 insertions, 11 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 |
1391 | static 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 | |||
1404 | static 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 | } | ||
1421 | static 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 | ||
1392 | static int get_urb32(struct usbdevfs_urb *kurb, | 1432 | static 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 | ||
1487 | static int proc_disconnectsignal(struct dev_state *ps, void __user *arg) | 1528 | static 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 | */ |
1651 | static int usbdev_ioctl(struct inode *inode, struct file *file, | 1692 | static 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 | ||
1863 | static 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 | ||
1876 | static 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 */ |
1805 | static unsigned int usbdev_poll(struct file *file, | 1890 | static 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 | ||
1819 | const struct file_operations usbdev_file_operations = { | 1904 | const 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 | ||
1829 | static void usbdev_remove(struct usb_device *udev) | 1917 | static void usbdev_remove(struct usb_device *udev) |