brintos

brintos / linux-shallow public Read only

0
0
Text · 34.1 KiB · 95a2202 Raw
1316 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * V4L2 controls framework uAPI implementation:4 *5 * Copyright (C) 2010-2021  Hans Verkuil <hverkuil-cisco@xs4all.nl>6 */7 8#define pr_fmt(fmt) "v4l2-ctrls: " fmt9 10#include <linux/export.h>11#include <linux/mm.h>12#include <linux/slab.h>13#include <media/v4l2-ctrls.h>14#include <media/v4l2-dev.h>15#include <media/v4l2-device.h>16#include <media/v4l2-event.h>17#include <media/v4l2-ioctl.h>18 19#include "v4l2-ctrls-priv.h"20 21/* Internal temporary helper struct, one for each v4l2_ext_control */22struct v4l2_ctrl_helper {23	/* Pointer to the control reference of the master control */24	struct v4l2_ctrl_ref *mref;25	/* The control ref corresponding to the v4l2_ext_control ID field. */26	struct v4l2_ctrl_ref *ref;27	/*28	 * v4l2_ext_control index of the next control belonging to the29	 * same cluster, or 0 if there isn't any.30	 */31	u32 next;32};33 34/*35 * Helper functions to copy control payload data from kernel space to36 * user space and vice versa.37 */38 39/* Helper function: copy the given control value back to the caller */40static int ptr_to_user(struct v4l2_ext_control *c,41		       struct v4l2_ctrl *ctrl,42		       union v4l2_ctrl_ptr ptr)43{44	u32 len;45 46	if (ctrl->is_ptr && !ctrl->is_string)47		return copy_to_user(c->ptr, ptr.p_const, c->size) ?48		       -EFAULT : 0;49 50	switch (ctrl->type) {51	case V4L2_CTRL_TYPE_STRING:52		len = strlen(ptr.p_char);53		if (c->size < len + 1) {54			c->size = ctrl->elem_size;55			return -ENOSPC;56		}57		return copy_to_user(c->string, ptr.p_char, len + 1) ?58		       -EFAULT : 0;59	case V4L2_CTRL_TYPE_INTEGER64:60		c->value64 = *ptr.p_s64;61		break;62	default:63		c->value = *ptr.p_s32;64		break;65	}66	return 0;67}68 69/* Helper function: copy the current control value back to the caller */70static int cur_to_user(struct v4l2_ext_control *c, struct v4l2_ctrl *ctrl)71{72	return ptr_to_user(c, ctrl, ctrl->p_cur);73}74 75/* Helper function: copy the new control value back to the caller */76static int new_to_user(struct v4l2_ext_control *c,77		       struct v4l2_ctrl *ctrl)78{79	return ptr_to_user(c, ctrl, ctrl->p_new);80}81 82/* Helper function: copy the request value back to the caller */83static int req_to_user(struct v4l2_ext_control *c,84		       struct v4l2_ctrl_ref *ref)85{86	return ptr_to_user(c, ref->ctrl, ref->p_req);87}88 89/* Helper function: copy the initial control value back to the caller */90static int def_to_user(struct v4l2_ext_control *c, struct v4l2_ctrl *ctrl)91{92	ctrl->type_ops->init(ctrl, 0, ctrl->p_new);93 94	return ptr_to_user(c, ctrl, ctrl->p_new);95}96 97/* Helper function: copy the caller-provider value as the new control value */98static int user_to_new(struct v4l2_ext_control *c, struct v4l2_ctrl *ctrl)99{100	int ret;101	u32 size;102 103	ctrl->is_new = 0;104	if (ctrl->is_dyn_array &&105	    c->size > ctrl->p_array_alloc_elems * ctrl->elem_size) {106		void *old = ctrl->p_array;107		void *tmp = kvzalloc(2 * c->size, GFP_KERNEL);108 109		if (!tmp)110			return -ENOMEM;111		memcpy(tmp, ctrl->p_new.p, ctrl->elems * ctrl->elem_size);112		memcpy(tmp + c->size, ctrl->p_cur.p, ctrl->elems * ctrl->elem_size);113		ctrl->p_new.p = tmp;114		ctrl->p_cur.p = tmp + c->size;115		ctrl->p_array = tmp;116		ctrl->p_array_alloc_elems = c->size / ctrl->elem_size;117		kvfree(old);118	}119 120	if (ctrl->is_ptr && !ctrl->is_string) {121		unsigned int elems = c->size / ctrl->elem_size;122 123		if (copy_from_user(ctrl->p_new.p, c->ptr, c->size))124			return -EFAULT;125		ctrl->is_new = 1;126		if (ctrl->is_dyn_array)127			ctrl->new_elems = elems;128		else if (ctrl->is_array)129			ctrl->type_ops->init(ctrl, elems, ctrl->p_new);130		return 0;131	}132 133	switch (ctrl->type) {134	case V4L2_CTRL_TYPE_INTEGER64:135		*ctrl->p_new.p_s64 = c->value64;136		break;137	case V4L2_CTRL_TYPE_STRING:138		size = c->size;139		if (size == 0)140			return -ERANGE;141		if (size > ctrl->maximum + 1)142			size = ctrl->maximum + 1;143		ret = copy_from_user(ctrl->p_new.p_char, c->string, size) ? -EFAULT : 0;144		if (!ret) {145			char last = ctrl->p_new.p_char[size - 1];146 147			ctrl->p_new.p_char[size - 1] = 0;148			/*149			 * If the string was longer than ctrl->maximum,150			 * then return an error.151			 */152			if (strlen(ctrl->p_new.p_char) == ctrl->maximum && last)153				return -ERANGE;154			ctrl->is_new = 1;155		}156		return ret;157	default:158		*ctrl->p_new.p_s32 = c->value;159		break;160	}161	ctrl->is_new = 1;162	return 0;163}164 165/*166 * VIDIOC_G/TRY/S_EXT_CTRLS implementation167 */168 169/*170 * Some general notes on the atomic requirements of VIDIOC_G/TRY/S_EXT_CTRLS:171 *172 * It is not a fully atomic operation, just best-effort only. After all, if173 * multiple controls have to be set through multiple i2c writes (for example)174 * then some initial writes may succeed while others fail. Thus leaving the175 * system in an inconsistent state. The question is how much effort you are176 * willing to spend on trying to make something atomic that really isn't.177 *178 * From the point of view of an application the main requirement is that179 * when you call VIDIOC_S_EXT_CTRLS and some values are invalid then an180 * error should be returned without actually affecting any controls.181 *182 * If all the values are correct, then it is acceptable to just give up183 * in case of low-level errors.184 *185 * It is important though that the application can tell when only a partial186 * configuration was done. The way we do that is through the error_idx field187 * of struct v4l2_ext_controls: if that is equal to the count field then no188 * controls were affected. Otherwise all controls before that index were189 * successful in performing their 'get' or 'set' operation, the control at190 * the given index failed, and you don't know what happened with the controls191 * after the failed one. Since if they were part of a control cluster they192 * could have been successfully processed (if a cluster member was encountered193 * at index < error_idx), they could have failed (if a cluster member was at194 * error_idx), or they may not have been processed yet (if the first cluster195 * member appeared after error_idx).196 *197 * It is all fairly theoretical, though. In practice all you can do is to198 * bail out. If error_idx == count, then it is an application bug. If199 * error_idx < count then it is only an application bug if the error code was200 * EBUSY. That usually means that something started streaming just when you201 * tried to set the controls. In all other cases it is a driver/hardware202 * problem and all you can do is to retry or bail out.203 *204 * Note that these rules do not apply to VIDIOC_TRY_EXT_CTRLS: since that205 * never modifies controls the error_idx is just set to whatever control206 * has an invalid value.207 */208 209/*210 * Prepare for the extended g/s/try functions.211 * Find the controls in the control array and do some basic checks.212 */213static int prepare_ext_ctrls(struct v4l2_ctrl_handler *hdl,214			     struct v4l2_ext_controls *cs,215			     struct v4l2_ctrl_helper *helpers,216			     struct video_device *vdev,217			     bool get)218{219	struct v4l2_ctrl_helper *h;220	bool have_clusters = false;221	u32 i;222 223	for (i = 0, h = helpers; i < cs->count; i++, h++) {224		struct v4l2_ext_control *c = &cs->controls[i];225		struct v4l2_ctrl_ref *ref;226		struct v4l2_ctrl *ctrl;227		u32 id = c->id & V4L2_CTRL_ID_MASK;228 229		cs->error_idx = i;230 231		if (cs->which &&232		    cs->which != V4L2_CTRL_WHICH_DEF_VAL &&233		    cs->which != V4L2_CTRL_WHICH_REQUEST_VAL &&234		    V4L2_CTRL_ID2WHICH(id) != cs->which) {235			dprintk(vdev,236				"invalid which 0x%x or control id 0x%x\n",237				cs->which, id);238			return -EINVAL;239		}240 241		/*242		 * Old-style private controls are not allowed for243		 * extended controls.244		 */245		if (id >= V4L2_CID_PRIVATE_BASE) {246			dprintk(vdev,247				"old-style private controls not allowed\n");248			return -EINVAL;249		}250		ref = find_ref_lock(hdl, id);251		if (!ref) {252			dprintk(vdev, "cannot find control id 0x%x\n", id);253			return -EINVAL;254		}255		h->ref = ref;256		ctrl = ref->ctrl;257		if (ctrl->flags & V4L2_CTRL_FLAG_DISABLED) {258			dprintk(vdev, "control id 0x%x is disabled\n", id);259			return -EINVAL;260		}261 262		if (ctrl->cluster[0]->ncontrols > 1)263			have_clusters = true;264		if (ctrl->cluster[0] != ctrl)265			ref = find_ref_lock(hdl, ctrl->cluster[0]->id);266		if (ctrl->is_dyn_array) {267			unsigned int max_size = ctrl->dims[0] * ctrl->elem_size;268			unsigned int tot_size = ctrl->elem_size;269 270			if (cs->which == V4L2_CTRL_WHICH_REQUEST_VAL)271				tot_size *= ref->p_req_elems;272			else273				tot_size *= ctrl->elems;274 275			c->size = ctrl->elem_size * (c->size / ctrl->elem_size);276			if (get) {277				if (c->size < tot_size) {278					c->size = tot_size;279					return -ENOSPC;280				}281				c->size = tot_size;282			} else {283				if (c->size > max_size) {284					c->size = max_size;285					return -ENOSPC;286				}287				if (!c->size)288					return -EFAULT;289			}290		} else if (ctrl->is_ptr && !ctrl->is_string) {291			unsigned int tot_size = ctrl->elems * ctrl->elem_size;292 293			if (c->size < tot_size) {294				/*295				 * In the get case the application first296				 * queries to obtain the size of the control.297				 */298				if (get) {299					c->size = tot_size;300					return -ENOSPC;301				}302				dprintk(vdev,303					"pointer control id 0x%x size too small, %d bytes but %d bytes needed\n",304					id, c->size, tot_size);305				return -EFAULT;306			}307			c->size = tot_size;308		}309		/* Store the ref to the master control of the cluster */310		h->mref = ref;311		/*312		 * Initially set next to 0, meaning that there is no other313		 * control in this helper array belonging to the same314		 * cluster.315		 */316		h->next = 0;317	}318 319	/*320	 * We are done if there were no controls that belong to a multi-321	 * control cluster.322	 */323	if (!have_clusters)324		return 0;325 326	/*327	 * The code below figures out in O(n) time which controls in the list328	 * belong to the same cluster.329	 */330 331	/* This has to be done with the handler lock taken. */332	mutex_lock(hdl->lock);333 334	/* First zero the helper field in the master control references */335	for (i = 0; i < cs->count; i++)336		helpers[i].mref->helper = NULL;337	for (i = 0, h = helpers; i < cs->count; i++, h++) {338		struct v4l2_ctrl_ref *mref = h->mref;339 340		/*341		 * If the mref->helper is set, then it points to an earlier342		 * helper that belongs to the same cluster.343		 */344		if (mref->helper) {345			/*346			 * Set the next field of mref->helper to the current347			 * index: this means that the earlier helper now348			 * points to the next helper in the same cluster.349			 */350			mref->helper->next = i;351			/*352			 * mref should be set only for the first helper in the353			 * cluster, clear the others.354			 */355			h->mref = NULL;356		}357		/* Point the mref helper to the current helper struct. */358		mref->helper = h;359	}360	mutex_unlock(hdl->lock);361	return 0;362}363 364/*365 * Handles the corner case where cs->count == 0. It checks whether the366 * specified control class exists. If that class ID is 0, then it checks367 * whether there are any controls at all.368 */369static int class_check(struct v4l2_ctrl_handler *hdl, u32 which)370{371	if (which == 0 || which == V4L2_CTRL_WHICH_DEF_VAL ||372	    which == V4L2_CTRL_WHICH_REQUEST_VAL)373		return 0;374	return find_ref_lock(hdl, which | 1) ? 0 : -EINVAL;375}376 377/*378 * Get extended controls. Allocates the helpers array if needed.379 *380 * Note that v4l2_g_ext_ctrls_common() with 'which' set to381 * V4L2_CTRL_WHICH_REQUEST_VAL is only called if the request was382 * completed, and in that case p_req_valid is true for all controls.383 */384int v4l2_g_ext_ctrls_common(struct v4l2_ctrl_handler *hdl,385			    struct v4l2_ext_controls *cs,386			    struct video_device *vdev)387{388	struct v4l2_ctrl_helper helper[4];389	struct v4l2_ctrl_helper *helpers = helper;390	int ret;391	int i, j;392	bool is_default, is_request;393 394	is_default = (cs->which == V4L2_CTRL_WHICH_DEF_VAL);395	is_request = (cs->which == V4L2_CTRL_WHICH_REQUEST_VAL);396 397	cs->error_idx = cs->count;398	cs->which = V4L2_CTRL_ID2WHICH(cs->which);399 400	if (!hdl)401		return -EINVAL;402 403	if (cs->count == 0)404		return class_check(hdl, cs->which);405 406	if (cs->count > ARRAY_SIZE(helper)) {407		helpers = kvmalloc_array(cs->count, sizeof(helper[0]),408					 GFP_KERNEL);409		if (!helpers)410			return -ENOMEM;411	}412 413	ret = prepare_ext_ctrls(hdl, cs, helpers, vdev, true);414	cs->error_idx = cs->count;415 416	for (i = 0; !ret && i < cs->count; i++)417		if (helpers[i].ref->ctrl->flags & V4L2_CTRL_FLAG_WRITE_ONLY)418			ret = -EACCES;419 420	for (i = 0; !ret && i < cs->count; i++) {421		struct v4l2_ctrl *master;422		bool is_volatile = false;423		u32 idx = i;424 425		if (!helpers[i].mref)426			continue;427 428		master = helpers[i].mref->ctrl;429		cs->error_idx = i;430 431		v4l2_ctrl_lock(master);432 433		/*434		 * g_volatile_ctrl will update the new control values.435		 * This makes no sense for V4L2_CTRL_WHICH_DEF_VAL and436		 * V4L2_CTRL_WHICH_REQUEST_VAL. In the case of requests437		 * it is v4l2_ctrl_request_complete() that copies the438		 * volatile controls at the time of request completion439		 * to the request, so you don't want to do that again.440		 */441		if (!is_default && !is_request &&442		    ((master->flags & V4L2_CTRL_FLAG_VOLATILE) ||443		    (master->has_volatiles && !is_cur_manual(master)))) {444			for (j = 0; j < master->ncontrols; j++)445				cur_to_new(master->cluster[j]);446			ret = call_op(master, g_volatile_ctrl);447			is_volatile = true;448		}449 450		if (ret) {451			v4l2_ctrl_unlock(master);452			break;453		}454 455		/*456		 * Copy the default value (if is_default is true), the457		 * request value (if is_request is true and p_req is valid),458		 * the new volatile value (if is_volatile is true) or the459		 * current value.460		 */461		do {462			struct v4l2_ctrl_ref *ref = helpers[idx].ref;463 464			if (is_default)465				ret = def_to_user(cs->controls + idx, ref->ctrl);466			else if (is_request && ref->p_req_array_enomem)467				ret = -ENOMEM;468			else if (is_request && ref->p_req_valid)469				ret = req_to_user(cs->controls + idx, ref);470			else if (is_volatile)471				ret = new_to_user(cs->controls + idx, ref->ctrl);472			else473				ret = cur_to_user(cs->controls + idx, ref->ctrl);474			idx = helpers[idx].next;475		} while (!ret && idx);476 477		v4l2_ctrl_unlock(master);478	}479 480	if (cs->count > ARRAY_SIZE(helper))481		kvfree(helpers);482	return ret;483}484 485int v4l2_g_ext_ctrls(struct v4l2_ctrl_handler *hdl, struct video_device *vdev,486		     struct media_device *mdev, struct v4l2_ext_controls *cs)487{488	if (cs->which == V4L2_CTRL_WHICH_REQUEST_VAL)489		return v4l2_g_ext_ctrls_request(hdl, vdev, mdev, cs);490 491	return v4l2_g_ext_ctrls_common(hdl, cs, vdev);492}493EXPORT_SYMBOL(v4l2_g_ext_ctrls);494 495/* Validate a new control */496static int validate_new(const struct v4l2_ctrl *ctrl, union v4l2_ctrl_ptr p_new)497{498	return ctrl->type_ops->validate(ctrl, p_new);499}500 501/* Validate controls. */502static int validate_ctrls(struct v4l2_ext_controls *cs,503			  struct v4l2_ctrl_helper *helpers,504			  struct video_device *vdev,505			  bool set)506{507	unsigned int i;508	int ret = 0;509 510	cs->error_idx = cs->count;511	for (i = 0; i < cs->count; i++) {512		struct v4l2_ctrl *ctrl = helpers[i].ref->ctrl;513		union v4l2_ctrl_ptr p_new;514 515		cs->error_idx = i;516 517		if (ctrl->flags & V4L2_CTRL_FLAG_READ_ONLY) {518			dprintk(vdev,519				"control id 0x%x is read-only\n",520				ctrl->id);521			return -EACCES;522		}523		/*524		 * This test is also done in try_set_control_cluster() which525		 * is called in atomic context, so that has the final say,526		 * but it makes sense to do an up-front check as well. Once527		 * an error occurs in try_set_control_cluster() some other528		 * controls may have been set already and we want to do a529		 * best-effort to avoid that.530		 */531		if (set && (ctrl->flags & V4L2_CTRL_FLAG_GRABBED)) {532			dprintk(vdev,533				"control id 0x%x is grabbed, cannot set\n",534				ctrl->id);535			return -EBUSY;536		}537		/*538		 * Skip validation for now if the payload needs to be copied539		 * from userspace into kernelspace. We'll validate those later.540		 */541		if (ctrl->is_ptr)542			continue;543		if (ctrl->type == V4L2_CTRL_TYPE_INTEGER64)544			p_new.p_s64 = &cs->controls[i].value64;545		else546			p_new.p_s32 = &cs->controls[i].value;547		ret = validate_new(ctrl, p_new);548		if (ret)549			return ret;550	}551	return 0;552}553 554/* Try or try-and-set controls */555int try_set_ext_ctrls_common(struct v4l2_fh *fh,556			     struct v4l2_ctrl_handler *hdl,557			     struct v4l2_ext_controls *cs,558			     struct video_device *vdev, bool set)559{560	struct v4l2_ctrl_helper helper[4];561	struct v4l2_ctrl_helper *helpers = helper;562	unsigned int i, j;563	int ret;564 565	cs->error_idx = cs->count;566 567	/* Default value cannot be changed */568	if (cs->which == V4L2_CTRL_WHICH_DEF_VAL) {569		dprintk(vdev, "%s: cannot change default value\n",570			video_device_node_name(vdev));571		return -EINVAL;572	}573 574	cs->which = V4L2_CTRL_ID2WHICH(cs->which);575 576	if (!hdl) {577		dprintk(vdev, "%s: invalid null control handler\n",578			video_device_node_name(vdev));579		return -EINVAL;580	}581 582	if (cs->count == 0)583		return class_check(hdl, cs->which);584 585	if (cs->count > ARRAY_SIZE(helper)) {586		helpers = kvmalloc_array(cs->count, sizeof(helper[0]),587					 GFP_KERNEL);588		if (!helpers)589			return -ENOMEM;590	}591	ret = prepare_ext_ctrls(hdl, cs, helpers, vdev, false);592	if (!ret)593		ret = validate_ctrls(cs, helpers, vdev, set);594	if (ret && set)595		cs->error_idx = cs->count;596	for (i = 0; !ret && i < cs->count; i++) {597		struct v4l2_ctrl *master;598		u32 idx = i;599 600		if (!helpers[i].mref)601			continue;602 603		cs->error_idx = i;604		master = helpers[i].mref->ctrl;605		v4l2_ctrl_lock(master);606 607		/* Reset the 'is_new' flags of the cluster */608		for (j = 0; j < master->ncontrols; j++)609			if (master->cluster[j])610				master->cluster[j]->is_new = 0;611 612		/*613		 * For volatile autoclusters that are currently in auto mode614		 * we need to discover if it will be set to manual mode.615		 * If so, then we have to copy the current volatile values616		 * first since those will become the new manual values (which617		 * may be overwritten by explicit new values from this set618		 * of controls).619		 */620		if (master->is_auto && master->has_volatiles &&621		    !is_cur_manual(master)) {622			/* Pick an initial non-manual value */623			s32 new_auto_val = master->manual_mode_value + 1;624			u32 tmp_idx = idx;625 626			do {627				/*628				 * Check if the auto control is part of the629				 * list, and remember the new value.630				 */631				if (helpers[tmp_idx].ref->ctrl == master)632					new_auto_val = cs->controls[tmp_idx].value;633				tmp_idx = helpers[tmp_idx].next;634			} while (tmp_idx);635			/*636			 * If the new value == the manual value, then copy637			 * the current volatile values.638			 */639			if (new_auto_val == master->manual_mode_value)640				update_from_auto_cluster(master);641		}642 643		/*644		 * Copy the new caller-supplied control values.645		 * user_to_new() sets 'is_new' to 1.646		 */647		do {648			struct v4l2_ctrl *ctrl = helpers[idx].ref->ctrl;649 650			ret = user_to_new(cs->controls + idx, ctrl);651			if (!ret && ctrl->is_ptr) {652				ret = validate_new(ctrl, ctrl->p_new);653				if (ret)654					dprintk(vdev,655						"failed to validate control %s (%d)\n",656						v4l2_ctrl_get_name(ctrl->id), ret);657			}658			idx = helpers[idx].next;659		} while (!ret && idx);660 661		if (!ret)662			ret = try_or_set_cluster(fh, master,663						 !hdl->req_obj.req && set, 0);664		if (!ret && hdl->req_obj.req && set) {665			for (j = 0; j < master->ncontrols; j++) {666				struct v4l2_ctrl_ref *ref =667					find_ref(hdl, master->cluster[j]->id);668 669				new_to_req(ref);670			}671		}672 673		/* Copy the new values back to userspace. */674		if (!ret) {675			idx = i;676			do {677				ret = new_to_user(cs->controls + idx,678						  helpers[idx].ref->ctrl);679				idx = helpers[idx].next;680			} while (!ret && idx);681		}682		v4l2_ctrl_unlock(master);683	}684 685	if (cs->count > ARRAY_SIZE(helper))686		kvfree(helpers);687	return ret;688}689 690static int try_set_ext_ctrls(struct v4l2_fh *fh,691			     struct v4l2_ctrl_handler *hdl,692			     struct video_device *vdev,693			     struct media_device *mdev,694			     struct v4l2_ext_controls *cs, bool set)695{696	int ret;697 698	if (cs->which == V4L2_CTRL_WHICH_REQUEST_VAL)699		return try_set_ext_ctrls_request(fh, hdl, vdev, mdev, cs, set);700 701	ret = try_set_ext_ctrls_common(fh, hdl, cs, vdev, set);702	if (ret)703		dprintk(vdev,704			"%s: try_set_ext_ctrls_common failed (%d)\n",705			video_device_node_name(vdev), ret);706 707	return ret;708}709 710int v4l2_try_ext_ctrls(struct v4l2_ctrl_handler *hdl,711		       struct video_device *vdev,712		       struct media_device *mdev,713		       struct v4l2_ext_controls *cs)714{715	return try_set_ext_ctrls(NULL, hdl, vdev, mdev, cs, false);716}717EXPORT_SYMBOL(v4l2_try_ext_ctrls);718 719int v4l2_s_ext_ctrls(struct v4l2_fh *fh,720		     struct v4l2_ctrl_handler *hdl,721		     struct video_device *vdev,722		     struct media_device *mdev,723		     struct v4l2_ext_controls *cs)724{725	return try_set_ext_ctrls(fh, hdl, vdev, mdev, cs, true);726}727EXPORT_SYMBOL(v4l2_s_ext_ctrls);728 729/*730 * VIDIOC_G/S_CTRL implementation731 */732 733/* Helper function to get a single control */734static int get_ctrl(struct v4l2_ctrl *ctrl, struct v4l2_ext_control *c)735{736	struct v4l2_ctrl *master = ctrl->cluster[0];737	int ret = 0;738	int i;739 740	/* Compound controls are not supported. The new_to_user() and741	 * cur_to_user() calls below would need to be modified not to access742	 * userspace memory when called from get_ctrl().743	 */744	if (!ctrl->is_int && ctrl->type != V4L2_CTRL_TYPE_INTEGER64)745		return -EINVAL;746 747	if (ctrl->flags & V4L2_CTRL_FLAG_WRITE_ONLY)748		return -EACCES;749 750	v4l2_ctrl_lock(master);751	/* g_volatile_ctrl will update the current control values */752	if (ctrl->flags & V4L2_CTRL_FLAG_VOLATILE) {753		for (i = 0; i < master->ncontrols; i++)754			cur_to_new(master->cluster[i]);755		ret = call_op(master, g_volatile_ctrl);756		if (!ret)757			ret = new_to_user(c, ctrl);758	} else {759		ret = cur_to_user(c, ctrl);760	}761	v4l2_ctrl_unlock(master);762	return ret;763}764 765int v4l2_g_ctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_control *control)766{767	struct v4l2_ctrl *ctrl = v4l2_ctrl_find(hdl, control->id);768	struct v4l2_ext_control c;769	int ret;770 771	if (!ctrl || !ctrl->is_int)772		return -EINVAL;773	ret = get_ctrl(ctrl, &c);774 775	if (!ret)776		control->value = c.value;777 778	return ret;779}780EXPORT_SYMBOL(v4l2_g_ctrl);781 782/* Helper function for VIDIOC_S_CTRL compatibility */783static int set_ctrl(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, u32 ch_flags)784{785	struct v4l2_ctrl *master = ctrl->cluster[0];786	int ret;787	int i;788 789	/* Reset the 'is_new' flags of the cluster */790	for (i = 0; i < master->ncontrols; i++)791		if (master->cluster[i])792			master->cluster[i]->is_new = 0;793 794	ret = validate_new(ctrl, ctrl->p_new);795	if (ret)796		return ret;797 798	/*799	 * For autoclusters with volatiles that are switched from auto to800	 * manual mode we have to update the current volatile values since801	 * those will become the initial manual values after such a switch.802	 */803	if (master->is_auto && master->has_volatiles && ctrl == master &&804	    !is_cur_manual(master) && ctrl->val == master->manual_mode_value)805		update_from_auto_cluster(master);806 807	ctrl->is_new = 1;808	return try_or_set_cluster(fh, master, true, ch_flags);809}810 811/* Helper function for VIDIOC_S_CTRL compatibility */812static int set_ctrl_lock(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl,813			 struct v4l2_ext_control *c)814{815	int ret;816 817	v4l2_ctrl_lock(ctrl);818	ret = user_to_new(c, ctrl);819	if (!ret)820		ret = set_ctrl(fh, ctrl, 0);821	if (!ret)822		ret = cur_to_user(c, ctrl);823	v4l2_ctrl_unlock(ctrl);824	return ret;825}826 827int v4l2_s_ctrl(struct v4l2_fh *fh, struct v4l2_ctrl_handler *hdl,828		struct v4l2_control *control)829{830	struct v4l2_ctrl *ctrl = v4l2_ctrl_find(hdl, control->id);831	struct v4l2_ext_control c = { control->id };832	int ret;833 834	if (!ctrl || !ctrl->is_int)835		return -EINVAL;836 837	if (ctrl->flags & V4L2_CTRL_FLAG_READ_ONLY)838		return -EACCES;839 840	c.value = control->value;841	ret = set_ctrl_lock(fh, ctrl, &c);842	control->value = c.value;843	return ret;844}845EXPORT_SYMBOL(v4l2_s_ctrl);846 847/*848 * Helper functions for drivers to get/set controls.849 */850 851s32 v4l2_ctrl_g_ctrl(struct v4l2_ctrl *ctrl)852{853	struct v4l2_ext_control c;854 855	/* It's a driver bug if this happens. */856	if (WARN_ON(!ctrl->is_int))857		return 0;858	c.value = 0;859	get_ctrl(ctrl, &c);860	return c.value;861}862EXPORT_SYMBOL(v4l2_ctrl_g_ctrl);863 864s64 v4l2_ctrl_g_ctrl_int64(struct v4l2_ctrl *ctrl)865{866	struct v4l2_ext_control c;867 868	/* It's a driver bug if this happens. */869	if (WARN_ON(ctrl->is_ptr || ctrl->type != V4L2_CTRL_TYPE_INTEGER64))870		return 0;871	c.value64 = 0;872	get_ctrl(ctrl, &c);873	return c.value64;874}875EXPORT_SYMBOL(v4l2_ctrl_g_ctrl_int64);876 877int __v4l2_ctrl_s_ctrl(struct v4l2_ctrl *ctrl, s32 val)878{879	lockdep_assert_held(ctrl->handler->lock);880 881	/* It's a driver bug if this happens. */882	if (WARN_ON(!ctrl->is_int))883		return -EINVAL;884	ctrl->val = val;885	return set_ctrl(NULL, ctrl, 0);886}887EXPORT_SYMBOL(__v4l2_ctrl_s_ctrl);888 889int __v4l2_ctrl_s_ctrl_int64(struct v4l2_ctrl *ctrl, s64 val)890{891	lockdep_assert_held(ctrl->handler->lock);892 893	/* It's a driver bug if this happens. */894	if (WARN_ON(ctrl->is_ptr || ctrl->type != V4L2_CTRL_TYPE_INTEGER64))895		return -EINVAL;896	*ctrl->p_new.p_s64 = val;897	return set_ctrl(NULL, ctrl, 0);898}899EXPORT_SYMBOL(__v4l2_ctrl_s_ctrl_int64);900 901int __v4l2_ctrl_s_ctrl_string(struct v4l2_ctrl *ctrl, const char *s)902{903	lockdep_assert_held(ctrl->handler->lock);904 905	/* It's a driver bug if this happens. */906	if (WARN_ON(ctrl->type != V4L2_CTRL_TYPE_STRING))907		return -EINVAL;908	strscpy(ctrl->p_new.p_char, s, ctrl->maximum + 1);909	return set_ctrl(NULL, ctrl, 0);910}911EXPORT_SYMBOL(__v4l2_ctrl_s_ctrl_string);912 913int __v4l2_ctrl_s_ctrl_compound(struct v4l2_ctrl *ctrl,914				enum v4l2_ctrl_type type, const void *p)915{916	lockdep_assert_held(ctrl->handler->lock);917 918	/* It's a driver bug if this happens. */919	if (WARN_ON(ctrl->type != type))920		return -EINVAL;921	/* Setting dynamic arrays is not (yet?) supported. */922	if (WARN_ON(ctrl->is_dyn_array))923		return -EINVAL;924	memcpy(ctrl->p_new.p, p, ctrl->elems * ctrl->elem_size);925	return set_ctrl(NULL, ctrl, 0);926}927EXPORT_SYMBOL(__v4l2_ctrl_s_ctrl_compound);928 929/*930 * Modify the range of a control.931 */932int __v4l2_ctrl_modify_range(struct v4l2_ctrl *ctrl,933			     s64 min, s64 max, u64 step, s64 def)934{935	bool value_changed;936	bool range_changed = false;937	int ret;938 939	lockdep_assert_held(ctrl->handler->lock);940 941	switch (ctrl->type) {942	case V4L2_CTRL_TYPE_INTEGER:943	case V4L2_CTRL_TYPE_INTEGER64:944	case V4L2_CTRL_TYPE_BOOLEAN:945	case V4L2_CTRL_TYPE_MENU:946	case V4L2_CTRL_TYPE_INTEGER_MENU:947	case V4L2_CTRL_TYPE_BITMASK:948	case V4L2_CTRL_TYPE_U8:949	case V4L2_CTRL_TYPE_U16:950	case V4L2_CTRL_TYPE_U32:951		if (ctrl->is_array)952			return -EINVAL;953		ret = check_range(ctrl->type, min, max, step, def);954		if (ret)955			return ret;956		break;957	default:958		return -EINVAL;959	}960	if (ctrl->minimum != min || ctrl->maximum != max ||961	    ctrl->step != step || ctrl->default_value != def) {962		range_changed = true;963		ctrl->minimum = min;964		ctrl->maximum = max;965		ctrl->step = step;966		ctrl->default_value = def;967	}968	cur_to_new(ctrl);969	if (validate_new(ctrl, ctrl->p_new)) {970		if (ctrl->type == V4L2_CTRL_TYPE_INTEGER64)971			*ctrl->p_new.p_s64 = def;972		else973			*ctrl->p_new.p_s32 = def;974	}975 976	if (ctrl->type == V4L2_CTRL_TYPE_INTEGER64)977		value_changed = *ctrl->p_new.p_s64 != *ctrl->p_cur.p_s64;978	else979		value_changed = *ctrl->p_new.p_s32 != *ctrl->p_cur.p_s32;980	if (value_changed)981		ret = set_ctrl(NULL, ctrl, V4L2_EVENT_CTRL_CH_RANGE);982	else if (range_changed)983		send_event(NULL, ctrl, V4L2_EVENT_CTRL_CH_RANGE);984	return ret;985}986EXPORT_SYMBOL(__v4l2_ctrl_modify_range);987 988int __v4l2_ctrl_modify_dimensions(struct v4l2_ctrl *ctrl,989				  u32 dims[V4L2_CTRL_MAX_DIMS])990{991	unsigned int elems = 1;992	unsigned int i;993	void *p_array;994 995	lockdep_assert_held(ctrl->handler->lock);996 997	if (!ctrl->is_array || ctrl->is_dyn_array)998		return -EINVAL;999 1000	for (i = 0; i < ctrl->nr_of_dims; i++)1001		elems *= dims[i];1002	if (elems == 0)1003		return -EINVAL;1004	p_array = kvzalloc(2 * elems * ctrl->elem_size, GFP_KERNEL);1005	if (!p_array)1006		return -ENOMEM;1007	kvfree(ctrl->p_array);1008	ctrl->p_array_alloc_elems = elems;1009	ctrl->elems = elems;1010	ctrl->new_elems = elems;1011	ctrl->p_array = p_array;1012	ctrl->p_new.p = p_array;1013	ctrl->p_cur.p = p_array + elems * ctrl->elem_size;1014	for (i = 0; i < ctrl->nr_of_dims; i++)1015		ctrl->dims[i] = dims[i];1016	ctrl->type_ops->init(ctrl, 0, ctrl->p_cur);1017	cur_to_new(ctrl);1018	send_event(NULL, ctrl, V4L2_EVENT_CTRL_CH_VALUE |1019			       V4L2_EVENT_CTRL_CH_DIMENSIONS);1020	return 0;1021}1022EXPORT_SYMBOL(__v4l2_ctrl_modify_dimensions);1023 1024/* Implement VIDIOC_QUERY_EXT_CTRL */1025int v4l2_query_ext_ctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_query_ext_ctrl *qc)1026{1027	const unsigned int next_flags = V4L2_CTRL_FLAG_NEXT_CTRL | V4L2_CTRL_FLAG_NEXT_COMPOUND;1028	u32 id = qc->id & V4L2_CTRL_ID_MASK;1029	struct v4l2_ctrl_ref *ref;1030	struct v4l2_ctrl *ctrl;1031 1032	if (!hdl)1033		return -EINVAL;1034 1035	mutex_lock(hdl->lock);1036 1037	/* Try to find it */1038	ref = find_ref(hdl, id);1039 1040	if ((qc->id & next_flags) && !list_empty(&hdl->ctrl_refs)) {1041		bool is_compound;1042		/* Match any control that is not hidden */1043		unsigned int mask = 1;1044		bool match = false;1045 1046		if ((qc->id & next_flags) == V4L2_CTRL_FLAG_NEXT_COMPOUND) {1047			/* Match any hidden control */1048			match = true;1049		} else if ((qc->id & next_flags) == next_flags) {1050			/* Match any control, compound or not */1051			mask = 0;1052		}1053 1054		/* Find the next control with ID > qc->id */1055 1056		/* Did we reach the end of the control list? */1057		if (id >= node2id(hdl->ctrl_refs.prev)) {1058			ref = NULL; /* Yes, so there is no next control */1059		} else if (ref) {1060			struct v4l2_ctrl_ref *pos = ref;1061 1062			/*1063			 * We found a control with the given ID, so just get1064			 * the next valid one in the list.1065			 */1066			ref = NULL;1067			list_for_each_entry_continue(pos, &hdl->ctrl_refs, node) {1068				is_compound = pos->ctrl->is_array ||1069					pos->ctrl->type >= V4L2_CTRL_COMPOUND_TYPES;1070				if (id < pos->ctrl->id &&1071				    (is_compound & mask) == match) {1072					ref = pos;1073					break;1074				}1075			}1076		} else {1077			struct v4l2_ctrl_ref *pos;1078 1079			/*1080			 * No control with the given ID exists, so start1081			 * searching for the next largest ID. We know there1082			 * is one, otherwise the first 'if' above would have1083			 * been true.1084			 */1085			list_for_each_entry(pos, &hdl->ctrl_refs, node) {1086				is_compound = pos->ctrl->is_array ||1087					pos->ctrl->type >= V4L2_CTRL_COMPOUND_TYPES;1088				if (id < pos->ctrl->id &&1089				    (is_compound & mask) == match) {1090					ref = pos;1091					break;1092				}1093			}1094		}1095	}1096	mutex_unlock(hdl->lock);1097 1098	if (!ref)1099		return -EINVAL;1100 1101	ctrl = ref->ctrl;1102	memset(qc, 0, sizeof(*qc));1103	if (id >= V4L2_CID_PRIVATE_BASE)1104		qc->id = id;1105	else1106		qc->id = ctrl->id;1107	strscpy(qc->name, ctrl->name, sizeof(qc->name));1108	qc->flags = user_flags(ctrl);1109	qc->type = ctrl->type;1110	qc->elem_size = ctrl->elem_size;1111	qc->elems = ctrl->elems;1112	qc->nr_of_dims = ctrl->nr_of_dims;1113	memcpy(qc->dims, ctrl->dims, qc->nr_of_dims * sizeof(qc->dims[0]));1114	qc->minimum = ctrl->minimum;1115	qc->maximum = ctrl->maximum;1116	qc->default_value = ctrl->default_value;1117	if (ctrl->type == V4L2_CTRL_TYPE_MENU ||1118	    ctrl->type == V4L2_CTRL_TYPE_INTEGER_MENU)1119		qc->step = 1;1120	else1121		qc->step = ctrl->step;1122	return 0;1123}1124EXPORT_SYMBOL(v4l2_query_ext_ctrl);1125 1126/* Implement VIDIOC_QUERYCTRL */1127int v4l2_queryctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_queryctrl *qc)1128{1129	struct v4l2_query_ext_ctrl qec = { qc->id };1130	int rc;1131 1132	rc = v4l2_query_ext_ctrl(hdl, &qec);1133	if (rc)1134		return rc;1135 1136	qc->id = qec.id;1137	qc->type = qec.type;1138	qc->flags = qec.flags;1139	strscpy(qc->name, qec.name, sizeof(qc->name));1140	switch (qc->type) {1141	case V4L2_CTRL_TYPE_INTEGER:1142	case V4L2_CTRL_TYPE_BOOLEAN:1143	case V4L2_CTRL_TYPE_MENU:1144	case V4L2_CTRL_TYPE_INTEGER_MENU:1145	case V4L2_CTRL_TYPE_STRING:1146	case V4L2_CTRL_TYPE_BITMASK:1147		qc->minimum = qec.minimum;1148		qc->maximum = qec.maximum;1149		qc->step = qec.step;1150		qc->default_value = qec.default_value;1151		break;1152	default:1153		qc->minimum = 0;1154		qc->maximum = 0;1155		qc->step = 0;1156		qc->default_value = 0;1157		break;1158	}1159	return 0;1160}1161EXPORT_SYMBOL(v4l2_queryctrl);1162 1163/* Implement VIDIOC_QUERYMENU */1164int v4l2_querymenu(struct v4l2_ctrl_handler *hdl, struct v4l2_querymenu *qm)1165{1166	struct v4l2_ctrl *ctrl;1167	u32 i = qm->index;1168 1169	ctrl = v4l2_ctrl_find(hdl, qm->id);1170	if (!ctrl)1171		return -EINVAL;1172 1173	qm->reserved = 0;1174	/* Sanity checks */1175	switch (ctrl->type) {1176	case V4L2_CTRL_TYPE_MENU:1177		if (!ctrl->qmenu)1178			return -EINVAL;1179		break;1180	case V4L2_CTRL_TYPE_INTEGER_MENU:1181		if (!ctrl->qmenu_int)1182			return -EINVAL;1183		break;1184	default:1185		return -EINVAL;1186	}1187 1188	if (i < ctrl->minimum || i > ctrl->maximum)1189		return -EINVAL;1190 1191	/* Use mask to see if this menu item should be skipped */1192	if (i < BITS_PER_LONG_LONG && (ctrl->menu_skip_mask & BIT_ULL(i)))1193		return -EINVAL;1194	/* Empty menu items should also be skipped */1195	if (ctrl->type == V4L2_CTRL_TYPE_MENU) {1196		if (!ctrl->qmenu[i] || ctrl->qmenu[i][0] == '\0')1197			return -EINVAL;1198		strscpy(qm->name, ctrl->qmenu[i], sizeof(qm->name));1199	} else {1200		qm->value = ctrl->qmenu_int[i];1201	}1202	return 0;1203}1204EXPORT_SYMBOL(v4l2_querymenu);1205 1206/*1207 * VIDIOC_LOG_STATUS helpers1208 */1209 1210int v4l2_ctrl_log_status(struct file *file, void *fh)1211{1212	struct video_device *vfd = video_devdata(file);1213	struct v4l2_fh *vfh = file->private_data;1214 1215	if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) && vfd->v4l2_dev)1216		v4l2_ctrl_handler_log_status(vfh->ctrl_handler,1217					     vfd->v4l2_dev->name);1218	return 0;1219}1220EXPORT_SYMBOL(v4l2_ctrl_log_status);1221 1222int v4l2_ctrl_subdev_log_status(struct v4l2_subdev *sd)1223{1224	v4l2_ctrl_handler_log_status(sd->ctrl_handler, sd->name);1225	return 0;1226}1227EXPORT_SYMBOL(v4l2_ctrl_subdev_log_status);1228 1229/*1230 * VIDIOC_(UN)SUBSCRIBE_EVENT implementation1231 */1232 1233static int v4l2_ctrl_add_event(struct v4l2_subscribed_event *sev,1234			       unsigned int elems)1235{1236	struct v4l2_ctrl *ctrl = v4l2_ctrl_find(sev->fh->ctrl_handler, sev->id);1237 1238	if (!ctrl)1239		return -EINVAL;1240 1241	v4l2_ctrl_lock(ctrl);1242	list_add_tail(&sev->node, &ctrl->ev_subs);1243	if (ctrl->type != V4L2_CTRL_TYPE_CTRL_CLASS &&1244	    (sev->flags & V4L2_EVENT_SUB_FL_SEND_INITIAL))1245		send_initial_event(sev->fh, ctrl);1246	v4l2_ctrl_unlock(ctrl);1247	return 0;1248}1249 1250static void v4l2_ctrl_del_event(struct v4l2_subscribed_event *sev)1251{1252	struct v4l2_ctrl *ctrl = v4l2_ctrl_find(sev->fh->ctrl_handler, sev->id);1253 1254	if (!ctrl)1255		return;1256 1257	v4l2_ctrl_lock(ctrl);1258	list_del(&sev->node);1259	v4l2_ctrl_unlock(ctrl);1260}1261 1262void v4l2_ctrl_replace(struct v4l2_event *old, const struct v4l2_event *new)1263{1264	u32 old_changes = old->u.ctrl.changes;1265 1266	old->u.ctrl = new->u.ctrl;1267	old->u.ctrl.changes |= old_changes;1268}1269EXPORT_SYMBOL(v4l2_ctrl_replace);1270 1271void v4l2_ctrl_merge(const struct v4l2_event *old, struct v4l2_event *new)1272{1273	new->u.ctrl.changes |= old->u.ctrl.changes;1274}1275EXPORT_SYMBOL(v4l2_ctrl_merge);1276 1277const struct v4l2_subscribed_event_ops v4l2_ctrl_sub_ev_ops = {1278	.add = v4l2_ctrl_add_event,1279	.del = v4l2_ctrl_del_event,1280	.replace = v4l2_ctrl_replace,1281	.merge = v4l2_ctrl_merge,1282};1283EXPORT_SYMBOL(v4l2_ctrl_sub_ev_ops);1284 1285int v4l2_ctrl_subscribe_event(struct v4l2_fh *fh,1286			      const struct v4l2_event_subscription *sub)1287{1288	if (sub->type == V4L2_EVENT_CTRL)1289		return v4l2_event_subscribe(fh, sub, 0, &v4l2_ctrl_sub_ev_ops);1290	return -EINVAL;1291}1292EXPORT_SYMBOL(v4l2_ctrl_subscribe_event);1293 1294int v4l2_ctrl_subdev_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,1295				     struct v4l2_event_subscription *sub)1296{1297	if (!sd->ctrl_handler)1298		return -EINVAL;1299	return v4l2_ctrl_subscribe_event(fh, sub);1300}1301EXPORT_SYMBOL(v4l2_ctrl_subdev_subscribe_event);1302 1303/*1304 * poll helper1305 */1306__poll_t v4l2_ctrl_poll(struct file *file, struct poll_table_struct *wait)1307{1308	struct v4l2_fh *fh = file->private_data;1309 1310	poll_wait(file, &fh->wait, wait);1311	if (v4l2_event_pending(fh))1312		return EPOLLPRI;1313	return 0;1314}1315EXPORT_SYMBOL(v4l2_ctrl_poll);1316