v4l2-ctrls-request.c (12731B)
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * V4L2 controls framework Request API implementation. 4 * 5 * Copyright (C) 2018-2021 Hans Verkuil <hverkuil-cisco@xs4all.nl> 6 */ 7 8#define pr_fmt(fmt) "v4l2-ctrls: " fmt 9 10#include <linux/export.h> 11#include <linux/slab.h> 12#include <media/v4l2-ctrls.h> 13#include <media/v4l2-dev.h> 14#include <media/v4l2-ioctl.h> 15 16#include "v4l2-ctrls-priv.h" 17 18/* Initialize the request-related fields in a control handler */ 19void v4l2_ctrl_handler_init_request(struct v4l2_ctrl_handler *hdl) 20{ 21 INIT_LIST_HEAD(&hdl->requests); 22 INIT_LIST_HEAD(&hdl->requests_queued); 23 hdl->request_is_queued = false; 24 media_request_object_init(&hdl->req_obj); 25} 26 27/* Free the request-related fields in a control handler */ 28void v4l2_ctrl_handler_free_request(struct v4l2_ctrl_handler *hdl) 29{ 30 struct v4l2_ctrl_handler *req, *next_req; 31 32 /* 33 * Do nothing if this isn't the main handler or the main 34 * handler is not used in any request. 35 * 36 * The main handler can be identified by having a NULL ops pointer in 37 * the request object. 38 */ 39 if (hdl->req_obj.ops || list_empty(&hdl->requests)) 40 return; 41 42 /* 43 * If the main handler is freed and it is used by handler objects in 44 * outstanding requests, then unbind and put those objects before 45 * freeing the main handler. 46 */ 47 list_for_each_entry_safe(req, next_req, &hdl->requests, requests) { 48 media_request_object_unbind(&req->req_obj); 49 media_request_object_put(&req->req_obj); 50 } 51} 52 53static int v4l2_ctrl_request_clone(struct v4l2_ctrl_handler *hdl, 54 const struct v4l2_ctrl_handler *from) 55{ 56 struct v4l2_ctrl_ref *ref; 57 int err = 0; 58 59 if (WARN_ON(!hdl || hdl == from)) 60 return -EINVAL; 61 62 if (hdl->error) 63 return hdl->error; 64 65 WARN_ON(hdl->lock != &hdl->_lock); 66 67 mutex_lock(from->lock); 68 list_for_each_entry(ref, &from->ctrl_refs, node) { 69 struct v4l2_ctrl *ctrl = ref->ctrl; 70 struct v4l2_ctrl_ref *new_ref; 71 72 /* Skip refs inherited from other devices */ 73 if (ref->from_other_dev) 74 continue; 75 err = handler_new_ref(hdl, ctrl, &new_ref, false, true); 76 if (err) 77 break; 78 } 79 mutex_unlock(from->lock); 80 return err; 81} 82 83static void v4l2_ctrl_request_queue(struct media_request_object *obj) 84{ 85 struct v4l2_ctrl_handler *hdl = 86 container_of(obj, struct v4l2_ctrl_handler, req_obj); 87 struct v4l2_ctrl_handler *main_hdl = obj->priv; 88 89 mutex_lock(main_hdl->lock); 90 list_add_tail(&hdl->requests_queued, &main_hdl->requests_queued); 91 hdl->request_is_queued = true; 92 mutex_unlock(main_hdl->lock); 93} 94 95static void v4l2_ctrl_request_unbind(struct media_request_object *obj) 96{ 97 struct v4l2_ctrl_handler *hdl = 98 container_of(obj, struct v4l2_ctrl_handler, req_obj); 99 struct v4l2_ctrl_handler *main_hdl = obj->priv; 100 101 mutex_lock(main_hdl->lock); 102 list_del_init(&hdl->requests); 103 if (hdl->request_is_queued) { 104 list_del_init(&hdl->requests_queued); 105 hdl->request_is_queued = false; 106 } 107 mutex_unlock(main_hdl->lock); 108} 109 110static void v4l2_ctrl_request_release(struct media_request_object *obj) 111{ 112 struct v4l2_ctrl_handler *hdl = 113 container_of(obj, struct v4l2_ctrl_handler, req_obj); 114 115 v4l2_ctrl_handler_free(hdl); 116 kfree(hdl); 117} 118 119static const struct media_request_object_ops req_ops = { 120 .queue = v4l2_ctrl_request_queue, 121 .unbind = v4l2_ctrl_request_unbind, 122 .release = v4l2_ctrl_request_release, 123}; 124 125struct v4l2_ctrl_handler *v4l2_ctrl_request_hdl_find(struct media_request *req, 126 struct v4l2_ctrl_handler *parent) 127{ 128 struct media_request_object *obj; 129 130 if (WARN_ON(req->state != MEDIA_REQUEST_STATE_VALIDATING && 131 req->state != MEDIA_REQUEST_STATE_QUEUED)) 132 return NULL; 133 134 obj = media_request_object_find(req, &req_ops, parent); 135 if (obj) 136 return container_of(obj, struct v4l2_ctrl_handler, req_obj); 137 return NULL; 138} 139EXPORT_SYMBOL_GPL(v4l2_ctrl_request_hdl_find); 140 141struct v4l2_ctrl * 142v4l2_ctrl_request_hdl_ctrl_find(struct v4l2_ctrl_handler *hdl, u32 id) 143{ 144 struct v4l2_ctrl_ref *ref = find_ref_lock(hdl, id); 145 146 return (ref && ref->valid_p_req) ? ref->ctrl : NULL; 147} 148EXPORT_SYMBOL_GPL(v4l2_ctrl_request_hdl_ctrl_find); 149 150static int v4l2_ctrl_request_bind(struct media_request *req, 151 struct v4l2_ctrl_handler *hdl, 152 struct v4l2_ctrl_handler *from) 153{ 154 int ret; 155 156 ret = v4l2_ctrl_request_clone(hdl, from); 157 158 if (!ret) { 159 ret = media_request_object_bind(req, &req_ops, 160 from, false, &hdl->req_obj); 161 if (!ret) { 162 mutex_lock(from->lock); 163 list_add_tail(&hdl->requests, &from->requests); 164 mutex_unlock(from->lock); 165 } 166 } 167 return ret; 168} 169 170static struct media_request_object * 171v4l2_ctrls_find_req_obj(struct v4l2_ctrl_handler *hdl, 172 struct media_request *req, bool set) 173{ 174 struct media_request_object *obj; 175 struct v4l2_ctrl_handler *new_hdl; 176 int ret; 177 178 if (IS_ERR(req)) 179 return ERR_CAST(req); 180 181 if (set && WARN_ON(req->state != MEDIA_REQUEST_STATE_UPDATING)) 182 return ERR_PTR(-EBUSY); 183 184 obj = media_request_object_find(req, &req_ops, hdl); 185 if (obj) 186 return obj; 187 /* 188 * If there are no controls in this completed request, 189 * then that can only happen if: 190 * 191 * 1) no controls were present in the queued request, and 192 * 2) v4l2_ctrl_request_complete() could not allocate a 193 * control handler object to store the completed state in. 194 * 195 * So return ENOMEM to indicate that there was an out-of-memory 196 * error. 197 */ 198 if (!set) 199 return ERR_PTR(-ENOMEM); 200 201 new_hdl = kzalloc(sizeof(*new_hdl), GFP_KERNEL); 202 if (!new_hdl) 203 return ERR_PTR(-ENOMEM); 204 205 obj = &new_hdl->req_obj; 206 ret = v4l2_ctrl_handler_init(new_hdl, (hdl->nr_of_buckets - 1) * 8); 207 if (!ret) 208 ret = v4l2_ctrl_request_bind(req, new_hdl, hdl); 209 if (ret) { 210 v4l2_ctrl_handler_free(new_hdl); 211 kfree(new_hdl); 212 return ERR_PTR(ret); 213 } 214 215 media_request_object_get(obj); 216 return obj; 217} 218 219int v4l2_g_ext_ctrls_request(struct v4l2_ctrl_handler *hdl, struct video_device *vdev, 220 struct media_device *mdev, struct v4l2_ext_controls *cs) 221{ 222 struct media_request_object *obj = NULL; 223 struct media_request *req = NULL; 224 int ret; 225 226 if (!mdev || cs->request_fd < 0) 227 return -EINVAL; 228 229 req = media_request_get_by_fd(mdev, cs->request_fd); 230 if (IS_ERR(req)) 231 return PTR_ERR(req); 232 233 if (req->state != MEDIA_REQUEST_STATE_COMPLETE) { 234 media_request_put(req); 235 return -EACCES; 236 } 237 238 ret = media_request_lock_for_access(req); 239 if (ret) { 240 media_request_put(req); 241 return ret; 242 } 243 244 obj = v4l2_ctrls_find_req_obj(hdl, req, false); 245 if (IS_ERR(obj)) { 246 media_request_unlock_for_access(req); 247 media_request_put(req); 248 return PTR_ERR(obj); 249 } 250 251 hdl = container_of(obj, struct v4l2_ctrl_handler, 252 req_obj); 253 ret = v4l2_g_ext_ctrls_common(hdl, cs, vdev); 254 255 media_request_unlock_for_access(req); 256 media_request_object_put(obj); 257 media_request_put(req); 258 return ret; 259} 260 261int try_set_ext_ctrls_request(struct v4l2_fh *fh, 262 struct v4l2_ctrl_handler *hdl, 263 struct video_device *vdev, 264 struct media_device *mdev, 265 struct v4l2_ext_controls *cs, bool set) 266{ 267 struct media_request_object *obj = NULL; 268 struct media_request *req = NULL; 269 int ret; 270 271 if (!mdev) { 272 dprintk(vdev, "%s: missing media device\n", 273 video_device_node_name(vdev)); 274 return -EINVAL; 275 } 276 277 if (cs->request_fd < 0) { 278 dprintk(vdev, "%s: invalid request fd %d\n", 279 video_device_node_name(vdev), cs->request_fd); 280 return -EINVAL; 281 } 282 283 req = media_request_get_by_fd(mdev, cs->request_fd); 284 if (IS_ERR(req)) { 285 dprintk(vdev, "%s: cannot find request fd %d\n", 286 video_device_node_name(vdev), cs->request_fd); 287 return PTR_ERR(req); 288 } 289 290 ret = media_request_lock_for_update(req); 291 if (ret) { 292 dprintk(vdev, "%s: cannot lock request fd %d\n", 293 video_device_node_name(vdev), cs->request_fd); 294 media_request_put(req); 295 return ret; 296 } 297 298 obj = v4l2_ctrls_find_req_obj(hdl, req, set); 299 if (IS_ERR(obj)) { 300 dprintk(vdev, 301 "%s: cannot find request object for request fd %d\n", 302 video_device_node_name(vdev), 303 cs->request_fd); 304 media_request_unlock_for_update(req); 305 media_request_put(req); 306 return PTR_ERR(obj); 307 } 308 309 hdl = container_of(obj, struct v4l2_ctrl_handler, 310 req_obj); 311 ret = try_set_ext_ctrls_common(fh, hdl, cs, vdev, set); 312 if (ret) 313 dprintk(vdev, 314 "%s: try_set_ext_ctrls_common failed (%d)\n", 315 video_device_node_name(vdev), ret); 316 317 media_request_unlock_for_update(req); 318 media_request_object_put(obj); 319 media_request_put(req); 320 321 return ret; 322} 323 324void v4l2_ctrl_request_complete(struct media_request *req, 325 struct v4l2_ctrl_handler *main_hdl) 326{ 327 struct media_request_object *obj; 328 struct v4l2_ctrl_handler *hdl; 329 struct v4l2_ctrl_ref *ref; 330 331 if (!req || !main_hdl) 332 return; 333 334 /* 335 * Note that it is valid if nothing was found. It means 336 * that this request doesn't have any controls and so just 337 * wants to leave the controls unchanged. 338 */ 339 obj = media_request_object_find(req, &req_ops, main_hdl); 340 if (!obj) { 341 int ret; 342 343 /* Create a new request so the driver can return controls */ 344 hdl = kzalloc(sizeof(*hdl), GFP_KERNEL); 345 if (!hdl) 346 return; 347 348 ret = v4l2_ctrl_handler_init(hdl, (main_hdl->nr_of_buckets - 1) * 8); 349 if (!ret) 350 ret = v4l2_ctrl_request_bind(req, hdl, main_hdl); 351 if (ret) { 352 v4l2_ctrl_handler_free(hdl); 353 kfree(hdl); 354 return; 355 } 356 hdl->request_is_queued = true; 357 obj = media_request_object_find(req, &req_ops, main_hdl); 358 } 359 hdl = container_of(obj, struct v4l2_ctrl_handler, req_obj); 360 361 list_for_each_entry(ref, &hdl->ctrl_refs, node) { 362 struct v4l2_ctrl *ctrl = ref->ctrl; 363 struct v4l2_ctrl *master = ctrl->cluster[0]; 364 unsigned int i; 365 366 if (ctrl->flags & V4L2_CTRL_FLAG_VOLATILE) { 367 v4l2_ctrl_lock(master); 368 /* g_volatile_ctrl will update the current control values */ 369 for (i = 0; i < master->ncontrols; i++) 370 cur_to_new(master->cluster[i]); 371 call_op(master, g_volatile_ctrl); 372 new_to_req(ref); 373 v4l2_ctrl_unlock(master); 374 continue; 375 } 376 if (ref->valid_p_req) 377 continue; 378 379 /* Copy the current control value into the request */ 380 v4l2_ctrl_lock(ctrl); 381 cur_to_req(ref); 382 v4l2_ctrl_unlock(ctrl); 383 } 384 385 mutex_lock(main_hdl->lock); 386 WARN_ON(!hdl->request_is_queued); 387 list_del_init(&hdl->requests_queued); 388 hdl->request_is_queued = false; 389 mutex_unlock(main_hdl->lock); 390 media_request_object_complete(obj); 391 media_request_object_put(obj); 392} 393EXPORT_SYMBOL(v4l2_ctrl_request_complete); 394 395int v4l2_ctrl_request_setup(struct media_request *req, 396 struct v4l2_ctrl_handler *main_hdl) 397{ 398 struct media_request_object *obj; 399 struct v4l2_ctrl_handler *hdl; 400 struct v4l2_ctrl_ref *ref; 401 int ret = 0; 402 403 if (!req || !main_hdl) 404 return 0; 405 406 if (WARN_ON(req->state != MEDIA_REQUEST_STATE_QUEUED)) 407 return -EBUSY; 408 409 /* 410 * Note that it is valid if nothing was found. It means 411 * that this request doesn't have any controls and so just 412 * wants to leave the controls unchanged. 413 */ 414 obj = media_request_object_find(req, &req_ops, main_hdl); 415 if (!obj) 416 return 0; 417 if (obj->completed) { 418 media_request_object_put(obj); 419 return -EBUSY; 420 } 421 hdl = container_of(obj, struct v4l2_ctrl_handler, req_obj); 422 423 list_for_each_entry(ref, &hdl->ctrl_refs, node) 424 ref->req_done = false; 425 426 list_for_each_entry(ref, &hdl->ctrl_refs, node) { 427 struct v4l2_ctrl *ctrl = ref->ctrl; 428 struct v4l2_ctrl *master = ctrl->cluster[0]; 429 bool have_new_data = false; 430 int i; 431 432 /* 433 * Skip if this control was already handled by a cluster. 434 * Skip button controls and read-only controls. 435 */ 436 if (ref->req_done || (ctrl->flags & V4L2_CTRL_FLAG_READ_ONLY)) 437 continue; 438 439 v4l2_ctrl_lock(master); 440 for (i = 0; i < master->ncontrols; i++) { 441 if (master->cluster[i]) { 442 struct v4l2_ctrl_ref *r = 443 find_ref(hdl, master->cluster[i]->id); 444 445 if (r->valid_p_req) { 446 have_new_data = true; 447 break; 448 } 449 } 450 } 451 if (!have_new_data) { 452 v4l2_ctrl_unlock(master); 453 continue; 454 } 455 456 for (i = 0; i < master->ncontrols; i++) { 457 if (master->cluster[i]) { 458 struct v4l2_ctrl_ref *r = 459 find_ref(hdl, master->cluster[i]->id); 460 461 req_to_new(r); 462 master->cluster[i]->is_new = 1; 463 r->req_done = true; 464 } 465 } 466 /* 467 * For volatile autoclusters that are currently in auto mode 468 * we need to discover if it will be set to manual mode. 469 * If so, then we have to copy the current volatile values 470 * first since those will become the new manual values (which 471 * may be overwritten by explicit new values from this set 472 * of controls). 473 */ 474 if (master->is_auto && master->has_volatiles && 475 !is_cur_manual(master)) { 476 s32 new_auto_val = *master->p_new.p_s32; 477 478 /* 479 * If the new value == the manual value, then copy 480 * the current volatile values. 481 */ 482 if (new_auto_val == master->manual_mode_value) 483 update_from_auto_cluster(master); 484 } 485 486 ret = try_or_set_cluster(NULL, master, true, 0); 487 v4l2_ctrl_unlock(master); 488 489 if (ret) 490 break; 491 } 492 493 media_request_object_put(obj); 494 return ret; 495} 496EXPORT_SYMBOL(v4l2_ctrl_request_setup);