aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/core/file.c29
-rw-r--r--drivers/usb/misc/adutux.c31
-rw-r--r--drivers/usb/misc/auerswald.c6
-rw-r--r--drivers/usb/misc/idmouse.c54
-rw-r--r--drivers/usb/misc/iowarrior.c26
-rw-r--r--drivers/usb/misc/ldusb.c33
-rw-r--r--drivers/usb/misc/legousbtower.c24
-rw-r--r--drivers/usb/misc/sisusbvga/sisusb.c38
-rw-r--r--drivers/usb/misc/sisusbvga/sisusb_con.c25
-rw-r--r--drivers/usb/misc/sisusbvga/sisusb_init.h2
-rw-r--r--drivers/usb/misc/usblcd.c21
-rw-r--r--drivers/usb/usb-skeleton.c14
12 files changed, 75 insertions, 228 deletions
diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c
index 01c857ac27af..5d860bc9b421 100644
--- a/drivers/usb/core/file.c
+++ b/drivers/usb/core/file.c
@@ -16,15 +16,15 @@
16 */ 16 */
17 17
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/spinlock.h>
20#include <linux/errno.h> 19#include <linux/errno.h>
20#include <linux/rwsem.h>
21#include <linux/usb.h> 21#include <linux/usb.h>
22 22
23#include "usb.h" 23#include "usb.h"
24 24
25#define MAX_USB_MINORS 256 25#define MAX_USB_MINORS 256
26static const struct file_operations *usb_minors[MAX_USB_MINORS]; 26static const struct file_operations *usb_minors[MAX_USB_MINORS];
27static DEFINE_SPINLOCK(minor_lock); 27static DECLARE_RWSEM(minor_rwsem);
28 28
29static int usb_open(struct inode * inode, struct file * file) 29static int usb_open(struct inode * inode, struct file * file)
30{ 30{
@@ -33,14 +33,11 @@ static int usb_open(struct inode * inode, struct file * file)
33 int err = -ENODEV; 33 int err = -ENODEV;
34 const struct file_operations *old_fops, *new_fops = NULL; 34 const struct file_operations *old_fops, *new_fops = NULL;
35 35
36 spin_lock (&minor_lock); 36 down_read(&minor_rwsem);
37 c = usb_minors[minor]; 37 c = usb_minors[minor];
38 38
39 if (!c || !(new_fops = fops_get(c))) { 39 if (!c || !(new_fops = fops_get(c)))
40 spin_unlock(&minor_lock); 40 goto done;
41 return err;
42 }
43 spin_unlock(&minor_lock);
44 41
45 old_fops = file->f_op; 42 old_fops = file->f_op;
46 file->f_op = new_fops; 43 file->f_op = new_fops;
@@ -52,6 +49,8 @@ static int usb_open(struct inode * inode, struct file * file)
52 file->f_op = fops_get(old_fops); 49 file->f_op = fops_get(old_fops);
53 } 50 }
54 fops_put(old_fops); 51 fops_put(old_fops);
52 done:
53 up_read(&minor_rwsem);
55 return err; 54 return err;
56} 55}
57 56
@@ -166,7 +165,7 @@ int usb_register_dev(struct usb_interface *intf,
166 if (class_driver->fops == NULL) 165 if (class_driver->fops == NULL)
167 goto exit; 166 goto exit;
168 167
169 spin_lock (&minor_lock); 168 down_write(&minor_rwsem);
170 for (minor = minor_base; minor < MAX_USB_MINORS; ++minor) { 169 for (minor = minor_base; minor < MAX_USB_MINORS; ++minor) {
171 if (usb_minors[minor]) 170 if (usb_minors[minor])
172 continue; 171 continue;
@@ -176,7 +175,7 @@ int usb_register_dev(struct usb_interface *intf,
176 retval = 0; 175 retval = 0;
177 break; 176 break;
178 } 177 }
179 spin_unlock (&minor_lock); 178 up_write(&minor_rwsem);
180 179
181 if (retval) 180 if (retval)
182 goto exit; 181 goto exit;
@@ -197,9 +196,9 @@ int usb_register_dev(struct usb_interface *intf,
197 intf->usb_dev = device_create(usb_class->class, &intf->dev, 196 intf->usb_dev = device_create(usb_class->class, &intf->dev,
198 MKDEV(USB_MAJOR, minor), "%s", temp); 197 MKDEV(USB_MAJOR, minor), "%s", temp);
199 if (IS_ERR(intf->usb_dev)) { 198 if (IS_ERR(intf->usb_dev)) {
200 spin_lock (&minor_lock); 199 down_write(&minor_rwsem);
201 usb_minors[intf->minor] = NULL; 200 usb_minors[intf->minor] = NULL;
202 spin_unlock (&minor_lock); 201 up_write(&minor_rwsem);
203 retval = PTR_ERR(intf->usb_dev); 202 retval = PTR_ERR(intf->usb_dev);
204 } 203 }
205exit: 204exit:
@@ -236,9 +235,9 @@ void usb_deregister_dev(struct usb_interface *intf,
236 235
237 dbg ("removing %d minor", intf->minor); 236 dbg ("removing %d minor", intf->minor);
238 237
239 spin_lock (&minor_lock); 238 down_write(&minor_rwsem);
240 usb_minors[intf->minor] = NULL; 239 usb_minors[intf->minor] = NULL;
241 spin_unlock (&minor_lock); 240 up_write(&minor_rwsem);
242 241
243 snprintf(name, BUS_ID_SIZE, class_driver->name, intf->minor - minor_base); 242 snprintf(name, BUS_ID_SIZE, class_driver->name, intf->minor - minor_base);
244 device_destroy(usb_class->class, MKDEV(USB_MAJOR, intf->minor)); 243 device_destroy(usb_class->class, MKDEV(USB_MAJOR, intf->minor));
@@ -247,5 +246,3 @@ void usb_deregister_dev(struct usb_interface *intf,
247 destroy_usb_class(); 246 destroy_usb_class();
248} 247}
249EXPORT_SYMBOL(usb_deregister_dev); 248EXPORT_SYMBOL(usb_deregister_dev);
250
251
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 */
112static DEFINE_MUTEX(disconnect_mutex);
113static struct usb_driver adu_driver; 111static struct usb_driver adu_driver;
114 112
115static void adu_debug_data(int level, const char *function, int size, 113static 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
308exit_no_device: 304exit_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
335exit:
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
373exit: 368exit:
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
diff --git a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c
index cac1500cba62..1fd5fc220cd7 100644
--- a/drivers/usb/misc/auerswald.c
+++ b/drivers/usb/misc/auerswald.c
@@ -2034,12 +2034,12 @@ static void auerswald_disconnect (struct usb_interface *intf)
2034 if (!cp) 2034 if (!cp)
2035 return; 2035 return;
2036 2036
2037 down (&cp->mutex);
2038 info ("device /dev/%s now disconnecting", cp->name);
2039
2040 /* give back our USB minor number */ 2037 /* give back our USB minor number */
2041 usb_deregister_dev(intf, &auerswald_class); 2038 usb_deregister_dev(intf, &auerswald_class);
2042 2039
2040 down (&cp->mutex);
2041 info ("device /dev/%s now disconnecting", cp->name);
2042
2043 /* Stop the interrupt endpoint */ 2043 /* Stop the interrupt endpoint */
2044 auerswald_int_release (cp); 2044 auerswald_int_release (cp);
2045 2045
diff --git a/drivers/usb/misc/idmouse.c b/drivers/usb/misc/idmouse.c
index 8d0e360636e6..e6fd024024f5 100644
--- a/drivers/usb/misc/idmouse.c
+++ b/drivers/usb/misc/idmouse.c
@@ -119,9 +119,6 @@ static struct usb_driver idmouse_driver = {
119 .id_table = idmouse_table, 119 .id_table = idmouse_table,
120}; 120};
121 121
122/* prevent races between open() and disconnect() */
123static DEFINE_MUTEX(disconnect_mutex);
124
125static int idmouse_create_image(struct usb_idmouse *dev) 122static int idmouse_create_image(struct usb_idmouse *dev)
126{ 123{
127 int bytes_read; 124 int bytes_read;
@@ -211,21 +208,15 @@ static int idmouse_open(struct inode *inode, struct file *file)
211 struct usb_interface *interface; 208 struct usb_interface *interface;
212 int result; 209 int result;
213 210
214 /* prevent disconnects */
215 mutex_lock(&disconnect_mutex);
216
217 /* get the interface from minor number and driver information */ 211 /* get the interface from minor number and driver information */
218 interface = usb_find_interface (&idmouse_driver, iminor (inode)); 212 interface = usb_find_interface (&idmouse_driver, iminor (inode));
219 if (!interface) { 213 if (!interface)
220 mutex_unlock(&disconnect_mutex);
221 return -ENODEV; 214 return -ENODEV;
222 } 215
223 /* get the device information block from the interface */ 216 /* get the device information block from the interface */
224 dev = usb_get_intfdata(interface); 217 dev = usb_get_intfdata(interface);
225 if (!dev) { 218 if (!dev)
226 mutex_unlock(&disconnect_mutex);
227 return -ENODEV; 219 return -ENODEV;
228 }
229 220
230 /* lock this device */ 221 /* lock this device */
231 down(&dev->sem); 222 down(&dev->sem);
@@ -255,9 +246,6 @@ error:
255 246
256 /* unlock this device */ 247 /* unlock this device */
257 up(&dev->sem); 248 up(&dev->sem);
258
259 /* unlock the disconnect semaphore */
260 mutex_unlock(&disconnect_mutex);
261 return result; 249 return result;
262} 250}
263 251
@@ -265,15 +253,10 @@ static int idmouse_release(struct inode *inode, struct file *file)
265{ 253{
266 struct usb_idmouse *dev; 254 struct usb_idmouse *dev;
267 255
268 /* prevent a race condition with open() */
269 mutex_lock(&disconnect_mutex);
270
271 dev = file->private_data; 256 dev = file->private_data;
272 257
273 if (dev == NULL) { 258 if (dev == NULL)
274 mutex_unlock(&disconnect_mutex);
275 return -ENODEV; 259 return -ENODEV;
276 }
277 260
278 /* lock our device */ 261 /* lock our device */
279 down(&dev->sem); 262 down(&dev->sem);
@@ -281,7 +264,6 @@ static int idmouse_release(struct inode *inode, struct file *file)
281 /* are we really open? */ 264 /* are we really open? */
282 if (dev->open <= 0) { 265 if (dev->open <= 0) {
283 up(&dev->sem); 266 up(&dev->sem);
284 mutex_unlock(&disconnect_mutex);
285 return -ENODEV; 267 return -ENODEV;
286 } 268 }
287 269
@@ -291,12 +273,9 @@ static int idmouse_release(struct inode *inode, struct file *file)
291 /* the device was unplugged before the file was released */ 273 /* the device was unplugged before the file was released */
292 up(&dev->sem); 274 up(&dev->sem);
293 idmouse_delete(dev); 275 idmouse_delete(dev);
294 mutex_unlock(&disconnect_mutex); 276 } else {
295 return 0; 277 up(&dev->sem);
296 } 278 }
297
298 up(&dev->sem);
299 mutex_unlock(&disconnect_mutex);
300 return 0; 279 return 0;
301} 280}
302 281
@@ -391,30 +370,27 @@ static void idmouse_disconnect(struct usb_interface *interface)
391{ 370{
392 struct usb_idmouse *dev; 371 struct usb_idmouse *dev;
393 372
394 /* prevent races with open() */
395 mutex_lock(&disconnect_mutex);
396
397 /* get device structure */ 373 /* get device structure */
398 dev = usb_get_intfdata(interface); 374 dev = usb_get_intfdata(interface);
399 usb_set_intfdata(interface, NULL); 375 usb_set_intfdata(interface, NULL);
400 376
401 /* lock it */
402 down(&dev->sem);
403
404 /* give back our minor */ 377 /* give back our minor */
405 usb_deregister_dev(interface, &idmouse_class); 378 usb_deregister_dev(interface, &idmouse_class);
406 379
380 /* lock it */
381 down(&dev->sem);
382
407 /* prevent device read, write and ioctl */ 383 /* prevent device read, write and ioctl */
408 dev->present = 0; 384 dev->present = 0;
409 385
410 /* unlock */
411 up(&dev->sem);
412
413 /* if the device is opened, idmouse_release will clean this up */ 386 /* if the device is opened, idmouse_release will clean this up */
414 if (!dev->open) 387 if (!dev->open) {
388 up(&dev->sem);
415 idmouse_delete(dev); 389 idmouse_delete(dev);
416 390 } else {
417 mutex_unlock(&disconnect_mutex); 391 /* unlock */
392 up(&dev->sem);
393 }
418 394
419 info("%s disconnected", DRIVER_DESC); 395 info("%s disconnected", DRIVER_DESC);
420} 396}
diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c
index 3bb33f7bfa36..28548d186712 100644
--- a/drivers/usb/misc/iowarrior.c
+++ b/drivers/usb/misc/iowarrior.c
@@ -100,8 +100,6 @@ struct iowarrior {
100/*--------------*/ 100/*--------------*/
101/* globals */ 101/* globals */
102/*--------------*/ 102/*--------------*/
103/* prevent races between open() and disconnect() */
104static DECLARE_MUTEX(disconnect_sem);
105 103
106/* 104/*
107 * USB spec identifies 5 second timeouts. 105 * USB spec identifies 5 second timeouts.
@@ -600,22 +598,18 @@ static int iowarrior_open(struct inode *inode, struct file *file)
600 598
601 subminor = iminor(inode); 599 subminor = iminor(inode);
602 600
603 /* prevent disconnects */
604 down(&disconnect_sem);
605
606 interface = usb_find_interface(&iowarrior_driver, subminor); 601 interface = usb_find_interface(&iowarrior_driver, subminor);
607 if (!interface) { 602 if (!interface) {
608 err("%s - error, can't find device for minor %d", __FUNCTION__, 603 err("%s - error, can't find device for minor %d", __FUNCTION__,
609 subminor); 604 subminor);
610 retval = -ENODEV; 605 return -ENODEV;
611 goto out;
612 } 606 }
613 607
614 dev = usb_get_intfdata(interface); 608 dev = usb_get_intfdata(interface);
615 if (!dev) { 609 if (!dev)
616 retval = -ENODEV; 610 return -ENODEV;
617 goto out; 611
618 } 612 mutex_lock(&dev->mutex);
619 613
620 /* Only one process can open each device, no sharing. */ 614 /* Only one process can open each device, no sharing. */
621 if (dev->opened) { 615 if (dev->opened) {
@@ -636,7 +630,7 @@ static int iowarrior_open(struct inode *inode, struct file *file)
636 retval = 0; 630 retval = 0;
637 631
638out: 632out:
639 up(&disconnect_sem); 633 mutex_unlock(&dev->mutex);
640 return retval; 634 return retval;
641} 635}
642 636
@@ -868,19 +862,16 @@ static void iowarrior_disconnect(struct usb_interface *interface)
868 struct iowarrior *dev; 862 struct iowarrior *dev;
869 int minor; 863 int minor;
870 864
871 /* prevent races with open() */
872 down(&disconnect_sem);
873
874 dev = usb_get_intfdata(interface); 865 dev = usb_get_intfdata(interface);
875 usb_set_intfdata(interface, NULL); 866 usb_set_intfdata(interface, NULL);
876 867
877 mutex_lock(&dev->mutex);
878
879 minor = dev->minor; 868 minor = dev->minor;
880 869
881 /* give back our minor */ 870 /* give back our minor */
882 usb_deregister_dev(interface, &iowarrior_class); 871 usb_deregister_dev(interface, &iowarrior_class);
883 872
873 mutex_lock(&dev->mutex);
874
884 /* prevent device read, write and ioctl */ 875 /* prevent device read, write and ioctl */
885 dev->present = 0; 876 dev->present = 0;
886 877
@@ -898,7 +889,6 @@ static void iowarrior_disconnect(struct usb_interface *interface)
898 /* no process is using the device, cleanup now */ 889 /* no process is using the device, cleanup now */
899 iowarrior_delete(dev); 890 iowarrior_delete(dev);
900 } 891 }
901 up(&disconnect_sem);
902 892
903 dev_info(&interface->dev, "I/O-Warror #%d now disconnected\n", 893 dev_info(&interface->dev, "I/O-Warror #%d now disconnected\n",
904 minor - IOWARRIOR_MINOR_BASE); 894 minor - IOWARRIOR_MINOR_BASE);
diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c
index 7bad49404762..5e950b90c541 100644
--- a/drivers/usb/misc/ldusb.c
+++ b/drivers/usb/misc/ldusb.c
@@ -176,9 +176,6 @@ struct ld_usb {
176 int interrupt_out_busy; 176 int interrupt_out_busy;
177}; 177};
178 178
179/* prevent races between open() and disconnect() */
180static DEFINE_MUTEX(disconnect_mutex);
181
182static struct usb_driver ld_usb_driver; 179static struct usb_driver ld_usb_driver;
183 180
184/** 181/**
@@ -298,35 +295,28 @@ static int ld_usb_open(struct inode *inode, struct file *file)
298{ 295{
299 struct ld_usb *dev; 296 struct ld_usb *dev;
300 int subminor; 297 int subminor;
301 int retval = 0; 298 int retval;
302 struct usb_interface *interface; 299 struct usb_interface *interface;
303 300
304 nonseekable_open(inode, file); 301 nonseekable_open(inode, file);
305 subminor = iminor(inode); 302 subminor = iminor(inode);
306 303
307 mutex_lock(&disconnect_mutex);
308
309 interface = usb_find_interface(&ld_usb_driver, subminor); 304 interface = usb_find_interface(&ld_usb_driver, subminor);
310 305
311 if (!interface) { 306 if (!interface) {
312 err("%s - error, can't find device for minor %d\n", 307 err("%s - error, can't find device for minor %d\n",
313 __FUNCTION__, subminor); 308 __FUNCTION__, subminor);
314 retval = -ENODEV; 309 return -ENODEV;
315 goto unlock_disconnect_exit;
316 } 310 }
317 311
318 dev = usb_get_intfdata(interface); 312 dev = usb_get_intfdata(interface);
319 313
320 if (!dev) { 314 if (!dev)
321 retval = -ENODEV; 315 return -ENODEV;
322 goto unlock_disconnect_exit;
323 }
324 316
325 /* lock this device */ 317 /* lock this device */
326 if (down_interruptible(&dev->sem)) { 318 if (down_interruptible(&dev->sem))
327 retval = -ERESTARTSYS; 319 return -ERESTARTSYS;
328 goto unlock_disconnect_exit;
329 }
330 320
331 /* allow opening only once */ 321 /* allow opening only once */
332 if (dev->open_count) { 322 if (dev->open_count) {
@@ -366,9 +356,6 @@ static int ld_usb_open(struct inode *inode, struct file *file)
366unlock_exit: 356unlock_exit:
367 up(&dev->sem); 357 up(&dev->sem);
368 358
369unlock_disconnect_exit:
370 mutex_unlock(&disconnect_mutex);
371
372 return retval; 359 return retval;
373} 360}
374 361
@@ -766,18 +753,16 @@ static void ld_usb_disconnect(struct usb_interface *intf)
766 struct ld_usb *dev; 753 struct ld_usb *dev;
767 int minor; 754 int minor;
768 755
769 mutex_lock(&disconnect_mutex);
770
771 dev = usb_get_intfdata(intf); 756 dev = usb_get_intfdata(intf);
772 usb_set_intfdata(intf, NULL); 757 usb_set_intfdata(intf, NULL);
773 758
774 down(&dev->sem);
775
776 minor = intf->minor; 759 minor = intf->minor;
777 760
778 /* give back our minor */ 761 /* give back our minor */
779 usb_deregister_dev(intf, &ld_usb_class); 762 usb_deregister_dev(intf, &ld_usb_class);
780 763
764 down(&dev->sem);
765
781 /* if the device is not opened, then we clean up right now */ 766 /* if the device is not opened, then we clean up right now */
782 if (!dev->open_count) { 767 if (!dev->open_count) {
783 up(&dev->sem); 768 up(&dev->sem);
@@ -787,8 +772,6 @@ static void ld_usb_disconnect(struct usb_interface *intf)
787 up(&dev->sem); 772 up(&dev->sem);
788 } 773 }
789 774
790 mutex_unlock(&disconnect_mutex);
791
792 dev_info(&intf->dev, "LD USB Device #%d now disconnected\n", 775 dev_info(&intf->dev, "LD USB Device #%d now disconnected\n",
793 (minor - USB_LD_MINOR_BASE)); 776 (minor - USB_LD_MINOR_BASE));
794} 777}
diff --git a/drivers/usb/misc/legousbtower.c b/drivers/usb/misc/legousbtower.c
index 1713e19a7899..2ed0daea894c 100644
--- a/drivers/usb/misc/legousbtower.c
+++ b/drivers/usb/misc/legousbtower.c
@@ -254,9 +254,6 @@ static int tower_probe (struct usb_interface *interface, const struct usb_devic
254static void tower_disconnect (struct usb_interface *interface); 254static void tower_disconnect (struct usb_interface *interface);
255 255
256 256
257/* prevent races between open() and disconnect */
258static DEFINE_MUTEX (disconnect_mutex);
259
260/* file operations needed when we register this driver */ 257/* file operations needed when we register this driver */
261static const struct file_operations tower_fops = { 258static const struct file_operations tower_fops = {
262 .owner = THIS_MODULE, 259 .owner = THIS_MODULE,
@@ -344,28 +341,26 @@ static int tower_open (struct inode *inode, struct file *file)
344 nonseekable_open(inode, file); 341 nonseekable_open(inode, file);
345 subminor = iminor(inode); 342 subminor = iminor(inode);
346 343
347 mutex_lock (&disconnect_mutex);
348
349 interface = usb_find_interface (&tower_driver, subminor); 344 interface = usb_find_interface (&tower_driver, subminor);
350 345
351 if (!interface) { 346 if (!interface) {
352 err ("%s - error, can't find device for minor %d", 347 err ("%s - error, can't find device for minor %d",
353 __FUNCTION__, subminor); 348 __FUNCTION__, subminor);
354 retval = -ENODEV; 349 retval = -ENODEV;
355 goto unlock_disconnect_exit; 350 goto exit;
356 } 351 }
357 352
358 dev = usb_get_intfdata(interface); 353 dev = usb_get_intfdata(interface);
359 354
360 if (!dev) { 355 if (!dev) {
361 retval = -ENODEV; 356 retval = -ENODEV;
362 goto unlock_disconnect_exit; 357 goto exit;
363 } 358 }
364 359
365 /* lock this device */ 360 /* lock this device */
366 if (down_interruptible (&dev->sem)) { 361 if (down_interruptible (&dev->sem)) {
367 retval = -ERESTARTSYS; 362 retval = -ERESTARTSYS;
368 goto unlock_disconnect_exit; 363 goto exit;
369 } 364 }
370 365
371 /* allow opening only once */ 366 /* allow opening only once */
@@ -421,9 +416,7 @@ static int tower_open (struct inode *inode, struct file *file)
421unlock_exit: 416unlock_exit:
422 up (&dev->sem); 417 up (&dev->sem);
423 418
424unlock_disconnect_exit: 419exit:
425 mutex_unlock (&disconnect_mutex);
426
427 dbg(2, "%s: leave, return value %d ", __FUNCTION__, retval); 420 dbg(2, "%s: leave, return value %d ", __FUNCTION__, retval);
428 421
429 return retval; 422 return retval;
@@ -993,19 +986,16 @@ static void tower_disconnect (struct usb_interface *interface)
993 986
994 dbg(2, "%s: enter", __FUNCTION__); 987 dbg(2, "%s: enter", __FUNCTION__);
995 988
996 mutex_lock (&disconnect_mutex);
997
998 dev = usb_get_intfdata (interface); 989 dev = usb_get_intfdata (interface);
999 usb_set_intfdata (interface, NULL); 990 usb_set_intfdata (interface, NULL);
1000 991
1001
1002 down (&dev->sem);
1003
1004 minor = dev->minor; 992 minor = dev->minor;
1005 993
1006 /* give back our minor */ 994 /* give back our minor */
1007 usb_deregister_dev (interface, &tower_class); 995 usb_deregister_dev (interface, &tower_class);
1008 996
997 down (&dev->sem);
998
1009 /* if the device is not opened, then we clean up right now */ 999 /* if the device is not opened, then we clean up right now */
1010 if (!dev->open_count) { 1000 if (!dev->open_count) {
1011 up (&dev->sem); 1001 up (&dev->sem);
@@ -1015,8 +1005,6 @@ static void tower_disconnect (struct usb_interface *interface)
1015 up (&dev->sem); 1005 up (&dev->sem);
1016 } 1006 }
1017 1007
1018 mutex_unlock (&disconnect_mutex);
1019
1020 info("LEGO USB Tower #%d now disconnected", (minor - LEGO_USB_TOWER_MINOR_BASE)); 1008 info("LEGO USB Tower #%d now disconnected", (minor - LEGO_USB_TOWER_MINOR_BASE));
1021 1009
1022 dbg(2, "%s: leave", __FUNCTION__); 1010 dbg(2, "%s: leave", __FUNCTION__);
diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c
index 6f8b134a79cb..9f37ba44c132 100644
--- a/drivers/usb/misc/sisusbvga/sisusb.c
+++ b/drivers/usb/misc/sisusbvga/sisusb.c
@@ -72,8 +72,6 @@ MODULE_PARM_DESC(last, "Number of last console to take over (1 - MAX_NR_CONSOLES
72 72
73static struct usb_driver sisusb_driver; 73static struct usb_driver sisusb_driver;
74 74
75DEFINE_MUTEX(disconnect_mutex);
76
77static void 75static void
78sisusb_free_buffers(struct sisusb_usb_data *sisusb) 76sisusb_free_buffers(struct sisusb_usb_data *sisusb)
79{ 77{
@@ -2511,31 +2509,24 @@ sisusb_open(struct inode *inode, struct file *file)
2511 struct usb_interface *interface; 2509 struct usb_interface *interface;
2512 int subminor = iminor(inode); 2510 int subminor = iminor(inode);
2513 2511
2514 mutex_lock(&disconnect_mutex);
2515
2516 if (!(interface = usb_find_interface(&sisusb_driver, subminor))) { 2512 if (!(interface = usb_find_interface(&sisusb_driver, subminor))) {
2517 printk(KERN_ERR "sisusb[%d]: Failed to find interface\n", 2513 printk(KERN_ERR "sisusb[%d]: Failed to find interface\n",
2518 subminor); 2514 subminor);
2519 mutex_unlock(&disconnect_mutex);
2520 return -ENODEV; 2515 return -ENODEV;
2521 } 2516 }
2522 2517
2523 if (!(sisusb = usb_get_intfdata(interface))) { 2518 if (!(sisusb = usb_get_intfdata(interface)))
2524 mutex_unlock(&disconnect_mutex);
2525 return -ENODEV; 2519 return -ENODEV;
2526 }
2527 2520
2528 mutex_lock(&sisusb->lock); 2521 mutex_lock(&sisusb->lock);
2529 2522
2530 if (!sisusb->present || !sisusb->ready) { 2523 if (!sisusb->present || !sisusb->ready) {
2531 mutex_unlock(&sisusb->lock); 2524 mutex_unlock(&sisusb->lock);
2532 mutex_unlock(&disconnect_mutex);
2533 return -ENODEV; 2525 return -ENODEV;
2534 } 2526 }
2535 2527
2536 if (sisusb->isopen) { 2528 if (sisusb->isopen) {
2537 mutex_unlock(&sisusb->lock); 2529 mutex_unlock(&sisusb->lock);
2538 mutex_unlock(&disconnect_mutex);
2539 return -EBUSY; 2530 return -EBUSY;
2540 } 2531 }
2541 2532
@@ -2543,7 +2534,6 @@ sisusb_open(struct inode *inode, struct file *file)
2543 if (sisusb->sisusb_dev->speed == USB_SPEED_HIGH) { 2534 if (sisusb->sisusb_dev->speed == USB_SPEED_HIGH) {
2544 if (sisusb_init_gfxdevice(sisusb, 0)) { 2535 if (sisusb_init_gfxdevice(sisusb, 0)) {
2545 mutex_unlock(&sisusb->lock); 2536 mutex_unlock(&sisusb->lock);
2546 mutex_unlock(&disconnect_mutex);
2547 printk(KERN_ERR 2537 printk(KERN_ERR
2548 "sisusbvga[%d]: Failed to initialize " 2538 "sisusbvga[%d]: Failed to initialize "
2549 "device\n", 2539 "device\n",
@@ -2552,7 +2542,6 @@ sisusb_open(struct inode *inode, struct file *file)
2552 } 2542 }
2553 } else { 2543 } else {
2554 mutex_unlock(&sisusb->lock); 2544 mutex_unlock(&sisusb->lock);
2555 mutex_unlock(&disconnect_mutex);
2556 printk(KERN_ERR 2545 printk(KERN_ERR
2557 "sisusbvga[%d]: Device not attached to " 2546 "sisusbvga[%d]: Device not attached to "
2558 "USB 2.0 hub\n", 2547 "USB 2.0 hub\n",
@@ -2570,8 +2559,6 @@ sisusb_open(struct inode *inode, struct file *file)
2570 2559
2571 mutex_unlock(&sisusb->lock); 2560 mutex_unlock(&sisusb->lock);
2572 2561
2573 mutex_unlock(&disconnect_mutex);
2574
2575 return 0; 2562 return 0;
2576} 2563}
2577 2564
@@ -2601,12 +2588,8 @@ sisusb_release(struct inode *inode, struct file *file)
2601 struct sisusb_usb_data *sisusb; 2588 struct sisusb_usb_data *sisusb;
2602 int myminor; 2589 int myminor;
2603 2590
2604 mutex_lock(&disconnect_mutex); 2591 if (!(sisusb = (struct sisusb_usb_data *)file->private_data))
2605
2606 if (!(sisusb = (struct sisusb_usb_data *)file->private_data)) {
2607 mutex_unlock(&disconnect_mutex);
2608 return -ENODEV; 2592 return -ENODEV;
2609 }
2610 2593
2611 mutex_lock(&sisusb->lock); 2594 mutex_lock(&sisusb->lock);
2612 2595
@@ -2626,8 +2609,6 @@ sisusb_release(struct inode *inode, struct file *file)
2626 /* decrement the usage count on our device */ 2609 /* decrement the usage count on our device */
2627 kref_put(&sisusb->kref, sisusb_delete); 2610 kref_put(&sisusb->kref, sisusb_delete);
2628 2611
2629 mutex_unlock(&disconnect_mutex);
2630
2631 return 0; 2612 return 0;
2632} 2613}
2633 2614
@@ -3383,12 +3364,9 @@ static void sisusb_disconnect(struct usb_interface *intf)
3383 sisusb_console_exit(sisusb); 3364 sisusb_console_exit(sisusb);
3384#endif 3365#endif
3385 3366
3386 /* The above code doesn't need the disconnect 3367 minor = sisusb->minor;
3387 * semaphore to be down; its meaning is to 3368
3388 * protect all other routines from the disconnect 3369 usb_deregister_dev(intf, &usb_sisusb_class);
3389 * case, not the other way round.
3390 */
3391 mutex_lock(&disconnect_mutex);
3392 3370
3393 mutex_lock(&sisusb->lock); 3371 mutex_lock(&sisusb->lock);
3394 3372
@@ -3396,12 +3374,8 @@ static void sisusb_disconnect(struct usb_interface *intf)
3396 if (!sisusb_wait_all_out_complete(sisusb)) 3374 if (!sisusb_wait_all_out_complete(sisusb))
3397 sisusb_kill_all_busy(sisusb); 3375 sisusb_kill_all_busy(sisusb);
3398 3376
3399 minor = sisusb->minor;
3400
3401 usb_set_intfdata(intf, NULL); 3377 usb_set_intfdata(intf, NULL);
3402 3378
3403 usb_deregister_dev(intf, &usb_sisusb_class);
3404
3405#ifdef SISUSB_OLD_CONFIG_COMPAT 3379#ifdef SISUSB_OLD_CONFIG_COMPAT
3406 if (sisusb->ioctl32registered) { 3380 if (sisusb->ioctl32registered) {
3407 int ret; 3381 int ret;
@@ -3426,8 +3400,6 @@ static void sisusb_disconnect(struct usb_interface *intf)
3426 /* decrement our usage count */ 3400 /* decrement our usage count */
3427 kref_put(&sisusb->kref, sisusb_delete); 3401 kref_put(&sisusb->kref, sisusb_delete);
3428 3402
3429 mutex_unlock(&disconnect_mutex);
3430
3431 printk(KERN_INFO "sisusbvga[%d]: Disconnected\n", minor); 3403 printk(KERN_INFO "sisusbvga[%d]: Disconnected\n", minor);
3432} 3404}
3433 3405
diff --git a/drivers/usb/misc/sisusbvga/sisusb_con.c b/drivers/usb/misc/sisusbvga/sisusb_con.c
index 5947afb0017e..8d0edc867f33 100644
--- a/drivers/usb/misc/sisusbvga/sisusb_con.c
+++ b/drivers/usb/misc/sisusbvga/sisusb_con.c
@@ -214,18 +214,13 @@ sisusbcon_init(struct vc_data *c, int init)
214 * are set up/restored. 214 * are set up/restored.
215 */ 215 */
216 216
217 mutex_lock(&disconnect_mutex); 217 if (!(sisusb = sisusb_get_sisusb(c->vc_num)))
218
219 if (!(sisusb = sisusb_get_sisusb(c->vc_num))) {
220 mutex_unlock(&disconnect_mutex);
221 return; 218 return;
222 }
223 219
224 mutex_lock(&sisusb->lock); 220 mutex_lock(&sisusb->lock);
225 221
226 if (!sisusb_sisusb_valid(sisusb)) { 222 if (!sisusb_sisusb_valid(sisusb)) {
227 mutex_unlock(&sisusb->lock); 223 mutex_unlock(&sisusb->lock);
228 mutex_unlock(&disconnect_mutex);
229 return; 224 return;
230 } 225 }
231 226
@@ -264,8 +259,6 @@ sisusbcon_init(struct vc_data *c, int init)
264 259
265 mutex_unlock(&sisusb->lock); 260 mutex_unlock(&sisusb->lock);
266 261
267 mutex_unlock(&disconnect_mutex);
268
269 if (init) { 262 if (init) {
270 c->vc_cols = cols; 263 c->vc_cols = cols;
271 c->vc_rows = rows; 264 c->vc_rows = rows;
@@ -284,12 +277,8 @@ sisusbcon_deinit(struct vc_data *c)
284 * and others, ie not under our control. 277 * and others, ie not under our control.
285 */ 278 */
286 279
287 mutex_lock(&disconnect_mutex); 280 if (!(sisusb = sisusb_get_sisusb(c->vc_num)))
288
289 if (!(sisusb = sisusb_get_sisusb(c->vc_num))) {
290 mutex_unlock(&disconnect_mutex);
291 return; 281 return;
292 }
293 282
294 mutex_lock(&sisusb->lock); 283 mutex_lock(&sisusb->lock);
295 284
@@ -314,8 +303,6 @@ sisusbcon_deinit(struct vc_data *c)
314 303
315 /* decrement the usage count on our sisusb */ 304 /* decrement the usage count on our sisusb */
316 kref_put(&sisusb->kref, sisusb_delete); 305 kref_put(&sisusb->kref, sisusb_delete);
317
318 mutex_unlock(&disconnect_mutex);
319} 306}
320 307
321/* interface routine */ 308/* interface routine */
@@ -1490,14 +1477,11 @@ sisusb_console_init(struct sisusb_usb_data *sisusb, int first, int last)
1490{ 1477{
1491 int i, ret, minor = sisusb->minor; 1478 int i, ret, minor = sisusb->minor;
1492 1479
1493 mutex_lock(&disconnect_mutex);
1494
1495 mutex_lock(&sisusb->lock); 1480 mutex_lock(&sisusb->lock);
1496 1481
1497 /* Erm.. that should not happen */ 1482 /* Erm.. that should not happen */
1498 if (sisusb->haveconsole || !sisusb->SiS_Pr) { 1483 if (sisusb->haveconsole || !sisusb->SiS_Pr) {
1499 mutex_unlock(&sisusb->lock); 1484 mutex_unlock(&sisusb->lock);
1500 mutex_unlock(&disconnect_mutex);
1501 return 1; 1485 return 1;
1502 } 1486 }
1503 1487
@@ -1508,14 +1492,12 @@ sisusb_console_init(struct sisusb_usb_data *sisusb, int first, int last)
1508 first > MAX_NR_CONSOLES || 1492 first > MAX_NR_CONSOLES ||
1509 last > MAX_NR_CONSOLES) { 1493 last > MAX_NR_CONSOLES) {
1510 mutex_unlock(&sisusb->lock); 1494 mutex_unlock(&sisusb->lock);
1511 mutex_unlock(&disconnect_mutex);
1512 return 1; 1495 return 1;
1513 } 1496 }
1514 1497
1515 /* If gfxcore not initialized or no consoles given, quit graciously */ 1498 /* If gfxcore not initialized or no consoles given, quit graciously */
1516 if (!sisusb->gfxinit || first < 1 || last < 1) { 1499 if (!sisusb->gfxinit || first < 1 || last < 1) {
1517 mutex_unlock(&sisusb->lock); 1500 mutex_unlock(&sisusb->lock);
1518 mutex_unlock(&disconnect_mutex);
1519 return 0; 1501 return 0;
1520 } 1502 }
1521 1503
@@ -1526,7 +1508,6 @@ sisusb_console_init(struct sisusb_usb_data *sisusb, int first, int last)
1526 /* Set up text mode (and upload default font) */ 1508 /* Set up text mode (and upload default font) */
1527 if (sisusb_reset_text_mode(sisusb, 1)) { 1509 if (sisusb_reset_text_mode(sisusb, 1)) {
1528 mutex_unlock(&sisusb->lock); 1510 mutex_unlock(&sisusb->lock);
1529 mutex_unlock(&disconnect_mutex);
1530 printk(KERN_ERR 1511 printk(KERN_ERR
1531 "sisusbvga[%d]: Failed to set up text mode\n", 1512 "sisusbvga[%d]: Failed to set up text mode\n",
1532 minor); 1513 minor);
@@ -1550,7 +1531,6 @@ sisusb_console_init(struct sisusb_usb_data *sisusb, int first, int last)
1550 /* Allocate screen buffer */ 1531 /* Allocate screen buffer */
1551 if (!(sisusb->scrbuf = (unsigned long)vmalloc(sisusb->scrbuf_size))) { 1532 if (!(sisusb->scrbuf = (unsigned long)vmalloc(sisusb->scrbuf_size))) {
1552 mutex_unlock(&sisusb->lock); 1533 mutex_unlock(&sisusb->lock);
1553 mutex_unlock(&disconnect_mutex);
1554 printk(KERN_ERR 1534 printk(KERN_ERR
1555 "sisusbvga[%d]: Failed to allocate screen buffer\n", 1535 "sisusbvga[%d]: Failed to allocate screen buffer\n",
1556 minor); 1536 minor);
@@ -1558,7 +1538,6 @@ sisusb_console_init(struct sisusb_usb_data *sisusb, int first, int last)
1558 } 1538 }
1559 1539
1560 mutex_unlock(&sisusb->lock); 1540 mutex_unlock(&sisusb->lock);
1561 mutex_unlock(&disconnect_mutex);
1562 1541
1563 /* Now grab the desired console(s) */ 1542 /* Now grab the desired console(s) */
1564 ret = take_over_console(&sisusb_con, first - 1, last - 1, 0); 1543 ret = take_over_console(&sisusb_con, first - 1, last - 1, 0);
diff --git a/drivers/usb/misc/sisusbvga/sisusb_init.h b/drivers/usb/misc/sisusbvga/sisusb_init.h
index f05f83268af4..864bc0e96591 100644
--- a/drivers/usb/misc/sisusbvga/sisusb_init.h
+++ b/drivers/usb/misc/sisusbvga/sisusb_init.h
@@ -808,8 +808,6 @@ static const struct SiS_VCLKData SiSUSB_VCLKData[] =
808 { 0x2b,0xc2, 35} /* 0x71 768@576@60 */ 808 { 0x2b,0xc2, 35} /* 0x71 768@576@60 */
809}; 809};
810 810
811extern struct mutex disconnect_mutex;
812
813int SiSUSBSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo); 811int SiSUSBSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo);
814int SiSUSBSetVESAMode(struct SiS_Private *SiS_Pr, unsigned short VModeNo); 812int SiSUSBSetVESAMode(struct SiS_Private *SiS_Pr, unsigned short VModeNo);
815 813
diff --git a/drivers/usb/misc/usblcd.c b/drivers/usb/misc/usblcd.c
index 12bad8a205a7..6e093c2aac2c 100644
--- a/drivers/usb/misc/usblcd.c
+++ b/drivers/usb/misc/usblcd.c
@@ -51,7 +51,6 @@ struct usb_lcd {
51#define USB_LCD_CONCURRENT_WRITES 5 51#define USB_LCD_CONCURRENT_WRITES 5
52 52
53static struct usb_driver lcd_driver; 53static struct usb_driver lcd_driver;
54static DEFINE_MUTEX(usb_lcd_open_mutex);
55 54
56 55
57static void lcd_delete(struct kref *kref) 56static void lcd_delete(struct kref *kref)
@@ -69,24 +68,19 @@ static int lcd_open(struct inode *inode, struct file *file)
69 struct usb_lcd *dev; 68 struct usb_lcd *dev;
70 struct usb_interface *interface; 69 struct usb_interface *interface;
71 int subminor; 70 int subminor;
72 int retval = 0;
73 71
74 subminor = iminor(inode); 72 subminor = iminor(inode);
75 73
76 mutex_lock(&usb_lcd_open_mutex);
77 interface = usb_find_interface(&lcd_driver, subminor); 74 interface = usb_find_interface(&lcd_driver, subminor);
78 if (!interface) { 75 if (!interface) {
79 err ("USBLCD: %s - error, can't find device for minor %d", 76 err ("USBLCD: %s - error, can't find device for minor %d",
80 __FUNCTION__, subminor); 77 __FUNCTION__, subminor);
81 retval = -ENODEV; 78 return -ENODEV;
82 goto exit;
83 } 79 }
84 80
85 dev = usb_get_intfdata(interface); 81 dev = usb_get_intfdata(interface);
86 if (!dev) { 82 if (!dev)
87 retval = -ENODEV; 83 return -ENODEV;
88 goto exit;
89 }
90 84
91 /* increment our usage count for the device */ 85 /* increment our usage count for the device */
92 kref_get(&dev->kref); 86 kref_get(&dev->kref);
@@ -94,9 +88,7 @@ static int lcd_open(struct inode *inode, struct file *file)
94 /* save our object in the file's private structure */ 88 /* save our object in the file's private structure */
95 file->private_data = dev; 89 file->private_data = dev;
96 90
97exit: 91 return 0;
98 mutex_unlock(&usb_lcd_open_mutex);
99 return retval;
100} 92}
101 93
102static int lcd_release(struct inode *inode, struct file *file) 94static int lcd_release(struct inode *inode, struct file *file)
@@ -363,17 +355,12 @@ static void lcd_disconnect(struct usb_interface *interface)
363 struct usb_lcd *dev; 355 struct usb_lcd *dev;
364 int minor = interface->minor; 356 int minor = interface->minor;
365 357
366 /* prevent skel_open() from racing skel_disconnect() */
367 mutex_lock(&usb_lcd_open_mutex);
368
369 dev = usb_get_intfdata(interface); 358 dev = usb_get_intfdata(interface);
370 usb_set_intfdata(interface, NULL); 359 usb_set_intfdata(interface, NULL);
371 360
372 /* give back our minor */ 361 /* give back our minor */
373 usb_deregister_dev(interface, &lcd_class); 362 usb_deregister_dev(interface, &lcd_class);
374 363
375 mutex_unlock(&usb_lcd_open_mutex);
376
377 /* decrement our usage count */ 364 /* decrement our usage count */
378 kref_put(&dev->kref, lcd_delete); 365 kref_put(&dev->kref, lcd_delete);
379 366
diff --git a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c
index 8432bf171d2e..38f8e4df9dd6 100644
--- a/drivers/usb/usb-skeleton.c
+++ b/drivers/usb/usb-skeleton.c
@@ -34,9 +34,6 @@ static struct usb_device_id skel_table [] = {
34}; 34};
35MODULE_DEVICE_TABLE(usb, skel_table); 35MODULE_DEVICE_TABLE(usb, skel_table);
36 36
37/* to prevent a race between open and disconnect */
38static DEFINE_MUTEX(skel_open_lock);
39
40 37
41/* Get a minor range for your devices from the usb maintainer */ 38/* Get a minor range for your devices from the usb maintainer */
42#define USB_SKEL_MINOR_BASE 192 39#define USB_SKEL_MINOR_BASE 192
@@ -83,10 +80,8 @@ static int skel_open(struct inode *inode, struct file *file)
83 80
84 subminor = iminor(inode); 81 subminor = iminor(inode);
85 82
86 mutex_lock(&skel_open_lock);
87 interface = usb_find_interface(&skel_driver, subminor); 83 interface = usb_find_interface(&skel_driver, subminor);
88 if (!interface) { 84 if (!interface) {
89 mutex_unlock(&skel_open_lock);
90 err ("%s - error, can't find device for minor %d", 85 err ("%s - error, can't find device for minor %d",
91 __FUNCTION__, subminor); 86 __FUNCTION__, subminor);
92 retval = -ENODEV; 87 retval = -ENODEV;
@@ -95,15 +90,12 @@ static int skel_open(struct inode *inode, struct file *file)
95 90
96 dev = usb_get_intfdata(interface); 91 dev = usb_get_intfdata(interface);
97 if (!dev) { 92 if (!dev) {
98 mutex_unlock(&skel_open_lock);
99 retval = -ENODEV; 93 retval = -ENODEV;
100 goto exit; 94 goto exit;
101 } 95 }
102 96
103 /* increment our usage count for the device */ 97 /* increment our usage count for the device */
104 kref_get(&dev->kref); 98 kref_get(&dev->kref);
105 /* now we can drop the lock */
106 mutex_unlock(&skel_open_lock);
107 99
108 /* prevent the device from being autosuspended */ 100 /* prevent the device from being autosuspended */
109 retval = usb_autopm_get_interface(interface); 101 retval = usb_autopm_get_interface(interface);
@@ -368,23 +360,17 @@ static void skel_disconnect(struct usb_interface *interface)
368 struct usb_skel *dev; 360 struct usb_skel *dev;
369 int minor = interface->minor; 361 int minor = interface->minor;
370 362
371 /* prevent skel_open() from racing skel_disconnect() */
372 mutex_lock(&skel_open_lock);
373
374 dev = usb_get_intfdata(interface); 363 dev = usb_get_intfdata(interface);
375 usb_set_intfdata(interface, NULL); 364 usb_set_intfdata(interface, NULL);
376 365
377 /* give back our minor */ 366 /* give back our minor */
378 usb_deregister_dev(interface, &skel_class); 367 usb_deregister_dev(interface, &skel_class);
379 mutex_unlock(&skel_open_lock);
380 368
381 /* prevent more I/O from starting */ 369 /* prevent more I/O from starting */
382 mutex_lock(&dev->io_mutex); 370 mutex_lock(&dev->io_mutex);
383 dev->interface = NULL; 371 dev->interface = NULL;
384 mutex_unlock(&dev->io_mutex); 372 mutex_unlock(&dev->io_mutex);
385 373
386
387
388 /* decrement our usage count */ 374 /* decrement our usage count */
389 kref_put(&dev->kref, skel_delete); 375 kref_put(&dev->kref, skel_delete);
390 376