diff options
author | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2012-08-28 17:38:58 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-11-28 07:24:48 -0500 |
commit | f0ed2ce840b3a59b587e8aa398538141a86e9588 (patch) | |
tree | 8a17d0bd6229e8a29d01a43d24d3fdfecb03d49a /drivers | |
parent | e9de051666a42dc7866267f85869170bcc6b957a (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.c | 17 | ||||
-rw-r--r-- | drivers/media/usb/uvc/uvc_v4l2.c | 19 |
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 | ||