From 0550513c7a559b4933c5e1d47fbd15d15f6078d5 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 28 Aug 2012 20:29:56 -0300 Subject: [media] uvcvideo: Add VIDIOC_[GS]_PRIORITY support Signed-off-by: Laurent Pinchart Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/uvc/uvc_driver.c | 3 +++ drivers/media/usb/uvc/uvc_v4l2.c | 45 ++++++++++++++++++++++++++++++++++++++ drivers/media/usb/uvc/uvcvideo.h | 1 + 3 files changed, 49 insertions(+) (limited to 'drivers/media/usb/uvc') diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c index ae24f7d70b0..22f14d286fb 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c @@ -1562,6 +1562,7 @@ static int uvc_scan_device(struct uvc_device *dev) INIT_LIST_HEAD(&chain->entities); mutex_init(&chain->ctrl_mutex); chain->dev = dev; + v4l2_prio_init(&chain->prio); if (uvc_scan_chain(chain, term) < 0) { kfree(chain); @@ -1722,6 +1723,8 @@ static int uvc_register_video(struct uvc_device *dev, vdev->v4l2_dev = &dev->vdev; vdev->fops = &uvc_fops; vdev->release = uvc_release; + vdev->prio = &stream->chain->prio; + set_bit(V4L2_FL_USE_FH_PRIO, &vdev->flags); if (stream->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) vdev->vfl_dir = VFL_DIR_TX; strlcpy(vdev->name, dev->name, sizeof vdev->name); diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c index bf9d0739313..8e056046bc2 100644 --- a/drivers/media/usb/uvc/uvc_v4l2.c +++ b/drivers/media/usb/uvc/uvc_v4l2.c @@ -576,6 +576,19 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) break; } + /* Priority */ + case VIDIOC_G_PRIORITY: + *(u32 *)arg = v4l2_prio_max(vdev->prio); + break; + + case VIDIOC_S_PRIORITY: + ret = v4l2_prio_check(vdev->prio, handle->vfh.prio); + if (ret < 0) + return ret; + + return v4l2_prio_change(vdev->prio, &handle->vfh.prio, + *(u32 *)arg); + /* Get, Set & Query control */ case VIDIOC_QUERYCTRL: return uvc_query_v4l2_ctrl(chain, arg); @@ -606,6 +619,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) struct v4l2_control *ctrl = arg; struct v4l2_ext_control xctrl; + ret = v4l2_prio_check(vdev->prio, handle->vfh.prio); + if (ret < 0) + return ret; + memset(&xctrl, 0, sizeof xctrl); xctrl.id = ctrl->id; xctrl.value = ctrl->value; @@ -653,6 +670,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) } case VIDIOC_S_EXT_CTRLS: + ret = v4l2_prio_check(vdev->prio, handle->vfh.prio); + if (ret < 0) + return ret; + /* Fall through */ case VIDIOC_TRY_EXT_CTRLS: { struct v4l2_ext_controls *ctrls = arg; @@ -747,6 +768,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) { u32 input = *(u32 *)arg + 1; + ret = v4l2_prio_check(vdev->prio, handle->vfh.prio); + if (ret < 0) + return ret; + if ((ret = uvc_acquire_privileges(handle)) < 0) return ret; @@ -800,6 +825,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) } case VIDIOC_S_FMT: + ret = v4l2_prio_check(vdev->prio, handle->vfh.prio); + if (ret < 0) + return ret; + if ((ret = uvc_acquire_privileges(handle)) < 0) return ret; @@ -902,6 +931,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) return uvc_v4l2_get_streamparm(stream, arg); case VIDIOC_S_PARM: + ret = v4l2_prio_check(vdev->prio, handle->vfh.prio); + if (ret < 0) + return ret; + if ((ret = uvc_acquire_privileges(handle)) < 0) return ret; @@ -936,6 +969,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) /* Buffers & streaming */ case VIDIOC_REQBUFS: + ret = v4l2_prio_check(vdev->prio, handle->vfh.prio); + if (ret < 0) + return ret; + if ((ret = uvc_acquire_privileges(handle)) < 0) return ret; @@ -981,6 +1018,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) if (*type != stream->type) return -EINVAL; + ret = v4l2_prio_check(vdev->prio, handle->vfh.prio); + if (ret < 0) + return ret; + if (!uvc_has_privileges(handle)) return -EBUSY; @@ -999,6 +1040,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) if (*type != stream->type) return -EINVAL; + ret = v4l2_prio_check(vdev->prio, handle->vfh.prio); + if (ret < 0) + return ret; + if (!uvc_has_privileges(handle)) return -EBUSY; diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h index a6c561f631a..006ae274d22 100644 --- a/drivers/media/usb/uvc/uvcvideo.h +++ b/drivers/media/usb/uvc/uvcvideo.h @@ -372,6 +372,7 @@ struct uvc_video_chain { struct mutex ctrl_mutex; /* Protects ctrl.info */ + struct v4l2_prio_state prio; /* V4L2 priority state */ u32 caps; /* V4L2 chain-wide caps */ }; -- cgit v1.2.3