aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2012-08-28 17:38:58 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-11-28 07:24:48 -0500
commitf0ed2ce840b3a59b587e8aa398538141a86e9588 (patch)
tree8a17d0bd6229e8a29d01a43d24d3fdfecb03d49a /drivers
parente9de051666a42dc7866267f85869170bcc6b957a (diff)
[media] uvcvideo: Set error_idx properly for extended controls API failures
When one of the requested controls doesn't exist the error_idx field must reflect that situation. For G_EXT_CTRLS and S_EXT_CTRLS, error_idx must be set to the control count. For TRY_EXT_CTRLS, it must be set to the index of the unexisting control. This issue was found by the v4l2-compliance tool. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Acked-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/usb/uvc/uvc_ctrl.c17
-rw-r--r--drivers/media/usb/uvc/uvc_v4l2.c19
2 files changed, 22 insertions, 14 deletions
diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c
index f7061a5ef1d2..7879d306f1fc 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 = -EINVAL; 1064 ret = -ENOENT;
1065 goto done; 1065 goto done;
1066 } 1066 }
1067 1067
@@ -1099,12 +1099,13 @@ 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 || mapping->v4l2_type != V4L2_CTRL_TYPE_MENU) { 1102 if (ctrl == NULL) {
1103 ret = -EINVAL; 1103 ret = -ENOENT;
1104 goto done; 1104 goto done;
1105 } 1105 }
1106 1106
1107 if (query_menu->index >= mapping->menu_count) { 1107 if (mapping->v4l2_type != V4L2_CTRL_TYPE_MENU ||
1108 query_menu->index >= mapping->menu_count) {
1108 ret = -EINVAL; 1109 ret = -EINVAL;
1109 goto done; 1110 goto done;
1110 } 1111 }
@@ -1263,7 +1264,7 @@ static int uvc_ctrl_add_event(struct v4l2_subscribed_event *sev, unsigned elems)
1263 1264
1264 ctrl = uvc_find_control(handle->chain, sev->id, &mapping); 1265 ctrl = uvc_find_control(handle->chain, sev->id, &mapping);
1265 if (ctrl == NULL) { 1266 if (ctrl == NULL) {
1266 ret = -EINVAL; 1267 ret = -ENOENT;
1267 goto done; 1268 goto done;
1268 } 1269 }
1269 1270
@@ -1414,7 +1415,7 @@ int uvc_ctrl_get(struct uvc_video_chain *chain,
1414 1415
1415 ctrl = uvc_find_control(chain, xctrl->id, &mapping); 1416 ctrl = uvc_find_control(chain, xctrl->id, &mapping);
1416 if (ctrl == NULL) 1417 if (ctrl == NULL)
1417 return -EINVAL; 1418 return -ENOENT;
1418 1419
1419 return __uvc_ctrl_get(chain, ctrl, mapping, &xctrl->value); 1420 return __uvc_ctrl_get(chain, ctrl, mapping, &xctrl->value);
1420} 1421}
@@ -1431,7 +1432,9 @@ int uvc_ctrl_set(struct uvc_video_chain *chain,
1431 int ret; 1432 int ret;
1432 1433
1433 ctrl = uvc_find_control(chain, xctrl->id, &mapping); 1434 ctrl = uvc_find_control(chain, xctrl->id, &mapping);
1434 if (ctrl == NULL || (ctrl->info.flags & UVC_CTRL_FLAG_SET_CUR) == 0) 1435 if (ctrl == NULL)
1436 return -ENOENT;
1437 if (!(ctrl->info.flags & UVC_CTRL_FLAG_SET_CUR))
1435 return -EINVAL; 1438 return -EINVAL;
1436 1439
1437 /* Clamp out of range values. */ 1440 /* Clamp out of range values. */
diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c
index f00db3060e0e..e5817b953938 100644
--- a/drivers/media/usb/uvc/uvc_v4l2.c
+++ b/drivers/media/usb/uvc/uvc_v4l2.c
@@ -591,8 +591,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
591 591
592 ret = uvc_ctrl_get(chain, &xctrl); 592 ret = uvc_ctrl_get(chain, &xctrl);
593 uvc_ctrl_rollback(handle); 593 uvc_ctrl_rollback(handle);
594 if (ret >= 0) 594 if (ret < 0)
595 ctrl->value = xctrl.value; 595 return ret == -ENOENT ? -EINVAL : ret;
596
597 ctrl->value = xctrl.value;
596 break; 598 break;
597 } 599 }
598 600
@@ -612,7 +614,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
612 ret = uvc_ctrl_set(chain, &xctrl); 614 ret = uvc_ctrl_set(chain, &xctrl);
613 if (ret < 0) { 615 if (ret < 0) {
614 uvc_ctrl_rollback(handle); 616 uvc_ctrl_rollback(handle);
615 return ret; 617 return ret == -ENOENT ? -EINVAL : ret;
616 } 618 }
617 ret = uvc_ctrl_commit(handle, &xctrl, 1); 619 ret = uvc_ctrl_commit(handle, &xctrl, 1);
618 if (ret == 0) 620 if (ret == 0)
@@ -637,8 +639,9 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
637 ret = uvc_ctrl_get(chain, ctrl); 639 ret = uvc_ctrl_get(chain, ctrl);
638 if (ret < 0) { 640 if (ret < 0) {
639 uvc_ctrl_rollback(handle); 641 uvc_ctrl_rollback(handle);
640 ctrls->error_idx = i; 642 ctrls->error_idx = ret == -ENOENT
641 return ret; 643 ? ctrls->count : i;
644 return ret == -ENOENT ? -EINVAL : ret;
642 } 645 }
643 } 646 }
644 ctrls->error_idx = 0; 647 ctrls->error_idx = 0;
@@ -661,8 +664,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
661 ret = uvc_ctrl_set(chain, ctrl); 664 ret = uvc_ctrl_set(chain, ctrl);
662 if (ret < 0) { 665 if (ret < 0) {
663 uvc_ctrl_rollback(handle); 666 uvc_ctrl_rollback(handle);
664 ctrls->error_idx = i; 667 ctrls->error_idx = (ret == -ENOENT &&
665 return ret; 668 cmd == VIDIOC_S_EXT_CTRLS)
669 ? ctrls->count : i;
670 return ret == -ENOENT ? -EINVAL : ret;
666 } 671 }
667 } 672 }
668 673