提交 9c016d61 编写于 作者: R Rafael J. Wysocki 提交者: Linus Torvalds

Partly revert "[media] uvcvideo: Set error_idx properly for extended controls API failures"

Commit f0ed2ce8 ("[media] uvcvideo: Set error_idx properly for
extended controls API failures") causes user space to behave incorrectly
on one of my test machines (there is no sound under KDE 4.9.4 using
pulseaudio and there is a knotify4 process occupying one of the CPU
cores 100% of the time).  Reverting that commit entirely fixes the
problem for me.

However, commit f0ed2ce8 appears to do more than it follows from its
changelog, because the changelog only says about the changes related to
ctrls->error_idx, while the commit additionally changes error codes
returned by various functions in uvc_ctrl.c and uvc_v4l2.c.  It turns
out that the changes of the returned error codes confuse the user spce,
so it is sufficient to revert the part of commit f0ed2ce8 not
mentioned in its changelog to fix the problem.

[ 'ENOENT' is not a valid error return from an ioctl to begin with, and
  I don't understand how anybody ever even thought it would be.  - Linus ]
Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: Mauro Carvalho Chehab <mchehab@redhat.com>
Cc: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
上级 a49f0d1e
...@@ -1061,7 +1061,7 @@ int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, ...@@ -1061,7 +1061,7 @@ int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
ctrl = uvc_find_control(chain, v4l2_ctrl->id, &mapping); ctrl = uvc_find_control(chain, v4l2_ctrl->id, &mapping);
if (ctrl == NULL) { if (ctrl == NULL) {
ret = -ENOENT; ret = -EINVAL;
goto done; goto done;
} }
...@@ -1099,13 +1099,12 @@ int uvc_query_v4l2_menu(struct uvc_video_chain *chain, ...@@ -1099,13 +1099,12 @@ int uvc_query_v4l2_menu(struct uvc_video_chain *chain,
return -ERESTARTSYS; return -ERESTARTSYS;
ctrl = uvc_find_control(chain, query_menu->id, &mapping); ctrl = uvc_find_control(chain, query_menu->id, &mapping);
if (ctrl == NULL) { if (ctrl == NULL || mapping->v4l2_type != V4L2_CTRL_TYPE_MENU) {
ret = -ENOENT; ret = -EINVAL;
goto done; goto done;
} }
if (mapping->v4l2_type != V4L2_CTRL_TYPE_MENU || if (query_menu->index >= mapping->menu_count) {
query_menu->index >= mapping->menu_count) {
ret = -EINVAL; ret = -EINVAL;
goto done; goto done;
} }
...@@ -1264,7 +1263,7 @@ static int uvc_ctrl_add_event(struct v4l2_subscribed_event *sev, unsigned elems) ...@@ -1264,7 +1263,7 @@ static int uvc_ctrl_add_event(struct v4l2_subscribed_event *sev, unsigned elems)
ctrl = uvc_find_control(handle->chain, sev->id, &mapping); ctrl = uvc_find_control(handle->chain, sev->id, &mapping);
if (ctrl == NULL) { if (ctrl == NULL) {
ret = -ENOENT; ret = -EINVAL;
goto done; goto done;
} }
...@@ -1415,7 +1414,7 @@ int uvc_ctrl_get(struct uvc_video_chain *chain, ...@@ -1415,7 +1414,7 @@ int uvc_ctrl_get(struct uvc_video_chain *chain,
ctrl = uvc_find_control(chain, xctrl->id, &mapping); ctrl = uvc_find_control(chain, xctrl->id, &mapping);
if (ctrl == NULL) if (ctrl == NULL)
return -ENOENT; return -EINVAL;
return __uvc_ctrl_get(chain, ctrl, mapping, &xctrl->value); return __uvc_ctrl_get(chain, ctrl, mapping, &xctrl->value);
} }
...@@ -1432,10 +1431,8 @@ int uvc_ctrl_set(struct uvc_video_chain *chain, ...@@ -1432,10 +1431,8 @@ int uvc_ctrl_set(struct uvc_video_chain *chain,
int ret; int ret;
ctrl = uvc_find_control(chain, xctrl->id, &mapping); ctrl = uvc_find_control(chain, xctrl->id, &mapping);
if (ctrl == NULL) if (ctrl == NULL || (ctrl->info.flags & UVC_CTRL_FLAG_SET_CUR) == 0)
return -ENOENT; return -EINVAL;
if (!(ctrl->info.flags & UVC_CTRL_FLAG_SET_CUR))
return -EACCES;
/* Clamp out of range values. */ /* Clamp out of range values. */
switch (mapping->v4l2_type) { switch (mapping->v4l2_type) {
......
...@@ -607,9 +607,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) ...@@ -607,9 +607,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
ret = uvc_ctrl_get(chain, &xctrl); ret = uvc_ctrl_get(chain, &xctrl);
uvc_ctrl_rollback(handle); uvc_ctrl_rollback(handle);
if (ret < 0) if (ret >= 0)
return ret == -ENOENT ? -EINVAL : ret;
ctrl->value = xctrl.value; ctrl->value = xctrl.value;
break; break;
} }
...@@ -634,7 +632,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) ...@@ -634,7 +632,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
ret = uvc_ctrl_set(chain, &xctrl); ret = uvc_ctrl_set(chain, &xctrl);
if (ret < 0) { if (ret < 0) {
uvc_ctrl_rollback(handle); uvc_ctrl_rollback(handle);
return ret == -ENOENT ? -EINVAL : ret; return ret;
} }
ret = uvc_ctrl_commit(handle, &xctrl, 1); ret = uvc_ctrl_commit(handle, &xctrl, 1);
if (ret == 0) if (ret == 0)
...@@ -661,7 +659,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) ...@@ -661,7 +659,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
uvc_ctrl_rollback(handle); uvc_ctrl_rollback(handle);
ctrls->error_idx = ret == -ENOENT ctrls->error_idx = ret == -ENOENT
? ctrls->count : i; ? ctrls->count : i;
return ret == -ENOENT ? -EINVAL : ret; return ret;
} }
} }
ctrls->error_idx = 0; ctrls->error_idx = 0;
...@@ -691,7 +689,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) ...@@ -691,7 +689,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
ctrls->error_idx = (ret == -ENOENT && ctrls->error_idx = (ret == -ENOENT &&
cmd == VIDIOC_S_EXT_CTRLS) cmd == VIDIOC_S_EXT_CTRLS)
? ctrls->count : i; ? ctrls->count : i;
return ret == -ENOENT ? -EINVAL : ret; return ret;
} }
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册