diff options
author | Hans de Goede <hdegoede@redhat.com> | 2011-06-26 11:13:44 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-07-27 16:53:44 -0400 |
commit | 4fba471e405f8f983085fd9f2fd9637bfc275f8f (patch) | |
tree | 0110147ec02ad39b74da40841ac84c6ea2cf1599 /drivers/media/video/pwc | |
parent | 6eba93573d2dda3f627006101c0652faeeaffde6 (diff) |
[media] pwc: Allow multiple opens
Allow multiple opens of the /dev/video node so that control panel apps
can be open to-gether with streaming apps.
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.c | 23 | ||||
-rw-r--r-- | drivers/media/video/pwc/pwc-v4l.c | 35 | ||||
-rw-r--r-- | drivers/media/video/pwc/pwc.h | 2 |
3 files changed, 42 insertions, 18 deletions
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c index b591b723f5a1..a6b5fde5c3ad 100644 --- a/drivers/media/video/pwc/pwc-if.c +++ b/drivers/media/video/pwc/pwc-if.c | |||
@@ -678,12 +678,6 @@ static int pwc_video_open(struct file *file) | |||
678 | if (!pdev->udev) | 678 | if (!pdev->udev) |
679 | return -ENODEV; | 679 | return -ENODEV; |
680 | 680 | ||
681 | if (pdev->vopen) { | ||
682 | PWC_DEBUG_OPEN("I'm busy, someone is using the device.\n"); | ||
683 | return -EBUSY; | ||
684 | } | ||
685 | |||
686 | pdev->vopen++; | ||
687 | file->private_data = vdev; | 681 | file->private_data = vdev; |
688 | PWC_DEBUG_OPEN("<< video_open() returns 0.\n"); | 682 | PWC_DEBUG_OPEN("<< video_open() returns 0.\n"); |
689 | return 0; | 683 | return 0; |
@@ -718,10 +712,12 @@ static int pwc_video_close(struct file *file) | |||
718 | PWC_DEBUG_OPEN(">> video_close called(vdev = 0x%p).\n", vdev); | 712 | PWC_DEBUG_OPEN(">> video_close called(vdev = 0x%p).\n", vdev); |
719 | 713 | ||
720 | pdev = video_get_drvdata(vdev); | 714 | pdev = video_get_drvdata(vdev); |
721 | vb2_queue_release(&pdev->vb_queue); | 715 | if (pdev->capt_file == file) { |
722 | pdev->vopen--; | 716 | vb2_queue_release(&pdev->vb_queue); |
717 | pdev->capt_file = NULL; | ||
718 | } | ||
723 | 719 | ||
724 | PWC_DEBUG_OPEN("<< video_close() vopen=%d\n", pdev->vopen); | 720 | PWC_DEBUG_OPEN("<< video_close()\n"); |
725 | return 0; | 721 | return 0; |
726 | } | 722 | } |
727 | 723 | ||
@@ -734,6 +730,12 @@ static ssize_t pwc_video_read(struct file *file, char __user *buf, | |||
734 | if (!pdev->udev) | 730 | if (!pdev->udev) |
735 | return -ENODEV; | 731 | return -ENODEV; |
736 | 732 | ||
733 | if (pdev->capt_file != NULL && | ||
734 | pdev->capt_file != file) | ||
735 | return -EBUSY; | ||
736 | |||
737 | pdev->capt_file = file; | ||
738 | |||
737 | return vb2_read(&pdev->vb_queue, buf, count, ppos, | 739 | return vb2_read(&pdev->vb_queue, buf, count, ppos, |
738 | file->f_flags & O_NONBLOCK); | 740 | file->f_flags & O_NONBLOCK); |
739 | } | 741 | } |
@@ -754,6 +756,9 @@ static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma) | |||
754 | struct video_device *vdev = file->private_data; | 756 | struct video_device *vdev = file->private_data; |
755 | struct pwc_device *pdev = video_get_drvdata(vdev); | 757 | struct pwc_device *pdev = video_get_drvdata(vdev); |
756 | 758 | ||
759 | if (pdev->capt_file != file) | ||
760 | return -EBUSY; | ||
761 | |||
757 | return vb2_mmap(&pdev->vb_queue, vma); | 762 | return vb2_mmap(&pdev->vb_queue, vma); |
758 | } | 763 | } |
759 | 764 | ||
diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c index 8bd0a681990d..834055b71e04 100644 --- a/drivers/media/video/pwc/pwc-v4l.c +++ b/drivers/media/video/pwc/pwc-v4l.c | |||
@@ -284,13 +284,21 @@ static int pwc_vidioc_try_fmt(struct pwc_device *pdev, struct v4l2_format *f) | |||
284 | } | 284 | } |
285 | 285 | ||
286 | /* ioctl(VIDIOC_SET_FMT) */ | 286 | /* ioctl(VIDIOC_SET_FMT) */ |
287 | static int pwc_vidioc_set_fmt(struct pwc_device *pdev, struct v4l2_format *f) | 287 | |
288 | static int pwc_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) | ||
288 | { | 289 | { |
290 | struct pwc_device *pdev = video_drvdata(file); | ||
289 | int ret, fps, snapshot, compression, pixelformat; | 291 | int ret, fps, snapshot, compression, pixelformat; |
290 | 292 | ||
291 | if (!pdev->udev) | 293 | if (!pdev->udev) |
292 | return -ENODEV; | 294 | return -ENODEV; |
293 | 295 | ||
296 | if (pdev->capt_file != NULL && | ||
297 | pdev->capt_file != file) | ||
298 | return -EBUSY; | ||
299 | |||
300 | pdev->capt_file = file; | ||
301 | |||
294 | ret = pwc_vidioc_try_fmt(pdev, f); | 302 | ret = pwc_vidioc_try_fmt(pdev, f); |
295 | if (ret<0) | 303 | if (ret<0) |
296 | return ret; | 304 | return ret; |
@@ -678,18 +686,17 @@ static int pwc_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format * | |||
678 | return pwc_vidioc_try_fmt(pdev, f); | 686 | return pwc_vidioc_try_fmt(pdev, f); |
679 | } | 687 | } |
680 | 688 | ||
681 | static int pwc_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) | ||
682 | { | ||
683 | struct pwc_device *pdev = video_drvdata(file); | ||
684 | |||
685 | return pwc_vidioc_set_fmt(pdev, f); | ||
686 | } | ||
687 | |||
688 | static int pwc_reqbufs(struct file *file, void *fh, | 689 | static int pwc_reqbufs(struct file *file, void *fh, |
689 | struct v4l2_requestbuffers *rb) | 690 | struct v4l2_requestbuffers *rb) |
690 | { | 691 | { |
691 | struct pwc_device *pdev = video_drvdata(file); | 692 | struct pwc_device *pdev = video_drvdata(file); |
692 | 693 | ||
694 | if (pdev->capt_file != NULL && | ||
695 | pdev->capt_file != file) | ||
696 | return -EBUSY; | ||
697 | |||
698 | pdev->capt_file = file; | ||
699 | |||
693 | return vb2_reqbufs(&pdev->vb_queue, rb); | 700 | return vb2_reqbufs(&pdev->vb_queue, rb); |
694 | } | 701 | } |
695 | 702 | ||
@@ -707,6 +714,9 @@ static int pwc_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf) | |||
707 | if (!pdev->udev) | 714 | if (!pdev->udev) |
708 | return -ENODEV; | 715 | return -ENODEV; |
709 | 716 | ||
717 | if (pdev->capt_file != file) | ||
718 | return -EBUSY; | ||
719 | |||
710 | return vb2_qbuf(&pdev->vb_queue, buf); | 720 | return vb2_qbuf(&pdev->vb_queue, buf); |
711 | } | 721 | } |
712 | 722 | ||
@@ -717,6 +727,9 @@ static int pwc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf) | |||
717 | if (!pdev->udev) | 727 | if (!pdev->udev) |
718 | return -ENODEV; | 728 | return -ENODEV; |
719 | 729 | ||
730 | if (pdev->capt_file != file) | ||
731 | return -EBUSY; | ||
732 | |||
720 | return vb2_dqbuf(&pdev->vb_queue, buf, file->f_flags & O_NONBLOCK); | 733 | return vb2_dqbuf(&pdev->vb_queue, buf, file->f_flags & O_NONBLOCK); |
721 | } | 734 | } |
722 | 735 | ||
@@ -727,6 +740,9 @@ static int pwc_streamon(struct file *file, void *fh, enum v4l2_buf_type i) | |||
727 | if (!pdev->udev) | 740 | if (!pdev->udev) |
728 | return -ENODEV; | 741 | return -ENODEV; |
729 | 742 | ||
743 | if (pdev->capt_file != file) | ||
744 | return -EBUSY; | ||
745 | |||
730 | return vb2_streamon(&pdev->vb_queue, i); | 746 | return vb2_streamon(&pdev->vb_queue, i); |
731 | } | 747 | } |
732 | 748 | ||
@@ -737,6 +753,9 @@ static int pwc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i) | |||
737 | if (!pdev->udev) | 753 | if (!pdev->udev) |
738 | return -ENODEV; | 754 | return -ENODEV; |
739 | 755 | ||
756 | if (pdev->capt_file != file) | ||
757 | return -EBUSY; | ||
758 | |||
740 | return vb2_streamoff(&pdev->vb_queue, i); | 759 | return vb2_streamoff(&pdev->vb_queue, i); |
741 | } | 760 | } |
742 | 761 | ||
diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h index 8d82c6aac42c..d65cd14ef9f2 100644 --- a/drivers/media/video/pwc/pwc.h +++ b/drivers/media/video/pwc/pwc.h | |||
@@ -160,7 +160,7 @@ struct pwc_device | |||
160 | char serial[30]; /* serial number (string) */ | 160 | char serial[30]; /* serial number (string) */ |
161 | 161 | ||
162 | /*** Video data ***/ | 162 | /*** Video data ***/ |
163 | int vopen; /* flag */ | 163 | struct file *capt_file; /* file doing video capture */ |
164 | int vendpoint; /* video isoc endpoint */ | 164 | int vendpoint; /* video isoc endpoint */ |
165 | int vcinterface; /* video control interface */ | 165 | int vcinterface; /* video control interface */ |
166 | int valternate; /* alternate interface needed */ | 166 | int valternate; /* alternate interface needed */ |