drivers/media/v4l2-core/v4l2-ctrls-request.c

Source file repositories/reference/linux-study-clean/drivers/media/v4l2-core/v4l2-ctrls-request.c

File Facts

System
Linux kernel
Corpus path
drivers/media/v4l2-core/v4l2-ctrls-request.c
Extension
.c
Size
12814 bytes
Lines
506
Domain
Driver Families
Bucket
drivers/media
Inferred role
Driver Families: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

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_obj(*new_hdl);
	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);
	}

Annotation

Implementation Notes