[media] uvcvideo: Add VIDIOC_[GS]_PRIORITY support
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Tue, 28 Aug 2012 23:29:56 +0000 (20:29 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Wed, 28 Nov 2012 12:29:07 +0000 (10:29 -0200)
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/usb/uvc/uvc_driver.c
drivers/media/usb/uvc/uvc_v4l2.c
drivers/media/usb/uvc/uvcvideo.h

index ae24f7d70b036e3315a5cfd614558995419f2f9c..22f14d286fbbe625384334516febbab4e077c996 100644 (file)
@@ -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);
index bf9d07393139c1e80ee314f41b59fa9e8f3d3fcf..8e056046bc203c4224dd08fa931f56219bdd6157 100644 (file)
@@ -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;
 
index a6c561f631a0ab772ed8e4932be8b7f6f8a6d304..006ae274d22ef14155c98c11bf8ac2a335cb2024 100644 (file)
@@ -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 */
 };