Skip to content

Commit 6350d6a

Browse files
ribaldamchehab
authored andcommitted
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>
1 parent ee929d5 commit 6350d6a

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
@@ -1582,7 +1582,7 @@ int uvc_ctrl_begin(struct uvc_video_chain *chain)
15821582
}
15831583

15841584
static int uvc_ctrl_commit_entity(struct uvc_device *dev,
1585-
struct uvc_entity *entity, int rollback)
1585+
struct uvc_entity *entity, int rollback, struct uvc_control **err_ctrl)
15861586
{
15871587
struct uvc_control *ctrl;
15881588
unsigned int i;
@@ -1624,31 +1624,59 @@ static int uvc_ctrl_commit_entity(struct uvc_device *dev,
16241624

16251625
ctrl->dirty = 0;
16261626

1627-
if (ret < 0)
1627+
if (ret < 0) {
1628+
if (err_ctrl)
1629+
*err_ctrl = ctrl;
16281630
return ret;
1631+
}
16291632
}
16301633

16311634
return 0;
16321635
}
16331636

1637+
static int uvc_ctrl_find_ctrl_idx(struct uvc_entity *entity,
1638+
struct v4l2_ext_controls *ctrls,
1639+
struct uvc_control *uvc_control)
1640+
{
1641+
struct uvc_control_mapping *mapping;
1642+
struct uvc_control *ctrl_found;
1643+
unsigned int i;
1644+
1645+
if (!entity)
1646+
return ctrls->count;
1647+
1648+
for (i = 0; i < ctrls->count; i++) {
1649+
__uvc_find_control(entity, ctrls->controls[i].id, &mapping,
1650+
&ctrl_found, 0);
1651+
if (uvc_control == ctrl_found)
1652+
return i;
1653+
}
1654+
1655+
return ctrls->count;
1656+
}
1657+
16341658
int __uvc_ctrl_commit(struct uvc_fh *handle, int rollback,
1635-
const struct v4l2_ext_control *xctrls,
1636-
unsigned int xctrls_count)
1659+
struct v4l2_ext_controls *ctrls)
16371660
{
16381661
struct uvc_video_chain *chain = handle->chain;
1662+
struct uvc_control *err_ctrl;
16391663
struct uvc_entity *entity;
16401664
int ret = 0;
16411665

16421666
/* Find the control. */
16431667
list_for_each_entry(entity, &chain->entities, chain) {
1644-
ret = uvc_ctrl_commit_entity(chain->dev, entity, rollback);
1668+
ret = uvc_ctrl_commit_entity(chain->dev, entity, rollback,
1669+
&err_ctrl);
16451670
if (ret < 0)
16461671
goto done;
16471672
}
16481673

16491674
if (!rollback)
1650-
uvc_ctrl_send_events(handle, xctrls, xctrls_count);
1675+
uvc_ctrl_send_events(handle, ctrls->controls, ctrls->count);
16511676
done:
1677+
if (ret < 0 && ctrls)
1678+
ctrls->error_idx = uvc_ctrl_find_ctrl_idx(entity, ctrls,
1679+
err_ctrl);
16521680
mutex_unlock(&chain->ctrl_mutex);
16531681
return ret;
16541682
}
@@ -2106,7 +2134,7 @@ int uvc_ctrl_restore_values(struct uvc_device *dev)
21062134
ctrl->dirty = 1;
21072135
}
21082136

2109-
ret = uvc_ctrl_commit_entity(dev, entity, 0);
2137+
ret = uvc_ctrl_commit_entity(dev, entity, 0, NULL);
21102138
if (ret < 0)
21112139
return ret;
21122140
}

drivers/media/usb/uvc/uvc_v4l2.c

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

11021102
if (ioctl == VIDIOC_S_EXT_CTRLS)
1103-
return uvc_ctrl_commit(handle, ctrls->controls, ctrls->count);
1103+
return uvc_ctrl_commit(handle, ctrls);
11041104
else
11051105
return uvc_ctrl_rollback(handle);
11061106
}

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)