aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/core/devio.c26
-rw-r--r--drivers/usb/core/notify.c3
-rw-r--r--drivers/usb/core/usb.h1
3 files changed, 19 insertions, 11 deletions
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index 32e03000420c..d8b0476237f3 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -59,6 +59,9 @@
59#define USB_DEVICE_MAX USB_MAXBUS * 128 59#define USB_DEVICE_MAX USB_MAXBUS * 128
60static struct class *usb_device_class; 60static struct class *usb_device_class;
61 61
62/* Mutual exclusion for removal, open, and release */
63DEFINE_MUTEX(usbfs_mutex);
64
62struct async { 65struct async {
63 struct list_head asynclist; 66 struct list_head asynclist;
64 struct dev_state *ps; 67 struct dev_state *ps;
@@ -541,15 +544,13 @@ static int usbdev_open(struct inode *inode, struct file *file)
541 struct dev_state *ps; 544 struct dev_state *ps;
542 int ret; 545 int ret;
543 546
544 /* 547 /* Protect against simultaneous removal or release */
545 * no locking necessary here, as chrdev_open has the kernel lock 548 mutex_lock(&usbfs_mutex);
546 * (still acquire the kernel lock for safety) 549
547 */
548 ret = -ENOMEM; 550 ret = -ENOMEM;
549 if (!(ps = kmalloc(sizeof(struct dev_state), GFP_KERNEL))) 551 if (!(ps = kmalloc(sizeof(struct dev_state), GFP_KERNEL)))
550 goto out_nolock; 552 goto out;
551 553
552 lock_kernel();
553 ret = -ENOENT; 554 ret = -ENOENT;
554 /* check if we are called from a real node or usbfs */ 555 /* check if we are called from a real node or usbfs */
555 if (imajor(inode) == USB_DEVICE_MAJOR) 556 if (imajor(inode) == USB_DEVICE_MAJOR)
@@ -579,9 +580,8 @@ static int usbdev_open(struct inode *inode, struct file *file)
579 list_add_tail(&ps->list, &dev->filelist); 580 list_add_tail(&ps->list, &dev->filelist);
580 file->private_data = ps; 581 file->private_data = ps;
581 out: 582 out:
582 unlock_kernel(); 583 mutex_unlock(&usbfs_mutex);
583 out_nolock: 584 return ret;
584 return ret;
585} 585}
586 586
587static int usbdev_release(struct inode *inode, struct file *file) 587static int usbdev_release(struct inode *inode, struct file *file)
@@ -591,7 +591,12 @@ static int usbdev_release(struct inode *inode, struct file *file)
591 unsigned int ifnum; 591 unsigned int ifnum;
592 592
593 usb_lock_device(dev); 593 usb_lock_device(dev);
594
595 /* Protect against simultaneous open */
596 mutex_lock(&usbfs_mutex);
594 list_del_init(&ps->list); 597 list_del_init(&ps->list);
598 mutex_unlock(&usbfs_mutex);
599
595 for (ifnum = 0; ps->ifclaimed && ifnum < 8*sizeof(ps->ifclaimed); 600 for (ifnum = 0; ps->ifclaimed && ifnum < 8*sizeof(ps->ifclaimed);
596 ifnum++) { 601 ifnum++) {
597 if (test_bit(ifnum, &ps->ifclaimed)) 602 if (test_bit(ifnum, &ps->ifclaimed))
@@ -600,9 +605,8 @@ static int usbdev_release(struct inode *inode, struct file *file)
600 destroy_all_async(ps); 605 destroy_all_async(ps);
601 usb_unlock_device(dev); 606 usb_unlock_device(dev);
602 usb_put_dev(dev); 607 usb_put_dev(dev);
603 ps->dev = NULL;
604 kfree(ps); 608 kfree(ps);
605 return 0; 609 return 0;
606} 610}
607 611
608static int proc_control(struct dev_state *ps, void __user *arg) 612static int proc_control(struct dev_state *ps, void __user *arg)
diff --git a/drivers/usb/core/notify.c b/drivers/usb/core/notify.c
index b042676af0a5..6b36897ca151 100644
--- a/drivers/usb/core/notify.c
+++ b/drivers/usb/core/notify.c
@@ -50,8 +50,11 @@ void usb_notify_add_device(struct usb_device *udev)
50 50
51void usb_notify_remove_device(struct usb_device *udev) 51void usb_notify_remove_device(struct usb_device *udev)
52{ 52{
53 /* Protect against simultaneous usbfs open */
54 mutex_lock(&usbfs_mutex);
53 blocking_notifier_call_chain(&usb_notifier_list, 55 blocking_notifier_call_chain(&usb_notifier_list,
54 USB_DEVICE_REMOVE, udev); 56 USB_DEVICE_REMOVE, udev);
57 mutex_unlock(&usbfs_mutex);
55} 58}
56 59
57void usb_notify_add_bus(struct usb_bus *ubus) 60void usb_notify_add_bus(struct usb_bus *ubus)
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
index 49f69236b420..1217fbbe5829 100644
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -59,6 +59,7 @@ static inline int is_active(struct usb_interface *f)
59extern const char *usbcore_name; 59extern const char *usbcore_name;
60 60
61/* usbfs stuff */ 61/* usbfs stuff */
62extern struct mutex usbfs_mutex;
62extern struct usb_driver usbfs_driver; 63extern struct usb_driver usbfs_driver;
63extern struct file_operations usbfs_devices_fops; 64extern struct file_operations usbfs_devices_fops;
64extern struct file_operations usbfs_device_file_operations; 65extern struct file_operations usbfs_device_file_operations;