diff options
author | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2009-09-29 20:07:19 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-12-05 15:40:36 -0500 |
commit | 716fdee110ceb816cca8c46c0890d08c5a1addb9 (patch) | |
tree | 69e4f133fbbf6549a73b03c3d72583ed66db5710 /drivers/media/video/uvc/uvc_v4l2.c | |
parent | 1a969d9863a0c8890eb799ec710dda9701f10483 (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.c | 32 |
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 | */ |
377 | static int uvc_acquire_privileges(struct uvc_fh *handle) | 377 | static 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; | |
395 | done: | ||
396 | mutex_unlock(&uvc_driver.open_mutex); | ||
397 | return ret; | ||
398 | } | 391 | } |
399 | 392 | ||
400 | static void uvc_dismiss_privileges(struct uvc_fh *handle) | 393 | static 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 | |||
461 | done: | ||
462 | mutex_unlock(&uvc_driver.open_mutex); | ||
463 | return ret; | ||
464 | } | 449 | } |
465 | 450 | ||
466 | static int uvc_v4l2_release(struct file *file) | 451 | static 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 | ||