Re: [PATCHv18 15/35] v4l2-ctrls: support g/s_ext_ctrls for requests

2018-08-14 Thread Mauro Carvalho Chehab
Em Tue, 14 Aug 2018 16:20:27 +0200
Hans Verkuil  escreveu:

> From: Hans Verkuil 
> 
> The v4l2_g/s_ext_ctrls functions now support control handlers that
> represent requests.
> 
> The v4l2_ctrls_find_req_obj() function is responsible for finding the
> request from the fd.
> 
> Signed-off-by: Hans Verkuil 
Reviewed-by: Mauro Carvalho Chehab 


> ---
>  drivers/media/platform/omap3isp/ispvideo.c |   2 +-
>  drivers/media/v4l2-core/v4l2-ctrls.c   | 138 +++--
>  drivers/media/v4l2-core/v4l2-ioctl.c   |  12 +-
>  drivers/media/v4l2-core/v4l2-subdev.c  |   9 +-
>  include/media/v4l2-ctrls.h |   7 +-
>  5 files changed, 149 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/media/platform/omap3isp/ispvideo.c 
> b/drivers/media/platform/omap3isp/ispvideo.c
> index 9d228eac24ea..674e7fd3ad99 100644
> --- a/drivers/media/platform/omap3isp/ispvideo.c
> +++ b/drivers/media/platform/omap3isp/ispvideo.c
> @@ -1028,7 +1028,7 @@ static int isp_video_check_external_subdevs(struct 
> isp_video *video,
>   ctrls.count = 1;
>   ctrls.controls = &ctrl;
>  
> - ret = v4l2_g_ext_ctrls(pipe->external->ctrl_handler, &ctrls);
> + ret = v4l2_g_ext_ctrls(pipe->external->ctrl_handler, NULL, &ctrls);
>   if (ret < 0) {
>   dev_warn(isp->dev, "no pixel rate control in subdev %s\n",
>pipe->external->name);
> diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c 
> b/drivers/media/v4l2-core/v4l2-ctrls.c
> index 89e7bfee108f..6d34d7a6f235 100644
> --- a/drivers/media/v4l2-core/v4l2-ctrls.c
> +++ b/drivers/media/v4l2-core/v4l2-ctrls.c
> @@ -3140,7 +3140,8 @@ static int class_check(struct v4l2_ctrl_handler *hdl, 
> u32 which)
>  }
>  
>  /* Get extended controls. Allocates the helpers array if needed. */
> -int v4l2_g_ext_ctrls(struct v4l2_ctrl_handler *hdl, struct v4l2_ext_controls 
> *cs)
> +static int v4l2_g_ext_ctrls_common(struct v4l2_ctrl_handler *hdl,
> +struct v4l2_ext_controls *cs)
>  {
>   struct v4l2_ctrl_helper helper[4];
>   struct v4l2_ctrl_helper *helpers = helper;
> @@ -3220,6 +3221,83 @@ int v4l2_g_ext_ctrls(struct v4l2_ctrl_handler *hdl, 
> struct v4l2_ext_controls *cs
>   kvfree(helpers);
>   return ret;
>  }
> +
> +static struct media_request_object *
> +v4l2_ctrls_find_req_obj(struct v4l2_ctrl_handler *hdl,
> + struct media_request *req, bool set)
> +{
> + struct media_request_object *obj;
> + struct v4l2_ctrl_handler *new_hdl;
> + int ret;
> +
> + if (IS_ERR(req))
> + return ERR_CAST(req);
> +
> + if (set && WARN_ON(req->state != MEDIA_REQUEST_STATE_UPDATING))
> + return ERR_PTR(-EBUSY);
> +
> + obj = media_request_object_find(req, &req_ops, hdl);
> + if (obj)
> + return obj;
> + if (!set)
> + return ERR_PTR(-ENOENT);
> +
> + new_hdl = kzalloc(sizeof(*new_hdl), GFP_KERNEL);
> + if (!new_hdl)
> + return ERR_PTR(-ENOMEM);
> +
> + obj = &new_hdl->req_obj;
> + ret = v4l2_ctrl_handler_init(new_hdl, (hdl->nr_of_buckets - 1) * 8);
> + if (!ret)
> + ret = v4l2_ctrl_request_bind(req, new_hdl, hdl);
> + if (ret) {
> + kfree(new_hdl);
> +
> + return ERR_PTR(ret);
> + }
> +
> + media_request_object_get(obj);
> + return obj;
> +}
> +
> +int v4l2_g_ext_ctrls(struct v4l2_ctrl_handler *hdl, struct media_device 
> *mdev,
> +  struct v4l2_ext_controls *cs)
> +{
> + struct media_request_object *obj = NULL;
> + int ret;
> +
> + if (cs->which == V4L2_CTRL_WHICH_REQUEST_VAL) {
> + struct media_request *req;
> +
> + if (!mdev || cs->request_fd < 0)
> + return -EINVAL;
> +
> + req = media_request_get_by_fd(mdev, cs->request_fd);
> + if (IS_ERR(req))
> + return PTR_ERR(req);
> +
> + if (req->state != MEDIA_REQUEST_STATE_IDLE &&
> + req->state != MEDIA_REQUEST_STATE_COMPLETE) {
> + media_request_put(req);
> + return -EBUSY;
> + }
> +
> + obj = v4l2_ctrls_find_req_obj(hdl, req, false);
> + /* Reference to the request held through obj */
> + media_request_put(req);
> + if (IS_ERR(obj))
> + return PTR_ERR(obj);
> +
> + hdl = container_of(obj, struct v4l2_ctrl_handler,
> +req_obj);
> + }
> +
> + ret = v4l2_g_ext_ctrls_common(hdl, cs);
> +
> + if (obj)
> + media_request_object_put(obj);
> + return ret;
> +}
>  EXPORT_SYMBOL(v4l2_g_ext_ctrls);
>  
>  /* Helper function to get a single control */
> @@ -3408,9 +3486,9 @@ static void update_from_auto_cluster(struct v4l2_ctrl 
> *master)
>  }
>  
>  /* Try or try-and-set controls */
> -static int try_set_ext_ctrls(struct v4l2_fh *fh, struc

[PATCHv18 15/35] v4l2-ctrls: support g/s_ext_ctrls for requests

2018-08-14 Thread Hans Verkuil
From: Hans Verkuil 

The v4l2_g/s_ext_ctrls functions now support control handlers that
represent requests.

The v4l2_ctrls_find_req_obj() function is responsible for finding the
request from the fd.

Signed-off-by: Hans Verkuil 
---
 drivers/media/platform/omap3isp/ispvideo.c |   2 +-
 drivers/media/v4l2-core/v4l2-ctrls.c   | 138 +++--
 drivers/media/v4l2-core/v4l2-ioctl.c   |  12 +-
 drivers/media/v4l2-core/v4l2-subdev.c  |   9 +-
 include/media/v4l2-ctrls.h |   7 +-
 5 files changed, 149 insertions(+), 19 deletions(-)

diff --git a/drivers/media/platform/omap3isp/ispvideo.c 
b/drivers/media/platform/omap3isp/ispvideo.c
index 9d228eac24ea..674e7fd3ad99 100644
--- a/drivers/media/platform/omap3isp/ispvideo.c
+++ b/drivers/media/platform/omap3isp/ispvideo.c
@@ -1028,7 +1028,7 @@ static int isp_video_check_external_subdevs(struct 
isp_video *video,
ctrls.count = 1;
ctrls.controls = &ctrl;
 
-   ret = v4l2_g_ext_ctrls(pipe->external->ctrl_handler, &ctrls);
+   ret = v4l2_g_ext_ctrls(pipe->external->ctrl_handler, NULL, &ctrls);
if (ret < 0) {
dev_warn(isp->dev, "no pixel rate control in subdev %s\n",
 pipe->external->name);
diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c 
b/drivers/media/v4l2-core/v4l2-ctrls.c
index 89e7bfee108f..6d34d7a6f235 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
@@ -3140,7 +3140,8 @@ static int class_check(struct v4l2_ctrl_handler *hdl, u32 
which)
 }
 
 /* Get extended controls. Allocates the helpers array if needed. */
-int v4l2_g_ext_ctrls(struct v4l2_ctrl_handler *hdl, struct v4l2_ext_controls 
*cs)
+static int v4l2_g_ext_ctrls_common(struct v4l2_ctrl_handler *hdl,
+  struct v4l2_ext_controls *cs)
 {
struct v4l2_ctrl_helper helper[4];
struct v4l2_ctrl_helper *helpers = helper;
@@ -3220,6 +3221,83 @@ int v4l2_g_ext_ctrls(struct v4l2_ctrl_handler *hdl, 
struct v4l2_ext_controls *cs
kvfree(helpers);
return ret;
 }
+
+static struct media_request_object *
+v4l2_ctrls_find_req_obj(struct v4l2_ctrl_handler *hdl,
+   struct media_request *req, bool set)
+{
+   struct media_request_object *obj;
+   struct v4l2_ctrl_handler *new_hdl;
+   int ret;
+
+   if (IS_ERR(req))
+   return ERR_CAST(req);
+
+   if (set && WARN_ON(req->state != MEDIA_REQUEST_STATE_UPDATING))
+   return ERR_PTR(-EBUSY);
+
+   obj = media_request_object_find(req, &req_ops, hdl);
+   if (obj)
+   return obj;
+   if (!set)
+   return ERR_PTR(-ENOENT);
+
+   new_hdl = kzalloc(sizeof(*new_hdl), GFP_KERNEL);
+   if (!new_hdl)
+   return ERR_PTR(-ENOMEM);
+
+   obj = &new_hdl->req_obj;
+   ret = v4l2_ctrl_handler_init(new_hdl, (hdl->nr_of_buckets - 1) * 8);
+   if (!ret)
+   ret = v4l2_ctrl_request_bind(req, new_hdl, hdl);
+   if (ret) {
+   kfree(new_hdl);
+
+   return ERR_PTR(ret);
+   }
+
+   media_request_object_get(obj);
+   return obj;
+}
+
+int v4l2_g_ext_ctrls(struct v4l2_ctrl_handler *hdl, struct media_device *mdev,
+struct v4l2_ext_controls *cs)
+{
+   struct media_request_object *obj = NULL;
+   int ret;
+
+   if (cs->which == V4L2_CTRL_WHICH_REQUEST_VAL) {
+   struct media_request *req;
+
+   if (!mdev || cs->request_fd < 0)
+   return -EINVAL;
+
+   req = media_request_get_by_fd(mdev, cs->request_fd);
+   if (IS_ERR(req))
+   return PTR_ERR(req);
+
+   if (req->state != MEDIA_REQUEST_STATE_IDLE &&
+   req->state != MEDIA_REQUEST_STATE_COMPLETE) {
+   media_request_put(req);
+   return -EBUSY;
+   }
+
+   obj = v4l2_ctrls_find_req_obj(hdl, req, false);
+   /* Reference to the request held through obj */
+   media_request_put(req);
+   if (IS_ERR(obj))
+   return PTR_ERR(obj);
+
+   hdl = container_of(obj, struct v4l2_ctrl_handler,
+  req_obj);
+   }
+
+   ret = v4l2_g_ext_ctrls_common(hdl, cs);
+
+   if (obj)
+   media_request_object_put(obj);
+   return ret;
+}
 EXPORT_SYMBOL(v4l2_g_ext_ctrls);
 
 /* Helper function to get a single control */
@@ -3408,9 +3486,9 @@ static void update_from_auto_cluster(struct v4l2_ctrl 
*master)
 }
 
 /* Try or try-and-set controls */
-static int try_set_ext_ctrls(struct v4l2_fh *fh, struct v4l2_ctrl_handler *hdl,
-struct v4l2_ext_controls *cs,
-bool set)
+static int try_set_ext_ctrls_common(struct v4l2_fh *fh,
+   struct v4l2_ctrl_handler *hdl,
+