diff options
Diffstat (limited to 'drivers/usb/misc/idmouse.c')
| -rw-r--r-- | drivers/usb/misc/idmouse.c | 45 |
1 files changed, 28 insertions, 17 deletions
diff --git a/drivers/usb/misc/idmouse.c b/drivers/usb/misc/idmouse.c index e6fd024024f5..4bcf7fb4e5da 100644 --- a/drivers/usb/misc/idmouse.c +++ b/drivers/usb/misc/idmouse.c | |||
| @@ -66,6 +66,7 @@ static struct usb_device_id idmouse_table[] = { | |||
| 66 | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT, value, index, NULL, 0, 1000) | 66 | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT, value, index, NULL, 0, 1000) |
| 67 | 67 | ||
| 68 | MODULE_DEVICE_TABLE(usb, idmouse_table); | 68 | MODULE_DEVICE_TABLE(usb, idmouse_table); |
| 69 | static DEFINE_MUTEX(open_disc_mutex); | ||
| 69 | 70 | ||
| 70 | /* structure to hold all of our device specific stuff */ | 71 | /* structure to hold all of our device specific stuff */ |
| 71 | struct usb_idmouse { | 72 | struct usb_idmouse { |
| @@ -80,7 +81,7 @@ struct usb_idmouse { | |||
| 80 | 81 | ||
| 81 | int open; /* if the port is open or not */ | 82 | int open; /* if the port is open or not */ |
| 82 | int present; /* if the device is not disconnected */ | 83 | int present; /* if the device is not disconnected */ |
| 83 | struct semaphore sem; /* locks this structure */ | 84 | struct mutex lock; /* locks this structure */ |
| 84 | 85 | ||
| 85 | }; | 86 | }; |
| 86 | 87 | ||
| @@ -213,13 +214,17 @@ static int idmouse_open(struct inode *inode, struct file *file) | |||
| 213 | if (!interface) | 214 | if (!interface) |
| 214 | return -ENODEV; | 215 | return -ENODEV; |
| 215 | 216 | ||
| 217 | mutex_lock(&open_disc_mutex); | ||
| 216 | /* get the device information block from the interface */ | 218 | /* get the device information block from the interface */ |
| 217 | dev = usb_get_intfdata(interface); | 219 | dev = usb_get_intfdata(interface); |
| 218 | if (!dev) | 220 | if (!dev) { |
| 221 | mutex_unlock(&open_disc_mutex); | ||
| 219 | return -ENODEV; | 222 | return -ENODEV; |
| 223 | } | ||
| 220 | 224 | ||
| 221 | /* lock this device */ | 225 | /* lock this device */ |
| 222 | down(&dev->sem); | 226 | mutex_lock(&dev->lock); |
| 227 | mutex_unlock(&open_disc_mutex); | ||
| 223 | 228 | ||
| 224 | /* check if already open */ | 229 | /* check if already open */ |
| 225 | if (dev->open) { | 230 | if (dev->open) { |
| @@ -245,7 +250,7 @@ static int idmouse_open(struct inode *inode, struct file *file) | |||
| 245 | error: | 250 | error: |
| 246 | 251 | ||
| 247 | /* unlock this device */ | 252 | /* unlock this device */ |
| 248 | up(&dev->sem); | 253 | mutex_unlock(&dev->lock); |
| 249 | return result; | 254 | return result; |
| 250 | } | 255 | } |
| 251 | 256 | ||
| @@ -258,12 +263,14 @@ static int idmouse_release(struct inode *inode, struct file *file) | |||
| 258 | if (dev == NULL) | 263 | if (dev == NULL) |
| 259 | return -ENODEV; | 264 | return -ENODEV; |
| 260 | 265 | ||
| 266 | mutex_lock(&open_disc_mutex); | ||
| 261 | /* lock our device */ | 267 | /* lock our device */ |
| 262 | down(&dev->sem); | 268 | mutex_lock(&dev->lock); |
| 263 | 269 | ||
| 264 | /* are we really open? */ | 270 | /* are we really open? */ |
| 265 | if (dev->open <= 0) { | 271 | if (dev->open <= 0) { |
| 266 | up(&dev->sem); | 272 | mutex_unlock(&dev->lock); |
| 273 | mutex_unlock(&open_disc_mutex); | ||
| 267 | return -ENODEV; | 274 | return -ENODEV; |
| 268 | } | 275 | } |
| 269 | 276 | ||
| @@ -271,10 +278,12 @@ static int idmouse_release(struct inode *inode, struct file *file) | |||
| 271 | 278 | ||
| 272 | if (!dev->present) { | 279 | if (!dev->present) { |
| 273 | /* the device was unplugged before the file was released */ | 280 | /* the device was unplugged before the file was released */ |
| 274 | up(&dev->sem); | 281 | mutex_unlock(&dev->lock); |
| 282 | mutex_unlock(&open_disc_mutex); | ||
| 275 | idmouse_delete(dev); | 283 | idmouse_delete(dev); |
| 276 | } else { | 284 | } else { |
| 277 | up(&dev->sem); | 285 | mutex_unlock(&dev->lock); |
| 286 | mutex_unlock(&open_disc_mutex); | ||
| 278 | } | 287 | } |
| 279 | return 0; | 288 | return 0; |
| 280 | } | 289 | } |
| @@ -286,18 +295,18 @@ static ssize_t idmouse_read(struct file *file, char __user *buffer, size_t count | |||
| 286 | int result; | 295 | int result; |
| 287 | 296 | ||
| 288 | /* lock this object */ | 297 | /* lock this object */ |
| 289 | down(&dev->sem); | 298 | mutex_lock(&dev->lock); |
| 290 | 299 | ||
| 291 | /* verify that the device wasn't unplugged */ | 300 | /* verify that the device wasn't unplugged */ |
| 292 | if (!dev->present) { | 301 | if (!dev->present) { |
| 293 | up(&dev->sem); | 302 | mutex_unlock(&dev->lock); |
| 294 | return -ENODEV; | 303 | return -ENODEV; |
| 295 | } | 304 | } |
| 296 | 305 | ||
| 297 | result = simple_read_from_buffer(buffer, count, ppos, | 306 | result = simple_read_from_buffer(buffer, count, ppos, |
| 298 | dev->bulk_in_buffer, IMGSIZE); | 307 | dev->bulk_in_buffer, IMGSIZE); |
| 299 | /* unlock the device */ | 308 | /* unlock the device */ |
| 300 | up(&dev->sem); | 309 | mutex_unlock(&dev->lock); |
| 301 | return result; | 310 | return result; |
| 302 | } | 311 | } |
| 303 | 312 | ||
| @@ -320,7 +329,7 @@ static int idmouse_probe(struct usb_interface *interface, | |||
| 320 | if (dev == NULL) | 329 | if (dev == NULL) |
| 321 | return -ENOMEM; | 330 | return -ENOMEM; |
| 322 | 331 | ||
| 323 | init_MUTEX(&dev->sem); | 332 | mutex_init(&dev->lock); |
| 324 | dev->udev = udev; | 333 | dev->udev = udev; |
| 325 | dev->interface = interface; | 334 | dev->interface = interface; |
| 326 | 335 | ||
| @@ -372,24 +381,26 @@ static void idmouse_disconnect(struct usb_interface *interface) | |||
| 372 | 381 | ||
| 373 | /* get device structure */ | 382 | /* get device structure */ |
| 374 | dev = usb_get_intfdata(interface); | 383 | dev = usb_get_intfdata(interface); |
| 375 | usb_set_intfdata(interface, NULL); | ||
| 376 | 384 | ||
| 377 | /* give back our minor */ | 385 | /* give back our minor */ |
| 378 | usb_deregister_dev(interface, &idmouse_class); | 386 | usb_deregister_dev(interface, &idmouse_class); |
| 379 | 387 | ||
| 380 | /* lock it */ | 388 | mutex_lock(&open_disc_mutex); |
| 381 | down(&dev->sem); | 389 | usb_set_intfdata(interface, NULL); |
| 390 | /* lock the device */ | ||
| 391 | mutex_lock(&dev->lock); | ||
| 392 | mutex_unlock(&open_disc_mutex); | ||
| 382 | 393 | ||
| 383 | /* prevent device read, write and ioctl */ | 394 | /* prevent device read, write and ioctl */ |
| 384 | dev->present = 0; | 395 | dev->present = 0; |
| 385 | 396 | ||
| 386 | /* if the device is opened, idmouse_release will clean this up */ | 397 | /* if the device is opened, idmouse_release will clean this up */ |
| 387 | if (!dev->open) { | 398 | if (!dev->open) { |
| 388 | up(&dev->sem); | 399 | mutex_unlock(&dev->lock); |
| 389 | idmouse_delete(dev); | 400 | idmouse_delete(dev); |
| 390 | } else { | 401 | } else { |
| 391 | /* unlock */ | 402 | /* unlock */ |
| 392 | up(&dev->sem); | 403 | mutex_unlock(&dev->lock); |
| 393 | } | 404 | } |
| 394 | 405 | ||
| 395 | info("%s disconnected", DRIVER_DESC); | 406 | info("%s disconnected", DRIVER_DESC); |
