Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f0ed2ce8 authored by Laurent Pinchart's avatar Laurent Pinchart Committed by Mauro Carvalho Chehab
Browse files

[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: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent e9de0516
Loading
Loading
Loading
Loading
+10 −7
Original line number Original line Diff line number Diff line
@@ -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 = -EINVAL;
		ret = -ENOENT;
		goto done;
		goto done;
	}
	}


@@ -1099,12 +1099,13 @@ 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 || mapping->v4l2_type != V4L2_CTRL_TYPE_MENU) {
	if (ctrl == NULL) {
		ret = -EINVAL;
		ret = -ENOENT;
		goto done;
		goto done;
	}
	}


	if (query_menu->index >= mapping->menu_count) {
	if (mapping->v4l2_type != V4L2_CTRL_TYPE_MENU ||
	    query_menu->index >= mapping->menu_count) {
		ret = -EINVAL;
		ret = -EINVAL;
		goto done;
		goto done;
	}
	}
@@ -1263,7 +1264,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 = -EINVAL;
		ret = -ENOENT;
		goto done;
		goto done;
	}
	}


@@ -1414,7 +1415,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 -EINVAL;
		return -ENOENT;


	return __uvc_ctrl_get(chain, ctrl, mapping, &xctrl->value);
	return __uvc_ctrl_get(chain, ctrl, mapping, &xctrl->value);
}
}
@@ -1431,7 +1432,9 @@ 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 || (ctrl->info.flags & UVC_CTRL_FLAG_SET_CUR) == 0)
	if (ctrl == NULL)
		return -ENOENT;
	if (!(ctrl->info.flags & UVC_CTRL_FLAG_SET_CUR))
		return -EINVAL;
		return -EINVAL;


	/* Clamp out of range values. */
	/* Clamp out of range values. */
+12 −7
Original line number Original line Diff line number Diff line
@@ -591,7 +591,9 @@ 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;
	}
	}
@@ -612,7 +614,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;
			return ret == -ENOENT ? -EINVAL : ret;
		}
		}
		ret = uvc_ctrl_commit(handle, &xctrl, 1);
		ret = uvc_ctrl_commit(handle, &xctrl, 1);
		if (ret == 0)
		if (ret == 0)
@@ -637,8 +639,9 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
			ret = uvc_ctrl_get(chain, ctrl);
			ret = uvc_ctrl_get(chain, ctrl);
			if (ret < 0) {
			if (ret < 0) {
				uvc_ctrl_rollback(handle);
				uvc_ctrl_rollback(handle);
				ctrls->error_idx = i;
				ctrls->error_idx = ret == -ENOENT
				return ret;
						 ? ctrls->count : i;
				return ret == -ENOENT ? -EINVAL : ret;
			}
			}
		}
		}
		ctrls->error_idx = 0;
		ctrls->error_idx = 0;
@@ -661,8 +664,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
			ret = uvc_ctrl_set(chain, ctrl);
			ret = uvc_ctrl_set(chain, ctrl);
			if (ret < 0) {
			if (ret < 0) {
				uvc_ctrl_rollback(handle);
				uvc_ctrl_rollback(handle);
				ctrls->error_idx = i;
				ctrls->error_idx = (ret == -ENOENT &&
				return ret;
						    cmd == VIDIOC_S_EXT_CTRLS)
						 ? ctrls->count : i;
				return ret == -ENOENT ? -EINVAL : ret;
			}
			}
		}
		}