diff options
-rw-r--r-- | drivers/usb/core/file.c | 29 | ||||
-rw-r--r-- | drivers/usb/misc/adutux.c | 31 | ||||
-rw-r--r-- | drivers/usb/misc/auerswald.c | 6 | ||||
-rw-r--r-- | drivers/usb/misc/idmouse.c | 54 | ||||
-rw-r--r-- | drivers/usb/misc/iowarrior.c | 26 | ||||
-rw-r--r-- | drivers/usb/misc/ldusb.c | 33 | ||||
-rw-r--r-- | drivers/usb/misc/legousbtower.c | 24 | ||||
-rw-r--r-- | drivers/usb/misc/sisusbvga/sisusb.c | 38 | ||||
-rw-r--r-- | drivers/usb/misc/sisusbvga/sisusb_con.c | 25 | ||||
-rw-r--r-- | drivers/usb/misc/sisusbvga/sisusb_init.h | 2 | ||||
-rw-r--r-- | drivers/usb/misc/usblcd.c | 21 | ||||
-rw-r--r-- | drivers/usb/usb-skeleton.c | 14 |
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 |
26 | static const struct file_operations *usb_minors[MAX_USB_MINORS]; | 26 | static const struct file_operations *usb_minors[MAX_USB_MINORS]; |
27 | static DEFINE_SPINLOCK(minor_lock); | 27 | static DECLARE_RWSEM(minor_rwsem); |
28 | 28 | ||
29 | static int usb_open(struct inode * inode, struct file * file) | 29 | static 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 | } |
205 | exit: | 204 | exit: |
@@ -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 | } |
249 | EXPORT_SYMBOL(usb_deregister_dev); | 248 | EXPORT_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 */ | ||
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 | ||
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() */ | ||
123 | static DEFINE_MUTEX(disconnect_mutex); | ||
124 | |||
125 | static int idmouse_create_image(struct usb_idmouse *dev) | 122 | static 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() */ | ||
104 | static 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 | ||
638 | out: | 632 | out: |
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() */ | ||
180 | static DEFINE_MUTEX(disconnect_mutex); | ||
181 | |||
182 | static struct usb_driver ld_usb_driver; | 179 | static 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) | |||
366 | unlock_exit: | 356 | unlock_exit: |
367 | up(&dev->sem); | 357 | up(&dev->sem); |
368 | 358 | ||
369 | unlock_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 | |||
254 | static void tower_disconnect (struct usb_interface *interface); | 254 | static void tower_disconnect (struct usb_interface *interface); |
255 | 255 | ||
256 | 256 | ||
257 | /* prevent races between open() and disconnect */ | ||
258 | static DEFINE_MUTEX (disconnect_mutex); | ||
259 | |||
260 | /* file operations needed when we register this driver */ | 257 | /* file operations needed when we register this driver */ |
261 | static const struct file_operations tower_fops = { | 258 | static 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) | |||
421 | unlock_exit: | 416 | unlock_exit: |
422 | up (&dev->sem); | 417 | up (&dev->sem); |
423 | 418 | ||
424 | unlock_disconnect_exit: | 419 | exit: |
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 | ||
73 | static struct usb_driver sisusb_driver; | 73 | static struct usb_driver sisusb_driver; |
74 | 74 | ||
75 | DEFINE_MUTEX(disconnect_mutex); | ||
76 | |||
77 | static void | 75 | static void |
78 | sisusb_free_buffers(struct sisusb_usb_data *sisusb) | 76 | sisusb_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 | ||
811 | extern struct mutex disconnect_mutex; | ||
812 | |||
813 | int SiSUSBSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo); | 811 | int SiSUSBSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo); |
814 | int SiSUSBSetVESAMode(struct SiS_Private *SiS_Pr, unsigned short VModeNo); | 812 | int 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 | ||
53 | static struct usb_driver lcd_driver; | 53 | static struct usb_driver lcd_driver; |
54 | static DEFINE_MUTEX(usb_lcd_open_mutex); | ||
55 | 54 | ||
56 | 55 | ||
57 | static void lcd_delete(struct kref *kref) | 56 | static 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 | ||
97 | exit: | 91 | return 0; |
98 | mutex_unlock(&usb_lcd_open_mutex); | ||
99 | return retval; | ||
100 | } | 92 | } |
101 | 93 | ||
102 | static int lcd_release(struct inode *inode, struct file *file) | 94 | static 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 | }; |
35 | MODULE_DEVICE_TABLE(usb, skel_table); | 35 | MODULE_DEVICE_TABLE(usb, skel_table); |
36 | 36 | ||
37 | /* to prevent a race between open and disconnect */ | ||
38 | static 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 | ||