From 4fba471e405f8f983085fd9f2fd9637bfc275f8f Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 26 Jun 2011 12:13:44 -0300 Subject: [PATCH] [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 Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pwc/pwc-if.c | 23 ++++++++++++++--------- drivers/media/video/pwc/pwc-v4l.c | 35 +++++++++++++++++++++++++++-------- 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) if (!pdev->udev) return -ENODEV; - if (pdev->vopen) { - PWC_DEBUG_OPEN("I'm busy, someone is using the device.\n"); - return -EBUSY; - } - - pdev->vopen++; file->private_data = vdev; PWC_DEBUG_OPEN("<< video_open() returns 0.\n"); return 0; @@ -718,10 +712,12 @@ static int pwc_video_close(struct file *file) PWC_DEBUG_OPEN(">> video_close called(vdev = 0x%p).\n", vdev); pdev = video_get_drvdata(vdev); - vb2_queue_release(&pdev->vb_queue); - pdev->vopen--; + if (pdev->capt_file == file) { + vb2_queue_release(&pdev->vb_queue); + pdev->capt_file = NULL; + } - PWC_DEBUG_OPEN("<< video_close() vopen=%d\n", pdev->vopen); + PWC_DEBUG_OPEN("<< video_close()\n"); return 0; } @@ -734,6 +730,12 @@ static ssize_t pwc_video_read(struct file *file, char __user *buf, if (!pdev->udev) return -ENODEV; + if (pdev->capt_file != NULL && + pdev->capt_file != file) + return -EBUSY; + + pdev->capt_file = file; + return vb2_read(&pdev->vb_queue, buf, count, ppos, file->f_flags & O_NONBLOCK); } @@ -754,6 +756,9 @@ static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma) struct video_device *vdev = file->private_data; struct pwc_device *pdev = video_get_drvdata(vdev); + if (pdev->capt_file != file) + return -EBUSY; + return vb2_mmap(&pdev->vb_queue, vma); } 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) } /* ioctl(VIDIOC_SET_FMT) */ -static int pwc_vidioc_set_fmt(struct pwc_device *pdev, struct v4l2_format *f) + +static int pwc_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) { + struct pwc_device *pdev = video_drvdata(file); int ret, fps, snapshot, compression, pixelformat; if (!pdev->udev) return -ENODEV; + if (pdev->capt_file != NULL && + pdev->capt_file != file) + return -EBUSY; + + pdev->capt_file = file; + ret = pwc_vidioc_try_fmt(pdev, f); if (ret<0) return ret; @@ -678,18 +686,17 @@ static int pwc_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format * return pwc_vidioc_try_fmt(pdev, f); } -static int pwc_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) -{ - struct pwc_device *pdev = video_drvdata(file); - - return pwc_vidioc_set_fmt(pdev, f); -} - static int pwc_reqbufs(struct file *file, void *fh, struct v4l2_requestbuffers *rb) { struct pwc_device *pdev = video_drvdata(file); + if (pdev->capt_file != NULL && + pdev->capt_file != file) + return -EBUSY; + + pdev->capt_file = file; + return vb2_reqbufs(&pdev->vb_queue, rb); } @@ -707,6 +714,9 @@ static int pwc_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf) if (!pdev->udev) return -ENODEV; + if (pdev->capt_file != file) + return -EBUSY; + return vb2_qbuf(&pdev->vb_queue, buf); } @@ -717,6 +727,9 @@ static int pwc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf) if (!pdev->udev) return -ENODEV; + if (pdev->capt_file != file) + return -EBUSY; + return vb2_dqbuf(&pdev->vb_queue, buf, file->f_flags & O_NONBLOCK); } @@ -727,6 +740,9 @@ static int pwc_streamon(struct file *file, void *fh, enum v4l2_buf_type i) if (!pdev->udev) return -ENODEV; + if (pdev->capt_file != file) + return -EBUSY; + return vb2_streamon(&pdev->vb_queue, i); } @@ -737,6 +753,9 @@ static int pwc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i) if (!pdev->udev) return -ENODEV; + if (pdev->capt_file != file) + return -EBUSY; + return vb2_streamoff(&pdev->vb_queue, i); } 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 char serial[30]; /* serial number (string) */ /*** Video data ***/ - int vopen; /* flag */ + struct file *capt_file; /* file doing video capture */ int vendpoint; /* video isoc endpoint */ int vcinterface; /* video control interface */ int valternate; /* alternate interface needed */ -- 2.11.4.GIT