/* 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);
}
}
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);
}
/* * 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);
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->p_req_valid) continue;
/* Copy the current control value into the request */
v4l2_ctrl_lock(ctrl);
cur_to_req(ref);
v4l2_ctrl_unlock(ctrl);
}
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);
/* * 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->p_req_valid) {
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);
ret = req_to_new(r); if (ret) {
v4l2_ctrl_unlock(master); goto error;
}
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);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.