// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * V4L2 controls framework Request API implementation.
 *
 * Copyright (C) 2018-2021  Hans Verkuil <hverkuil-cisco@xs4all.nl>
 */

#define pr_fmt(fmt) "v4l2-ctrls: " fmt

#include <linux/export.h>
#include <linux/slab.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-dev.h>
#include <media/v4l2-ioctl.h>

#include "v4l2-ctrls-priv.h"

/* Initialize the request-related fields in a control handler */
void v4l2_ctrl_handler_init_request(struct v4l2_ctrl_handler *hdl)
{
	INIT_LIST_HEAD(&hdl->requests);
	INIT_LIST_HEAD(&hdl->requests_queued);
	hdl->request_is_queued = false;
	media_request_object_init(&hdl->req_obj);
}

/* Free the request-related fields in a control handler */
void v4l2_ctrl_handler_free_request(struct v4l2_ctrl_handler *hdl)
{
	struct v4l2_ctrl_handler *req, *next_req;

	/*
	 * Do nothing if this isn't the main handler or the main
	 * handler is not used in any request.
	 *
	 * The main handler can be identified by having a NULL ops pointer in
	 * the request object.
	 */
	if (hdl->req_obj.ops || list_empty(&hdl->requests))
		return;

	/*
	 * If the main handler is freed and it is used by handler objects in
	 * outstanding requests, then unbind and put those objects before
	 * freeing the main handler.
	 */
	list_for_each_entry_safe(req, next_req, &hdl->requests, requests) {
		media_request_object_unbind(&req->req_obj);
		media_request_object_put(&req->req_obj);
	}
}

static int v4l2_ctrl_request_clone(struct v4l2_ctrl_handler *hdl,
				   const struct v4l2_ctrl_handler *from)
{
	struct v4l2_ctrl_ref *ref;
	int err = 0;

	if (WARN_ON(!hdl || hdl == from))
		return -EINVAL;

	if (hdl->error)
		return hdl->error;

	WARN_ON(hdl->lock != &hdl->_lock);

	mutex_lock(from->lock);
	list_for_each_entry(ref, &from->ctrl_refs, node) {
		struct v4l2_ctrl *ctrl = ref->ctrl;
		struct v4l2_ctrl_ref *new_ref;

		/* Skip refs inherited from other devices */
		if (ref->from_other_dev)
			continue;
		err = handler_new_ref(hdl, ctrl, &new_ref, false, true);
		if (err)
			break;
	}
	mutex_unlock(from->lock);
	return err;
}

static void v4l2_ctrl_request_queue(struct media_request_object *obj)
{
	struct v4l2_ctrl_handler *hdl =
		container_of(obj, struct v4l2_ctrl_handler, req_obj);
	struct v4l2_ctrl_handler *main_hdl = obj->priv;

	mutex_lock(main_hdl->lock);
	list_add_tail(&hdl->requests_queued, &main_hdl->requests_queued);
	hdl->request_is_queued = true;
	mutex_unlock(main_hdl->lock);
}

static void v4l2_ctrl_request_unbind(struct media_request_object *obj)
{
	struct v4l2_ctrl_handler *hdl =
		container_of(obj, struct v4l2_ctrl_handler, req_obj);
	struct v4l2_ctrl_handler *main_hdl = obj->priv;

	mutex_lock(main_hdl->lock);
	list_del_init(&hdl->requests);
	if (hdl->request_is_queued) {
		list_del_init(&hdl->requests_queued);
		hdl->request_is_queued = false;
	}
	mutex_unlock(main_hdl->lock);
}

static void v4l2_ctrl_request_release(struct media_request_object *obj)
{
	struct v4l2_ctrl_handler *hdl =
		container_of(obj, struct v4l2_ctrl_handler, req_obj);

	v4l2_ctrl_handler_free(hdl);
	kfree(hdl);
}

static const struct media_request_object_ops req_ops = {
	.queue = v4l2_ctrl_request_queue,
	.unbind = v4l2_ctrl_request_unbind,
	.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, &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->valid_p_req) ? ref->ctrl : 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)
{
	int ret;

	ret = v4l2_ctrl_request_clone(hdl, from);

	if (!ret) {
		ret = media_request_object_bind(req, &req_ops,
						from, false, &hdl->req_obj);
		if (!ret) {
			mutex_lock(from->lock);
			list_add_tail(&hdl->requests, &from->requests);
			mutex_unlock(from->lock);
		}
	}
	return ret;
}

static struct media_request_object *
v4l2_ctrls_find_req_obj(struct v4l2_ctrl_handler *hdl,
			struct media_request *req, bool set)
{
	struct media_request_object *obj;
	struct v4l2_ctrl_handler *new_hdl;
	int ret;

	if (IS_ERR(req))
		return ERR_CAST(req);

	if (set && WARN_ON(req->state != MEDIA_REQUEST_STATE_UPDATING))
		return ERR_PTR(-EBUSY);

	obj = media_request_object_find(req, &req_ops, hdl);
	if (obj)
		return obj;
	/*
	 * If there are no controls in this completed request,
	 * then that can only happen if:
	 *
	 * 1) no controls were present in the queued request, and
	 * 2) v4l2_ctrl_request_complete() could not allocate a
	 *    control handler object to store the completed state in.
	 *
	 * So return ENOMEM to indicate that there was an out-of-memory
	 * error.
	 */
	if (!set)
		return ERR_PTR(-ENOMEM);

	new_hdl = kzalloc(sizeof(*new_hdl), GFP_KERNEL);
	if (!new_hdl)
		return ERR_PTR(-ENOMEM);

	obj = &new_hdl->req_obj;
	ret = v4l2_ctrl_handler_init(new_hdl, (hdl->nr_of_buckets - 1) * 8);
	if (!ret)
		ret = v4l2_ctrl_request_bind(req, new_hdl, hdl);
	if (ret) {
		v4l2_ctrl_handler_free(new_hdl);
		kfree(new_hdl);
		return ERR_PTR(ret);
	}

	media_request_object_get(obj);
	return obj;
}

int v4l2_g_ext_ctrls_request(struct v4l2_ctrl_handler *hdl, struct video_device *vdev,
			     struct media_device *mdev, struct v4l2_ext_controls *cs)
{
	struct media_request_object *obj = NULL;
	struct media_request *req = NULL;
	int ret;

	if (!mdev || cs->request_fd < 0)
		return -EINVAL;

	req = media_request_get_by_fd(mdev, cs->request_fd);
	if (IS_ERR(req))
		return PTR_ERR(req);

	if (req->state != MEDIA_REQUEST_STATE_COMPLETE) {
		media_request_put(req);
		return -EACCES;
	}

	ret = media_request_lock_for_access(req);
	if (ret) {
		media_request_put(req);
		return ret;
	}

	obj = v4l2_ctrls_find_req_obj(hdl, req, false);
	if (IS_ERR(obj)) {
		media_request_unlock_for_access(req);
		media_request_put(req);
		return PTR_ERR(obj);
	}

	hdl = container_of(obj, struct v4l2_ctrl_handler,
			   req_obj);
	ret = v4l2_g_ext_ctrls_common(hdl, cs, vdev);

	media_request_unlock_for_access(req);
	media_request_object_put(obj);
	media_request_put(req);
	return ret;
}

int try_set_ext_ctrls_request(struct v4l2_fh *fh,
			      struct v4l2_ctrl_handler *hdl,
			      struct video_device *vdev,
			      struct media_device *mdev,
			      struct v4l2_ext_controls *cs, bool set)
{
	struct media_request_object *obj = NULL;
	struct media_request *req = NULL;
	int ret;

	if (!mdev) {
		dprintk(vdev, "%s: missing media device\n",
			video_device_node_name(vdev));
		return -EINVAL;
	}

	if (cs->request_fd < 0) {
		dprintk(vdev, "%s: invalid request fd %d\n",
			video_device_node_name(vdev), cs->request_fd);
		return -EINVAL;
	}

	req = media_request_get_by_fd(mdev, cs->request_fd);
	if (IS_ERR(req)) {
		dprintk(vdev, "%s: cannot find request fd %d\n",
			video_device_node_name(vdev), cs->request_fd);
		return PTR_ERR(req);
	}

	ret = media_request_lock_for_update(req);
	if (ret) {
		dprintk(vdev, "%s: cannot lock request fd %d\n",
			video_device_node_name(vdev), cs->request_fd);
		media_request_put(req);
		return ret;
	}

	obj = v4l2_ctrls_find_req_obj(hdl, req, set);
	if (IS_ERR(obj)) {
		dprintk(vdev,
			"%s: cannot find request object for request fd %d\n",
			video_device_node_name(vdev),
			cs->request_fd);
		media_request_unlock_for_update(req);
		media_request_put(req);
		return PTR_ERR(obj);
	}

	hdl = container_of(obj, struct v4l2_ctrl_handler,
			   req_obj);
	ret = try_set_ext_ctrls_common(fh, hdl, cs, vdev, set);
	if (ret)
		dprintk(vdev,
			"%s: try_set_ext_ctrls_common failed (%d)\n",
			video_device_node_name(vdev), ret);

	media_request_unlock_for_update(req);
	media_request_object_put(obj);
	media_request_put(req);

	return ret;
}

void v4l2_ctrl_request_complete(struct media_request *req,
				struct v4l2_ctrl_handler *main_hdl)
{
	struct media_request_object *obj;
	struct v4l2_ctrl_handler *hdl;
	struct v4l2_ctrl_ref *ref;

	if (!req || !main_hdl)
		return;

	/*
	 * Note that it is valid if nothing was found. It means
	 * that this request doesn't have any controls and so just
	 * wants to leave the controls unchanged.
	 */
	obj = media_request_object_find(req, &req_ops, main_hdl);
	if (!obj) {
		int ret;

		/* Create a new request so the driver can return controls */
		hdl = kzalloc(sizeof(*hdl), GFP_KERNEL);
		if (!hdl)
			return;

		ret = v4l2_ctrl_handler_init(hdl, (main_hdl->nr_of_buckets - 1) * 8);
		if (!ret)
			ret = v4l2_ctrl_request_bind(req, hdl, main_hdl);
		if (ret) {
			v4l2_ctrl_handler_free(hdl);
			kfree(hdl);
			return;
		}
		hdl->request_is_queued = true;
		obj = media_request_object_find(req, &req_ops, main_hdl);
	}
	hdl = container_of(obj, struct v4l2_ctrl_handler, req_obj);

	list_for_each_entry(ref, &hdl->ctrl_refs, node) {
		struct v4l2_ctrl *ctrl = ref->ctrl;
		struct v4l2_ctrl *master = ctrl->cluster[0];
		unsigned int i;

		if (ctrl->flags & V4L2_CTRL_FLAG_VOLATILE) {
			v4l2_ctrl_lock(master);
			/* g_volatile_ctrl will update the current control values */
			for (i = 0; i < master->ncontrols; i++)
				cur_to_new(master->cluster[i]);
			call_op(master, g_volatile_ctrl);
			new_to_req(ref);
			v4l2_ctrl_unlock(master);
			continue;
		}
		if (ref->valid_p_req)
			continue;

		/* Copy the current control value into the request */
		v4l2_ctrl_lock(ctrl);
		cur_to_req(ref);
		v4l2_ctrl_unlock(ctrl);
	}

	mutex_lock(main_hdl->lock);
	WARN_ON(!hdl->request_is_queued);
	list_del_init(&hdl->requests_queued);
	hdl->request_is_queued = false;
	mutex_unlock(main_hdl->lock);
	media_request_object_complete(obj);
	media_request_object_put(obj);
}
EXPORT_SYMBOL(v4l2_ctrl_request_complete);

int v4l2_ctrl_request_setup(struct media_request *req,
			    struct v4l2_ctrl_handler *main_hdl)
{
	struct media_request_object *obj;
	struct v4l2_ctrl_handler *hdl;
	struct v4l2_ctrl_ref *ref;
	int ret = 0;

	if (!req || !main_hdl)
		return 0;

	if (WARN_ON(req->state != MEDIA_REQUEST_STATE_QUEUED))
		return -EBUSY;

	/*
	 * Note that it is valid if nothing was found. It means
	 * that this request doesn't have any controls and so just
	 * wants to leave the controls unchanged.
	 */
	obj = media_request_object_find(req, &req_ops, main_hdl);
	if (!obj)
		return 0;
	if (obj->completed) {
		media_request_object_put(obj);
		return -EBUSY;
	}
	hdl = container_of(obj, struct v4l2_ctrl_handler, req_obj);

	list_for_each_entry(ref, &hdl->ctrl_refs, node)
		ref->req_done = false;

	list_for_each_entry(ref, &hdl->ctrl_refs, node) {
		struct v4l2_ctrl *ctrl = ref->ctrl;
		struct v4l2_ctrl *master = ctrl->cluster[0];
		bool have_new_data = false;
		int i;

		/*
		 * Skip if this control was already handled by a cluster.
		 * Skip button controls and read-only controls.
		 */
		if (ref->req_done || (ctrl->flags & V4L2_CTRL_FLAG_READ_ONLY))
			continue;

		v4l2_ctrl_lock(master);
		for (i = 0; i < master->ncontrols; i++) {
			if (master->cluster[i]) {
				struct v4l2_ctrl_ref *r =
					find_ref(hdl, master->cluster[i]->id);

				if (r->valid_p_req) {
					have_new_data = true;
					break;
				}
			}
		}
		if (!have_new_data) {
			v4l2_ctrl_unlock(master);
			continue;
		}

		for (i = 0; i < master->ncontrols; i++) {
			if (master->cluster[i]) {
				struct v4l2_ctrl_ref *r =
					find_ref(hdl, master->cluster[i]->id);

				req_to_new(r);
				master->cluster[i]->is_new = 1;
				r->req_done = true;
			}
		}
		/*
		 * For volatile autoclusters that are currently in auto mode
		 * we need to discover if it will be set to manual mode.
		 * If so, then we have to copy the current volatile values
		 * first since those will become the new manual values (which
		 * may be overwritten by explicit new values from this set
		 * of controls).
		 */
		if (master->is_auto && master->has_volatiles &&
		    !is_cur_manual(master)) {
			s32 new_auto_val = *master->p_new.p_s32;

			/*
			 * If the new value == the manual value, then copy
			 * the current volatile values.
			 */
			if (new_auto_val == master->manual_mode_value)
				update_from_auto_cluster(master);
		}

		ret = try_or_set_cluster(NULL, master, true, 0);
		v4l2_ctrl_unlock(master);

		if (ret)
			break;
	}

	media_request_object_put(obj);
	return ret;
}
EXPORT_SYMBOL(v4l2_ctrl_request_setup);
