Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * V4L2 controls framework Request API implementation.
0004  *
0005  * Copyright (C) 2018-2021  Hans Verkuil <hverkuil-cisco@xs4all.nl>
0006  */
0007 
0008 #define pr_fmt(fmt) "v4l2-ctrls: " fmt
0009 
0010 #include <linux/export.h>
0011 #include <linux/slab.h>
0012 #include <media/v4l2-ctrls.h>
0013 #include <media/v4l2-dev.h>
0014 #include <media/v4l2-ioctl.h>
0015 
0016 #include "v4l2-ctrls-priv.h"
0017 
0018 /* Initialize the request-related fields in a control handler */
0019 void v4l2_ctrl_handler_init_request(struct v4l2_ctrl_handler *hdl)
0020 {
0021     INIT_LIST_HEAD(&hdl->requests);
0022     INIT_LIST_HEAD(&hdl->requests_queued);
0023     hdl->request_is_queued = false;
0024     media_request_object_init(&hdl->req_obj);
0025 }
0026 
0027 /* Free the request-related fields in a control handler */
0028 void v4l2_ctrl_handler_free_request(struct v4l2_ctrl_handler *hdl)
0029 {
0030     struct v4l2_ctrl_handler *req, *next_req;
0031 
0032     /*
0033      * Do nothing if this isn't the main handler or the main
0034      * handler is not used in any request.
0035      *
0036      * The main handler can be identified by having a NULL ops pointer in
0037      * the request object.
0038      */
0039     if (hdl->req_obj.ops || list_empty(&hdl->requests))
0040         return;
0041 
0042     /*
0043      * If the main handler is freed and it is used by handler objects in
0044      * outstanding requests, then unbind and put those objects before
0045      * freeing the main handler.
0046      */
0047     list_for_each_entry_safe(req, next_req, &hdl->requests, requests) {
0048         media_request_object_unbind(&req->req_obj);
0049         media_request_object_put(&req->req_obj);
0050     }
0051 }
0052 
0053 static int v4l2_ctrl_request_clone(struct v4l2_ctrl_handler *hdl,
0054                    const struct v4l2_ctrl_handler *from)
0055 {
0056     struct v4l2_ctrl_ref *ref;
0057     int err = 0;
0058 
0059     if (WARN_ON(!hdl || hdl == from))
0060         return -EINVAL;
0061 
0062     if (hdl->error)
0063         return hdl->error;
0064 
0065     WARN_ON(hdl->lock != &hdl->_lock);
0066 
0067     mutex_lock(from->lock);
0068     list_for_each_entry(ref, &from->ctrl_refs, node) {
0069         struct v4l2_ctrl *ctrl = ref->ctrl;
0070         struct v4l2_ctrl_ref *new_ref;
0071 
0072         /* Skip refs inherited from other devices */
0073         if (ref->from_other_dev)
0074             continue;
0075         err = handler_new_ref(hdl, ctrl, &new_ref, false, true);
0076         if (err)
0077             break;
0078     }
0079     mutex_unlock(from->lock);
0080     return err;
0081 }
0082 
0083 static void v4l2_ctrl_request_queue(struct media_request_object *obj)
0084 {
0085     struct v4l2_ctrl_handler *hdl =
0086         container_of(obj, struct v4l2_ctrl_handler, req_obj);
0087     struct v4l2_ctrl_handler *main_hdl = obj->priv;
0088 
0089     mutex_lock(main_hdl->lock);
0090     list_add_tail(&hdl->requests_queued, &main_hdl->requests_queued);
0091     hdl->request_is_queued = true;
0092     mutex_unlock(main_hdl->lock);
0093 }
0094 
0095 static void v4l2_ctrl_request_unbind(struct media_request_object *obj)
0096 {
0097     struct v4l2_ctrl_handler *hdl =
0098         container_of(obj, struct v4l2_ctrl_handler, req_obj);
0099     struct v4l2_ctrl_handler *main_hdl = obj->priv;
0100 
0101     mutex_lock(main_hdl->lock);
0102     list_del_init(&hdl->requests);
0103     if (hdl->request_is_queued) {
0104         list_del_init(&hdl->requests_queued);
0105         hdl->request_is_queued = false;
0106     }
0107     mutex_unlock(main_hdl->lock);
0108 }
0109 
0110 static void v4l2_ctrl_request_release(struct media_request_object *obj)
0111 {
0112     struct v4l2_ctrl_handler *hdl =
0113         container_of(obj, struct v4l2_ctrl_handler, req_obj);
0114 
0115     v4l2_ctrl_handler_free(hdl);
0116     kfree(hdl);
0117 }
0118 
0119 static const struct media_request_object_ops req_ops = {
0120     .queue = v4l2_ctrl_request_queue,
0121     .unbind = v4l2_ctrl_request_unbind,
0122     .release = v4l2_ctrl_request_release,
0123 };
0124 
0125 struct v4l2_ctrl_handler *v4l2_ctrl_request_hdl_find(struct media_request *req,
0126                              struct v4l2_ctrl_handler *parent)
0127 {
0128     struct media_request_object *obj;
0129 
0130     if (WARN_ON(req->state != MEDIA_REQUEST_STATE_VALIDATING &&
0131             req->state != MEDIA_REQUEST_STATE_QUEUED))
0132         return NULL;
0133 
0134     obj = media_request_object_find(req, &req_ops, parent);
0135     if (obj)
0136         return container_of(obj, struct v4l2_ctrl_handler, req_obj);
0137     return NULL;
0138 }
0139 EXPORT_SYMBOL_GPL(v4l2_ctrl_request_hdl_find);
0140 
0141 struct v4l2_ctrl *
0142 v4l2_ctrl_request_hdl_ctrl_find(struct v4l2_ctrl_handler *hdl, u32 id)
0143 {
0144     struct v4l2_ctrl_ref *ref = find_ref_lock(hdl, id);
0145 
0146     return (ref && ref->p_req_valid) ? ref->ctrl : NULL;
0147 }
0148 EXPORT_SYMBOL_GPL(v4l2_ctrl_request_hdl_ctrl_find);
0149 
0150 static int v4l2_ctrl_request_bind(struct media_request *req,
0151                   struct v4l2_ctrl_handler *hdl,
0152                   struct v4l2_ctrl_handler *from)
0153 {
0154     int ret;
0155 
0156     ret = v4l2_ctrl_request_clone(hdl, from);
0157 
0158     if (!ret) {
0159         ret = media_request_object_bind(req, &req_ops,
0160                         from, false, &hdl->req_obj);
0161         if (!ret) {
0162             mutex_lock(from->lock);
0163             list_add_tail(&hdl->requests, &from->requests);
0164             mutex_unlock(from->lock);
0165         }
0166     }
0167     return ret;
0168 }
0169 
0170 static struct media_request_object *
0171 v4l2_ctrls_find_req_obj(struct v4l2_ctrl_handler *hdl,
0172             struct media_request *req, bool set)
0173 {
0174     struct media_request_object *obj;
0175     struct v4l2_ctrl_handler *new_hdl;
0176     int ret;
0177 
0178     if (IS_ERR(req))
0179         return ERR_CAST(req);
0180 
0181     if (set && WARN_ON(req->state != MEDIA_REQUEST_STATE_UPDATING))
0182         return ERR_PTR(-EBUSY);
0183 
0184     obj = media_request_object_find(req, &req_ops, hdl);
0185     if (obj)
0186         return obj;
0187     /*
0188      * If there are no controls in this completed request,
0189      * then that can only happen if:
0190      *
0191      * 1) no controls were present in the queued request, and
0192      * 2) v4l2_ctrl_request_complete() could not allocate a
0193      *    control handler object to store the completed state in.
0194      *
0195      * So return ENOMEM to indicate that there was an out-of-memory
0196      * error.
0197      */
0198     if (!set)
0199         return ERR_PTR(-ENOMEM);
0200 
0201     new_hdl = kzalloc(sizeof(*new_hdl), GFP_KERNEL);
0202     if (!new_hdl)
0203         return ERR_PTR(-ENOMEM);
0204 
0205     obj = &new_hdl->req_obj;
0206     ret = v4l2_ctrl_handler_init(new_hdl, (hdl->nr_of_buckets - 1) * 8);
0207     if (!ret)
0208         ret = v4l2_ctrl_request_bind(req, new_hdl, hdl);
0209     if (ret) {
0210         v4l2_ctrl_handler_free(new_hdl);
0211         kfree(new_hdl);
0212         return ERR_PTR(ret);
0213     }
0214 
0215     media_request_object_get(obj);
0216     return obj;
0217 }
0218 
0219 int v4l2_g_ext_ctrls_request(struct v4l2_ctrl_handler *hdl, struct video_device *vdev,
0220                  struct media_device *mdev, struct v4l2_ext_controls *cs)
0221 {
0222     struct media_request_object *obj = NULL;
0223     struct media_request *req = NULL;
0224     int ret;
0225 
0226     if (!mdev || cs->request_fd < 0)
0227         return -EINVAL;
0228 
0229     req = media_request_get_by_fd(mdev, cs->request_fd);
0230     if (IS_ERR(req))
0231         return PTR_ERR(req);
0232 
0233     if (req->state != MEDIA_REQUEST_STATE_COMPLETE) {
0234         media_request_put(req);
0235         return -EACCES;
0236     }
0237 
0238     ret = media_request_lock_for_access(req);
0239     if (ret) {
0240         media_request_put(req);
0241         return ret;
0242     }
0243 
0244     obj = v4l2_ctrls_find_req_obj(hdl, req, false);
0245     if (IS_ERR(obj)) {
0246         media_request_unlock_for_access(req);
0247         media_request_put(req);
0248         return PTR_ERR(obj);
0249     }
0250 
0251     hdl = container_of(obj, struct v4l2_ctrl_handler,
0252                req_obj);
0253     ret = v4l2_g_ext_ctrls_common(hdl, cs, vdev);
0254 
0255     media_request_unlock_for_access(req);
0256     media_request_object_put(obj);
0257     media_request_put(req);
0258     return ret;
0259 }
0260 
0261 int try_set_ext_ctrls_request(struct v4l2_fh *fh,
0262                   struct v4l2_ctrl_handler *hdl,
0263                   struct video_device *vdev,
0264                   struct media_device *mdev,
0265                   struct v4l2_ext_controls *cs, bool set)
0266 {
0267     struct media_request_object *obj = NULL;
0268     struct media_request *req = NULL;
0269     int ret;
0270 
0271     if (!mdev) {
0272         dprintk(vdev, "%s: missing media device\n",
0273             video_device_node_name(vdev));
0274         return -EINVAL;
0275     }
0276 
0277     if (cs->request_fd < 0) {
0278         dprintk(vdev, "%s: invalid request fd %d\n",
0279             video_device_node_name(vdev), cs->request_fd);
0280         return -EINVAL;
0281     }
0282 
0283     req = media_request_get_by_fd(mdev, cs->request_fd);
0284     if (IS_ERR(req)) {
0285         dprintk(vdev, "%s: cannot find request fd %d\n",
0286             video_device_node_name(vdev), cs->request_fd);
0287         return PTR_ERR(req);
0288     }
0289 
0290     ret = media_request_lock_for_update(req);
0291     if (ret) {
0292         dprintk(vdev, "%s: cannot lock request fd %d\n",
0293             video_device_node_name(vdev), cs->request_fd);
0294         media_request_put(req);
0295         return ret;
0296     }
0297 
0298     obj = v4l2_ctrls_find_req_obj(hdl, req, set);
0299     if (IS_ERR(obj)) {
0300         dprintk(vdev,
0301             "%s: cannot find request object for request fd %d\n",
0302             video_device_node_name(vdev),
0303             cs->request_fd);
0304         media_request_unlock_for_update(req);
0305         media_request_put(req);
0306         return PTR_ERR(obj);
0307     }
0308 
0309     hdl = container_of(obj, struct v4l2_ctrl_handler,
0310                req_obj);
0311     ret = try_set_ext_ctrls_common(fh, hdl, cs, vdev, set);
0312     if (ret)
0313         dprintk(vdev,
0314             "%s: try_set_ext_ctrls_common failed (%d)\n",
0315             video_device_node_name(vdev), ret);
0316 
0317     media_request_unlock_for_update(req);
0318     media_request_object_put(obj);
0319     media_request_put(req);
0320 
0321     return ret;
0322 }
0323 
0324 void v4l2_ctrl_request_complete(struct media_request *req,
0325                 struct v4l2_ctrl_handler *main_hdl)
0326 {
0327     struct media_request_object *obj;
0328     struct v4l2_ctrl_handler *hdl;
0329     struct v4l2_ctrl_ref *ref;
0330 
0331     if (!req || !main_hdl)
0332         return;
0333 
0334     /*
0335      * Note that it is valid if nothing was found. It means
0336      * that this request doesn't have any controls and so just
0337      * wants to leave the controls unchanged.
0338      */
0339     obj = media_request_object_find(req, &req_ops, main_hdl);
0340     if (!obj) {
0341         int ret;
0342 
0343         /* Create a new request so the driver can return controls */
0344         hdl = kzalloc(sizeof(*hdl), GFP_KERNEL);
0345         if (!hdl)
0346             return;
0347 
0348         ret = v4l2_ctrl_handler_init(hdl, (main_hdl->nr_of_buckets - 1) * 8);
0349         if (!ret)
0350             ret = v4l2_ctrl_request_bind(req, hdl, main_hdl);
0351         if (ret) {
0352             v4l2_ctrl_handler_free(hdl);
0353             kfree(hdl);
0354             return;
0355         }
0356         hdl->request_is_queued = true;
0357         obj = media_request_object_find(req, &req_ops, main_hdl);
0358     }
0359     hdl = container_of(obj, struct v4l2_ctrl_handler, req_obj);
0360 
0361     list_for_each_entry(ref, &hdl->ctrl_refs, node) {
0362         struct v4l2_ctrl *ctrl = ref->ctrl;
0363         struct v4l2_ctrl *master = ctrl->cluster[0];
0364         unsigned int i;
0365 
0366         if (ctrl->flags & V4L2_CTRL_FLAG_VOLATILE) {
0367             v4l2_ctrl_lock(master);
0368             /* g_volatile_ctrl will update the current control values */
0369             for (i = 0; i < master->ncontrols; i++)
0370                 cur_to_new(master->cluster[i]);
0371             call_op(master, g_volatile_ctrl);
0372             new_to_req(ref);
0373             v4l2_ctrl_unlock(master);
0374             continue;
0375         }
0376         if (ref->p_req_valid)
0377             continue;
0378 
0379         /* Copy the current control value into the request */
0380         v4l2_ctrl_lock(ctrl);
0381         cur_to_req(ref);
0382         v4l2_ctrl_unlock(ctrl);
0383     }
0384 
0385     mutex_lock(main_hdl->lock);
0386     WARN_ON(!hdl->request_is_queued);
0387     list_del_init(&hdl->requests_queued);
0388     hdl->request_is_queued = false;
0389     mutex_unlock(main_hdl->lock);
0390     media_request_object_complete(obj);
0391     media_request_object_put(obj);
0392 }
0393 EXPORT_SYMBOL(v4l2_ctrl_request_complete);
0394 
0395 int v4l2_ctrl_request_setup(struct media_request *req,
0396                 struct v4l2_ctrl_handler *main_hdl)
0397 {
0398     struct media_request_object *obj;
0399     struct v4l2_ctrl_handler *hdl;
0400     struct v4l2_ctrl_ref *ref;
0401     int ret = 0;
0402 
0403     if (!req || !main_hdl)
0404         return 0;
0405 
0406     if (WARN_ON(req->state != MEDIA_REQUEST_STATE_QUEUED))
0407         return -EBUSY;
0408 
0409     /*
0410      * Note that it is valid if nothing was found. It means
0411      * that this request doesn't have any controls and so just
0412      * wants to leave the controls unchanged.
0413      */
0414     obj = media_request_object_find(req, &req_ops, main_hdl);
0415     if (!obj)
0416         return 0;
0417     if (obj->completed) {
0418         media_request_object_put(obj);
0419         return -EBUSY;
0420     }
0421     hdl = container_of(obj, struct v4l2_ctrl_handler, req_obj);
0422 
0423     list_for_each_entry(ref, &hdl->ctrl_refs, node)
0424         ref->req_done = false;
0425 
0426     list_for_each_entry(ref, &hdl->ctrl_refs, node) {
0427         struct v4l2_ctrl *ctrl = ref->ctrl;
0428         struct v4l2_ctrl *master = ctrl->cluster[0];
0429         bool have_new_data = false;
0430         int i;
0431 
0432         /*
0433          * Skip if this control was already handled by a cluster.
0434          * Skip button controls and read-only controls.
0435          */
0436         if (ref->req_done || (ctrl->flags & V4L2_CTRL_FLAG_READ_ONLY))
0437             continue;
0438 
0439         v4l2_ctrl_lock(master);
0440         for (i = 0; i < master->ncontrols; i++) {
0441             if (master->cluster[i]) {
0442                 struct v4l2_ctrl_ref *r =
0443                     find_ref(hdl, master->cluster[i]->id);
0444 
0445                 if (r->p_req_valid) {
0446                     have_new_data = true;
0447                     break;
0448                 }
0449             }
0450         }
0451         if (!have_new_data) {
0452             v4l2_ctrl_unlock(master);
0453             continue;
0454         }
0455 
0456         for (i = 0; i < master->ncontrols; i++) {
0457             if (master->cluster[i]) {
0458                 struct v4l2_ctrl_ref *r =
0459                     find_ref(hdl, master->cluster[i]->id);
0460 
0461                 ret = req_to_new(r);
0462                 if (ret) {
0463                     v4l2_ctrl_unlock(master);
0464                     goto error;
0465                 }
0466                 master->cluster[i]->is_new = 1;
0467                 r->req_done = true;
0468             }
0469         }
0470         /*
0471          * For volatile autoclusters that are currently in auto mode
0472          * we need to discover if it will be set to manual mode.
0473          * If so, then we have to copy the current volatile values
0474          * first since those will become the new manual values (which
0475          * may be overwritten by explicit new values from this set
0476          * of controls).
0477          */
0478         if (master->is_auto && master->has_volatiles &&
0479             !is_cur_manual(master)) {
0480             s32 new_auto_val = *master->p_new.p_s32;
0481 
0482             /*
0483              * If the new value == the manual value, then copy
0484              * the current volatile values.
0485              */
0486             if (new_auto_val == master->manual_mode_value)
0487                 update_from_auto_cluster(master);
0488         }
0489 
0490         ret = try_or_set_cluster(NULL, master, true, 0);
0491         v4l2_ctrl_unlock(master);
0492 
0493         if (ret)
0494             break;
0495     }
0496 
0497 error:
0498     media_request_object_put(obj);
0499     return ret;
0500 }
0501 EXPORT_SYMBOL(v4l2_ctrl_request_setup);