aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/uvc/uvc_v4l2.c
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2009-09-29 20:07:19 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-12-05 15:40:36 -0500
commit716fdee110ceb816cca8c46c0890d08c5a1addb9 (patch)
tree69e4f133fbbf6549a73b03c3d72583ed66db5710 /drivers/media/video/uvc/uvc_v4l2.c
parent1a969d9863a0c8890eb799ec710dda9701f10483 (diff)
V4L/DVB (13152): uvcvideo: Rely on videodev to reference-count the device
The uvcvideo driver has a driver-wide lock and a reference count to protect against a disconnect/open race. Now that videodev handles the race itself, reference-counting in the driver can be removed. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/uvc/uvc_v4l2.c')
-rw-r--r--drivers/media/video/uvc/uvc_v4l2.c32
1 files changed, 8 insertions, 24 deletions
diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c
index 94c1d6696af5..b3478d0eaf41 100644
--- a/drivers/media/video/uvc/uvc_v4l2.c
+++ b/drivers/media/video/uvc/uvc_v4l2.c
@@ -376,25 +376,18 @@ static int uvc_v4l2_set_streamparm(struct uvc_streaming *stream,
376 */ 376 */
377static int uvc_acquire_privileges(struct uvc_fh *handle) 377static int uvc_acquire_privileges(struct uvc_fh *handle)
378{ 378{
379 int ret = 0;
380
381 /* Always succeed if the handle is already privileged. */ 379 /* Always succeed if the handle is already privileged. */
382 if (handle->state == UVC_HANDLE_ACTIVE) 380 if (handle->state == UVC_HANDLE_ACTIVE)
383 return 0; 381 return 0;
384 382
385 /* Check if the device already has a privileged handle. */ 383 /* Check if the device already has a privileged handle. */
386 mutex_lock(&uvc_driver.open_mutex);
387 if (atomic_inc_return(&handle->stream->active) != 1) { 384 if (atomic_inc_return(&handle->stream->active) != 1) {
388 atomic_dec(&handle->stream->active); 385 atomic_dec(&handle->stream->active);
389 ret = -EBUSY; 386 return -EBUSY;
390 goto done;
391 } 387 }
392 388
393 handle->state = UVC_HANDLE_ACTIVE; 389 handle->state = UVC_HANDLE_ACTIVE;
394 390 return 0;
395done:
396 mutex_unlock(&uvc_driver.open_mutex);
397 return ret;
398} 391}
399 392
400static void uvc_dismiss_privileges(struct uvc_fh *handle) 393static void uvc_dismiss_privileges(struct uvc_fh *handle)
@@ -421,24 +414,20 @@ static int uvc_v4l2_open(struct file *file)
421 int ret = 0; 414 int ret = 0;
422 415
423 uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_open\n"); 416 uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_open\n");
424 mutex_lock(&uvc_driver.open_mutex);
425 stream = video_drvdata(file); 417 stream = video_drvdata(file);
426 418
427 if (stream->dev->state & UVC_DEV_DISCONNECTED) { 419 if (stream->dev->state & UVC_DEV_DISCONNECTED)
428 ret = -ENODEV; 420 return -ENODEV;
429 goto done;
430 }
431 421
432 ret = usb_autopm_get_interface(stream->dev->intf); 422 ret = usb_autopm_get_interface(stream->dev->intf);
433 if (ret < 0) 423 if (ret < 0)
434 goto done; 424 return ret;
435 425
436 /* Create the device handle. */ 426 /* Create the device handle. */
437 handle = kzalloc(sizeof *handle, GFP_KERNEL); 427 handle = kzalloc(sizeof *handle, GFP_KERNEL);
438 if (handle == NULL) { 428 if (handle == NULL) {
439 usb_autopm_put_interface(stream->dev->intf); 429 usb_autopm_put_interface(stream->dev->intf);
440 ret = -ENOMEM; 430 return -ENOMEM;
441 goto done;
442 } 431 }
443 432
444 if (atomic_inc_return(&stream->dev->users) == 1) { 433 if (atomic_inc_return(&stream->dev->users) == 1) {
@@ -447,7 +436,7 @@ static int uvc_v4l2_open(struct file *file)
447 usb_autopm_put_interface(stream->dev->intf); 436 usb_autopm_put_interface(stream->dev->intf);
448 atomic_dec(&stream->dev->users); 437 atomic_dec(&stream->dev->users);
449 kfree(handle); 438 kfree(handle);
450 goto done; 439 return ret;
451 } 440 }
452 } 441 }
453 442
@@ -456,11 +445,7 @@ static int uvc_v4l2_open(struct file *file)
456 handle->state = UVC_HANDLE_PASSIVE; 445 handle->state = UVC_HANDLE_PASSIVE;
457 file->private_data = handle; 446 file->private_data = handle;
458 447
459 kref_get(&stream->dev->kref); 448 return 0;
460
461done:
462 mutex_unlock(&uvc_driver.open_mutex);
463 return ret;
464} 449}
465 450
466static int uvc_v4l2_release(struct file *file) 451static int uvc_v4l2_release(struct file *file)
@@ -490,7 +475,6 @@ static int uvc_v4l2_release(struct file *file)
490 uvc_status_stop(stream->dev); 475 uvc_status_stop(stream->dev);
491 476
492 usb_autopm_put_interface(stream->dev->intf); 477 usb_autopm_put_interface(stream->dev->intf);
493 kref_put(&stream->dev->kref, uvc_delete);
494 return 0; 478 return 0;
495} 479}
496 480