media: uvcvideo: Set error_idx during ctrl_commit errors
If we have an error setting a control, return the affected control in the error_idx field. Reviewed-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Signed-off-by: Ricardo Ribalda <ribalda@chromium.org> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
This commit is contained in:
parent
ee929d5a10
commit
6350d6a4ed
|
@ -1582,7 +1582,7 @@ int uvc_ctrl_begin(struct uvc_video_chain *chain)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int uvc_ctrl_commit_entity(struct uvc_device *dev,
|
static int uvc_ctrl_commit_entity(struct uvc_device *dev,
|
||||||
struct uvc_entity *entity, int rollback)
|
struct uvc_entity *entity, int rollback, struct uvc_control **err_ctrl)
|
||||||
{
|
{
|
||||||
struct uvc_control *ctrl;
|
struct uvc_control *ctrl;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
@ -1624,31 +1624,59 @@ static int uvc_ctrl_commit_entity(struct uvc_device *dev,
|
||||||
|
|
||||||
ctrl->dirty = 0;
|
ctrl->dirty = 0;
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0) {
|
||||||
|
if (err_ctrl)
|
||||||
|
*err_ctrl = ctrl;
|
||||||
return ret;
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int uvc_ctrl_find_ctrl_idx(struct uvc_entity *entity,
|
||||||
|
struct v4l2_ext_controls *ctrls,
|
||||||
|
struct uvc_control *uvc_control)
|
||||||
|
{
|
||||||
|
struct uvc_control_mapping *mapping;
|
||||||
|
struct uvc_control *ctrl_found;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
if (!entity)
|
||||||
|
return ctrls->count;
|
||||||
|
|
||||||
|
for (i = 0; i < ctrls->count; i++) {
|
||||||
|
__uvc_find_control(entity, ctrls->controls[i].id, &mapping,
|
||||||
|
&ctrl_found, 0);
|
||||||
|
if (uvc_control == ctrl_found)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ctrls->count;
|
||||||
|
}
|
||||||
|
|
||||||
int __uvc_ctrl_commit(struct uvc_fh *handle, int rollback,
|
int __uvc_ctrl_commit(struct uvc_fh *handle, int rollback,
|
||||||
const struct v4l2_ext_control *xctrls,
|
struct v4l2_ext_controls *ctrls)
|
||||||
unsigned int xctrls_count)
|
|
||||||
{
|
{
|
||||||
struct uvc_video_chain *chain = handle->chain;
|
struct uvc_video_chain *chain = handle->chain;
|
||||||
|
struct uvc_control *err_ctrl;
|
||||||
struct uvc_entity *entity;
|
struct uvc_entity *entity;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
/* Find the control. */
|
/* Find the control. */
|
||||||
list_for_each_entry(entity, &chain->entities, chain) {
|
list_for_each_entry(entity, &chain->entities, chain) {
|
||||||
ret = uvc_ctrl_commit_entity(chain->dev, entity, rollback);
|
ret = uvc_ctrl_commit_entity(chain->dev, entity, rollback,
|
||||||
|
&err_ctrl);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!rollback)
|
if (!rollback)
|
||||||
uvc_ctrl_send_events(handle, xctrls, xctrls_count);
|
uvc_ctrl_send_events(handle, ctrls->controls, ctrls->count);
|
||||||
done:
|
done:
|
||||||
|
if (ret < 0 && ctrls)
|
||||||
|
ctrls->error_idx = uvc_ctrl_find_ctrl_idx(entity, ctrls,
|
||||||
|
err_ctrl);
|
||||||
mutex_unlock(&chain->ctrl_mutex);
|
mutex_unlock(&chain->ctrl_mutex);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -2106,7 +2134,7 @@ int uvc_ctrl_restore_values(struct uvc_device *dev)
|
||||||
ctrl->dirty = 1;
|
ctrl->dirty = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = uvc_ctrl_commit_entity(dev, entity, 0);
|
ret = uvc_ctrl_commit_entity(dev, entity, 0, NULL);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1100,7 +1100,7 @@ static int uvc_ioctl_s_try_ext_ctrls(struct uvc_fh *handle,
|
||||||
ctrls->error_idx = 0;
|
ctrls->error_idx = 0;
|
||||||
|
|
||||||
if (ioctl == VIDIOC_S_EXT_CTRLS)
|
if (ioctl == VIDIOC_S_EXT_CTRLS)
|
||||||
return uvc_ctrl_commit(handle, ctrls->controls, ctrls->count);
|
return uvc_ctrl_commit(handle, ctrls);
|
||||||
else
|
else
|
||||||
return uvc_ctrl_rollback(handle);
|
return uvc_ctrl_rollback(handle);
|
||||||
}
|
}
|
||||||
|
|
|
@ -886,17 +886,15 @@ void uvc_ctrl_status_event(struct uvc_video_chain *chain,
|
||||||
|
|
||||||
int uvc_ctrl_begin(struct uvc_video_chain *chain);
|
int uvc_ctrl_begin(struct uvc_video_chain *chain);
|
||||||
int __uvc_ctrl_commit(struct uvc_fh *handle, int rollback,
|
int __uvc_ctrl_commit(struct uvc_fh *handle, int rollback,
|
||||||
const struct v4l2_ext_control *xctrls,
|
struct v4l2_ext_controls *ctrls);
|
||||||
unsigned int xctrls_count);
|
|
||||||
static inline int uvc_ctrl_commit(struct uvc_fh *handle,
|
static inline int uvc_ctrl_commit(struct uvc_fh *handle,
|
||||||
const struct v4l2_ext_control *xctrls,
|
struct v4l2_ext_controls *ctrls)
|
||||||
unsigned int xctrls_count)
|
|
||||||
{
|
{
|
||||||
return __uvc_ctrl_commit(handle, 0, xctrls, xctrls_count);
|
return __uvc_ctrl_commit(handle, 0, ctrls);
|
||||||
}
|
}
|
||||||
static inline int uvc_ctrl_rollback(struct uvc_fh *handle)
|
static inline int uvc_ctrl_rollback(struct uvc_fh *handle)
|
||||||
{
|
{
|
||||||
return __uvc_ctrl_commit(handle, 1, NULL, 0);
|
return __uvc_ctrl_commit(handle, 1, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
int uvc_ctrl_get(struct uvc_video_chain *chain, struct v4l2_ext_control *xctrl);
|
int uvc_ctrl_get(struct uvc_video_chain *chain, struct v4l2_ext_control *xctrl);
|
||||||
|
|
Loading…
Reference in New Issue