Skip to content

Commit 972f412

Browse files
ribaldagregkh
authored andcommitted
media: uvcvideo: Set error_idx during ctrl_commit errors
[ Upstream commit 6350d6a ] 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> Stable-dep-of: d9fecd0 ("media: uvcvideo: Only save async fh if success") Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent c113bcc commit 972f412

File tree

3 files changed

+40
-14
lines changed

3 files changed

+40
-14
lines changed

drivers/media/usb/uvc/uvc_ctrl.c

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1645,7 +1645,7 @@ int uvc_ctrl_begin(struct uvc_video_chain *chain)
16451645
}
16461646

16471647
static int uvc_ctrl_commit_entity(struct uvc_device *dev,
1648-
struct uvc_entity *entity, int rollback)
1648+
struct uvc_entity *entity, int rollback, struct uvc_control **err_ctrl)
16491649
{
16501650
struct uvc_control *ctrl;
16511651
unsigned int i;
@@ -1687,31 +1687,59 @@ static int uvc_ctrl_commit_entity(struct uvc_device *dev,
16871687

16881688
ctrl->dirty = 0;
16891689

1690-
if (ret < 0)
1690+
if (ret < 0) {
1691+
if (err_ctrl)
1692+
*err_ctrl = ctrl;
16911693
return ret;
1694+
}
16921695
}
16931696

16941697
return 0;
16951698
}
16961699

1700+
static int uvc_ctrl_find_ctrl_idx(struct uvc_entity *entity,
1701+
struct v4l2_ext_controls *ctrls,
1702+
struct uvc_control *uvc_control)
1703+
{
1704+
struct uvc_control_mapping *mapping;
1705+
struct uvc_control *ctrl_found;
1706+
unsigned int i;
1707+
1708+
if (!entity)
1709+
return ctrls->count;
1710+
1711+
for (i = 0; i < ctrls->count; i++) {
1712+
__uvc_find_control(entity, ctrls->controls[i].id, &mapping,
1713+
&ctrl_found, 0);
1714+
if (uvc_control == ctrl_found)
1715+
return i;
1716+
}
1717+
1718+
return ctrls->count;
1719+
}
1720+
16971721
int __uvc_ctrl_commit(struct uvc_fh *handle, int rollback,
1698-
const struct v4l2_ext_control *xctrls,
1699-
unsigned int xctrls_count)
1722+
struct v4l2_ext_controls *ctrls)
17001723
{
17011724
struct uvc_video_chain *chain = handle->chain;
1725+
struct uvc_control *err_ctrl;
17021726
struct uvc_entity *entity;
17031727
int ret = 0;
17041728

17051729
/* Find the control. */
17061730
list_for_each_entry(entity, &chain->entities, chain) {
1707-
ret = uvc_ctrl_commit_entity(chain->dev, entity, rollback);
1731+
ret = uvc_ctrl_commit_entity(chain->dev, entity, rollback,
1732+
&err_ctrl);
17081733
if (ret < 0)
17091734
goto done;
17101735
}
17111736

17121737
if (!rollback)
1713-
uvc_ctrl_send_events(handle, xctrls, xctrls_count);
1738+
uvc_ctrl_send_events(handle, ctrls->controls, ctrls->count);
17141739
done:
1740+
if (ret < 0 && ctrls)
1741+
ctrls->error_idx = uvc_ctrl_find_ctrl_idx(entity, ctrls,
1742+
err_ctrl);
17151743
mutex_unlock(&chain->ctrl_mutex);
17161744
return ret;
17171745
}
@@ -2165,7 +2193,7 @@ int uvc_ctrl_restore_values(struct uvc_device *dev)
21652193
ctrl->dirty = 1;
21662194
}
21672195

2168-
ret = uvc_ctrl_commit_entity(dev, entity, 0);
2196+
ret = uvc_ctrl_commit_entity(dev, entity, 0, NULL);
21692197
if (ret < 0)
21702198
return ret;
21712199
}

drivers/media/usb/uvc/uvc_v4l2.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1102,7 +1102,7 @@ static int uvc_ioctl_s_try_ext_ctrls(struct uvc_fh *handle,
11021102
ctrls->error_idx = 0;
11031103

11041104
if (ioctl == VIDIOC_S_EXT_CTRLS)
1105-
return uvc_ctrl_commit(handle, ctrls->controls, ctrls->count);
1105+
return uvc_ctrl_commit(handle, ctrls);
11061106
else
11071107
return uvc_ctrl_rollback(handle);
11081108
}

drivers/media/usb/uvc/uvcvideo.h

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -886,17 +886,15 @@ void uvc_ctrl_status_event(struct uvc_video_chain *chain,
886886

887887
int uvc_ctrl_begin(struct uvc_video_chain *chain);
888888
int __uvc_ctrl_commit(struct uvc_fh *handle, int rollback,
889-
const struct v4l2_ext_control *xctrls,
890-
unsigned int xctrls_count);
889+
struct v4l2_ext_controls *ctrls);
891890
static inline int uvc_ctrl_commit(struct uvc_fh *handle,
892-
const struct v4l2_ext_control *xctrls,
893-
unsigned int xctrls_count)
891+
struct v4l2_ext_controls *ctrls)
894892
{
895-
return __uvc_ctrl_commit(handle, 0, xctrls, xctrls_count);
893+
return __uvc_ctrl_commit(handle, 0, ctrls);
896894
}
897895
static inline int uvc_ctrl_rollback(struct uvc_fh *handle)
898896
{
899-
return __uvc_ctrl_commit(handle, 1, NULL, 0);
897+
return __uvc_ctrl_commit(handle, 1, NULL);
900898
}
901899

902900
int uvc_ctrl_get(struct uvc_video_chain *chain, struct v4l2_ext_control *xctrl);

0 commit comments

Comments
 (0)