From patchwork Thu Sep 27 15:16:20 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 1514841 Return-Path: X-Original-To: patchwork-linux-media@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id 0BCB93FC71 for ; Thu, 27 Sep 2012 15:15:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754973Ab2I0PP4 (ORCPT ); Thu, 27 Sep 2012 11:15:56 -0400 Received: from perceval.ideasonboard.com ([95.142.166.194]:60155 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755035Ab2I0PPx (ORCPT ); Thu, 27 Sep 2012 11:15:53 -0400 Received: from avalon.ideasonboard.com (unknown [91.178.154.29]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id DA69935A8F; Thu, 27 Sep 2012 17:15:50 +0200 (CEST) From: Laurent Pinchart To: linux-media@vger.kernel.org Cc: Hans Verkuil Subject: [PATCH 6/6] uvcvideo: Add VIDIOC_[GS]_PRIORITY support Date: Thu, 27 Sep 2012 17:16:20 +0200 Message-Id: <1348758980-21683-7-git-send-email-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 1.7.8.6 In-Reply-To: <1348758980-21683-1-git-send-email-laurent.pinchart@ideasonboard.com> References: <1348758980-21683-1-git-send-email-laurent.pinchart@ideasonboard.com> Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Signed-off-by: Laurent Pinchart --- 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(+), 0 deletions(-) diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c index ae24f7d..22f14d2 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 bf9d073..d6aa402 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; + 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 28ff015..acf6bf2 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 */ };