diff options
Diffstat (limited to 'drivers/usb/misc/adutux.c')
-rw-r--r-- | drivers/usb/misc/adutux.c | 31 |
1 files changed, 11 insertions, 20 deletions
diff --git a/drivers/usb/misc/adutux.c b/drivers/usb/misc/adutux.c index 77145f9db043..d72c42e5f22d 100644 --- a/drivers/usb/misc/adutux.c +++ b/drivers/usb/misc/adutux.c | |||
@@ -108,8 +108,6 @@ struct adu_device { | |||
108 | struct urb* interrupt_out_urb; | 108 | struct urb* interrupt_out_urb; |
109 | }; | 109 | }; |
110 | 110 | ||
111 | /* prevent races between open() and disconnect */ | ||
112 | static DEFINE_MUTEX(disconnect_mutex); | ||
113 | static struct usb_driver adu_driver; | 111 | static struct usb_driver adu_driver; |
114 | 112 | ||
115 | static void adu_debug_data(int level, const char *function, int size, | 113 | static void adu_debug_data(int level, const char *function, int size, |
@@ -256,8 +254,6 @@ static int adu_open(struct inode *inode, struct file *file) | |||
256 | 254 | ||
257 | subminor = iminor(inode); | 255 | subminor = iminor(inode); |
258 | 256 | ||
259 | mutex_lock(&disconnect_mutex); | ||
260 | |||
261 | interface = usb_find_interface(&adu_driver, subminor); | 257 | interface = usb_find_interface(&adu_driver, subminor); |
262 | if (!interface) { | 258 | if (!interface) { |
263 | err("%s - error, can't find device for minor %d", | 259 | err("%s - error, can't find device for minor %d", |
@@ -306,7 +302,6 @@ static int adu_open(struct inode *inode, struct file *file) | |||
306 | up(&dev->sem); | 302 | up(&dev->sem); |
307 | 303 | ||
308 | exit_no_device: | 304 | exit_no_device: |
309 | mutex_unlock(&disconnect_mutex); | ||
310 | dbg(2,"%s : leave, return value %d ", __FUNCTION__, retval); | 305 | dbg(2,"%s : leave, return value %d ", __FUNCTION__, retval); |
311 | 306 | ||
312 | return retval; | 307 | return retval; |
@@ -318,12 +313,6 @@ static int adu_release_internal(struct adu_device *dev) | |||
318 | 313 | ||
319 | dbg(2," %s : enter", __FUNCTION__); | 314 | dbg(2," %s : enter", __FUNCTION__); |
320 | 315 | ||
321 | if (dev->udev == NULL) { | ||
322 | /* the device was unplugged before the file was released */ | ||
323 | adu_delete(dev); | ||
324 | goto exit; | ||
325 | } | ||
326 | |||
327 | /* decrement our usage count for the device */ | 316 | /* decrement our usage count for the device */ |
328 | --dev->open_count; | 317 | --dev->open_count; |
329 | dbg(2," %s : open count %d", __FUNCTION__, dev->open_count); | 318 | dbg(2," %s : open count %d", __FUNCTION__, dev->open_count); |
@@ -332,7 +321,6 @@ static int adu_release_internal(struct adu_device *dev) | |||
332 | dev->open_count = 0; | 321 | dev->open_count = 0; |
333 | } | 322 | } |
334 | 323 | ||
335 | exit: | ||
336 | dbg(2," %s : leave", __FUNCTION__); | 324 | dbg(2," %s : leave", __FUNCTION__); |
337 | return retval; | 325 | return retval; |
338 | } | 326 | } |
@@ -367,8 +355,15 @@ static int adu_release(struct inode *inode, struct file *file) | |||
367 | goto exit; | 355 | goto exit; |
368 | } | 356 | } |
369 | 357 | ||
370 | /* do the work */ | 358 | if (dev->udev == NULL) { |
371 | retval = adu_release_internal(dev); | 359 | /* the device was unplugged before the file was released */ |
360 | up(&dev->sem); | ||
361 | adu_delete(dev); | ||
362 | dev = NULL; | ||
363 | } else { | ||
364 | /* do the work */ | ||
365 | retval = adu_release_internal(dev); | ||
366 | } | ||
372 | 367 | ||
373 | exit: | 368 | exit: |
374 | if (dev) | 369 | if (dev) |
@@ -831,19 +826,17 @@ static void adu_disconnect(struct usb_interface *interface) | |||
831 | 826 | ||
832 | dbg(2," %s : enter", __FUNCTION__); | 827 | dbg(2," %s : enter", __FUNCTION__); |
833 | 828 | ||
834 | mutex_lock(&disconnect_mutex); /* not interruptible */ | ||
835 | |||
836 | dev = usb_get_intfdata(interface); | 829 | dev = usb_get_intfdata(interface); |
837 | usb_set_intfdata(interface, NULL); | 830 | usb_set_intfdata(interface, NULL); |
838 | 831 | ||
839 | down(&dev->sem); /* not interruptible */ | ||
840 | |||
841 | minor = dev->minor; | 832 | minor = dev->minor; |
842 | 833 | ||
843 | /* give back our minor */ | 834 | /* give back our minor */ |
844 | usb_deregister_dev(interface, &adu_class); | 835 | usb_deregister_dev(interface, &adu_class); |
845 | dev->minor = 0; | 836 | dev->minor = 0; |
846 | 837 | ||
838 | down(&dev->sem); /* not interruptible */ | ||
839 | |||
847 | /* if the device is not opened, then we clean up right now */ | 840 | /* if the device is not opened, then we clean up right now */ |
848 | dbg(2," %s : open count %d", __FUNCTION__, dev->open_count); | 841 | dbg(2," %s : open count %d", __FUNCTION__, dev->open_count); |
849 | if (!dev->open_count) { | 842 | if (!dev->open_count) { |
@@ -854,8 +847,6 @@ static void adu_disconnect(struct usb_interface *interface) | |||
854 | up(&dev->sem); | 847 | up(&dev->sem); |
855 | } | 848 | } |
856 | 849 | ||
857 | mutex_unlock(&disconnect_mutex); | ||
858 | |||
859 | dev_info(&interface->dev, "ADU device adutux%d now disconnected", | 850 | dev_info(&interface->dev, "ADU device adutux%d now disconnected", |
860 | (minor - ADU_MINOR_BASE)); | 851 | (minor - ADU_MINOR_BASE)); |
861 | 852 | ||