Re: [PATCH] v4l2-ctrls: add v4l2_ctrl_request_hdl_find/put/ctrl_find functions
Hi, On Wed, 2018-07-04 at 17:38 +0200, Hans Verkuil wrote: > If a driver needs to find/inspect the controls set in a request then > it can use these functions. > > E.g. to check if a required control is set in a request use this in the > req_validate() implementation: > > int res = -EINVAL; > > hdl = v4l2_ctrl_request_hdl_find(req, parent_hdl); > if (hdl) { > if (v4l2_ctrl_request_hdl_ctrl_find(hdl, ctrl_id)) > res = 0; > v4l2_ctrl_request_hdl_put(hdl); > } > return res; Thanks again for pulling this off, that's definitely what I neeeded! I was able to test the patch and get it to work with sunxi-cedrus, with one modification highlighted below. Note that for my use case, I need to have access to the driver's private data (context) to get the parent hdl. I'm iterating over request objects and getting the context from a buffer object (checked via vb2_request_object_is_buffer), a bit like it's done in vb2_m2m_request_queue. > Signed-off-by: Hans Verkuil > --- > Paul, please test this. This should be what you need. > > Regards, > > Hans > --- > diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c > b/drivers/media/v4l2-core/v4l2-ctrls.c > index 3ff17c87b3c8..03fd140736fd 100644 > --- a/drivers/media/v4l2-core/v4l2-ctrls.c > +++ b/drivers/media/v4l2-core/v4l2-ctrls.c > @@ -2976,6 +2976,31 @@ static const struct media_request_object_ops req_ops = > { > .release = v4l2_ctrl_request_release, > }; > > +struct v4l2_ctrl_handler *v4l2_ctrl_request_hdl_find(struct media_request > *req, > + struct v4l2_ctrl_handler *parent) > +{ > + struct media_request_object *obj; > + > + if (WARN_ON(req->state != MEDIA_REQUEST_STATE_VALIDATING && > + req->state != MEDIA_REQUEST_STATE_QUEUED)) > + return NULL; > + > + obj = media_request_object_find(req, _ops, parent); > + if (obj) > + return container_of(obj, struct v4l2_ctrl_handler, req_obj); > + return NULL; > +} > +EXPORT_SYMBOL_GPL(v4l2_ctrl_request_hdl_find); > + > +struct v4l2_ctrl * > +v4l2_ctrl_request_hdl_ctrl_find(struct v4l2_ctrl_handler *hdl, u32 id) > +{ > + struct v4l2_ctrl_ref *ref = find_ref_lock(hdl, id); > + > + return (ref && ref->req == ref) ? ref : NULL; When req && ref->req == ref, ref->ctrl should be returned instead of ref. Cheers, Paul -- Paul Kocialkowski, Bootlin (formerly Free Electrons) Embedded Linux and kernel engineering https://bootlin.com signature.asc Description: This is a digitally signed message part
[PATCH] v4l2-ctrls: add v4l2_ctrl_request_hdl_find/put/ctrl_find functions
If a driver needs to find/inspect the controls set in a request then it can use these functions. E.g. to check if a required control is set in a request use this in the req_validate() implementation: int res = -EINVAL; hdl = v4l2_ctrl_request_hdl_find(req, parent_hdl); if (hdl) { if (v4l2_ctrl_request_hdl_ctrl_find(hdl, ctrl_id)) res = 0; v4l2_ctrl_request_hdl_put(hdl); } return res; Signed-off-by: Hans Verkuil --- Paul, please test this. This should be what you need. Regards, Hans --- diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c index 3ff17c87b3c8..03fd140736fd 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls.c +++ b/drivers/media/v4l2-core/v4l2-ctrls.c @@ -2976,6 +2976,31 @@ static const struct media_request_object_ops req_ops = { .release = v4l2_ctrl_request_release, }; +struct v4l2_ctrl_handler *v4l2_ctrl_request_hdl_find(struct media_request *req, + struct v4l2_ctrl_handler *parent) +{ + struct media_request_object *obj; + + if (WARN_ON(req->state != MEDIA_REQUEST_STATE_VALIDATING && + req->state != MEDIA_REQUEST_STATE_QUEUED)) + return NULL; + + obj = media_request_object_find(req, _ops, parent); + if (obj) + return container_of(obj, struct v4l2_ctrl_handler, req_obj); + return NULL; +} +EXPORT_SYMBOL_GPL(v4l2_ctrl_request_hdl_find); + +struct v4l2_ctrl * +v4l2_ctrl_request_hdl_ctrl_find(struct v4l2_ctrl_handler *hdl, u32 id) +{ + struct v4l2_ctrl_ref *ref = find_ref_lock(hdl, id); + + return (ref && ref->req == ref) ? ref : NULL; +} +EXPORT_SYMBOL_GPL(v4l2_ctrl_request_hdl_ctrl_find); + static int v4l2_ctrl_request_bind(struct media_request *req, struct v4l2_ctrl_handler *hdl, struct v4l2_ctrl_handler *from) diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h index de70cc3a1b80..34ee3167d7dd 100644 --- a/include/media/v4l2-ctrls.h +++ b/include/media/v4l2-ctrls.h @@ -,7 +,49 @@ void v4l2_ctrl_request_setup(struct media_request *req, * request object. */ void v4l2_ctrl_request_complete(struct media_request *req, - struct v4l2_ctrl_handler *hdl); + struct v4l2_ctrl_handler *parent); + +/** + * v4l2_ctrl_request_hdl_find - Find the control handler in the request + * + * @req: The request + * @parent: The parent control handler ('priv' in media_request_object_find()) + * + * This function finds the control handler in the request. It may return + * NULL if not found. When done, you must call v4l2_ctrl_request_put_hdl() + * with the returned handler pointer. + * + * If the request is not in state VALIDATING or QUEUED, then this function + * will always return NULL. + */ +struct v4l2_ctrl_handler *v4l2_ctrl_request_hdl_find(struct media_request *req, + struct v4l2_ctrl_handler *parent); + +/** + * v4l2_ctrl_request_hdl_put - Put the control handler + * + * @hdl: Put this control handler + * + * This function released the control handler previously obtained from' + * v4l2_ctrl_request_hdl_find(). + */ +static inline void v4l2_ctrl_request_hdl_put(struct v4l2_ctrl_handler *hdl) +{ + if (hdl) + media_request_object_put(>req_obj); +} + +/** + * v4l2_ctrl_request_ctrl_find() - Find a control with the given ID. + * + * @hdl: The control handler from the request. + * @id: The ID of the control to find. + * + * This function returns a pointer to the control if this control is + * part of the request or NULL otherwise. + */ +struct v4l2_ctrl * +v4l2_ctrl_request_hdl_ctrl_find(struct v4l2_ctrl_handler *hdl, u32 id); /* Helpers for ioctl_ops */