aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2012-12-23 08:39:32 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-12-23 12:39:14 -0500
commit9c016d61097cc39427a2f5025bdd97ac633d26a6 (patch)
tree3a694f797800c0f3c34fb4f6148c824f64b5ca68
parenta49f0d1ea3ec94fc7cf33a7c36a16343b74bd565 (diff)
Partly revert "[media] uvcvideo: Set error_idx properly for extended controls API failures"
Commit f0ed2ce840b3 ("[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 f0ed2ce840b3 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 f0ed2ce840b3 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: Rafael 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: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--drivers/media/usb/uvc/uvc_ctrl.c19
-rw-r--r--drivers/media/usb/uvc/uvc_v4l2.c12
2 files changed, 13 insertions, 18 deletions
diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c
index 516a5b188ea5..2bb7613ddebb 100644
--- a/drivers/media/usb/uvc/uvc_ctrl.c
+++ b/drivers/media/usb/uvc/uvc_ctrl.c
@@ -1061,7 +1061,7 @@ int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
1061 1061
1062 ctrl = uvc_find_control(chain, v4l2_ctrl->id, &mapping); 1062 ctrl = uvc_find_control(chain, v4l2_ctrl->id, &mapping);
1063 if (ctrl == NULL) { 1063 if (ctrl == NULL) {
1064 ret = -ENOENT; 1064 ret = -EINVAL;
1065 goto done; 1065 goto done;
1066 } 1066 }
1067 1067
@@ -1099,13 +1099,12 @@ int uvc_query_v4l2_menu(struct uvc_video_chain *chain,
1099 return -ERESTARTSYS; 1099 return -ERESTARTSYS;
1100 1100
1101 ctrl = uvc_find_control(chain, query_menu->id, &mapping); 1101 ctrl = uvc_find_control(chain, query_menu->id, &mapping);
1102 if (ctrl == NULL) { 1102 if (ctrl == NULL || mapping->v4l2_type != V4L2_CTRL_TYPE_MENU) {
1103 ret = -ENOENT; 1103 ret = -EINVAL;
1104 goto done; 1104 goto done;
1105 } 1105 }
1106 1106
1107 if (mapping->v4l2_type != V4L2_CTRL_TYPE_MENU || 1107 if (query_menu->index >= mapping->menu_count) {
1108 query_menu->index >= mapping->menu_count) {
1109 ret = -EINVAL; 1108 ret = -EINVAL;
1110 goto done; 1109 goto done;
1111 } 1110 }
@@ -1264,7 +1263,7 @@ static int uvc_ctrl_add_event(struct v4l2_subscribed_event *sev, unsigned elems)
1264 1263
1265 ctrl = uvc_find_control(handle->chain, sev->id, &mapping); 1264 ctrl = uvc_find_control(handle->chain, sev->id, &mapping);
1266 if (ctrl == NULL) { 1265 if (ctrl == NULL) {
1267 ret = -ENOENT; 1266 ret = -EINVAL;
1268 goto done; 1267 goto done;
1269 } 1268 }
1270 1269
@@ -1415,7 +1414,7 @@ int uvc_ctrl_get(struct uvc_video_chain *chain,
1415 1414
1416 ctrl = uvc_find_control(chain, xctrl->id, &mapping); 1415 ctrl = uvc_find_control(chain, xctrl->id, &mapping);
1417 if (ctrl == NULL) 1416 if (ctrl == NULL)
1418 return -ENOENT; 1417 return -EINVAL;
1419 1418
1420 return __uvc_ctrl_get(chain, ctrl, mapping, &xctrl->value); 1419 return __uvc_ctrl_get(chain, ctrl, mapping, &xctrl->value);
1421} 1420}
@@ -1432,10 +1431,8 @@ int uvc_ctrl_set(struct uvc_video_chain *chain,
1432 int ret; 1431 int ret;
1433 1432
1434 ctrl = uvc_find_control(chain, xctrl->id, &mapping); 1433 ctrl = uvc_find_control(chain, xctrl->id, &mapping);
1435 if (ctrl == NULL) 1434 if (ctrl == NULL || (ctrl->info.flags & UVC_CTRL_FLAG_SET_CUR) == 0)
1436 return -ENOENT; 1435 return -EINVAL;
1437 if (!(ctrl->info.flags & UVC_CTRL_FLAG_SET_CUR))
1438 return -EACCES;
1439 1436
1440 /* Clamp out of range values. */ 1437 /* Clamp out of range values. */
1441 switch (mapping->v4l2_type) { 1438 switch (mapping->v4l2_type) {
diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c
index 8e056046bc20..f2ee8c6b0d8d 100644
--- a/drivers/media/usb/uvc/uvc_v4l2.c
+++ b/drivers/media/usb/uvc/uvc_v4l2.c
@@ -607,10 +607,8 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
607 607
608 ret = uvc_ctrl_get(chain, &xctrl); 608 ret = uvc_ctrl_get(chain, &xctrl);
609 uvc_ctrl_rollback(handle); 609 uvc_ctrl_rollback(handle);
610 if (ret < 0) 610 if (ret >= 0)
611 return ret == -ENOENT ? -EINVAL : ret; 611 ctrl->value = xctrl.value;
612
613 ctrl->value = xctrl.value;
614 break; 612 break;
615 } 613 }
616 614
@@ -634,7 +632,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
634 ret = uvc_ctrl_set(chain, &xctrl); 632 ret = uvc_ctrl_set(chain, &xctrl);
635 if (ret < 0) { 633 if (ret < 0) {
636 uvc_ctrl_rollback(handle); 634 uvc_ctrl_rollback(handle);
637 return ret == -ENOENT ? -EINVAL : ret; 635 return ret;
638 } 636 }
639 ret = uvc_ctrl_commit(handle, &xctrl, 1); 637 ret = uvc_ctrl_commit(handle, &xctrl, 1);
640 if (ret == 0) 638 if (ret == 0)
@@ -661,7 +659,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
661 uvc_ctrl_rollback(handle); 659 uvc_ctrl_rollback(handle);
662 ctrls->error_idx = ret == -ENOENT 660 ctrls->error_idx = ret == -ENOENT
663 ? ctrls->count : i; 661 ? ctrls->count : i;
664 return ret == -ENOENT ? -EINVAL : ret; 662 return ret;
665 } 663 }
666 } 664 }
667 ctrls->error_idx = 0; 665 ctrls->error_idx = 0;
@@ -691,7 +689,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
691 ctrls->error_idx = (ret == -ENOENT && 689 ctrls->error_idx = (ret == -ENOENT &&
692 cmd == VIDIOC_S_EXT_CTRLS) 690 cmd == VIDIOC_S_EXT_CTRLS)
693 ? ctrls->count : i; 691 ? ctrls->count : i;
694 return ret == -ENOENT ? -EINVAL : ret; 692 return ret;
695 } 693 }
696 } 694 }
697 695