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/media | |
| 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/media')
| -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 f7061a5ef1d..7879d306f1f 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 f00db3060e0..e5817b95393 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 | ||
