aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/core/devio.c40
-rw-r--r--drivers/usb/core/driver.c8
-rw-r--r--drivers/usb/core/sysfs.c2
3 files changed, 30 insertions, 20 deletions
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index 431d17287a86..825e0abfed0a 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -654,19 +654,21 @@ static int usbdev_open(struct inode *inode, struct file *file)
654 int ret; 654 int ret;
655 655
656 lock_kernel(); 656 lock_kernel();
657 /* Protect against simultaneous removal or release */
658 mutex_lock(&usbfs_mutex);
659 657
660 ret = -ENOMEM; 658 ret = -ENOMEM;
661 ps = kmalloc(sizeof(struct dev_state), GFP_KERNEL); 659 ps = kmalloc(sizeof(struct dev_state), GFP_KERNEL);
662 if (!ps) 660 if (!ps)
663 goto out; 661 goto out_free_ps;
664 662
665 ret = -ENODEV; 663 ret = -ENODEV;
666 664
665 /* Protect against simultaneous removal or release */
666 mutex_lock(&usbfs_mutex);
667
667 /* usbdev device-node */ 668 /* usbdev device-node */
668 if (imajor(inode) == USB_DEVICE_MAJOR) 669 if (imajor(inode) == USB_DEVICE_MAJOR)
669 dev = usbdev_lookup_by_devt(inode->i_rdev); 670 dev = usbdev_lookup_by_devt(inode->i_rdev);
671
670#ifdef CONFIG_USB_DEVICEFS 672#ifdef CONFIG_USB_DEVICEFS
671 /* procfs file */ 673 /* procfs file */
672 if (!dev) { 674 if (!dev) {
@@ -678,13 +680,19 @@ static int usbdev_open(struct inode *inode, struct file *file)
678 dev = NULL; 680 dev = NULL;
679 } 681 }
680#endif 682#endif
681 if (!dev || dev->state == USB_STATE_NOTATTACHED) 683 mutex_unlock(&usbfs_mutex);
682 goto out; 684
685 if (!dev)
686 goto out_free_ps;
687
688 usb_lock_device(dev);
689 if (dev->state == USB_STATE_NOTATTACHED)
690 goto out_unlock_device;
691
683 ret = usb_autoresume_device(dev); 692 ret = usb_autoresume_device(dev);
684 if (ret) 693 if (ret)
685 goto out; 694 goto out_unlock_device;
686 695
687 ret = 0;
688 ps->dev = dev; 696 ps->dev = dev;
689 ps->file = file; 697 ps->file = file;
690 spin_lock_init(&ps->lock); 698 spin_lock_init(&ps->lock);
@@ -702,14 +710,17 @@ static int usbdev_open(struct inode *inode, struct file *file)
702 smp_wmb(); 710 smp_wmb();
703 list_add_tail(&ps->list, &dev->filelist); 711 list_add_tail(&ps->list, &dev->filelist);
704 file->private_data = ps; 712 file->private_data = ps;
713 usb_unlock_device(dev);
705 snoop(&dev->dev, "opened by process %d: %s\n", task_pid_nr(current), 714 snoop(&dev->dev, "opened by process %d: %s\n", task_pid_nr(current),
706 current->comm); 715 current->comm);
707 out: 716 unlock_kernel();
708 if (ret) { 717 return ret;
709 kfree(ps); 718
710 usb_put_dev(dev); 719 out_unlock_device:
711 } 720 usb_unlock_device(dev);
712 mutex_unlock(&usbfs_mutex); 721 usb_put_dev(dev);
722 out_free_ps:
723 kfree(ps);
713 unlock_kernel(); 724 unlock_kernel();
714 return ret; 725 return ret;
715} 726}
@@ -724,10 +735,7 @@ static int usbdev_release(struct inode *inode, struct file *file)
724 usb_lock_device(dev); 735 usb_lock_device(dev);
725 usb_hub_release_all_ports(dev, ps); 736 usb_hub_release_all_ports(dev, ps);
726 737
727 /* Protect against simultaneous open */
728 mutex_lock(&usbfs_mutex);
729 list_del_init(&ps->list); 738 list_del_init(&ps->list);
730 mutex_unlock(&usbfs_mutex);
731 739
732 for (ifnum = 0; ps->ifclaimed && ifnum < 8*sizeof(ps->ifclaimed); 740 for (ifnum = 0; ps->ifclaimed && ifnum < 8*sizeof(ps->ifclaimed);
733 ifnum++) { 741 ifnum++) {
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index fcafb2dce3ac..2b39583040d0 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -1478,8 +1478,7 @@ void usb_autoresume_work(struct work_struct *work)
1478 * driver requires remote-wakeup capability during autosuspend but remote 1478 * driver requires remote-wakeup capability during autosuspend but remote
1479 * wakeup is disabled, the autosuspend will fail. 1479 * wakeup is disabled, the autosuspend will fail.
1480 * 1480 *
1481 * Often the caller will hold @udev's device lock, but this is not 1481 * The caller must hold @udev's device lock.
1482 * necessary.
1483 * 1482 *
1484 * This routine can run only in process context. 1483 * This routine can run only in process context.
1485 */ 1484 */
@@ -1503,6 +1502,8 @@ void usb_autosuspend_device(struct usb_device *udev)
1503 * for an active interface is greater than 0, or autosuspend is not allowed 1502 * for an active interface is greater than 0, or autosuspend is not allowed
1504 * for any other reason, no autosuspend request will be queued. 1503 * for any other reason, no autosuspend request will be queued.
1505 * 1504 *
1505 * The caller must hold @udev's device lock.
1506 *
1506 * This routine can run only in process context. 1507 * This routine can run only in process context.
1507 */ 1508 */
1508void usb_try_autosuspend_device(struct usb_device *udev) 1509void usb_try_autosuspend_device(struct usb_device *udev)
@@ -1526,8 +1527,7 @@ void usb_try_autosuspend_device(struct usb_device *udev)
1526 * @udev's usage counter is incremented to prevent subsequent autosuspends. 1527 * @udev's usage counter is incremented to prevent subsequent autosuspends.
1527 * However if the autoresume fails then the usage counter is re-decremented. 1528 * However if the autoresume fails then the usage counter is re-decremented.
1528 * 1529 *
1529 * Often the caller will hold @udev's device lock, but this is not 1530 * The caller must hold @udev's device lock.
1530 * necessary (and attempting it might cause deadlock).
1531 * 1531 *
1532 * This routine can run only in process context. 1532 * This routine can run only in process context.
1533 */ 1533 */
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c
index 1b3c00b3ca3f..d8f3bfe1559f 100644
--- a/drivers/usb/core/sysfs.c
+++ b/drivers/usb/core/sysfs.c
@@ -352,6 +352,7 @@ set_autosuspend(struct device *dev, struct device_attribute *attr,
352 return -EINVAL; 352 return -EINVAL;
353 value *= HZ; 353 value *= HZ;
354 354
355 usb_lock_device(udev);
355 udev->autosuspend_delay = value; 356 udev->autosuspend_delay = value;
356 if (value >= 0) 357 if (value >= 0)
357 usb_try_autosuspend_device(udev); 358 usb_try_autosuspend_device(udev);
@@ -359,6 +360,7 @@ set_autosuspend(struct device *dev, struct device_attribute *attr,
359 if (usb_autoresume_device(udev) == 0) 360 if (usb_autoresume_device(udev) == 0)
360 usb_autosuspend_device(udev); 361 usb_autosuspend_device(udev);
361 } 362 }
363 usb_unlock_device(udev);
362 return count; 364 return count;
363} 365}
364 366