aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/core/devio.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/core/devio.c')
-rw-r--r--drivers/usb/core/devio.c93
1 files changed, 25 insertions, 68 deletions
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index 8df4b76465a..e0f107948eb 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -333,17 +333,14 @@ static struct async *async_getcompleted(struct dev_state *ps)
333static struct async *async_getpending(struct dev_state *ps, 333static struct async *async_getpending(struct dev_state *ps,
334 void __user *userurb) 334 void __user *userurb)
335{ 335{
336 unsigned long flags;
337 struct async *as; 336 struct async *as;
338 337
339 spin_lock_irqsave(&ps->lock, flags);
340 list_for_each_entry(as, &ps->async_pending, asynclist) 338 list_for_each_entry(as, &ps->async_pending, asynclist)
341 if (as->userurb == userurb) { 339 if (as->userurb == userurb) {
342 list_del_init(&as->asynclist); 340 list_del_init(&as->asynclist);
343 spin_unlock_irqrestore(&ps->lock, flags);
344 return as; 341 return as;
345 } 342 }
346 spin_unlock_irqrestore(&ps->lock, flags); 343
347 return NULL; 344 return NULL;
348} 345}
349 346
@@ -398,6 +395,7 @@ static void cancel_bulk_urbs(struct dev_state *ps, unsigned bulk_addr)
398__releases(ps->lock) 395__releases(ps->lock)
399__acquires(ps->lock) 396__acquires(ps->lock)
400{ 397{
398 struct urb *urb;
401 struct async *as; 399 struct async *as;
402 400
403 /* Mark all the pending URBs that match bulk_addr, up to but not 401 /* Mark all the pending URBs that match bulk_addr, up to but not
@@ -420,8 +418,11 @@ __acquires(ps->lock)
420 list_for_each_entry(as, &ps->async_pending, asynclist) { 418 list_for_each_entry(as, &ps->async_pending, asynclist) {
421 if (as->bulk_status == AS_UNLINK) { 419 if (as->bulk_status == AS_UNLINK) {
422 as->bulk_status = 0; /* Only once */ 420 as->bulk_status = 0; /* Only once */
421 urb = as->urb;
422 usb_get_urb(urb);
423 spin_unlock(&ps->lock); /* Allow completions */ 423 spin_unlock(&ps->lock); /* Allow completions */
424 usb_unlink_urb(as->urb); 424 usb_unlink_urb(urb);
425 usb_put_urb(urb);
425 spin_lock(&ps->lock); 426 spin_lock(&ps->lock);
426 goto rescan; 427 goto rescan;
427 } 428 }
@@ -472,6 +473,7 @@ static void async_completed(struct urb *urb)
472 473
473static void destroy_async(struct dev_state *ps, struct list_head *list) 474static void destroy_async(struct dev_state *ps, struct list_head *list)
474{ 475{
476 struct urb *urb;
475 struct async *as; 477 struct async *as;
476 unsigned long flags; 478 unsigned long flags;
477 479
@@ -479,10 +481,13 @@ static void destroy_async(struct dev_state *ps, struct list_head *list)
479 while (!list_empty(list)) { 481 while (!list_empty(list)) {
480 as = list_entry(list->next, struct async, asynclist); 482 as = list_entry(list->next, struct async, asynclist);
481 list_del_init(&as->asynclist); 483 list_del_init(&as->asynclist);
484 urb = as->urb;
485 usb_get_urb(urb);
482 486
483 /* drop the spinlock so the completion handler can run */ 487 /* drop the spinlock so the completion handler can run */
484 spin_unlock_irqrestore(&ps->lock, flags); 488 spin_unlock_irqrestore(&ps->lock, flags);
485 usb_kill_urb(as->urb); 489 usb_kill_urb(urb);
490 usb_put_urb(urb);
486 spin_lock_irqsave(&ps->lock, flags); 491 spin_lock_irqsave(&ps->lock, flags);
487 } 492 }
488 spin_unlock_irqrestore(&ps->lock, flags); 493 spin_unlock_irqrestore(&ps->lock, flags);
@@ -727,17 +732,6 @@ static int usbdev_open(struct inode *inode, struct file *file)
727 if (imajor(inode) == USB_DEVICE_MAJOR) 732 if (imajor(inode) == USB_DEVICE_MAJOR)
728 dev = usbdev_lookup_by_devt(inode->i_rdev); 733 dev = usbdev_lookup_by_devt(inode->i_rdev);
729 734
730#ifdef CONFIG_USB_DEVICEFS
731 /* procfs file */
732 if (!dev) {
733 dev = inode->i_private;
734 if (dev && dev->usbfs_dentry &&
735 dev->usbfs_dentry->d_inode == inode)
736 usb_get_dev(dev);
737 else
738 dev = NULL;
739 }
740#endif
741 mutex_unlock(&usbfs_mutex); 735 mutex_unlock(&usbfs_mutex);
742 736
743 if (!dev) 737 if (!dev)
@@ -1410,12 +1404,24 @@ static int proc_submiturb(struct dev_state *ps, void __user *arg)
1410 1404
1411static int proc_unlinkurb(struct dev_state *ps, void __user *arg) 1405static int proc_unlinkurb(struct dev_state *ps, void __user *arg)
1412{ 1406{
1407 struct urb *urb;
1413 struct async *as; 1408 struct async *as;
1409 unsigned long flags;
1414 1410
1411 spin_lock_irqsave(&ps->lock, flags);
1415 as = async_getpending(ps, arg); 1412 as = async_getpending(ps, arg);
1416 if (!as) 1413 if (!as) {
1414 spin_unlock_irqrestore(&ps->lock, flags);
1417 return -EINVAL; 1415 return -EINVAL;
1418 usb_kill_urb(as->urb); 1416 }
1417
1418 urb = as->urb;
1419 usb_get_urb(urb);
1420 spin_unlock_irqrestore(&ps->lock, flags);
1421
1422 usb_kill_urb(urb);
1423 usb_put_urb(urb);
1424
1419 return 0; 1425 return 0;
1420} 1426}
1421 1427
@@ -2062,44 +2068,13 @@ static void usbdev_remove(struct usb_device *udev)
2062 } 2068 }
2063} 2069}
2064 2070
2065#ifdef CONFIG_USB_DEVICE_CLASS
2066static struct class *usb_classdev_class;
2067
2068static int usb_classdev_add(struct usb_device *dev)
2069{
2070 struct device *cldev;
2071
2072 cldev = device_create(usb_classdev_class, &dev->dev, dev->dev.devt,
2073 NULL, "usbdev%d.%d", dev->bus->busnum,
2074 dev->devnum);
2075 if (IS_ERR(cldev))
2076 return PTR_ERR(cldev);
2077 dev->usb_classdev = cldev;
2078 return 0;
2079}
2080
2081static void usb_classdev_remove(struct usb_device *dev)
2082{
2083 if (dev->usb_classdev)
2084 device_unregister(dev->usb_classdev);
2085}
2086
2087#else
2088#define usb_classdev_add(dev) 0
2089#define usb_classdev_remove(dev) do {} while (0)
2090
2091#endif
2092
2093static int usbdev_notify(struct notifier_block *self, 2071static int usbdev_notify(struct notifier_block *self,
2094 unsigned long action, void *dev) 2072 unsigned long action, void *dev)
2095{ 2073{
2096 switch (action) { 2074 switch (action) {
2097 case USB_DEVICE_ADD: 2075 case USB_DEVICE_ADD:
2098 if (usb_classdev_add(dev))
2099 return NOTIFY_BAD;
2100 break; 2076 break;
2101 case USB_DEVICE_REMOVE: 2077 case USB_DEVICE_REMOVE:
2102 usb_classdev_remove(dev);
2103 usbdev_remove(dev); 2078 usbdev_remove(dev);
2104 break; 2079 break;
2105 } 2080 }
@@ -2129,21 +2104,6 @@ int __init usb_devio_init(void)
2129 USB_DEVICE_MAJOR); 2104 USB_DEVICE_MAJOR);
2130 goto error_cdev; 2105 goto error_cdev;
2131 } 2106 }
2132#ifdef CONFIG_USB_DEVICE_CLASS
2133 usb_classdev_class = class_create(THIS_MODULE, "usb_device");
2134 if (IS_ERR(usb_classdev_class)) {
2135 printk(KERN_ERR "Unable to register usb_device class\n");
2136 retval = PTR_ERR(usb_classdev_class);
2137 cdev_del(&usb_device_cdev);
2138 usb_classdev_class = NULL;
2139 goto out;
2140 }
2141 /* devices of this class shadow the major:minor of their parent
2142 * device, so clear ->dev_kobj to prevent adding duplicate entries
2143 * to /sys/dev
2144 */
2145 usb_classdev_class->dev_kobj = NULL;
2146#endif
2147 usb_register_notify(&usbdev_nb); 2107 usb_register_notify(&usbdev_nb);
2148out: 2108out:
2149 return retval; 2109 return retval;
@@ -2156,9 +2116,6 @@ error_cdev:
2156void usb_devio_cleanup(void) 2116void usb_devio_cleanup(void)
2157{ 2117{
2158 usb_unregister_notify(&usbdev_nb); 2118 usb_unregister_notify(&usbdev_nb);
2159#ifdef CONFIG_USB_DEVICE_CLASS
2160 class_destroy(usb_classdev_class);
2161#endif
2162 cdev_del(&usb_device_cdev); 2119 cdev_del(&usb_device_cdev);
2163 unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX); 2120 unregister_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX);
2164} 2121}