diff options
Diffstat (limited to 'drivers/usb/core')
-rw-r--r-- | drivers/usb/core/devio.c | 110 | ||||
-rw-r--r-- | drivers/usb/core/driver.c | 135 | ||||
-rw-r--r-- | drivers/usb/core/file.c | 1 | ||||
-rw-r--r-- | drivers/usb/core/generic.c | 2 | ||||
-rw-r--r-- | drivers/usb/core/hcd-pci.c | 2 | ||||
-rw-r--r-- | drivers/usb/core/hcd.c | 82 | ||||
-rw-r--r-- | drivers/usb/core/hcd.h | 21 | ||||
-rw-r--r-- | drivers/usb/core/hub.c | 142 | ||||
-rw-r--r-- | drivers/usb/core/message.c | 82 | ||||
-rw-r--r-- | drivers/usb/core/sysfs.c | 61 | ||||
-rw-r--r-- | drivers/usb/core/urb.c | 22 | ||||
-rw-r--r-- | drivers/usb/core/usb.c | 72 | ||||
-rw-r--r-- | drivers/usb/core/usb.h | 1 |
13 files changed, 562 insertions, 171 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) |
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 4f864472c5c4..60a45f1e3a67 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c | |||
@@ -83,6 +83,47 @@ static ssize_t store_new_id(struct device_driver *driver, | |||
83 | } | 83 | } |
84 | static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id); | 84 | static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id); |
85 | 85 | ||
86 | /** | ||
87 | * store_remove_id - remove a USB device ID from this driver | ||
88 | * @driver: target device driver | ||
89 | * @buf: buffer for scanning device ID data | ||
90 | * @count: input size | ||
91 | * | ||
92 | * Removes a dynamic usb device ID from this driver. | ||
93 | */ | ||
94 | static ssize_t | ||
95 | store_remove_id(struct device_driver *driver, const char *buf, size_t count) | ||
96 | { | ||
97 | struct usb_dynid *dynid, *n; | ||
98 | struct usb_driver *usb_driver = to_usb_driver(driver); | ||
99 | u32 idVendor = 0; | ||
100 | u32 idProduct = 0; | ||
101 | int fields = 0; | ||
102 | int retval = 0; | ||
103 | |||
104 | fields = sscanf(buf, "%x %x", &idVendor, &idProduct); | ||
105 | if (fields < 2) | ||
106 | return -EINVAL; | ||
107 | |||
108 | spin_lock(&usb_driver->dynids.lock); | ||
109 | list_for_each_entry_safe(dynid, n, &usb_driver->dynids.list, node) { | ||
110 | struct usb_device_id *id = &dynid->id; | ||
111 | if ((id->idVendor == idVendor) && | ||
112 | (id->idProduct == idProduct)) { | ||
113 | list_del(&dynid->node); | ||
114 | kfree(dynid); | ||
115 | retval = 0; | ||
116 | break; | ||
117 | } | ||
118 | } | ||
119 | spin_unlock(&usb_driver->dynids.lock); | ||
120 | |||
121 | if (retval) | ||
122 | return retval; | ||
123 | return count; | ||
124 | } | ||
125 | static DRIVER_ATTR(remove_id, S_IWUSR, NULL, store_remove_id); | ||
126 | |||
86 | static int usb_create_newid_file(struct usb_driver *usb_drv) | 127 | static int usb_create_newid_file(struct usb_driver *usb_drv) |
87 | { | 128 | { |
88 | int error = 0; | 129 | int error = 0; |
@@ -107,6 +148,21 @@ static void usb_remove_newid_file(struct usb_driver *usb_drv) | |||
107 | &driver_attr_new_id); | 148 | &driver_attr_new_id); |
108 | } | 149 | } |
109 | 150 | ||
151 | static int | ||
152 | usb_create_removeid_file(struct usb_driver *drv) | ||
153 | { | ||
154 | int error = 0; | ||
155 | if (drv->probe != NULL) | ||
156 | error = driver_create_file(&drv->drvwrap.driver, | ||
157 | &driver_attr_remove_id); | ||
158 | return error; | ||
159 | } | ||
160 | |||
161 | static void usb_remove_removeid_file(struct usb_driver *drv) | ||
162 | { | ||
163 | driver_remove_file(&drv->drvwrap.driver, &driver_attr_remove_id); | ||
164 | } | ||
165 | |||
110 | static void usb_free_dynids(struct usb_driver *usb_drv) | 166 | static void usb_free_dynids(struct usb_driver *usb_drv) |
111 | { | 167 | { |
112 | struct usb_dynid *dynid, *n; | 168 | struct usb_dynid *dynid, *n; |
@@ -128,6 +184,16 @@ static void usb_remove_newid_file(struct usb_driver *usb_drv) | |||
128 | { | 184 | { |
129 | } | 185 | } |
130 | 186 | ||
187 | static int | ||
188 | usb_create_removeid_file(struct usb_driver *drv) | ||
189 | { | ||
190 | return 0; | ||
191 | } | ||
192 | |||
193 | static void usb_remove_removeid_file(struct usb_driver *drv) | ||
194 | { | ||
195 | } | ||
196 | |||
131 | static inline void usb_free_dynids(struct usb_driver *usb_drv) | 197 | static inline void usb_free_dynids(struct usb_driver *usb_drv) |
132 | { | 198 | { |
133 | } | 199 | } |
@@ -774,19 +840,34 @@ int usb_register_driver(struct usb_driver *new_driver, struct module *owner, | |||
774 | INIT_LIST_HEAD(&new_driver->dynids.list); | 840 | INIT_LIST_HEAD(&new_driver->dynids.list); |
775 | 841 | ||
776 | retval = driver_register(&new_driver->drvwrap.driver); | 842 | retval = driver_register(&new_driver->drvwrap.driver); |
843 | if (retval) | ||
844 | goto out; | ||
777 | 845 | ||
778 | if (!retval) { | 846 | usbfs_update_special(); |
779 | pr_info("%s: registered new interface driver %s\n", | 847 | |
848 | retval = usb_create_newid_file(new_driver); | ||
849 | if (retval) | ||
850 | goto out_newid; | ||
851 | |||
852 | retval = usb_create_removeid_file(new_driver); | ||
853 | if (retval) | ||
854 | goto out_removeid; | ||
855 | |||
856 | pr_info("%s: registered new interface driver %s\n", | ||
780 | usbcore_name, new_driver->name); | 857 | usbcore_name, new_driver->name); |
781 | usbfs_update_special(); | ||
782 | usb_create_newid_file(new_driver); | ||
783 | } else { | ||
784 | printk(KERN_ERR "%s: error %d registering interface " | ||
785 | " driver %s\n", | ||
786 | usbcore_name, retval, new_driver->name); | ||
787 | } | ||
788 | 858 | ||
859 | out: | ||
789 | return retval; | 860 | return retval; |
861 | |||
862 | out_removeid: | ||
863 | usb_remove_newid_file(new_driver); | ||
864 | out_newid: | ||
865 | driver_unregister(&new_driver->drvwrap.driver); | ||
866 | |||
867 | printk(KERN_ERR "%s: error %d registering interface " | ||
868 | " driver %s\n", | ||
869 | usbcore_name, retval, new_driver->name); | ||
870 | goto out; | ||
790 | } | 871 | } |
791 | EXPORT_SYMBOL_GPL(usb_register_driver); | 872 | EXPORT_SYMBOL_GPL(usb_register_driver); |
792 | 873 | ||
@@ -806,6 +887,7 @@ void usb_deregister(struct usb_driver *driver) | |||
806 | pr_info("%s: deregistering interface driver %s\n", | 887 | pr_info("%s: deregistering interface driver %s\n", |
807 | usbcore_name, driver->name); | 888 | usbcore_name, driver->name); |
808 | 889 | ||
890 | usb_remove_removeid_file(driver); | ||
809 | usb_remove_newid_file(driver); | 891 | usb_remove_newid_file(driver); |
810 | usb_free_dynids(driver); | 892 | usb_free_dynids(driver); |
811 | driver_unregister(&driver->drvwrap.driver); | 893 | driver_unregister(&driver->drvwrap.driver); |
@@ -948,8 +1030,6 @@ static int usb_resume_device(struct usb_device *udev, pm_message_t msg) | |||
948 | 1030 | ||
949 | done: | 1031 | done: |
950 | dev_vdbg(&udev->dev, "%s: status %d\n", __func__, status); | 1032 | dev_vdbg(&udev->dev, "%s: status %d\n", __func__, status); |
951 | if (status == 0) | ||
952 | udev->autoresume_disabled = 0; | ||
953 | return status; | 1033 | return status; |
954 | } | 1034 | } |
955 | 1035 | ||
@@ -1280,11 +1360,6 @@ static int usb_resume_both(struct usb_device *udev, pm_message_t msg) | |||
1280 | 1360 | ||
1281 | /* Propagate the resume up the tree, if necessary */ | 1361 | /* Propagate the resume up the tree, if necessary */ |
1282 | if (udev->state == USB_STATE_SUSPENDED) { | 1362 | if (udev->state == USB_STATE_SUSPENDED) { |
1283 | if ((msg.event & PM_EVENT_AUTO) && | ||
1284 | udev->autoresume_disabled) { | ||
1285 | status = -EPERM; | ||
1286 | goto done; | ||
1287 | } | ||
1288 | if (parent) { | 1363 | if (parent) { |
1289 | status = usb_autoresume_device(parent); | 1364 | status = usb_autoresume_device(parent); |
1290 | if (status == 0) { | 1365 | if (status == 0) { |
@@ -1341,7 +1416,6 @@ static int usb_autopm_do_device(struct usb_device *udev, int inc_usage_cnt) | |||
1341 | int status = 0; | 1416 | int status = 0; |
1342 | 1417 | ||
1343 | usb_pm_lock(udev); | 1418 | usb_pm_lock(udev); |
1344 | udev->auto_pm = 1; | ||
1345 | udev->pm_usage_cnt += inc_usage_cnt; | 1419 | udev->pm_usage_cnt += inc_usage_cnt; |
1346 | WARN_ON(udev->pm_usage_cnt < 0); | 1420 | WARN_ON(udev->pm_usage_cnt < 0); |
1347 | if (inc_usage_cnt) | 1421 | if (inc_usage_cnt) |
@@ -1473,7 +1547,6 @@ static int usb_autopm_do_interface(struct usb_interface *intf, | |||
1473 | if (intf->condition == USB_INTERFACE_UNBOUND) | 1547 | if (intf->condition == USB_INTERFACE_UNBOUND) |
1474 | status = -ENODEV; | 1548 | status = -ENODEV; |
1475 | else { | 1549 | else { |
1476 | udev->auto_pm = 1; | ||
1477 | atomic_add(inc_usage_cnt, &intf->pm_usage_cnt); | 1550 | atomic_add(inc_usage_cnt, &intf->pm_usage_cnt); |
1478 | udev->last_busy = jiffies; | 1551 | udev->last_busy = jiffies; |
1479 | if (inc_usage_cnt >= 0 && | 1552 | if (inc_usage_cnt >= 0 && |
@@ -1640,8 +1713,6 @@ int usb_autopm_get_interface_async(struct usb_interface *intf) | |||
1640 | 1713 | ||
1641 | if (intf->condition == USB_INTERFACE_UNBOUND) | 1714 | if (intf->condition == USB_INTERFACE_UNBOUND) |
1642 | status = -ENODEV; | 1715 | status = -ENODEV; |
1643 | else if (udev->autoresume_disabled) | ||
1644 | status = -EPERM; | ||
1645 | else { | 1716 | else { |
1646 | atomic_inc(&intf->pm_usage_cnt); | 1717 | atomic_inc(&intf->pm_usage_cnt); |
1647 | if (atomic_read(&intf->pm_usage_cnt) > 0 && | 1718 | if (atomic_read(&intf->pm_usage_cnt) > 0 && |
@@ -1654,28 +1725,6 @@ int usb_autopm_get_interface_async(struct usb_interface *intf) | |||
1654 | } | 1725 | } |
1655 | EXPORT_SYMBOL_GPL(usb_autopm_get_interface_async); | 1726 | EXPORT_SYMBOL_GPL(usb_autopm_get_interface_async); |
1656 | 1727 | ||
1657 | /** | ||
1658 | * usb_autopm_set_interface - set a USB interface's autosuspend state | ||
1659 | * @intf: the usb_interface whose state should be set | ||
1660 | * | ||
1661 | * This routine sets the autosuspend state of @intf's device according | ||
1662 | * to @intf's usage counter, which the caller must have set previously. | ||
1663 | * If the counter is <= 0, the device is autosuspended (if it isn't | ||
1664 | * already suspended and if nothing else prevents the autosuspend). If | ||
1665 | * the counter is > 0, the device is autoresumed (if it isn't already | ||
1666 | * awake). | ||
1667 | */ | ||
1668 | int usb_autopm_set_interface(struct usb_interface *intf) | ||
1669 | { | ||
1670 | int status; | ||
1671 | |||
1672 | status = usb_autopm_do_interface(intf, 0); | ||
1673 | dev_vdbg(&intf->dev, "%s: status %d cnt %d\n", | ||
1674 | __func__, status, atomic_read(&intf->pm_usage_cnt)); | ||
1675 | return status; | ||
1676 | } | ||
1677 | EXPORT_SYMBOL_GPL(usb_autopm_set_interface); | ||
1678 | |||
1679 | #else | 1728 | #else |
1680 | 1729 | ||
1681 | void usb_autosuspend_work(struct work_struct *work) | 1730 | void usb_autosuspend_work(struct work_struct *work) |
@@ -1707,7 +1756,6 @@ int usb_external_suspend_device(struct usb_device *udev, pm_message_t msg) | |||
1707 | 1756 | ||
1708 | do_unbind_rebind(udev, DO_UNBIND); | 1757 | do_unbind_rebind(udev, DO_UNBIND); |
1709 | usb_pm_lock(udev); | 1758 | usb_pm_lock(udev); |
1710 | udev->auto_pm = 0; | ||
1711 | status = usb_suspend_both(udev, msg); | 1759 | status = usb_suspend_both(udev, msg); |
1712 | usb_pm_unlock(udev); | 1760 | usb_pm_unlock(udev); |
1713 | return status; | 1761 | return status; |
@@ -1730,7 +1778,6 @@ int usb_external_resume_device(struct usb_device *udev, pm_message_t msg) | |||
1730 | int status; | 1778 | int status; |
1731 | 1779 | ||
1732 | usb_pm_lock(udev); | 1780 | usb_pm_lock(udev); |
1733 | udev->auto_pm = 0; | ||
1734 | status = usb_resume_both(udev, msg); | 1781 | status = usb_resume_both(udev, msg); |
1735 | udev->last_busy = jiffies; | 1782 | udev->last_busy = jiffies; |
1736 | usb_pm_unlock(udev); | 1783 | usb_pm_unlock(udev); |
diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c index 222ee07ea680..bfc6c2eea647 100644 --- a/drivers/usb/core/file.c +++ b/drivers/usb/core/file.c | |||
@@ -99,6 +99,7 @@ static int init_usb_class(void) | |||
99 | printk(KERN_ERR "class_create failed for usb devices\n"); | 99 | printk(KERN_ERR "class_create failed for usb devices\n"); |
100 | kfree(usb_class); | 100 | kfree(usb_class); |
101 | usb_class = NULL; | 101 | usb_class = NULL; |
102 | goto exit; | ||
102 | } | 103 | } |
103 | usb_class->class->devnode = usb_devnode; | 104 | usb_class->class->devnode = usb_devnode; |
104 | 105 | ||
diff --git a/drivers/usb/core/generic.c b/drivers/usb/core/generic.c index 05e6d313961e..bdf87a8414a1 100644 --- a/drivers/usb/core/generic.c +++ b/drivers/usb/core/generic.c | |||
@@ -139,7 +139,7 @@ int usb_choose_configuration(struct usb_device *udev) | |||
139 | 139 | ||
140 | if (best) { | 140 | if (best) { |
141 | i = best->desc.bConfigurationValue; | 141 | i = best->desc.bConfigurationValue; |
142 | dev_info(&udev->dev, | 142 | dev_dbg(&udev->dev, |
143 | "configuration #%d chosen from %d choice%s\n", | 143 | "configuration #%d chosen from %d choice%s\n", |
144 | i, num_configs, plural(num_configs)); | 144 | i, num_configs, plural(num_configs)); |
145 | } else { | 145 | } else { |
diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c index 91f2885b6ee1..2dcf906df569 100644 --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c | |||
@@ -363,7 +363,7 @@ static int hcd_pci_restore(struct device *dev) | |||
363 | return resume_common(dev, true); | 363 | return resume_common(dev, true); |
364 | } | 364 | } |
365 | 365 | ||
366 | struct dev_pm_ops usb_hcd_pci_pm_ops = { | 366 | const struct dev_pm_ops usb_hcd_pci_pm_ops = { |
367 | .suspend = hcd_pci_suspend, | 367 | .suspend = hcd_pci_suspend, |
368 | .suspend_noirq = hcd_pci_suspend_noirq, | 368 | .suspend_noirq = hcd_pci_suspend_noirq, |
369 | .resume_noirq = hcd_pci_resume_noirq, | 369 | .resume_noirq = hcd_pci_resume_noirq, |
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 34de475f016e..6dac3b802d41 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <asm/unaligned.h> | 38 | #include <asm/unaligned.h> |
39 | #include <linux/platform_device.h> | 39 | #include <linux/platform_device.h> |
40 | #include <linux/workqueue.h> | 40 | #include <linux/workqueue.h> |
41 | #include <linux/mutex.h> | ||
41 | 42 | ||
42 | #include <linux/usb.h> | 43 | #include <linux/usb.h> |
43 | 44 | ||
@@ -1275,13 +1276,16 @@ static int map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, | |||
1275 | 1276 | ||
1276 | if (usb_endpoint_xfer_control(&urb->ep->desc) | 1277 | if (usb_endpoint_xfer_control(&urb->ep->desc) |
1277 | && !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP)) { | 1278 | && !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP)) { |
1278 | if (hcd->self.uses_dma) | 1279 | if (hcd->self.uses_dma) { |
1279 | urb->setup_dma = dma_map_single( | 1280 | urb->setup_dma = dma_map_single( |
1280 | hcd->self.controller, | 1281 | hcd->self.controller, |
1281 | urb->setup_packet, | 1282 | urb->setup_packet, |
1282 | sizeof(struct usb_ctrlrequest), | 1283 | sizeof(struct usb_ctrlrequest), |
1283 | DMA_TO_DEVICE); | 1284 | DMA_TO_DEVICE); |
1284 | else if (hcd->driver->flags & HCD_LOCAL_MEM) | 1285 | if (dma_mapping_error(hcd->self.controller, |
1286 | urb->setup_dma)) | ||
1287 | return -EAGAIN; | ||
1288 | } else if (hcd->driver->flags & HCD_LOCAL_MEM) | ||
1285 | ret = hcd_alloc_coherent( | 1289 | ret = hcd_alloc_coherent( |
1286 | urb->dev->bus, mem_flags, | 1290 | urb->dev->bus, mem_flags, |
1287 | &urb->setup_dma, | 1291 | &urb->setup_dma, |
@@ -1293,13 +1297,16 @@ static int map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, | |||
1293 | dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; | 1297 | dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; |
1294 | if (ret == 0 && urb->transfer_buffer_length != 0 | 1298 | if (ret == 0 && urb->transfer_buffer_length != 0 |
1295 | && !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)) { | 1299 | && !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)) { |
1296 | if (hcd->self.uses_dma) | 1300 | if (hcd->self.uses_dma) { |
1297 | urb->transfer_dma = dma_map_single ( | 1301 | urb->transfer_dma = dma_map_single ( |
1298 | hcd->self.controller, | 1302 | hcd->self.controller, |
1299 | urb->transfer_buffer, | 1303 | urb->transfer_buffer, |
1300 | urb->transfer_buffer_length, | 1304 | urb->transfer_buffer_length, |
1301 | dir); | 1305 | dir); |
1302 | else if (hcd->driver->flags & HCD_LOCAL_MEM) { | 1306 | if (dma_mapping_error(hcd->self.controller, |
1307 | urb->transfer_dma)) | ||
1308 | return -EAGAIN; | ||
1309 | } else if (hcd->driver->flags & HCD_LOCAL_MEM) { | ||
1303 | ret = hcd_alloc_coherent( | 1310 | ret = hcd_alloc_coherent( |
1304 | urb->dev->bus, mem_flags, | 1311 | urb->dev->bus, mem_flags, |
1305 | &urb->transfer_dma, | 1312 | &urb->transfer_dma, |
@@ -1589,19 +1596,32 @@ rescan: | |||
1589 | } | 1596 | } |
1590 | } | 1597 | } |
1591 | 1598 | ||
1592 | /* Check whether a new configuration or alt setting for an interface | 1599 | /** |
1593 | * will exceed the bandwidth for the bus (or the host controller resources). | 1600 | * Check whether a new bandwidth setting exceeds the bus bandwidth. |
1594 | * Only pass in a non-NULL config or interface, not both! | 1601 | * @new_config: new configuration to install |
1595 | * Passing NULL for both new_config and new_intf means the device will be | 1602 | * @cur_alt: the current alternate interface setting |
1596 | * de-configured by issuing a set configuration 0 command. | 1603 | * @new_alt: alternate interface setting that is being installed |
1604 | * | ||
1605 | * To change configurations, pass in the new configuration in new_config, | ||
1606 | * and pass NULL for cur_alt and new_alt. | ||
1607 | * | ||
1608 | * To reset a device's configuration (put the device in the ADDRESSED state), | ||
1609 | * pass in NULL for new_config, cur_alt, and new_alt. | ||
1610 | * | ||
1611 | * To change alternate interface settings, pass in NULL for new_config, | ||
1612 | * pass in the current alternate interface setting in cur_alt, | ||
1613 | * and pass in the new alternate interface setting in new_alt. | ||
1614 | * | ||
1615 | * Returns an error if the requested bandwidth change exceeds the | ||
1616 | * bus bandwidth or host controller internal resources. | ||
1597 | */ | 1617 | */ |
1598 | int usb_hcd_check_bandwidth(struct usb_device *udev, | 1618 | int usb_hcd_alloc_bandwidth(struct usb_device *udev, |
1599 | struct usb_host_config *new_config, | 1619 | struct usb_host_config *new_config, |
1600 | struct usb_interface *new_intf) | 1620 | struct usb_host_interface *cur_alt, |
1621 | struct usb_host_interface *new_alt) | ||
1601 | { | 1622 | { |
1602 | int num_intfs, i, j; | 1623 | int num_intfs, i, j; |
1603 | struct usb_interface_cache *intf_cache; | 1624 | struct usb_host_interface *alt = NULL; |
1604 | struct usb_host_interface *alt = 0; | ||
1605 | int ret = 0; | 1625 | int ret = 0; |
1606 | struct usb_hcd *hcd; | 1626 | struct usb_hcd *hcd; |
1607 | struct usb_host_endpoint *ep; | 1627 | struct usb_host_endpoint *ep; |
@@ -1611,7 +1631,7 @@ int usb_hcd_check_bandwidth(struct usb_device *udev, | |||
1611 | return 0; | 1631 | return 0; |
1612 | 1632 | ||
1613 | /* Configuration is being removed - set configuration 0 */ | 1633 | /* Configuration is being removed - set configuration 0 */ |
1614 | if (!new_config && !new_intf) { | 1634 | if (!new_config && !cur_alt) { |
1615 | for (i = 1; i < 16; ++i) { | 1635 | for (i = 1; i < 16; ++i) { |
1616 | ep = udev->ep_out[i]; | 1636 | ep = udev->ep_out[i]; |
1617 | if (ep) | 1637 | if (ep) |
@@ -1648,19 +1668,12 @@ int usb_hcd_check_bandwidth(struct usb_device *udev, | |||
1648 | } | 1668 | } |
1649 | } | 1669 | } |
1650 | for (i = 0; i < num_intfs; ++i) { | 1670 | for (i = 0; i < num_intfs; ++i) { |
1671 | /* Set up endpoints for alternate interface setting 0 */ | ||
1672 | alt = usb_find_alt_setting(new_config, i, 0); | ||
1673 | if (!alt) | ||
1674 | /* No alt setting 0? Pick the first setting. */ | ||
1675 | alt = &new_config->intf_cache[i]->altsetting[0]; | ||
1651 | 1676 | ||
1652 | /* Dig the endpoints for alt setting 0 out of the | ||
1653 | * interface cache for this interface | ||
1654 | */ | ||
1655 | intf_cache = new_config->intf_cache[i]; | ||
1656 | for (j = 0; j < intf_cache->num_altsetting; j++) { | ||
1657 | if (intf_cache->altsetting[j].desc.bAlternateSetting == 0) | ||
1658 | alt = &intf_cache->altsetting[j]; | ||
1659 | } | ||
1660 | if (!alt) { | ||
1661 | printk(KERN_DEBUG "Did not find alt setting 0 for intf %d\n", i); | ||
1662 | continue; | ||
1663 | } | ||
1664 | for (j = 0; j < alt->desc.bNumEndpoints; j++) { | 1677 | for (j = 0; j < alt->desc.bNumEndpoints; j++) { |
1665 | ret = hcd->driver->add_endpoint(hcd, udev, &alt->endpoint[j]); | 1678 | ret = hcd->driver->add_endpoint(hcd, udev, &alt->endpoint[j]); |
1666 | if (ret < 0) | 1679 | if (ret < 0) |
@@ -1668,6 +1681,22 @@ int usb_hcd_check_bandwidth(struct usb_device *udev, | |||
1668 | } | 1681 | } |
1669 | } | 1682 | } |
1670 | } | 1683 | } |
1684 | if (cur_alt && new_alt) { | ||
1685 | /* Drop all the endpoints in the current alt setting */ | ||
1686 | for (i = 0; i < cur_alt->desc.bNumEndpoints; i++) { | ||
1687 | ret = hcd->driver->drop_endpoint(hcd, udev, | ||
1688 | &cur_alt->endpoint[i]); | ||
1689 | if (ret < 0) | ||
1690 | goto reset; | ||
1691 | } | ||
1692 | /* Add all the endpoints in the new alt setting */ | ||
1693 | for (i = 0; i < new_alt->desc.bNumEndpoints; i++) { | ||
1694 | ret = hcd->driver->add_endpoint(hcd, udev, | ||
1695 | &new_alt->endpoint[i]); | ||
1696 | if (ret < 0) | ||
1697 | goto reset; | ||
1698 | } | ||
1699 | } | ||
1671 | ret = hcd->driver->check_bandwidth(hcd, udev); | 1700 | ret = hcd->driver->check_bandwidth(hcd, udev); |
1672 | reset: | 1701 | reset: |
1673 | if (ret < 0) | 1702 | if (ret < 0) |
@@ -1984,6 +2013,7 @@ struct usb_hcd *usb_create_hcd (const struct hc_driver *driver, | |||
1984 | #ifdef CONFIG_PM | 2013 | #ifdef CONFIG_PM |
1985 | INIT_WORK(&hcd->wakeup_work, hcd_resume_work); | 2014 | INIT_WORK(&hcd->wakeup_work, hcd_resume_work); |
1986 | #endif | 2015 | #endif |
2016 | mutex_init(&hcd->bandwidth_mutex); | ||
1987 | 2017 | ||
1988 | hcd->driver = driver; | 2018 | hcd->driver = driver; |
1989 | hcd->product_desc = (driver->product_desc) ? driver->product_desc : | 2019 | hcd->product_desc = (driver->product_desc) ? driver->product_desc : |
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h index 79782a1c43f6..bbe2b924aae8 100644 --- a/drivers/usb/core/hcd.h +++ b/drivers/usb/core/hcd.h | |||
@@ -111,6 +111,20 @@ struct usb_hcd { | |||
111 | u64 rsrc_len; /* memory/io resource length */ | 111 | u64 rsrc_len; /* memory/io resource length */ |
112 | unsigned power_budget; /* in mA, 0 = no limit */ | 112 | unsigned power_budget; /* in mA, 0 = no limit */ |
113 | 113 | ||
114 | /* bandwidth_mutex should be taken before adding or removing | ||
115 | * any new bus bandwidth constraints: | ||
116 | * 1. Before adding a configuration for a new device. | ||
117 | * 2. Before removing the configuration to put the device into | ||
118 | * the addressed state. | ||
119 | * 3. Before selecting a different configuration. | ||
120 | * 4. Before selecting an alternate interface setting. | ||
121 | * | ||
122 | * bandwidth_mutex should be dropped after a successful control message | ||
123 | * to the device, or resetting the bandwidth after a failed attempt. | ||
124 | */ | ||
125 | struct mutex bandwidth_mutex; | ||
126 | |||
127 | |||
114 | #define HCD_BUFFER_POOLS 4 | 128 | #define HCD_BUFFER_POOLS 4 |
115 | struct dma_pool *pool [HCD_BUFFER_POOLS]; | 129 | struct dma_pool *pool [HCD_BUFFER_POOLS]; |
116 | 130 | ||
@@ -290,9 +304,10 @@ extern void usb_hcd_disable_endpoint(struct usb_device *udev, | |||
290 | extern void usb_hcd_reset_endpoint(struct usb_device *udev, | 304 | extern void usb_hcd_reset_endpoint(struct usb_device *udev, |
291 | struct usb_host_endpoint *ep); | 305 | struct usb_host_endpoint *ep); |
292 | extern void usb_hcd_synchronize_unlinks(struct usb_device *udev); | 306 | extern void usb_hcd_synchronize_unlinks(struct usb_device *udev); |
293 | extern int usb_hcd_check_bandwidth(struct usb_device *udev, | 307 | extern int usb_hcd_alloc_bandwidth(struct usb_device *udev, |
294 | struct usb_host_config *new_config, | 308 | struct usb_host_config *new_config, |
295 | struct usb_interface *new_intf); | 309 | struct usb_host_interface *old_alt, |
310 | struct usb_host_interface *new_alt); | ||
296 | extern int usb_hcd_get_frame_number(struct usb_device *udev); | 311 | extern int usb_hcd_get_frame_number(struct usb_device *udev); |
297 | 312 | ||
298 | extern struct usb_hcd *usb_create_hcd(const struct hc_driver *driver, | 313 | extern struct usb_hcd *usb_create_hcd(const struct hc_driver *driver, |
@@ -315,7 +330,7 @@ extern void usb_hcd_pci_remove(struct pci_dev *dev); | |||
315 | extern void usb_hcd_pci_shutdown(struct pci_dev *dev); | 330 | extern void usb_hcd_pci_shutdown(struct pci_dev *dev); |
316 | 331 | ||
317 | #ifdef CONFIG_PM_SLEEP | 332 | #ifdef CONFIG_PM_SLEEP |
318 | extern struct dev_pm_ops usb_hcd_pci_pm_ops; | 333 | extern const struct dev_pm_ops usb_hcd_pci_pm_ops; |
319 | #endif | 334 | #endif |
320 | #endif /* CONFIG_PCI */ | 335 | #endif /* CONFIG_PCI */ |
321 | 336 | ||
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 0f857e645058..06af970e1064 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -45,7 +45,6 @@ struct usb_hub { | |||
45 | 45 | ||
46 | /* buffer for urb ... with extra space in case of babble */ | 46 | /* buffer for urb ... with extra space in case of babble */ |
47 | char (*buffer)[8]; | 47 | char (*buffer)[8]; |
48 | dma_addr_t buffer_dma; /* DMA address for buffer */ | ||
49 | union { | 48 | union { |
50 | struct usb_hub_status hub; | 49 | struct usb_hub_status hub; |
51 | struct usb_port_status port; | 50 | struct usb_port_status port; |
@@ -61,6 +60,8 @@ struct usb_hub { | |||
61 | status change */ | 60 | status change */ |
62 | unsigned long busy_bits[1]; /* ports being reset or | 61 | unsigned long busy_bits[1]; /* ports being reset or |
63 | resumed */ | 62 | resumed */ |
63 | unsigned long removed_bits[1]; /* ports with a "removed" | ||
64 | device present */ | ||
64 | #if USB_MAXCHILDREN > 31 /* 8*sizeof(unsigned long) - 1 */ | 65 | #if USB_MAXCHILDREN > 31 /* 8*sizeof(unsigned long) - 1 */ |
65 | #error event_bits[] is too short! | 66 | #error event_bits[] is too short! |
66 | #endif | 67 | #endif |
@@ -70,6 +71,7 @@ struct usb_hub { | |||
70 | 71 | ||
71 | unsigned mA_per_port; /* current for each child */ | 72 | unsigned mA_per_port; /* current for each child */ |
72 | 73 | ||
74 | unsigned init_done:1; | ||
73 | unsigned limited_power:1; | 75 | unsigned limited_power:1; |
74 | unsigned quiescing:1; | 76 | unsigned quiescing:1; |
75 | unsigned disconnected:1; | 77 | unsigned disconnected:1; |
@@ -374,12 +376,13 @@ static void kick_khubd(struct usb_hub *hub) | |||
374 | { | 376 | { |
375 | unsigned long flags; | 377 | unsigned long flags; |
376 | 378 | ||
377 | /* Suppress autosuspend until khubd runs */ | ||
378 | atomic_set(&to_usb_interface(hub->intfdev)->pm_usage_cnt, 1); | ||
379 | |||
380 | spin_lock_irqsave(&hub_event_lock, flags); | 379 | spin_lock_irqsave(&hub_event_lock, flags); |
381 | if (!hub->disconnected && list_empty(&hub->event_list)) { | 380 | if (!hub->disconnected && list_empty(&hub->event_list)) { |
382 | list_add_tail(&hub->event_list, &hub_event_list); | 381 | list_add_tail(&hub->event_list, &hub_event_list); |
382 | |||
383 | /* Suppress autosuspend until khubd runs */ | ||
384 | usb_autopm_get_interface_no_resume( | ||
385 | to_usb_interface(hub->intfdev)); | ||
383 | wake_up(&khubd_wait); | 386 | wake_up(&khubd_wait); |
384 | } | 387 | } |
385 | spin_unlock_irqrestore(&hub_event_lock, flags); | 388 | spin_unlock_irqrestore(&hub_event_lock, flags); |
@@ -636,8 +639,35 @@ static void hub_port_logical_disconnect(struct usb_hub *hub, int port1) | |||
636 | kick_khubd(hub); | 639 | kick_khubd(hub); |
637 | } | 640 | } |
638 | 641 | ||
642 | /** | ||
643 | * usb_remove_device - disable a device's port on its parent hub | ||
644 | * @udev: device to be disabled and removed | ||
645 | * Context: @udev locked, must be able to sleep. | ||
646 | * | ||
647 | * After @udev's port has been disabled, khubd is notified and it will | ||
648 | * see that the device has been disconnected. When the device is | ||
649 | * physically unplugged and something is plugged in, the events will | ||
650 | * be received and processed normally. | ||
651 | */ | ||
652 | int usb_remove_device(struct usb_device *udev) | ||
653 | { | ||
654 | struct usb_hub *hub; | ||
655 | struct usb_interface *intf; | ||
656 | |||
657 | if (!udev->parent) /* Can't remove a root hub */ | ||
658 | return -EINVAL; | ||
659 | hub = hdev_to_hub(udev->parent); | ||
660 | intf = to_usb_interface(hub->intfdev); | ||
661 | |||
662 | usb_autopm_get_interface(intf); | ||
663 | set_bit(udev->portnum, hub->removed_bits); | ||
664 | hub_port_logical_disconnect(hub, udev->portnum); | ||
665 | usb_autopm_put_interface(intf); | ||
666 | return 0; | ||
667 | } | ||
668 | |||
639 | enum hub_activation_type { | 669 | enum hub_activation_type { |
640 | HUB_INIT, HUB_INIT2, HUB_INIT3, | 670 | HUB_INIT, HUB_INIT2, HUB_INIT3, /* INITs must come first */ |
641 | HUB_POST_RESET, HUB_RESUME, HUB_RESET_RESUME, | 671 | HUB_POST_RESET, HUB_RESUME, HUB_RESET_RESUME, |
642 | }; | 672 | }; |
643 | 673 | ||
@@ -682,8 +712,8 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) | |||
682 | msecs_to_jiffies(delay)); | 712 | msecs_to_jiffies(delay)); |
683 | 713 | ||
684 | /* Suppress autosuspend until init is done */ | 714 | /* Suppress autosuspend until init is done */ |
685 | atomic_set(&to_usb_interface(hub->intfdev)-> | 715 | usb_autopm_get_interface_no_resume( |
686 | pm_usage_cnt, 1); | 716 | to_usb_interface(hub->intfdev)); |
687 | return; /* Continues at init2: below */ | 717 | return; /* Continues at init2: below */ |
688 | } else { | 718 | } else { |
689 | hub_power_on(hub, true); | 719 | hub_power_on(hub, true); |
@@ -731,6 +761,13 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) | |||
731 | USB_PORT_FEAT_C_ENABLE); | 761 | USB_PORT_FEAT_C_ENABLE); |
732 | } | 762 | } |
733 | 763 | ||
764 | /* We can forget about a "removed" device when there's a | ||
765 | * physical disconnect or the connect status changes. | ||
766 | */ | ||
767 | if (!(portstatus & USB_PORT_STAT_CONNECTION) || | ||
768 | (portchange & USB_PORT_STAT_C_CONNECTION)) | ||
769 | clear_bit(port1, hub->removed_bits); | ||
770 | |||
734 | if (!udev || udev->state == USB_STATE_NOTATTACHED) { | 771 | if (!udev || udev->state == USB_STATE_NOTATTACHED) { |
735 | /* Tell khubd to disconnect the device or | 772 | /* Tell khubd to disconnect the device or |
736 | * check for a new connection | 773 | * check for a new connection |
@@ -783,6 +820,7 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) | |||
783 | } | 820 | } |
784 | init3: | 821 | init3: |
785 | hub->quiescing = 0; | 822 | hub->quiescing = 0; |
823 | hub->init_done = 1; | ||
786 | 824 | ||
787 | status = usb_submit_urb(hub->urb, GFP_NOIO); | 825 | status = usb_submit_urb(hub->urb, GFP_NOIO); |
788 | if (status < 0) | 826 | if (status < 0) |
@@ -792,6 +830,10 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) | |||
792 | 830 | ||
793 | /* Scan all ports that need attention */ | 831 | /* Scan all ports that need attention */ |
794 | kick_khubd(hub); | 832 | kick_khubd(hub); |
833 | |||
834 | /* Allow autosuspend if it was suppressed */ | ||
835 | if (type <= HUB_INIT3) | ||
836 | usb_autopm_put_interface_async(to_usb_interface(hub->intfdev)); | ||
795 | } | 837 | } |
796 | 838 | ||
797 | /* Implement the continuations for the delays above */ | 839 | /* Implement the continuations for the delays above */ |
@@ -819,6 +861,11 @@ static void hub_quiesce(struct usb_hub *hub, enum hub_quiescing_type type) | |||
819 | int i; | 861 | int i; |
820 | 862 | ||
821 | cancel_delayed_work_sync(&hub->init_work); | 863 | cancel_delayed_work_sync(&hub->init_work); |
864 | if (!hub->init_done) { | ||
865 | hub->init_done = 1; | ||
866 | usb_autopm_put_interface_no_suspend( | ||
867 | to_usb_interface(hub->intfdev)); | ||
868 | } | ||
822 | 869 | ||
823 | /* khubd and related activity won't re-trigger */ | 870 | /* khubd and related activity won't re-trigger */ |
824 | hub->quiescing = 1; | 871 | hub->quiescing = 1; |
@@ -869,8 +916,7 @@ static int hub_configure(struct usb_hub *hub, | |||
869 | int maxp, ret; | 916 | int maxp, ret; |
870 | char *message = "out of memory"; | 917 | char *message = "out of memory"; |
871 | 918 | ||
872 | hub->buffer = usb_buffer_alloc(hdev, sizeof(*hub->buffer), GFP_KERNEL, | 919 | hub->buffer = kmalloc(sizeof(*hub->buffer), GFP_KERNEL); |
873 | &hub->buffer_dma); | ||
874 | if (!hub->buffer) { | 920 | if (!hub->buffer) { |
875 | ret = -ENOMEM; | 921 | ret = -ENOMEM; |
876 | goto fail; | 922 | goto fail; |
@@ -1111,8 +1157,6 @@ static int hub_configure(struct usb_hub *hub, | |||
1111 | 1157 | ||
1112 | usb_fill_int_urb(hub->urb, hdev, pipe, *hub->buffer, maxp, hub_irq, | 1158 | usb_fill_int_urb(hub->urb, hdev, pipe, *hub->buffer, maxp, hub_irq, |
1113 | hub, endpoint->bInterval); | 1159 | hub, endpoint->bInterval); |
1114 | hub->urb->transfer_dma = hub->buffer_dma; | ||
1115 | hub->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | ||
1116 | 1160 | ||
1117 | /* maybe cycle the hub leds */ | 1161 | /* maybe cycle the hub leds */ |
1118 | if (hub->has_indicators && blinkenlights) | 1162 | if (hub->has_indicators && blinkenlights) |
@@ -1144,7 +1188,10 @@ static void hub_disconnect(struct usb_interface *intf) | |||
1144 | 1188 | ||
1145 | /* Take the hub off the event list and don't let it be added again */ | 1189 | /* Take the hub off the event list and don't let it be added again */ |
1146 | spin_lock_irq(&hub_event_lock); | 1190 | spin_lock_irq(&hub_event_lock); |
1147 | list_del_init(&hub->event_list); | 1191 | if (!list_empty(&hub->event_list)) { |
1192 | list_del_init(&hub->event_list); | ||
1193 | usb_autopm_put_interface_no_suspend(intf); | ||
1194 | } | ||
1148 | hub->disconnected = 1; | 1195 | hub->disconnected = 1; |
1149 | spin_unlock_irq(&hub_event_lock); | 1196 | spin_unlock_irq(&hub_event_lock); |
1150 | 1197 | ||
@@ -1162,8 +1209,7 @@ static void hub_disconnect(struct usb_interface *intf) | |||
1162 | kfree(hub->port_owners); | 1209 | kfree(hub->port_owners); |
1163 | kfree(hub->descriptor); | 1210 | kfree(hub->descriptor); |
1164 | kfree(hub->status); | 1211 | kfree(hub->status); |
1165 | usb_buffer_free(hub->hdev, sizeof(*hub->buffer), hub->buffer, | 1212 | kfree(hub->buffer); |
1166 | hub->buffer_dma); | ||
1167 | 1213 | ||
1168 | kref_put(&hub->kref, hub_release); | 1214 | kref_put(&hub->kref, hub_release); |
1169 | } | 1215 | } |
@@ -1630,7 +1676,7 @@ static int usb_configure_device_otg(struct usb_device *udev) | |||
1630 | if (!udev->bus->is_b_host | 1676 | if (!udev->bus->is_b_host |
1631 | && udev->config | 1677 | && udev->config |
1632 | && udev->parent == udev->bus->root_hub) { | 1678 | && udev->parent == udev->bus->root_hub) { |
1633 | struct usb_otg_descriptor *desc = 0; | 1679 | struct usb_otg_descriptor *desc = NULL; |
1634 | struct usb_bus *bus = udev->bus; | 1680 | struct usb_bus *bus = udev->bus; |
1635 | 1681 | ||
1636 | /* descriptor may appear anywhere in config */ | 1682 | /* descriptor may appear anywhere in config */ |
@@ -2123,9 +2169,13 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg) | |||
2123 | USB_DEVICE_REMOTE_WAKEUP, 0, | 2169 | USB_DEVICE_REMOTE_WAKEUP, 0, |
2124 | NULL, 0, | 2170 | NULL, 0, |
2125 | USB_CTRL_SET_TIMEOUT); | 2171 | USB_CTRL_SET_TIMEOUT); |
2126 | if (status) | 2172 | if (status) { |
2127 | dev_dbg(&udev->dev, "won't remote wakeup, status %d\n", | 2173 | dev_dbg(&udev->dev, "won't remote wakeup, status %d\n", |
2128 | status); | 2174 | status); |
2175 | /* bail if autosuspend is requested */ | ||
2176 | if (msg.event & PM_EVENT_AUTO) | ||
2177 | return status; | ||
2178 | } | ||
2129 | } | 2179 | } |
2130 | 2180 | ||
2131 | /* see 7.1.7.6 */ | 2181 | /* see 7.1.7.6 */ |
@@ -2134,7 +2184,8 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg) | |||
2134 | dev_dbg(hub->intfdev, "can't suspend port %d, status %d\n", | 2184 | dev_dbg(hub->intfdev, "can't suspend port %d, status %d\n", |
2135 | port1, status); | 2185 | port1, status); |
2136 | /* paranoia: "should not happen" */ | 2186 | /* paranoia: "should not happen" */ |
2137 | (void) usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | 2187 | if (udev->do_remote_wakeup) |
2188 | (void) usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | ||
2138 | USB_REQ_CLEAR_FEATURE, USB_RECIP_DEVICE, | 2189 | USB_REQ_CLEAR_FEATURE, USB_RECIP_DEVICE, |
2139 | USB_DEVICE_REMOTE_WAKEUP, 0, | 2190 | USB_DEVICE_REMOTE_WAKEUP, 0, |
2140 | NULL, 0, | 2191 | NULL, 0, |
@@ -2965,6 +3016,13 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, | |||
2965 | usb_disconnect(&hdev->children[port1-1]); | 3016 | usb_disconnect(&hdev->children[port1-1]); |
2966 | clear_bit(port1, hub->change_bits); | 3017 | clear_bit(port1, hub->change_bits); |
2967 | 3018 | ||
3019 | /* We can forget about a "removed" device when there's a physical | ||
3020 | * disconnect or the connect status changes. | ||
3021 | */ | ||
3022 | if (!(portstatus & USB_PORT_STAT_CONNECTION) || | ||
3023 | (portchange & USB_PORT_STAT_C_CONNECTION)) | ||
3024 | clear_bit(port1, hub->removed_bits); | ||
3025 | |||
2968 | if (portchange & (USB_PORT_STAT_C_CONNECTION | | 3026 | if (portchange & (USB_PORT_STAT_C_CONNECTION | |
2969 | USB_PORT_STAT_C_ENABLE)) { | 3027 | USB_PORT_STAT_C_ENABLE)) { |
2970 | status = hub_port_debounce(hub, port1); | 3028 | status = hub_port_debounce(hub, port1); |
@@ -2978,8 +3036,11 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, | |||
2978 | } | 3036 | } |
2979 | } | 3037 | } |
2980 | 3038 | ||
2981 | /* Return now if debouncing failed or nothing is connected */ | 3039 | /* Return now if debouncing failed or nothing is connected or |
2982 | if (!(portstatus & USB_PORT_STAT_CONNECTION)) { | 3040 | * the device was "removed". |
3041 | */ | ||
3042 | if (!(portstatus & USB_PORT_STAT_CONNECTION) || | ||
3043 | test_bit(port1, hub->removed_bits)) { | ||
2983 | 3044 | ||
2984 | /* maybe switch power back on (e.g. root hub was reset) */ | 3045 | /* maybe switch power back on (e.g. root hub was reset) */ |
2985 | if ((wHubCharacteristics & HUB_CHAR_LPSM) < 2 | 3046 | if ((wHubCharacteristics & HUB_CHAR_LPSM) < 2 |
@@ -3189,7 +3250,7 @@ static void hub_events(void) | |||
3189 | * disconnected while waiting for the lock to succeed. */ | 3250 | * disconnected while waiting for the lock to succeed. */ |
3190 | usb_lock_device(hdev); | 3251 | usb_lock_device(hdev); |
3191 | if (unlikely(hub->disconnected)) | 3252 | if (unlikely(hub->disconnected)) |
3192 | goto loop; | 3253 | goto loop2; |
3193 | 3254 | ||
3194 | /* If the hub has died, clean up after it */ | 3255 | /* If the hub has died, clean up after it */ |
3195 | if (hdev->state == USB_STATE_NOTATTACHED) { | 3256 | if (hdev->state == USB_STATE_NOTATTACHED) { |
@@ -3338,11 +3399,15 @@ static void hub_events(void) | |||
3338 | } | 3399 | } |
3339 | } | 3400 | } |
3340 | 3401 | ||
3341 | loop_autopm: | 3402 | loop_autopm: |
3342 | /* Allow autosuspend if we're not going to run again */ | 3403 | /* Balance the usb_autopm_get_interface() above */ |
3343 | if (list_empty(&hub->event_list)) | 3404 | usb_autopm_put_interface_no_suspend(intf); |
3344 | usb_autopm_enable(intf); | 3405 | loop: |
3345 | loop: | 3406 | /* Balance the usb_autopm_get_interface_no_resume() in |
3407 | * kick_khubd() and allow autosuspend. | ||
3408 | */ | ||
3409 | usb_autopm_put_interface(intf); | ||
3410 | loop2: | ||
3346 | usb_unlock_device(hdev); | 3411 | usb_unlock_device(hdev); |
3347 | kref_put(&hub->kref, hub_release); | 3412 | kref_put(&hub->kref, hub_release); |
3348 | 3413 | ||
@@ -3534,6 +3599,7 @@ static int usb_reset_and_verify_device(struct usb_device *udev) | |||
3534 | { | 3599 | { |
3535 | struct usb_device *parent_hdev = udev->parent; | 3600 | struct usb_device *parent_hdev = udev->parent; |
3536 | struct usb_hub *parent_hub; | 3601 | struct usb_hub *parent_hub; |
3602 | struct usb_hcd *hcd = bus_to_hcd(udev->bus); | ||
3537 | struct usb_device_descriptor descriptor = udev->descriptor; | 3603 | struct usb_device_descriptor descriptor = udev->descriptor; |
3538 | int i, ret = 0; | 3604 | int i, ret = 0; |
3539 | int port1 = udev->portnum; | 3605 | int port1 = udev->portnum; |
@@ -3577,6 +3643,16 @@ static int usb_reset_and_verify_device(struct usb_device *udev) | |||
3577 | /* Restore the device's previous configuration */ | 3643 | /* Restore the device's previous configuration */ |
3578 | if (!udev->actconfig) | 3644 | if (!udev->actconfig) |
3579 | goto done; | 3645 | goto done; |
3646 | |||
3647 | mutex_lock(&hcd->bandwidth_mutex); | ||
3648 | ret = usb_hcd_alloc_bandwidth(udev, udev->actconfig, NULL, NULL); | ||
3649 | if (ret < 0) { | ||
3650 | dev_warn(&udev->dev, | ||
3651 | "Busted HC? Not enough HCD resources for " | ||
3652 | "old configuration.\n"); | ||
3653 | mutex_unlock(&hcd->bandwidth_mutex); | ||
3654 | goto re_enumerate; | ||
3655 | } | ||
3580 | ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | 3656 | ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), |
3581 | USB_REQ_SET_CONFIGURATION, 0, | 3657 | USB_REQ_SET_CONFIGURATION, 0, |
3582 | udev->actconfig->desc.bConfigurationValue, 0, | 3658 | udev->actconfig->desc.bConfigurationValue, 0, |
@@ -3585,8 +3661,10 @@ static int usb_reset_and_verify_device(struct usb_device *udev) | |||
3585 | dev_err(&udev->dev, | 3661 | dev_err(&udev->dev, |
3586 | "can't restore configuration #%d (error=%d)\n", | 3662 | "can't restore configuration #%d (error=%d)\n", |
3587 | udev->actconfig->desc.bConfigurationValue, ret); | 3663 | udev->actconfig->desc.bConfigurationValue, ret); |
3664 | mutex_unlock(&hcd->bandwidth_mutex); | ||
3588 | goto re_enumerate; | 3665 | goto re_enumerate; |
3589 | } | 3666 | } |
3667 | mutex_unlock(&hcd->bandwidth_mutex); | ||
3590 | usb_set_device_state(udev, USB_STATE_CONFIGURED); | 3668 | usb_set_device_state(udev, USB_STATE_CONFIGURED); |
3591 | 3669 | ||
3592 | /* Put interfaces back into the same altsettings as before. | 3670 | /* Put interfaces back into the same altsettings as before. |
@@ -3596,7 +3674,8 @@ static int usb_reset_and_verify_device(struct usb_device *udev) | |||
3596 | * endpoint state. | 3674 | * endpoint state. |
3597 | */ | 3675 | */ |
3598 | for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) { | 3676 | for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) { |
3599 | struct usb_interface *intf = udev->actconfig->interface[i]; | 3677 | struct usb_host_config *config = udev->actconfig; |
3678 | struct usb_interface *intf = config->interface[i]; | ||
3600 | struct usb_interface_descriptor *desc; | 3679 | struct usb_interface_descriptor *desc; |
3601 | 3680 | ||
3602 | desc = &intf->cur_altsetting->desc; | 3681 | desc = &intf->cur_altsetting->desc; |
@@ -3605,6 +3684,17 @@ static int usb_reset_and_verify_device(struct usb_device *udev) | |||
3605 | usb_enable_interface(udev, intf, true); | 3684 | usb_enable_interface(udev, intf, true); |
3606 | ret = 0; | 3685 | ret = 0; |
3607 | } else { | 3686 | } else { |
3687 | /* We've just reset the device, so it will think alt | ||
3688 | * setting 0 is installed. For usb_set_interface() to | ||
3689 | * work properly, we need to set the current alternate | ||
3690 | * interface setting to 0 (or the first alt setting, if | ||
3691 | * the device doesn't have alt setting 0). | ||
3692 | */ | ||
3693 | intf->cur_altsetting = | ||
3694 | usb_find_alt_setting(config, i, 0); | ||
3695 | if (!intf->cur_altsetting) | ||
3696 | intf->cur_altsetting = | ||
3697 | &config->intf_cache[i]->altsetting[0]; | ||
3608 | ret = usb_set_interface(udev, desc->bInterfaceNumber, | 3698 | ret = usb_set_interface(udev, desc->bInterfaceNumber, |
3609 | desc->bAlternateSetting); | 3699 | desc->bAlternateSetting); |
3610 | } | 3700 | } |
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index e80f1af438c8..1b994846e8e0 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
@@ -393,13 +393,7 @@ int usb_sg_init(struct usb_sg_request *io, struct usb_device *dev, | |||
393 | if (io->entries <= 0) | 393 | if (io->entries <= 0) |
394 | return io->entries; | 394 | return io->entries; |
395 | 395 | ||
396 | /* If we're running on an xHCI host controller, queue the whole scatter | 396 | if (dev->bus->sg_tablesize > 0) { |
397 | * gather list with one call to urb_enqueue(). This is only for bulk, | ||
398 | * as that endpoint type does not care how the data gets broken up | ||
399 | * across frames. | ||
400 | */ | ||
401 | if (usb_pipebulk(pipe) && | ||
402 | bus_to_hcd(dev->bus)->driver->flags & HCD_USB3) { | ||
403 | io->urbs = kmalloc(sizeof *io->urbs, mem_flags); | 397 | io->urbs = kmalloc(sizeof *io->urbs, mem_flags); |
404 | use_sg = true; | 398 | use_sg = true; |
405 | } else { | 399 | } else { |
@@ -409,7 +403,7 @@ int usb_sg_init(struct usb_sg_request *io, struct usb_device *dev, | |||
409 | if (!io->urbs) | 403 | if (!io->urbs) |
410 | goto nomem; | 404 | goto nomem; |
411 | 405 | ||
412 | urb_flags = URB_NO_INTERRUPT; | 406 | urb_flags = 0; |
413 | if (dma) | 407 | if (dma) |
414 | urb_flags |= URB_NO_TRANSFER_DMA_MAP; | 408 | urb_flags |= URB_NO_TRANSFER_DMA_MAP; |
415 | if (usb_pipein(pipe)) | 409 | if (usb_pipein(pipe)) |
@@ -441,6 +435,7 @@ int usb_sg_init(struct usb_sg_request *io, struct usb_device *dev, | |||
441 | io->urbs[0]->num_sgs = io->entries; | 435 | io->urbs[0]->num_sgs = io->entries; |
442 | io->entries = 1; | 436 | io->entries = 1; |
443 | } else { | 437 | } else { |
438 | urb_flags |= URB_NO_INTERRUPT; | ||
444 | for_each_sg(sg, sg, io->entries, i) { | 439 | for_each_sg(sg, sg, io->entries, i) { |
445 | unsigned len; | 440 | unsigned len; |
446 | 441 | ||
@@ -1303,6 +1298,7 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate) | |||
1303 | { | 1298 | { |
1304 | struct usb_interface *iface; | 1299 | struct usb_interface *iface; |
1305 | struct usb_host_interface *alt; | 1300 | struct usb_host_interface *alt; |
1301 | struct usb_hcd *hcd = bus_to_hcd(dev->bus); | ||
1306 | int ret; | 1302 | int ret; |
1307 | int manual = 0; | 1303 | int manual = 0; |
1308 | unsigned int epaddr; | 1304 | unsigned int epaddr; |
@@ -1325,6 +1321,18 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate) | |||
1325 | return -EINVAL; | 1321 | return -EINVAL; |
1326 | } | 1322 | } |
1327 | 1323 | ||
1324 | /* Make sure we have enough bandwidth for this alternate interface. | ||
1325 | * Remove the current alt setting and add the new alt setting. | ||
1326 | */ | ||
1327 | mutex_lock(&hcd->bandwidth_mutex); | ||
1328 | ret = usb_hcd_alloc_bandwidth(dev, NULL, iface->cur_altsetting, alt); | ||
1329 | if (ret < 0) { | ||
1330 | dev_info(&dev->dev, "Not enough bandwidth for altsetting %d\n", | ||
1331 | alternate); | ||
1332 | mutex_unlock(&hcd->bandwidth_mutex); | ||
1333 | return ret; | ||
1334 | } | ||
1335 | |||
1328 | if (dev->quirks & USB_QUIRK_NO_SET_INTF) | 1336 | if (dev->quirks & USB_QUIRK_NO_SET_INTF) |
1329 | ret = -EPIPE; | 1337 | ret = -EPIPE; |
1330 | else | 1338 | else |
@@ -1340,8 +1348,13 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate) | |||
1340 | "manual set_interface for iface %d, alt %d\n", | 1348 | "manual set_interface for iface %d, alt %d\n", |
1341 | interface, alternate); | 1349 | interface, alternate); |
1342 | manual = 1; | 1350 | manual = 1; |
1343 | } else if (ret < 0) | 1351 | } else if (ret < 0) { |
1352 | /* Re-instate the old alt setting */ | ||
1353 | usb_hcd_alloc_bandwidth(dev, NULL, alt, iface->cur_altsetting); | ||
1354 | mutex_unlock(&hcd->bandwidth_mutex); | ||
1344 | return ret; | 1355 | return ret; |
1356 | } | ||
1357 | mutex_unlock(&hcd->bandwidth_mutex); | ||
1345 | 1358 | ||
1346 | /* FIXME drivers shouldn't need to replicate/bugfix the logic here | 1359 | /* FIXME drivers shouldn't need to replicate/bugfix the logic here |
1347 | * when they implement async or easily-killable versions of this or | 1360 | * when they implement async or easily-killable versions of this or |
@@ -1423,6 +1436,7 @@ int usb_reset_configuration(struct usb_device *dev) | |||
1423 | { | 1436 | { |
1424 | int i, retval; | 1437 | int i, retval; |
1425 | struct usb_host_config *config; | 1438 | struct usb_host_config *config; |
1439 | struct usb_hcd *hcd = bus_to_hcd(dev->bus); | ||
1426 | 1440 | ||
1427 | if (dev->state == USB_STATE_SUSPENDED) | 1441 | if (dev->state == USB_STATE_SUSPENDED) |
1428 | return -EHOSTUNREACH; | 1442 | return -EHOSTUNREACH; |
@@ -1438,12 +1452,46 @@ int usb_reset_configuration(struct usb_device *dev) | |||
1438 | } | 1452 | } |
1439 | 1453 | ||
1440 | config = dev->actconfig; | 1454 | config = dev->actconfig; |
1455 | retval = 0; | ||
1456 | mutex_lock(&hcd->bandwidth_mutex); | ||
1457 | /* Make sure we have enough bandwidth for each alternate setting 0 */ | ||
1458 | for (i = 0; i < config->desc.bNumInterfaces; i++) { | ||
1459 | struct usb_interface *intf = config->interface[i]; | ||
1460 | struct usb_host_interface *alt; | ||
1461 | |||
1462 | alt = usb_altnum_to_altsetting(intf, 0); | ||
1463 | if (!alt) | ||
1464 | alt = &intf->altsetting[0]; | ||
1465 | if (alt != intf->cur_altsetting) | ||
1466 | retval = usb_hcd_alloc_bandwidth(dev, NULL, | ||
1467 | intf->cur_altsetting, alt); | ||
1468 | if (retval < 0) | ||
1469 | break; | ||
1470 | } | ||
1471 | /* If not, reinstate the old alternate settings */ | ||
1472 | if (retval < 0) { | ||
1473 | reset_old_alts: | ||
1474 | for (; i >= 0; i--) { | ||
1475 | struct usb_interface *intf = config->interface[i]; | ||
1476 | struct usb_host_interface *alt; | ||
1477 | |||
1478 | alt = usb_altnum_to_altsetting(intf, 0); | ||
1479 | if (!alt) | ||
1480 | alt = &intf->altsetting[0]; | ||
1481 | if (alt != intf->cur_altsetting) | ||
1482 | usb_hcd_alloc_bandwidth(dev, NULL, | ||
1483 | alt, intf->cur_altsetting); | ||
1484 | } | ||
1485 | mutex_unlock(&hcd->bandwidth_mutex); | ||
1486 | return retval; | ||
1487 | } | ||
1441 | retval = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | 1488 | retval = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), |
1442 | USB_REQ_SET_CONFIGURATION, 0, | 1489 | USB_REQ_SET_CONFIGURATION, 0, |
1443 | config->desc.bConfigurationValue, 0, | 1490 | config->desc.bConfigurationValue, 0, |
1444 | NULL, 0, USB_CTRL_SET_TIMEOUT); | 1491 | NULL, 0, USB_CTRL_SET_TIMEOUT); |
1445 | if (retval < 0) | 1492 | if (retval < 0) |
1446 | return retval; | 1493 | goto reset_old_alts; |
1494 | mutex_unlock(&hcd->bandwidth_mutex); | ||
1447 | 1495 | ||
1448 | /* re-init hc/hcd interface/endpoint state */ | 1496 | /* re-init hc/hcd interface/endpoint state */ |
1449 | for (i = 0; i < config->desc.bNumInterfaces; i++) { | 1497 | for (i = 0; i < config->desc.bNumInterfaces; i++) { |
@@ -1585,7 +1633,7 @@ static struct usb_interface_assoc_descriptor *find_iad(struct usb_device *dev, | |||
1585 | * | 1633 | * |
1586 | * See usb_queue_reset_device() for more details | 1634 | * See usb_queue_reset_device() for more details |
1587 | */ | 1635 | */ |
1588 | void __usb_queue_reset_device(struct work_struct *ws) | 1636 | static void __usb_queue_reset_device(struct work_struct *ws) |
1589 | { | 1637 | { |
1590 | int rc; | 1638 | int rc; |
1591 | struct usb_interface *iface = | 1639 | struct usb_interface *iface = |
@@ -1652,6 +1700,7 @@ int usb_set_configuration(struct usb_device *dev, int configuration) | |||
1652 | int i, ret; | 1700 | int i, ret; |
1653 | struct usb_host_config *cp = NULL; | 1701 | struct usb_host_config *cp = NULL; |
1654 | struct usb_interface **new_interfaces = NULL; | 1702 | struct usb_interface **new_interfaces = NULL; |
1703 | struct usb_hcd *hcd = bus_to_hcd(dev->bus); | ||
1655 | int n, nintf; | 1704 | int n, nintf; |
1656 | 1705 | ||
1657 | if (dev->authorized == 0 || configuration == -1) | 1706 | if (dev->authorized == 0 || configuration == -1) |
@@ -1721,12 +1770,11 @@ free_interfaces: | |||
1721 | * host controller will not allow submissions to dropped endpoints. If | 1770 | * host controller will not allow submissions to dropped endpoints. If |
1722 | * this call fails, the device state is unchanged. | 1771 | * this call fails, the device state is unchanged. |
1723 | */ | 1772 | */ |
1724 | if (cp) | 1773 | mutex_lock(&hcd->bandwidth_mutex); |
1725 | ret = usb_hcd_check_bandwidth(dev, cp, NULL); | 1774 | ret = usb_hcd_alloc_bandwidth(dev, cp, NULL, NULL); |
1726 | else | ||
1727 | ret = usb_hcd_check_bandwidth(dev, NULL, NULL); | ||
1728 | if (ret < 0) { | 1775 | if (ret < 0) { |
1729 | usb_autosuspend_device(dev); | 1776 | usb_autosuspend_device(dev); |
1777 | mutex_unlock(&hcd->bandwidth_mutex); | ||
1730 | goto free_interfaces; | 1778 | goto free_interfaces; |
1731 | } | 1779 | } |
1732 | 1780 | ||
@@ -1752,10 +1800,12 @@ free_interfaces: | |||
1752 | dev->actconfig = cp; | 1800 | dev->actconfig = cp; |
1753 | if (!cp) { | 1801 | if (!cp) { |
1754 | usb_set_device_state(dev, USB_STATE_ADDRESS); | 1802 | usb_set_device_state(dev, USB_STATE_ADDRESS); |
1755 | usb_hcd_check_bandwidth(dev, NULL, NULL); | 1803 | usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL); |
1756 | usb_autosuspend_device(dev); | 1804 | usb_autosuspend_device(dev); |
1805 | mutex_unlock(&hcd->bandwidth_mutex); | ||
1757 | goto free_interfaces; | 1806 | goto free_interfaces; |
1758 | } | 1807 | } |
1808 | mutex_unlock(&hcd->bandwidth_mutex); | ||
1759 | usb_set_device_state(dev, USB_STATE_CONFIGURED); | 1809 | usb_set_device_state(dev, USB_STATE_CONFIGURED); |
1760 | 1810 | ||
1761 | /* Initialize the new interface structures and the | 1811 | /* Initialize the new interface structures and the |
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index 7ec3041ae79e..15477008b631 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c | |||
@@ -139,6 +139,16 @@ show_devnum(struct device *dev, struct device_attribute *attr, char *buf) | |||
139 | static DEVICE_ATTR(devnum, S_IRUGO, show_devnum, NULL); | 139 | static DEVICE_ATTR(devnum, S_IRUGO, show_devnum, NULL); |
140 | 140 | ||
141 | static ssize_t | 141 | static ssize_t |
142 | show_devpath(struct device *dev, struct device_attribute *attr, char *buf) | ||
143 | { | ||
144 | struct usb_device *udev; | ||
145 | |||
146 | udev = to_usb_device(dev); | ||
147 | return sprintf(buf, "%s\n", udev->devpath); | ||
148 | } | ||
149 | static DEVICE_ATTR(devpath, S_IRUGO, show_devpath, NULL); | ||
150 | |||
151 | static ssize_t | ||
142 | show_version(struct device *dev, struct device_attribute *attr, char *buf) | 152 | show_version(struct device *dev, struct device_attribute *attr, char *buf) |
143 | { | 153 | { |
144 | struct usb_device *udev; | 154 | struct usb_device *udev; |
@@ -317,7 +327,6 @@ static DEVICE_ATTR(autosuspend, S_IRUGO | S_IWUSR, | |||
317 | 327 | ||
318 | static const char on_string[] = "on"; | 328 | static const char on_string[] = "on"; |
319 | static const char auto_string[] = "auto"; | 329 | static const char auto_string[] = "auto"; |
320 | static const char suspend_string[] = "suspend"; | ||
321 | 330 | ||
322 | static ssize_t | 331 | static ssize_t |
323 | show_level(struct device *dev, struct device_attribute *attr, char *buf) | 332 | show_level(struct device *dev, struct device_attribute *attr, char *buf) |
@@ -325,13 +334,8 @@ show_level(struct device *dev, struct device_attribute *attr, char *buf) | |||
325 | struct usb_device *udev = to_usb_device(dev); | 334 | struct usb_device *udev = to_usb_device(dev); |
326 | const char *p = auto_string; | 335 | const char *p = auto_string; |
327 | 336 | ||
328 | if (udev->state == USB_STATE_SUSPENDED) { | 337 | if (udev->state != USB_STATE_SUSPENDED && udev->autosuspend_disabled) |
329 | if (udev->autoresume_disabled) | 338 | p = on_string; |
330 | p = suspend_string; | ||
331 | } else { | ||
332 | if (udev->autosuspend_disabled) | ||
333 | p = on_string; | ||
334 | } | ||
335 | return sprintf(buf, "%s\n", p); | 339 | return sprintf(buf, "%s\n", p); |
336 | } | 340 | } |
337 | 341 | ||
@@ -343,7 +347,7 @@ set_level(struct device *dev, struct device_attribute *attr, | |||
343 | int len = count; | 347 | int len = count; |
344 | char *cp; | 348 | char *cp; |
345 | int rc = 0; | 349 | int rc = 0; |
346 | int old_autosuspend_disabled, old_autoresume_disabled; | 350 | int old_autosuspend_disabled; |
347 | 351 | ||
348 | cp = memchr(buf, '\n', count); | 352 | cp = memchr(buf, '\n', count); |
349 | if (cp) | 353 | if (cp) |
@@ -351,7 +355,6 @@ set_level(struct device *dev, struct device_attribute *attr, | |||
351 | 355 | ||
352 | usb_lock_device(udev); | 356 | usb_lock_device(udev); |
353 | old_autosuspend_disabled = udev->autosuspend_disabled; | 357 | old_autosuspend_disabled = udev->autosuspend_disabled; |
354 | old_autoresume_disabled = udev->autoresume_disabled; | ||
355 | 358 | ||
356 | /* Setting the flags without calling usb_pm_lock is a subject to | 359 | /* Setting the flags without calling usb_pm_lock is a subject to |
357 | * races, but who cares... | 360 | * races, but who cares... |
@@ -359,28 +362,18 @@ set_level(struct device *dev, struct device_attribute *attr, | |||
359 | if (len == sizeof on_string - 1 && | 362 | if (len == sizeof on_string - 1 && |
360 | strncmp(buf, on_string, len) == 0) { | 363 | strncmp(buf, on_string, len) == 0) { |
361 | udev->autosuspend_disabled = 1; | 364 | udev->autosuspend_disabled = 1; |
362 | udev->autoresume_disabled = 0; | ||
363 | rc = usb_external_resume_device(udev, PMSG_USER_RESUME); | 365 | rc = usb_external_resume_device(udev, PMSG_USER_RESUME); |
364 | 366 | ||
365 | } else if (len == sizeof auto_string - 1 && | 367 | } else if (len == sizeof auto_string - 1 && |
366 | strncmp(buf, auto_string, len) == 0) { | 368 | strncmp(buf, auto_string, len) == 0) { |
367 | udev->autosuspend_disabled = 0; | 369 | udev->autosuspend_disabled = 0; |
368 | udev->autoresume_disabled = 0; | ||
369 | rc = usb_external_resume_device(udev, PMSG_USER_RESUME); | 370 | rc = usb_external_resume_device(udev, PMSG_USER_RESUME); |
370 | 371 | ||
371 | } else if (len == sizeof suspend_string - 1 && | ||
372 | strncmp(buf, suspend_string, len) == 0) { | ||
373 | udev->autosuspend_disabled = 0; | ||
374 | udev->autoresume_disabled = 1; | ||
375 | rc = usb_external_suspend_device(udev, PMSG_USER_SUSPEND); | ||
376 | |||
377 | } else | 372 | } else |
378 | rc = -EINVAL; | 373 | rc = -EINVAL; |
379 | 374 | ||
380 | if (rc) { | 375 | if (rc) |
381 | udev->autosuspend_disabled = old_autosuspend_disabled; | 376 | udev->autosuspend_disabled = old_autosuspend_disabled; |
382 | udev->autoresume_disabled = old_autoresume_disabled; | ||
383 | } | ||
384 | usb_unlock_device(udev); | 377 | usb_unlock_device(udev); |
385 | return (rc < 0 ? rc : count); | 378 | return (rc < 0 ? rc : count); |
386 | } | 379 | } |
@@ -508,6 +501,28 @@ static ssize_t usb_dev_authorized_store(struct device *dev, | |||
508 | static DEVICE_ATTR(authorized, 0644, | 501 | static DEVICE_ATTR(authorized, 0644, |
509 | usb_dev_authorized_show, usb_dev_authorized_store); | 502 | usb_dev_authorized_show, usb_dev_authorized_store); |
510 | 503 | ||
504 | /* "Safely remove a device" */ | ||
505 | static ssize_t usb_remove_store(struct device *dev, | ||
506 | struct device_attribute *attr, | ||
507 | const char *buf, size_t count) | ||
508 | { | ||
509 | struct usb_device *udev = to_usb_device(dev); | ||
510 | int rc = 0; | ||
511 | |||
512 | usb_lock_device(udev); | ||
513 | if (udev->state != USB_STATE_NOTATTACHED) { | ||
514 | |||
515 | /* To avoid races, first unconfigure and then remove */ | ||
516 | usb_set_configuration(udev, -1); | ||
517 | rc = usb_remove_device(udev); | ||
518 | } | ||
519 | if (rc == 0) | ||
520 | rc = count; | ||
521 | usb_unlock_device(udev); | ||
522 | return rc; | ||
523 | } | ||
524 | static DEVICE_ATTR(remove, 0200, NULL, usb_remove_store); | ||
525 | |||
511 | 526 | ||
512 | static struct attribute *dev_attrs[] = { | 527 | static struct attribute *dev_attrs[] = { |
513 | /* current configuration's attributes */ | 528 | /* current configuration's attributes */ |
@@ -516,8 +531,8 @@ static struct attribute *dev_attrs[] = { | |||
516 | &dev_attr_bConfigurationValue.attr, | 531 | &dev_attr_bConfigurationValue.attr, |
517 | &dev_attr_bmAttributes.attr, | 532 | &dev_attr_bmAttributes.attr, |
518 | &dev_attr_bMaxPower.attr, | 533 | &dev_attr_bMaxPower.attr, |
519 | &dev_attr_urbnum.attr, | ||
520 | /* device attributes */ | 534 | /* device attributes */ |
535 | &dev_attr_urbnum.attr, | ||
521 | &dev_attr_idVendor.attr, | 536 | &dev_attr_idVendor.attr, |
522 | &dev_attr_idProduct.attr, | 537 | &dev_attr_idProduct.attr, |
523 | &dev_attr_bcdDevice.attr, | 538 | &dev_attr_bcdDevice.attr, |
@@ -529,10 +544,12 @@ static struct attribute *dev_attrs[] = { | |||
529 | &dev_attr_speed.attr, | 544 | &dev_attr_speed.attr, |
530 | &dev_attr_busnum.attr, | 545 | &dev_attr_busnum.attr, |
531 | &dev_attr_devnum.attr, | 546 | &dev_attr_devnum.attr, |
547 | &dev_attr_devpath.attr, | ||
532 | &dev_attr_version.attr, | 548 | &dev_attr_version.attr, |
533 | &dev_attr_maxchild.attr, | 549 | &dev_attr_maxchild.attr, |
534 | &dev_attr_quirks.attr, | 550 | &dev_attr_quirks.attr, |
535 | &dev_attr_authorized.attr, | 551 | &dev_attr_authorized.attr, |
552 | &dev_attr_remove.attr, | ||
536 | NULL, | 553 | NULL, |
537 | }; | 554 | }; |
538 | static struct attribute_group dev_attr_grp = { | 555 | static struct attribute_group dev_attr_grp = { |
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index 0885d4abdc62..e7cae1334693 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c | |||
@@ -429,8 +429,16 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) | |||
429 | case USB_ENDPOINT_XFER_ISOC: | 429 | case USB_ENDPOINT_XFER_ISOC: |
430 | case USB_ENDPOINT_XFER_INT: | 430 | case USB_ENDPOINT_XFER_INT: |
431 | /* too small? */ | 431 | /* too small? */ |
432 | if (urb->interval <= 0) | 432 | switch (dev->speed) { |
433 | return -EINVAL; | 433 | case USB_SPEED_VARIABLE: |
434 | if (urb->interval < 6) | ||
435 | return -EINVAL; | ||
436 | break; | ||
437 | default: | ||
438 | if (urb->interval <= 0) | ||
439 | return -EINVAL; | ||
440 | break; | ||
441 | } | ||
434 | /* too big? */ | 442 | /* too big? */ |
435 | switch (dev->speed) { | 443 | switch (dev->speed) { |
436 | case USB_SPEED_SUPER: /* units are 125us */ | 444 | case USB_SPEED_SUPER: /* units are 125us */ |
@@ -438,6 +446,10 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) | |||
438 | if (urb->interval > (1 << 15)) | 446 | if (urb->interval > (1 << 15)) |
439 | return -EINVAL; | 447 | return -EINVAL; |
440 | max = 1 << 15; | 448 | max = 1 << 15; |
449 | case USB_SPEED_VARIABLE: | ||
450 | if (urb->interval > 16) | ||
451 | return -EINVAL; | ||
452 | break; | ||
441 | case USB_SPEED_HIGH: /* units are microframes */ | 453 | case USB_SPEED_HIGH: /* units are microframes */ |
442 | /* NOTE usb handles 2^15 */ | 454 | /* NOTE usb handles 2^15 */ |
443 | if (urb->interval > (1024 * 8)) | 455 | if (urb->interval > (1024 * 8)) |
@@ -461,8 +473,10 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) | |||
461 | default: | 473 | default: |
462 | return -EINVAL; | 474 | return -EINVAL; |
463 | } | 475 | } |
464 | /* Round down to a power of 2, no more than max */ | 476 | if (dev->speed != USB_SPEED_VARIABLE) { |
465 | urb->interval = min(max, 1 << ilog2(urb->interval)); | 477 | /* Round down to a power of 2, no more than max */ |
478 | urb->interval = min(max, 1 << ilog2(urb->interval)); | ||
479 | } | ||
466 | } | 480 | } |
467 | 481 | ||
468 | return usb_hcd_submit_urb(urb, mem_flags); | 482 | return usb_hcd_submit_urb(urb, mem_flags); |
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index b1b85abb9a2d..2fb42043b305 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c | |||
@@ -64,6 +64,43 @@ MODULE_PARM_DESC(autosuspend, "default autosuspend delay"); | |||
64 | 64 | ||
65 | 65 | ||
66 | /** | 66 | /** |
67 | * usb_find_alt_setting() - Given a configuration, find the alternate setting | ||
68 | * for the given interface. | ||
69 | * @config - the configuration to search (not necessarily the current config). | ||
70 | * @iface_num - interface number to search in | ||
71 | * @alt_num - alternate interface setting number to search for. | ||
72 | * | ||
73 | * Search the configuration's interface cache for the given alt setting. | ||
74 | */ | ||
75 | struct usb_host_interface *usb_find_alt_setting( | ||
76 | struct usb_host_config *config, | ||
77 | unsigned int iface_num, | ||
78 | unsigned int alt_num) | ||
79 | { | ||
80 | struct usb_interface_cache *intf_cache = NULL; | ||
81 | int i; | ||
82 | |||
83 | for (i = 0; i < config->desc.bNumInterfaces; i++) { | ||
84 | if (config->intf_cache[i]->altsetting[0].desc.bInterfaceNumber | ||
85 | == iface_num) { | ||
86 | intf_cache = config->intf_cache[i]; | ||
87 | break; | ||
88 | } | ||
89 | } | ||
90 | if (!intf_cache) | ||
91 | return NULL; | ||
92 | for (i = 0; i < intf_cache->num_altsetting; i++) | ||
93 | if (intf_cache->altsetting[i].desc.bAlternateSetting == alt_num) | ||
94 | return &intf_cache->altsetting[i]; | ||
95 | |||
96 | printk(KERN_DEBUG "Did not find alt setting %u for intf %u, " | ||
97 | "config %u\n", alt_num, iface_num, | ||
98 | config->desc.bConfigurationValue); | ||
99 | return NULL; | ||
100 | } | ||
101 | EXPORT_SYMBOL_GPL(usb_find_alt_setting); | ||
102 | |||
103 | /** | ||
67 | * usb_ifnum_to_if - get the interface object with a given interface number | 104 | * usb_ifnum_to_if - get the interface object with a given interface number |
68 | * @dev: the device whose current configuration is considered | 105 | * @dev: the device whose current configuration is considered |
69 | * @ifnum: the desired interface | 106 | * @ifnum: the desired interface |
@@ -132,7 +169,7 @@ EXPORT_SYMBOL_GPL(usb_altnum_to_altsetting); | |||
132 | 169 | ||
133 | struct find_interface_arg { | 170 | struct find_interface_arg { |
134 | int minor; | 171 | int minor; |
135 | struct usb_interface *interface; | 172 | struct device_driver *drv; |
136 | }; | 173 | }; |
137 | 174 | ||
138 | static int __find_interface(struct device *dev, void *data) | 175 | static int __find_interface(struct device *dev, void *data) |
@@ -143,12 +180,10 @@ static int __find_interface(struct device *dev, void *data) | |||
143 | if (!is_usb_interface(dev)) | 180 | if (!is_usb_interface(dev)) |
144 | return 0; | 181 | return 0; |
145 | 182 | ||
183 | if (dev->driver != arg->drv) | ||
184 | return 0; | ||
146 | intf = to_usb_interface(dev); | 185 | intf = to_usb_interface(dev); |
147 | if (intf->minor != -1 && intf->minor == arg->minor) { | 186 | return intf->minor == arg->minor; |
148 | arg->interface = intf; | ||
149 | return 1; | ||
150 | } | ||
151 | return 0; | ||
152 | } | 187 | } |
153 | 188 | ||
154 | /** | 189 | /** |
@@ -156,21 +191,24 @@ static int __find_interface(struct device *dev, void *data) | |||
156 | * @drv: the driver whose current configuration is considered | 191 | * @drv: the driver whose current configuration is considered |
157 | * @minor: the minor number of the desired device | 192 | * @minor: the minor number of the desired device |
158 | * | 193 | * |
159 | * This walks the driver device list and returns a pointer to the interface | 194 | * This walks the bus device list and returns a pointer to the interface |
160 | * with the matching minor. Note, this only works for devices that share the | 195 | * with the matching minor and driver. Note, this only works for devices |
161 | * USB major number. | 196 | * that share the USB major number. |
162 | */ | 197 | */ |
163 | struct usb_interface *usb_find_interface(struct usb_driver *drv, int minor) | 198 | struct usb_interface *usb_find_interface(struct usb_driver *drv, int minor) |
164 | { | 199 | { |
165 | struct find_interface_arg argb; | 200 | struct find_interface_arg argb; |
166 | int retval; | 201 | struct device *dev; |
167 | 202 | ||
168 | argb.minor = minor; | 203 | argb.minor = minor; |
169 | argb.interface = NULL; | 204 | argb.drv = &drv->drvwrap.driver; |
170 | /* eat the error, it will be in argb.interface */ | 205 | |
171 | retval = driver_for_each_device(&drv->drvwrap.driver, NULL, &argb, | 206 | dev = bus_find_device(&usb_bus_type, NULL, &argb, __find_interface); |
172 | __find_interface); | 207 | |
173 | return argb.interface; | 208 | /* Drop reference count from bus_find_device */ |
209 | put_device(dev); | ||
210 | |||
211 | return dev ? to_usb_interface(dev) : NULL; | ||
174 | } | 212 | } |
175 | EXPORT_SYMBOL_GPL(usb_find_interface); | 213 | EXPORT_SYMBOL_GPL(usb_find_interface); |
176 | 214 | ||
@@ -291,7 +329,7 @@ static int usb_dev_restore(struct device *dev) | |||
291 | return usb_resume(dev, PMSG_RESTORE); | 329 | return usb_resume(dev, PMSG_RESTORE); |
292 | } | 330 | } |
293 | 331 | ||
294 | static struct dev_pm_ops usb_device_pm_ops = { | 332 | static const struct dev_pm_ops usb_device_pm_ops = { |
295 | .prepare = usb_dev_prepare, | 333 | .prepare = usb_dev_prepare, |
296 | .complete = usb_dev_complete, | 334 | .complete = usb_dev_complete, |
297 | .suspend = usb_dev_suspend, | 335 | .suspend = usb_dev_suspend, |
@@ -1038,7 +1076,7 @@ static struct notifier_block usb_bus_nb = { | |||
1038 | struct dentry *usb_debug_root; | 1076 | struct dentry *usb_debug_root; |
1039 | EXPORT_SYMBOL_GPL(usb_debug_root); | 1077 | EXPORT_SYMBOL_GPL(usb_debug_root); |
1040 | 1078 | ||
1041 | struct dentry *usb_debug_devices; | 1079 | static struct dentry *usb_debug_devices; |
1042 | 1080 | ||
1043 | static int usb_debugfs_init(void) | 1081 | static int usb_debugfs_init(void) |
1044 | { | 1082 | { |
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index 9a8b15e6377a..4c36c7f512a0 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h | |||
@@ -24,6 +24,7 @@ extern void usb_disable_device(struct usb_device *dev, int skip_ep0); | |||
24 | extern int usb_deauthorize_device(struct usb_device *); | 24 | extern int usb_deauthorize_device(struct usb_device *); |
25 | extern int usb_authorize_device(struct usb_device *); | 25 | extern int usb_authorize_device(struct usb_device *); |
26 | extern void usb_detect_quirks(struct usb_device *udev); | 26 | extern void usb_detect_quirks(struct usb_device *udev); |
27 | extern int usb_remove_device(struct usb_device *udev); | ||
27 | 28 | ||
28 | extern int usb_get_device_descriptor(struct usb_device *dev, | 29 | extern int usb_get_device_descriptor(struct usb_device *dev, |
29 | unsigned int size); | 30 | unsigned int size); |