aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/pwc
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2012-05-09 03:43:12 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-05-14 08:21:59 -0400
commitceede9fa8939e40ad0ddb4ad1355f45c6f1d3478 (patch)
tree201155f368f69a4875b523f899aed80226fe8822 /drivers/media/video/pwc
parenta67e17221429c0322e543ae4bf0b25259c3416a5 (diff)
[media] pwc: Fix locking
My last locking rework for pwc mistakenly assumed that videbuf2 does its own locking, but it does not! This patch fixes the missing locking by moving over the the video_device lock, and introducing a separate lock for the videobuf2_queue. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/pwc')
-rw-r--r--drivers/media/video/pwc/pwc-if.c190
-rw-r--r--drivers/media/video/pwc/pwc-v4l.c143
-rw-r--r--drivers/media/video/pwc/pwc.h21
3 files changed, 201 insertions, 153 deletions
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c
index f3370a87cbc0..998e809765a7 100644
--- a/drivers/media/video/pwc/pwc-if.c
+++ b/drivers/media/video/pwc/pwc-if.c
@@ -357,6 +357,7 @@ handler_end:
357 PWC_ERROR("Error (%d) re-submitting urb in pwc_isoc_handler.\n", i); 357 PWC_ERROR("Error (%d) re-submitting urb in pwc_isoc_handler.\n", i);
358} 358}
359 359
360/* Both v4l2_lock and vb_queue_lock should be locked when calling this */
360static int pwc_isoc_init(struct pwc_device *pdev) 361static int pwc_isoc_init(struct pwc_device *pdev)
361{ 362{
362 struct usb_device *udev; 363 struct usb_device *udev;
@@ -366,9 +367,6 @@ static int pwc_isoc_init(struct pwc_device *pdev)
366 struct usb_host_interface *idesc = NULL; 367 struct usb_host_interface *idesc = NULL;
367 int compression = 0; /* 0..3 = uncompressed..high */ 368 int compression = 0; /* 0..3 = uncompressed..high */
368 369
369 if (pdev->iso_init)
370 return 0;
371
372 pdev->vsync = 0; 370 pdev->vsync = 0;
373 pdev->vlast_packet_size = 0; 371 pdev->vlast_packet_size = 0;
374 pdev->fill_buf = NULL; 372 pdev->fill_buf = NULL;
@@ -418,7 +416,6 @@ retry:
418 urb = usb_alloc_urb(ISO_FRAMES_PER_DESC, GFP_KERNEL); 416 urb = usb_alloc_urb(ISO_FRAMES_PER_DESC, GFP_KERNEL);
419 if (urb == NULL) { 417 if (urb == NULL) {
420 PWC_ERROR("Failed to allocate urb %d\n", i); 418 PWC_ERROR("Failed to allocate urb %d\n", i);
421 pdev->iso_init = 1;
422 pwc_isoc_cleanup(pdev); 419 pwc_isoc_cleanup(pdev);
423 return -ENOMEM; 420 return -ENOMEM;
424 } 421 }
@@ -435,7 +432,6 @@ retry:
435 &urb->transfer_dma); 432 &urb->transfer_dma);
436 if (urb->transfer_buffer == NULL) { 433 if (urb->transfer_buffer == NULL) {
437 PWC_ERROR("Failed to allocate urb buffer %d\n", i); 434 PWC_ERROR("Failed to allocate urb buffer %d\n", i);
438 pdev->iso_init = 1;
439 pwc_isoc_cleanup(pdev); 435 pwc_isoc_cleanup(pdev);
440 return -ENOMEM; 436 return -ENOMEM;
441 } 437 }
@@ -455,13 +451,11 @@ retry:
455 ret = usb_submit_urb(pdev->urbs[i], GFP_KERNEL); 451 ret = usb_submit_urb(pdev->urbs[i], GFP_KERNEL);
456 if (ret == -ENOSPC && compression < 3) { 452 if (ret == -ENOSPC && compression < 3) {
457 compression++; 453 compression++;
458 pdev->iso_init = 1;
459 pwc_isoc_cleanup(pdev); 454 pwc_isoc_cleanup(pdev);
460 goto retry; 455 goto retry;
461 } 456 }
462 if (ret) { 457 if (ret) {
463 PWC_ERROR("isoc_init() submit_urb %d failed with error %d\n", i, ret); 458 PWC_ERROR("isoc_init() submit_urb %d failed with error %d\n", i, ret);
464 pdev->iso_init = 1;
465 pwc_isoc_cleanup(pdev); 459 pwc_isoc_cleanup(pdev);
466 return ret; 460 return ret;
467 } 461 }
@@ -469,7 +463,6 @@ retry:
469 } 463 }
470 464
471 /* All is done... */ 465 /* All is done... */
472 pdev->iso_init = 1;
473 PWC_DEBUG_OPEN("<< pwc_isoc_init()\n"); 466 PWC_DEBUG_OPEN("<< pwc_isoc_init()\n");
474 return 0; 467 return 0;
475} 468}
@@ -507,21 +500,19 @@ static void pwc_iso_free(struct pwc_device *pdev)
507 } 500 }
508} 501}
509 502
503/* Both v4l2_lock and vb_queue_lock should be locked when calling this */
510static void pwc_isoc_cleanup(struct pwc_device *pdev) 504static void pwc_isoc_cleanup(struct pwc_device *pdev)
511{ 505{
512 PWC_DEBUG_OPEN(">> pwc_isoc_cleanup()\n"); 506 PWC_DEBUG_OPEN(">> pwc_isoc_cleanup()\n");
513 507
514 if (pdev->iso_init == 0)
515 return;
516
517 pwc_iso_stop(pdev); 508 pwc_iso_stop(pdev);
518 pwc_iso_free(pdev); 509 pwc_iso_free(pdev);
519 usb_set_interface(pdev->udev, 0, 0); 510 usb_set_interface(pdev->udev, 0, 0);
520 511
521 pdev->iso_init = 0;
522 PWC_DEBUG_OPEN("<< pwc_isoc_cleanup()\n"); 512 PWC_DEBUG_OPEN("<< pwc_isoc_cleanup()\n");
523} 513}
524 514
515/* Must be called with vb_queue_lock hold */
525static void pwc_cleanup_queued_bufs(struct pwc_device *pdev) 516static void pwc_cleanup_queued_bufs(struct pwc_device *pdev)
526{ 517{
527 unsigned long flags = 0; 518 unsigned long flags = 0;
@@ -573,18 +564,13 @@ static const char *pwc_sensor_type_to_string(unsigned int sensor_type)
573 564
574int pwc_test_n_set_capt_file(struct pwc_device *pdev, struct file *file) 565int pwc_test_n_set_capt_file(struct pwc_device *pdev, struct file *file)
575{ 566{
576 int r = 0;
577
578 mutex_lock(&pdev->capt_file_lock);
579 if (pdev->capt_file != NULL && 567 if (pdev->capt_file != NULL &&
580 pdev->capt_file != file) { 568 pdev->capt_file != file)
581 r = -EBUSY; 569 return -EBUSY;
582 goto leave; 570
583 }
584 pdev->capt_file = file; 571 pdev->capt_file = file;
585leave: 572
586 mutex_unlock(&pdev->capt_file_lock); 573 return 0;
587 return r;
588} 574}
589 575
590static void pwc_video_release(struct v4l2_device *v) 576static void pwc_video_release(struct v4l2_device *v)
@@ -592,6 +578,7 @@ static void pwc_video_release(struct v4l2_device *v)
592 struct pwc_device *pdev = container_of(v, struct pwc_device, v4l2_dev); 578 struct pwc_device *pdev = container_of(v, struct pwc_device, v4l2_dev);
593 579
594 v4l2_ctrl_handler_free(&pdev->ctrl_handler); 580 v4l2_ctrl_handler_free(&pdev->ctrl_handler);
581 v4l2_device_unregister(&pdev->v4l2_dev);
595 kfree(pdev->ctrl_buf); 582 kfree(pdev->ctrl_buf);
596 kfree(pdev); 583 kfree(pdev);
597} 584}
@@ -600,10 +587,25 @@ static int pwc_video_close(struct file *file)
600{ 587{
601 struct pwc_device *pdev = video_drvdata(file); 588 struct pwc_device *pdev = video_drvdata(file);
602 589
590 /*
591 * If we're still streaming vb2_queue_release will call stream_stop
592 * so we must take both the v4l2_lock and the vb_queue_lock.
593 */
594 if (mutex_lock_interruptible(&pdev->v4l2_lock))
595 return -ERESTARTSYS;
596 if (mutex_lock_interruptible(&pdev->vb_queue_lock)) {
597 mutex_unlock(&pdev->v4l2_lock);
598 return -ERESTARTSYS;
599 }
600
603 if (pdev->capt_file == file) { 601 if (pdev->capt_file == file) {
604 vb2_queue_release(&pdev->vb_queue); 602 vb2_queue_release(&pdev->vb_queue);
605 pdev->capt_file = NULL; 603 pdev->capt_file = NULL;
606 } 604 }
605
606 mutex_unlock(&pdev->vb_queue_lock);
607 mutex_unlock(&pdev->v4l2_lock);
608
607 return v4l2_fh_release(file); 609 return v4l2_fh_release(file);
608} 610}
609 611
@@ -611,44 +613,81 @@ static ssize_t pwc_video_read(struct file *file, char __user *buf,
611 size_t count, loff_t *ppos) 613 size_t count, loff_t *ppos)
612{ 614{
613 struct pwc_device *pdev = video_drvdata(file); 615 struct pwc_device *pdev = video_drvdata(file);
616 int lock_v4l2 = 0;
617 ssize_t ret;
614 618
615 if (!pdev->udev) 619 if (mutex_lock_interruptible(&pdev->vb_queue_lock))
616 return -ENODEV; 620 return -ERESTARTSYS;
617 621
618 if (pwc_test_n_set_capt_file(pdev, file)) 622 ret = pwc_test_n_set_capt_file(pdev, file);
619 return -EBUSY; 623 if (ret)
624 goto out;
625
626 /* stream_start will get called so we must take the v4l2_lock */
627 if (pdev->vb_queue.fileio == NULL)
628 lock_v4l2 = 1;
620 629
621 return vb2_read(&pdev->vb_queue, buf, count, ppos, 630 /* Use try_lock, since we're taking the locks in the *wrong* order! */
622 file->f_flags & O_NONBLOCK); 631 if (lock_v4l2 && !mutex_trylock(&pdev->v4l2_lock)) {
632 ret = -ERESTARTSYS;
633 goto out;
634 }
635 ret = vb2_read(&pdev->vb_queue, buf, count, ppos,
636 file->f_flags & O_NONBLOCK);
637 if (lock_v4l2)
638 mutex_unlock(&pdev->v4l2_lock);
639out:
640 mutex_unlock(&pdev->vb_queue_lock);
641 return ret;
623} 642}
624 643
625static unsigned int pwc_video_poll(struct file *file, poll_table *wait) 644static unsigned int pwc_video_poll(struct file *file, poll_table *wait)
626{ 645{
627 struct pwc_device *pdev = video_drvdata(file); 646 struct pwc_device *pdev = video_drvdata(file);
647 struct vb2_queue *q = &pdev->vb_queue;
628 unsigned long req_events = poll_requested_events(wait); 648 unsigned long req_events = poll_requested_events(wait);
649 unsigned int ret = POLL_ERR;
650 int lock_v4l2 = 0;
629 651
630 if (!pdev->udev) 652 if (mutex_lock_interruptible(&pdev->vb_queue_lock))
631 return POLL_ERR; 653 return POLL_ERR;
632 654
655 /* Will this start fileio and thus call start_stream? */
633 if ((req_events & (POLLIN | POLLRDNORM)) && 656 if ((req_events & (POLLIN | POLLRDNORM)) &&
634 pdev->vb_queue.num_buffers == 0 && 657 q->num_buffers == 0 && !q->streaming && q->fileio == NULL) {
635 !pdev->iso_init) {
636 /* This poll will start a read stream, check capt_file */
637 if (pwc_test_n_set_capt_file(pdev, file)) 658 if (pwc_test_n_set_capt_file(pdev, file))
638 return POLL_ERR; 659 goto out;
660 lock_v4l2 = 1;
639 } 661 }
640 662
641 return vb2_poll(&pdev->vb_queue, file, wait); 663 /* Use try_lock, since we're taking the locks in the *wrong* order! */
664 if (lock_v4l2 && !mutex_trylock(&pdev->v4l2_lock))
665 goto out;
666 ret = vb2_poll(&pdev->vb_queue, file, wait);
667 if (lock_v4l2)
668 mutex_unlock(&pdev->v4l2_lock);
669
670out:
671 if (!pdev->udev)
672 ret |= POLLHUP;
673 mutex_unlock(&pdev->vb_queue_lock);
674 return ret;
642} 675}
643 676
644static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma) 677static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma)
645{ 678{
646 struct pwc_device *pdev = video_drvdata(file); 679 struct pwc_device *pdev = video_drvdata(file);
680 int ret;
647 681
648 if (pdev->capt_file != file) 682 if (mutex_lock_interruptible(&pdev->vb_queue_lock))
649 return -EBUSY; 683 return -ERESTARTSYS;
684
685 ret = pwc_test_n_set_capt_file(pdev, file);
686 if (ret == 0)
687 ret = vb2_mmap(&pdev->vb_queue, vma);
650 688
651 return vb2_mmap(&pdev->vb_queue, vma); 689 mutex_unlock(&pdev->vb_queue_lock);
690 return ret;
652} 691}
653 692
654/***************************************************************************/ 693/***************************************************************************/
@@ -724,12 +763,14 @@ static void buffer_queue(struct vb2_buffer *vb)
724 struct pwc_frame_buf *buf = container_of(vb, struct pwc_frame_buf, vb); 763 struct pwc_frame_buf *buf = container_of(vb, struct pwc_frame_buf, vb);
725 unsigned long flags = 0; 764 unsigned long flags = 0;
726 765
727 spin_lock_irqsave(&pdev->queued_bufs_lock, flags);
728 /* Check the device has not disconnected between prep and queuing */ 766 /* Check the device has not disconnected between prep and queuing */
729 if (pdev->udev) 767 if (!pdev->udev) {
730 list_add_tail(&buf->list, &pdev->queued_bufs);
731 else
732 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR); 768 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
769 return;
770 }
771
772 spin_lock_irqsave(&pdev->queued_bufs_lock, flags);
773 list_add_tail(&buf->list, &pdev->queued_bufs);
733 spin_unlock_irqrestore(&pdev->queued_bufs_lock, flags); 774 spin_unlock_irqrestore(&pdev->queued_bufs_lock, flags);
734} 775}
735 776
@@ -738,11 +779,8 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count)
738 struct pwc_device *pdev = vb2_get_drv_priv(vq); 779 struct pwc_device *pdev = vb2_get_drv_priv(vq);
739 int r; 780 int r;
740 781
741 mutex_lock(&pdev->udevlock); 782 if (!pdev->udev)
742 if (!pdev->udev) { 783 return -ENODEV;
743 r = -ENODEV;
744 goto leave;
745 }
746 784
747 /* Turn on camera and set LEDS on */ 785 /* Turn on camera and set LEDS on */
748 pwc_camera_power(pdev, 1); 786 pwc_camera_power(pdev, 1);
@@ -756,8 +794,7 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count)
756 /* And cleanup any queued bufs!! */ 794 /* And cleanup any queued bufs!! */
757 pwc_cleanup_queued_bufs(pdev); 795 pwc_cleanup_queued_bufs(pdev);
758 } 796 }
759leave: 797
760 mutex_unlock(&pdev->udevlock);
761 return r; 798 return r;
762} 799}
763 800
@@ -765,19 +802,29 @@ static int stop_streaming(struct vb2_queue *vq)
765{ 802{
766 struct pwc_device *pdev = vb2_get_drv_priv(vq); 803 struct pwc_device *pdev = vb2_get_drv_priv(vq);
767 804
768 mutex_lock(&pdev->udevlock);
769 if (pdev->udev) { 805 if (pdev->udev) {
770 pwc_set_leds(pdev, 0, 0); 806 pwc_set_leds(pdev, 0, 0);
771 pwc_camera_power(pdev, 0); 807 pwc_camera_power(pdev, 0);
772 pwc_isoc_cleanup(pdev); 808 pwc_isoc_cleanup(pdev);
773 } 809 }
774 mutex_unlock(&pdev->udevlock);
775 810
776 pwc_cleanup_queued_bufs(pdev); 811 pwc_cleanup_queued_bufs(pdev);
777 812
778 return 0; 813 return 0;
779} 814}
780 815
816static void wait_prepare(struct vb2_queue *vq)
817{
818 struct pwc_device *pdev = vb2_get_drv_priv(vq);
819 mutex_unlock(&pdev->vb_queue_lock);
820}
821
822static void wait_finish(struct vb2_queue *vq)
823{
824 struct pwc_device *pdev = vb2_get_drv_priv(vq);
825 mutex_lock(&pdev->vb_queue_lock);
826}
827
781static struct vb2_ops pwc_vb_queue_ops = { 828static struct vb2_ops pwc_vb_queue_ops = {
782 .queue_setup = queue_setup, 829 .queue_setup = queue_setup,
783 .buf_init = buffer_init, 830 .buf_init = buffer_init,
@@ -787,6 +834,8 @@ static struct vb2_ops pwc_vb_queue_ops = {
787 .buf_queue = buffer_queue, 834 .buf_queue = buffer_queue,
788 .start_streaming = start_streaming, 835 .start_streaming = start_streaming,
789 .stop_streaming = stop_streaming, 836 .stop_streaming = stop_streaming,
837 .wait_prepare = wait_prepare,
838 .wait_finish = wait_finish,
790}; 839};
791 840
792/***************************************************************************/ 841/***************************************************************************/
@@ -1066,8 +1115,8 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1066 pdev->features = features; 1115 pdev->features = features;
1067 pwc_construct(pdev); /* set min/max sizes correct */ 1116 pwc_construct(pdev); /* set min/max sizes correct */
1068 1117
1069 mutex_init(&pdev->capt_file_lock); 1118 mutex_init(&pdev->v4l2_lock);
1070 mutex_init(&pdev->udevlock); 1119 mutex_init(&pdev->vb_queue_lock);
1071 spin_lock_init(&pdev->queued_bufs_lock); 1120 spin_lock_init(&pdev->queued_bufs_lock);
1072 INIT_LIST_HEAD(&pdev->queued_bufs); 1121 INIT_LIST_HEAD(&pdev->queued_bufs);
1073 1122
@@ -1139,6 +1188,16 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1139 1188
1140 pdev->v4l2_dev.ctrl_handler = &pdev->ctrl_handler; 1189 pdev->v4l2_dev.ctrl_handler = &pdev->ctrl_handler;
1141 pdev->vdev.v4l2_dev = &pdev->v4l2_dev; 1190 pdev->vdev.v4l2_dev = &pdev->v4l2_dev;
1191 pdev->vdev.lock = &pdev->v4l2_lock;
1192
1193 /*
1194 * Don't take v4l2_lock for these ioctls. This improves latency if
1195 * v4l2_lock is taken for a long time, e.g. when changing a control
1196 * value, and a new frame is ready to be dequeued.
1197 */
1198 v4l2_dont_use_lock(&pdev->vdev, VIDIOC_DQBUF);
1199 v4l2_dont_use_lock(&pdev->vdev, VIDIOC_QBUF);
1200 v4l2_dont_use_lock(&pdev->vdev, VIDIOC_QUERYBUF);
1142 1201
1143 rc = video_register_device(&pdev->vdev, VFL_TYPE_GRABBER, -1); 1202 rc = video_register_device(&pdev->vdev, VFL_TYPE_GRABBER, -1);
1144 if (rc < 0) { 1203 if (rc < 0) {
@@ -1194,16 +1253,20 @@ static void usb_pwc_disconnect(struct usb_interface *intf)
1194 struct v4l2_device *v = usb_get_intfdata(intf); 1253 struct v4l2_device *v = usb_get_intfdata(intf);
1195 struct pwc_device *pdev = container_of(v, struct pwc_device, v4l2_dev); 1254 struct pwc_device *pdev = container_of(v, struct pwc_device, v4l2_dev);
1196 1255
1197 mutex_lock(&pdev->udevlock); 1256 mutex_lock(&pdev->v4l2_lock);
1257
1258 mutex_lock(&pdev->vb_queue_lock);
1198 /* No need to keep the urbs around after disconnection */ 1259 /* No need to keep the urbs around after disconnection */
1199 pwc_isoc_cleanup(pdev); 1260 if (pdev->vb_queue.streaming)
1261 pwc_isoc_cleanup(pdev);
1200 pdev->udev = NULL; 1262 pdev->udev = NULL;
1201 mutex_unlock(&pdev->udevlock);
1202
1203 pwc_cleanup_queued_bufs(pdev); 1263 pwc_cleanup_queued_bufs(pdev);
1264 mutex_unlock(&pdev->vb_queue_lock);
1204 1265
1266 v4l2_device_disconnect(&pdev->v4l2_dev);
1205 video_unregister_device(&pdev->vdev); 1267 video_unregister_device(&pdev->vdev);
1206 v4l2_device_unregister(&pdev->v4l2_dev); 1268
1269 mutex_unlock(&pdev->v4l2_lock);
1207 1270
1208#ifdef CONFIG_USB_PWC_INPUT_EVDEV 1271#ifdef CONFIG_USB_PWC_INPUT_EVDEV
1209 if (pdev->button_dev) 1272 if (pdev->button_dev)
@@ -1238,15 +1301,4 @@ MODULE_LICENSE("GPL");
1238MODULE_ALIAS("pwcx"); 1301MODULE_ALIAS("pwcx");
1239MODULE_VERSION( PWC_VERSION ); 1302MODULE_VERSION( PWC_VERSION );
1240 1303
1241static int __init usb_pwc_init(void) 1304module_usb_driver(pwc_driver);
1242{
1243 return usb_register(&pwc_driver);
1244}
1245
1246static void __exit usb_pwc_exit(void)
1247{
1248 usb_deregister(&pwc_driver);
1249}
1250
1251module_init(usb_pwc_init);
1252module_exit(usb_pwc_exit);
diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c
index c1ba1a060c93..c691e29cc36e 100644
--- a/drivers/media/video/pwc/pwc-v4l.c
+++ b/drivers/media/video/pwc/pwc-v4l.c
@@ -464,26 +464,24 @@ static int pwc_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
464 struct pwc_device *pdev = video_drvdata(file); 464 struct pwc_device *pdev = video_drvdata(file);
465 int ret, pixelformat, compression = 0; 465 int ret, pixelformat, compression = 0;
466 466
467 if (pwc_test_n_set_capt_file(pdev, file))
468 return -EBUSY;
469
470 ret = pwc_vidioc_try_fmt(pdev, f); 467 ret = pwc_vidioc_try_fmt(pdev, f);
471 if (ret < 0) 468 if (ret < 0)
472 return ret; 469 return ret;
473 470
474 pixelformat = f->fmt.pix.pixelformat; 471 if (mutex_lock_interruptible(&pdev->vb_queue_lock))
472 return -ERESTARTSYS;
475 473
476 mutex_lock(&pdev->udevlock); 474 ret = pwc_test_n_set_capt_file(pdev, file);
477 if (!pdev->udev) { 475 if (ret)
478 ret = -ENODEV;
479 goto leave; 476 goto leave;
480 }
481 477
482 if (pdev->iso_init) { 478 if (pdev->vb_queue.streaming) {
483 ret = -EBUSY; 479 ret = -EBUSY;
484 goto leave; 480 goto leave;
485 } 481 }
486 482
483 pixelformat = f->fmt.pix.pixelformat;
484
487 PWC_DEBUG_IOCTL("Trying to set format to: width=%d height=%d fps=%d " 485 PWC_DEBUG_IOCTL("Trying to set format to: width=%d height=%d fps=%d "
488 "format=%c%c%c%c\n", 486 "format=%c%c%c%c\n",
489 f->fmt.pix.width, f->fmt.pix.height, pdev->vframes, 487 f->fmt.pix.width, f->fmt.pix.height, pdev->vframes,
@@ -499,7 +497,7 @@ static int pwc_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
499 497
500 pwc_vidioc_fill_fmt(f, pdev->width, pdev->height, pdev->pixfmt); 498 pwc_vidioc_fill_fmt(f, pdev->width, pdev->height, pdev->pixfmt);
501leave: 499leave:
502 mutex_unlock(&pdev->udevlock); 500 mutex_unlock(&pdev->vb_queue_lock);
503 return ret; 501 return ret;
504} 502}
505 503
@@ -507,9 +505,6 @@ static int pwc_querycap(struct file *file, void *fh, struct v4l2_capability *cap
507{ 505{
508 struct pwc_device *pdev = video_drvdata(file); 506 struct pwc_device *pdev = video_drvdata(file);
509 507
510 if (!pdev->udev)
511 return -ENODEV;
512
513 strcpy(cap->driver, PWC_NAME); 508 strcpy(cap->driver, PWC_NAME);
514 strlcpy(cap->card, pdev->vdev.name, sizeof(cap->card)); 509 strlcpy(cap->card, pdev->vdev.name, sizeof(cap->card));
515 usb_make_path(pdev->udev, cap->bus_info, sizeof(cap->bus_info)); 510 usb_make_path(pdev->udev, cap->bus_info, sizeof(cap->bus_info));
@@ -540,15 +535,12 @@ static int pwc_s_input(struct file *file, void *fh, unsigned int i)
540 return i ? -EINVAL : 0; 535 return i ? -EINVAL : 0;
541} 536}
542 537
543static int pwc_g_volatile_ctrl_unlocked(struct v4l2_ctrl *ctrl) 538static int pwc_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
544{ 539{
545 struct pwc_device *pdev = 540 struct pwc_device *pdev =
546 container_of(ctrl->handler, struct pwc_device, ctrl_handler); 541 container_of(ctrl->handler, struct pwc_device, ctrl_handler);
547 int ret = 0; 542 int ret = 0;
548 543
549 if (!pdev->udev)
550 return -ENODEV;
551
552 switch (ctrl->id) { 544 switch (ctrl->id) {
553 case V4L2_CID_AUTO_WHITE_BALANCE: 545 case V4L2_CID_AUTO_WHITE_BALANCE:
554 if (pdev->color_bal_valid && 546 if (pdev->color_bal_valid &&
@@ -615,18 +607,6 @@ static int pwc_g_volatile_ctrl_unlocked(struct v4l2_ctrl *ctrl)
615 return ret; 607 return ret;
616} 608}
617 609
618static int pwc_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
619{
620 struct pwc_device *pdev =
621 container_of(ctrl->handler, struct pwc_device, ctrl_handler);
622 int ret;
623
624 mutex_lock(&pdev->udevlock);
625 ret = pwc_g_volatile_ctrl_unlocked(ctrl);
626 mutex_unlock(&pdev->udevlock);
627 return ret;
628}
629
630static int pwc_set_awb(struct pwc_device *pdev) 610static int pwc_set_awb(struct pwc_device *pdev)
631{ 611{
632 int ret; 612 int ret;
@@ -648,7 +628,7 @@ static int pwc_set_awb(struct pwc_device *pdev)
648 if (pdev->auto_white_balance->val == awb_indoor || 628 if (pdev->auto_white_balance->val == awb_indoor ||
649 pdev->auto_white_balance->val == awb_outdoor || 629 pdev->auto_white_balance->val == awb_outdoor ||
650 pdev->auto_white_balance->val == awb_fl) 630 pdev->auto_white_balance->val == awb_fl)
651 pwc_g_volatile_ctrl_unlocked(pdev->auto_white_balance); 631 pwc_g_volatile_ctrl(pdev->auto_white_balance);
652 } 632 }
653 if (pdev->auto_white_balance->val != awb_manual) 633 if (pdev->auto_white_balance->val != awb_manual)
654 return 0; 634 return 0;
@@ -812,13 +792,6 @@ static int pwc_s_ctrl(struct v4l2_ctrl *ctrl)
812 container_of(ctrl->handler, struct pwc_device, ctrl_handler); 792 container_of(ctrl->handler, struct pwc_device, ctrl_handler);
813 int ret = 0; 793 int ret = 0;
814 794
815 mutex_lock(&pdev->udevlock);
816
817 if (!pdev->udev) {
818 ret = -ENODEV;
819 goto leave;
820 }
821
822 switch (ctrl->id) { 795 switch (ctrl->id) {
823 case V4L2_CID_BRIGHTNESS: 796 case V4L2_CID_BRIGHTNESS:
824 ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL, 797 ret = pwc_set_u8_ctrl(pdev, SET_LUM_CTL,
@@ -915,8 +888,6 @@ static int pwc_s_ctrl(struct v4l2_ctrl *ctrl)
915 if (ret) 888 if (ret)
916 PWC_ERROR("s_ctrl %s error %d\n", ctrl->name, ret); 889 PWC_ERROR("s_ctrl %s error %d\n", ctrl->name, ret);
917 890
918leave:
919 mutex_unlock(&pdev->udevlock);
920 return ret; 891 return ret;
921} 892}
922 893
@@ -949,11 +920,9 @@ static int pwc_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
949 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 920 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
950 return -EINVAL; 921 return -EINVAL;
951 922
952 mutex_lock(&pdev->udevlock); /* To avoid race with s_fmt */
953 PWC_DEBUG_IOCTL("ioctl(VIDIOC_G_FMT) return size %dx%d\n", 923 PWC_DEBUG_IOCTL("ioctl(VIDIOC_G_FMT) return size %dx%d\n",
954 pdev->width, pdev->height); 924 pdev->width, pdev->height);
955 pwc_vidioc_fill_fmt(f, pdev->width, pdev->height, pdev->pixfmt); 925 pwc_vidioc_fill_fmt(f, pdev->width, pdev->height, pdev->pixfmt);
956 mutex_unlock(&pdev->udevlock);
957 return 0; 926 return 0;
958} 927}
959 928
@@ -968,70 +937,98 @@ static int pwc_reqbufs(struct file *file, void *fh,
968 struct v4l2_requestbuffers *rb) 937 struct v4l2_requestbuffers *rb)
969{ 938{
970 struct pwc_device *pdev = video_drvdata(file); 939 struct pwc_device *pdev = video_drvdata(file);
940 int ret;
971 941
972 if (pwc_test_n_set_capt_file(pdev, file)) 942 if (mutex_lock_interruptible(&pdev->vb_queue_lock))
973 return -EBUSY; 943 return -ERESTARTSYS;
974 944
975 return vb2_reqbufs(&pdev->vb_queue, rb); 945 ret = pwc_test_n_set_capt_file(pdev, file);
946 if (ret == 0)
947 ret = vb2_reqbufs(&pdev->vb_queue, rb);
948
949 mutex_unlock(&pdev->vb_queue_lock);
950 return ret;
976} 951}
977 952
978static int pwc_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf) 953static int pwc_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf)
979{ 954{
980 struct pwc_device *pdev = video_drvdata(file); 955 struct pwc_device *pdev = video_drvdata(file);
956 int ret;
981 957
982 return vb2_querybuf(&pdev->vb_queue, buf); 958 if (mutex_lock_interruptible(&pdev->vb_queue_lock))
959 return -ERESTARTSYS;
960
961 ret = pwc_test_n_set_capt_file(pdev, file);
962 if (ret == 0)
963 ret = vb2_querybuf(&pdev->vb_queue, buf);
964
965 mutex_unlock(&pdev->vb_queue_lock);
966 return ret;
983} 967}
984 968
985static int pwc_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf) 969static int pwc_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
986{ 970{
987 struct pwc_device *pdev = video_drvdata(file); 971 struct pwc_device *pdev = video_drvdata(file);
972 int ret;
988 973
989 if (!pdev->udev) 974 if (mutex_lock_interruptible(&pdev->vb_queue_lock))
990 return -ENODEV; 975 return -ERESTARTSYS;
991 976
992 if (pdev->capt_file != file) 977 ret = pwc_test_n_set_capt_file(pdev, file);
993 return -EBUSY; 978 if (ret == 0)
979 ret = vb2_qbuf(&pdev->vb_queue, buf);
994 980
995 return vb2_qbuf(&pdev->vb_queue, buf); 981 mutex_unlock(&pdev->vb_queue_lock);
982 return ret;
996} 983}
997 984
998static int pwc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf) 985static int pwc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
999{ 986{
1000 struct pwc_device *pdev = video_drvdata(file); 987 struct pwc_device *pdev = video_drvdata(file);
988 int ret;
1001 989
1002 if (!pdev->udev) 990 if (mutex_lock_interruptible(&pdev->vb_queue_lock))
1003 return -ENODEV; 991 return -ERESTARTSYS;
1004 992
1005 if (pdev->capt_file != file) 993 ret = pwc_test_n_set_capt_file(pdev, file);
1006 return -EBUSY; 994 if (ret == 0)
995 ret = vb2_dqbuf(&pdev->vb_queue, buf,
996 file->f_flags & O_NONBLOCK);
1007 997
1008 return vb2_dqbuf(&pdev->vb_queue, buf, file->f_flags & O_NONBLOCK); 998 mutex_unlock(&pdev->vb_queue_lock);
999 return ret;
1009} 1000}
1010 1001
1011static int pwc_streamon(struct file *file, void *fh, enum v4l2_buf_type i) 1002static int pwc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
1012{ 1003{
1013 struct pwc_device *pdev = video_drvdata(file); 1004 struct pwc_device *pdev = video_drvdata(file);
1005 int ret;
1014 1006
1015 if (!pdev->udev) 1007 if (mutex_lock_interruptible(&pdev->vb_queue_lock))
1016 return -ENODEV; 1008 return -ERESTARTSYS;
1017 1009
1018 if (pdev->capt_file != file) 1010 ret = pwc_test_n_set_capt_file(pdev, file);
1019 return -EBUSY; 1011 if (ret == 0)
1012 ret = vb2_streamon(&pdev->vb_queue, i);
1020 1013
1021 return vb2_streamon(&pdev->vb_queue, i); 1014 mutex_unlock(&pdev->vb_queue_lock);
1015 return ret;
1022} 1016}
1023 1017
1024static int pwc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i) 1018static int pwc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i)
1025{ 1019{
1026 struct pwc_device *pdev = video_drvdata(file); 1020 struct pwc_device *pdev = video_drvdata(file);
1021 int ret;
1027 1022
1028 if (!pdev->udev) 1023 if (mutex_lock_interruptible(&pdev->vb_queue_lock))
1029 return -ENODEV; 1024 return -ERESTARTSYS;
1030 1025
1031 if (pdev->capt_file != file) 1026 ret = pwc_test_n_set_capt_file(pdev, file);
1032 return -EBUSY; 1027 if (ret == 0)
1028 ret = vb2_streamoff(&pdev->vb_queue, i);
1033 1029
1034 return vb2_streamoff(&pdev->vb_queue, i); 1030 mutex_unlock(&pdev->vb_queue_lock);
1031 return ret;
1035} 1032}
1036 1033
1037static int pwc_enum_framesizes(struct file *file, void *fh, 1034static int pwc_enum_framesizes(struct file *file, void *fh,
@@ -1119,19 +1116,17 @@ static int pwc_s_parm(struct file *file, void *fh,
1119 parm->parm.capture.timeperframe.numerator == 0) 1116 parm->parm.capture.timeperframe.numerator == 0)
1120 return -EINVAL; 1117 return -EINVAL;
1121 1118
1122 if (pwc_test_n_set_capt_file(pdev, file))
1123 return -EBUSY;
1124
1125 fps = parm->parm.capture.timeperframe.denominator / 1119 fps = parm->parm.capture.timeperframe.denominator /
1126 parm->parm.capture.timeperframe.numerator; 1120 parm->parm.capture.timeperframe.numerator;
1127 1121
1128 mutex_lock(&pdev->udevlock); 1122 if (mutex_lock_interruptible(&pdev->vb_queue_lock))
1129 if (!pdev->udev) { 1123 return -ERESTARTSYS;
1130 ret = -ENODEV; 1124
1125 ret = pwc_test_n_set_capt_file(pdev, file);
1126 if (ret)
1131 goto leave; 1127 goto leave;
1132 }
1133 1128
1134 if (pdev->iso_init) { 1129 if (pdev->vb_queue.streaming) {
1135 ret = -EBUSY; 1130 ret = -EBUSY;
1136 goto leave; 1131 goto leave;
1137 } 1132 }
@@ -1142,7 +1137,7 @@ static int pwc_s_parm(struct file *file, void *fh,
1142 pwc_g_parm(file, fh, parm); 1137 pwc_g_parm(file, fh, parm);
1143 1138
1144leave: 1139leave:
1145 mutex_unlock(&pdev->udevlock); 1140 mutex_unlock(&pdev->vb_queue_lock);
1146 return ret; 1141 return ret;
1147} 1142}
1148 1143
diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h
index e4d4d711dd1f..d6b5b216b9d6 100644
--- a/drivers/media/video/pwc/pwc.h
+++ b/drivers/media/video/pwc/pwc.h
@@ -221,9 +221,17 @@ struct pwc_device
221 struct video_device vdev; 221 struct video_device vdev;
222 struct v4l2_device v4l2_dev; 222 struct v4l2_device v4l2_dev;
223 223
224 /* Pointer to our usb_device, may be NULL after unplug */ 224 /* videobuf2 queue and queued buffers list */
225 struct usb_device *udev; 225 struct vb2_queue vb_queue;
226 struct mutex udevlock; 226 struct list_head queued_bufs;
227 spinlock_t queued_bufs_lock; /* Protects queued_bufs */
228
229 /* Note if taking both locks v4l2_lock must always be locked first! */
230 struct mutex v4l2_lock; /* Protects everything else */
231 struct mutex vb_queue_lock; /* Protects vb_queue and capt_file */
232
233 /* Pointer to our usb_device, will be NULL after unplug */
234 struct usb_device *udev; /* Both mutexes most be hold when setting! */
227 235
228 /* type of cam (645, 646, 675, 680, 690, 720, 730, 740, 750) */ 236 /* type of cam (645, 646, 675, 680, 690, 720, 730, 740, 750) */
229 int type; 237 int type;
@@ -232,7 +240,6 @@ struct pwc_device
232 240
233 /*** Video data ***/ 241 /*** Video data ***/
234 struct file *capt_file; /* file doing video capture */ 242 struct file *capt_file; /* file doing video capture */
235 struct mutex capt_file_lock;
236 int vendpoint; /* video isoc endpoint */ 243 int vendpoint; /* video isoc endpoint */
237 int vcinterface; /* video control interface */ 244 int vcinterface; /* video control interface */
238 int valternate; /* alternate interface needed */ 245 int valternate; /* alternate interface needed */
@@ -251,12 +258,6 @@ struct pwc_device
251 unsigned char *ctrl_buf; 258 unsigned char *ctrl_buf;
252 259
253 struct urb *urbs[MAX_ISO_BUFS]; 260 struct urb *urbs[MAX_ISO_BUFS];
254 char iso_init;
255
256 /* videobuf2 queue and queued buffers list */
257 struct vb2_queue vb_queue;
258 struct list_head queued_bufs;
259 spinlock_t queued_bufs_lock;
260 261
261 /* 262 /*
262 * Frame currently being filled, this only gets touched by the 263 * Frame currently being filled, this only gets touched by the