xref: /linux/drivers/media/v4l2-core/v4l2-ctrls-request.c (revision 7821fa101eab529521aa4b724bf708149d70820c)
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 */
19  void 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 */
28  void 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  
53  static 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  
83  static 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  
95  static 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  
110  static 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  
119  static 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  
125  struct 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  }
139  EXPORT_SYMBOL_GPL(v4l2_ctrl_request_hdl_find);
140  
141  struct v4l2_ctrl *
142  v4l2_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->p_req_valid) ? ref->ctrl : NULL;
147  }
148  EXPORT_SYMBOL_GPL(v4l2_ctrl_request_hdl_ctrl_find);
149  
150  static 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  
170  static struct media_request_object *
171  v4l2_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  
219  int 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  
261  int 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  
324  void 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->p_req_valid)
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  }
393  EXPORT_SYMBOL(v4l2_ctrl_request_complete);
394  
395  int 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->p_req_valid) {
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  				ret = req_to_new(r);
462  				if (ret) {
463  					v4l2_ctrl_unlock(master);
464  					goto error;
465  				}
466  				master->cluster[i]->is_new = 1;
467  				r->req_done = true;
468  			}
469  		}
470  		/*
471  		 * For volatile autoclusters that are currently in auto mode
472  		 * we need to discover if it will be set to manual mode.
473  		 * If so, then we have to copy the current volatile values
474  		 * first since those will become the new manual values (which
475  		 * may be overwritten by explicit new values from this set
476  		 * of controls).
477  		 */
478  		if (master->is_auto && master->has_volatiles &&
479  		    !is_cur_manual(master)) {
480  			s32 new_auto_val = *master->p_new.p_s32;
481  
482  			/*
483  			 * If the new value == the manual value, then copy
484  			 * the current volatile values.
485  			 */
486  			if (new_auto_val == master->manual_mode_value)
487  				update_from_auto_cluster(master);
488  		}
489  
490  		ret = try_or_set_cluster(NULL, master, true, 0);
491  		v4l2_ctrl_unlock(master);
492  
493  		if (ret)
494  			break;
495  	}
496  
497  error:
498  	media_request_object_put(obj);
499  	return ret;
500  }
501  EXPORT_SYMBOL(v4l2_ctrl_request_setup);
502