diff options
Diffstat (limited to 'drivers/usb/misc/idmouse.c')
-rw-r--r-- | drivers/usb/misc/idmouse.c | 54 |
1 files changed, 15 insertions, 39 deletions
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 | } |