From patchwork Thu Sep 27 15:16:15 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 1514831 Return-Path: X-Original-To: patchwork-linux-media@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id 7F45FDF266 for ; Thu, 27 Sep 2012 15:15:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754926Ab2I0PPv (ORCPT ); Thu, 27 Sep 2012 11:15:51 -0400 Received: from perceval.ideasonboard.com ([95.142.166.194]:60154 "EHLO perceval.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754382Ab2I0PPu (ORCPT ); Thu, 27 Sep 2012 11:15:50 -0400 Received: from avalon.ideasonboard.com (unknown [91.178.154.29]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id C890835A8A; Thu, 27 Sep 2012 17:15:49 +0200 (CEST) From: Laurent Pinchart To: linux-media@vger.kernel.org Cc: Hans Verkuil Subject: [PATCH 1/6] uvcvideo: Set error_idx properly for extended controls API failures Date: Thu, 27 Sep 2012 17:16:15 +0200 Message-Id: <1348758980-21683-2-git-send-email-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 1.7.8.6 In-Reply-To: <1348758980-21683-1-git-send-email-laurent.pinchart@ideasonboard.com> References: <1348758980-21683-1-git-send-email-laurent.pinchart@ideasonboard.com> Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org 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 --- drivers/media/usb/uvc/uvc_ctrl.c | 17 ++++++++++------- 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 f7061a5..7879d30 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, ctrl = uvc_find_control(chain, v4l2_ctrl->id, &mapping); if (ctrl == NULL) { - ret = -EINVAL; + ret = -ENOENT; goto done; } @@ -1099,12 +1099,13 @@ int uvc_query_v4l2_menu(struct uvc_video_chain *chain, return -ERESTARTSYS; ctrl = uvc_find_control(chain, query_menu->id, &mapping); - if (ctrl == NULL || mapping->v4l2_type != V4L2_CTRL_TYPE_MENU) { - ret = -EINVAL; + if (ctrl == NULL) { + ret = -ENOENT; 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; 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); if (ctrl == NULL) { - ret = -EINVAL; + ret = -ENOENT; goto done; } @@ -1414,7 +1415,7 @@ int uvc_ctrl_get(struct uvc_video_chain *chain, ctrl = uvc_find_control(chain, xctrl->id, &mapping); if (ctrl == NULL) - return -EINVAL; + return -ENOENT; return __uvc_ctrl_get(chain, ctrl, mapping, &xctrl->value); } @@ -1431,7 +1432,9 @@ int uvc_ctrl_set(struct uvc_video_chain *chain, int ret; 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; /* Clamp out of range values. */ diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c index f00db30..e5817b9 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) ret = uvc_ctrl_get(chain, &xctrl); uvc_ctrl_rollback(handle); - if (ret >= 0) - ctrl->value = xctrl.value; + if (ret < 0) + return ret == -ENOENT ? -EINVAL : ret; + + ctrl->value = xctrl.value; 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); if (ret < 0) { uvc_ctrl_rollback(handle); - return ret; + return ret == -ENOENT ? -EINVAL : ret; } ret = uvc_ctrl_commit(handle, &xctrl, 1); 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); if (ret < 0) { uvc_ctrl_rollback(handle); - ctrls->error_idx = i; - return ret; + ctrls->error_idx = ret == -ENOENT + ? ctrls->count : i; + return ret == -ENOENT ? -EINVAL : ret; } } 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); if (ret < 0) { uvc_ctrl_rollback(handle); - ctrls->error_idx = i; - return ret; + ctrls->error_idx = (ret == -ENOENT && + cmd == VIDIOC_S_EXT_CTRLS) + ? ctrls->count : i; + return ret == -ENOENT ? -EINVAL : ret; } }