From patchwork Fri Dec 2 17:21:35 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Ricardo Ribalda X-Patchwork-Id: 630495 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 80CACC4321E for ; Fri, 2 Dec 2022 17:21:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233821AbiLBRVy (ORCPT ); Fri, 2 Dec 2022 12:21:54 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33148 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233133AbiLBRVx (ORCPT ); Fri, 2 Dec 2022 12:21:53 -0500 Received: from mail-ej1-x62a.google.com (mail-ej1-x62a.google.com [IPv6:2a00:1450:4864:20::62a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7A837E7854 for ; Fri, 2 Dec 2022 09:21:52 -0800 (PST) Received: by mail-ej1-x62a.google.com with SMTP id bj12so13034774ejb.13 for ; Fri, 02 Dec 2022 09:21:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=EhS+JBqxHQJxyGff9DpvK+kt09IedMih5IP8k22GY28=; b=CDmPCRBe4IMk6p0oPlsz1zfKi7fsgZn30ytnDuUodDsq+R0J3sCgnUXk2+KAwY84qz dhYh/JyqBoWJgHb86Hw+Uc/s6Ej7yTzgzxNPALs9bCzWRbpPq++MZeNZxEd9DTOyXmWf oNAHsYnMqAvXhSUylCHPDssa5ks2raFhpco4s= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=EhS+JBqxHQJxyGff9DpvK+kt09IedMih5IP8k22GY28=; b=orDOTL9kpq3k/qxU38mR7jbx9TMJSkGOw0fqJUUdJX9+mz0wTS0UJQg7KJ7CbU9h0Z Tcb8VgAG2NetHkfTExq4Fr8+TMMOlUKvPcqkTs3/TB6R8ogeMJeQn0qKOa2qOwPAbdGE CvbBAfo6cBqvqh5qO4nJb/6o5xh0n1j2DdTIcBjWJ+2Julu2PEwzThAplPm+yTUubYQu B2O5x5iuCi7wpVa3TxH54VBPBv5+UtUBScCvFRVOHXara0NzEk4+TcB4Jf/G0aFtQDJm gp8gEQEf+6QEL6se3lle+0NSTVWDNFXqTZlzwvwiKyZ4t+wmXInkbLkN9XVenBx81KB/ 6D/A== X-Gm-Message-State: ANoB5pmJpeekePtRKiclM0vwItiikSTCi6NZlcEDVJx9kGwY7VVg1hgO Olyos96BNmWJv/w8dj5ckGORfA== X-Google-Smtp-Source: AA0mqf7JWgDbMIHLMrOHMVSeCYaxJbQsRDC1nP0YmwjU76wCPH/5s9B8MdAkRHhsIDfobJHnnQ/z6w== X-Received: by 2002:a17:906:2352:b0:7ad:a030:487e with SMTP id m18-20020a170906235200b007ada030487emr62542555eja.508.1670001710996; Fri, 02 Dec 2022 09:21:50 -0800 (PST) Received: from alco.roam.corp.google.com (80.71.134.83.ipv4.parknet.dk. [80.71.134.83]) by smtp.gmail.com with ESMTPSA id fe17-20020a1709072a5100b007be301a1d51sm3206685ejc.211.2022.12.02.09.21.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 02 Dec 2022 09:21:50 -0800 (PST) From: Ricardo Ribalda Date: Fri, 02 Dec 2022 18:21:35 +0100 Subject: [PATCH RESEND v2 1/7] media: uvcvideo: uvc_ctrl_is_accessible: check for INACTIVE MIME-Version: 1.0 Message-Id: <20220920-resend-v4l2-compliance-v2-1-b0ceb15353ac@chromium.org> References: <20220920-resend-v4l2-compliance-v2-0-b0ceb15353ac@chromium.org> In-Reply-To: <20220920-resend-v4l2-compliance-v2-0-b0ceb15353ac@chromium.org> To: Mauro Carvalho Chehab , Laurent Pinchart Cc: Hans Verkuil , Hans Verkuil , linux-media@vger.kernel.org, Ricardo Ribalda , linux-kernel@vger.kernel.org, Hans Verkuil X-Mailer: b4 0.11.0-dev-696ae X-Developer-Signature: v=1; a=openpgp-sha256; l=5265; i=ribalda@chromium.org; h=from:subject:message-id; bh=tVt2FQwFWMzsSMl0muyb+NJLs92ZMfXZ/5urTCanEaY=; b=owEBbQKS/ZANAwAKAdE30T7POsSIAcsmYgBjijQj5Jwb/s3MtZM6LnzqyJVwaqUWM2+ULqkL3TGt 3vilUAyJAjMEAAEKAB0WIQREDzjr+/4oCDLSsx7RN9E+zzrEiAUCY4o0IwAKCRDRN9E+zzrEiOlCEA Ca5s+4X4YKwXvy9cPwI/cDHlh15ZgXJZ+3di0azDRwhMWVjUZDovHBJhz7sDnwO7gWCn7omPDq5mdF IEgEJw5ZyyqjFp33oDe4xjBdafldE23hYh8gXUj6DjyxsdkSrLbUaZfS+PeCeiHNEVu8FWnsvEtwkJ Nv34577sjadbyXkNpaQFJFAdfbB5BOy667bUv06sCYdrzNAlXS1JyJmanypFGF4pUHAuQLH74LdWHq Z55HJJQCp8e+PqgHP/Lenhxe6FbBNvjIQ8D2abzxdOENvF8lND3G5q1zWbXYD+BeLFjhhq0bh/iIY4 bQdpdusLhL3llwyD88qaeaYOv/vnKpjGwdkRsVYuO8CaHQEaxNO/zjJ6k9NM0zU6fSCeC06MlmKup8 qKk1p4Cmm/nK6UDPpDOV+iA5LCFocWb9ADgm30RqsBKBr7+j7Of+D9KaNXWr6JUk5lTbPcIEBthnaf Qsg7kW2hihNgm1+AehAEodK3mqIcw29zpU2PCtERvf7hHZ7rD75wYTfFWBz3TM+PnTARDuVI/aXLDF b7tTXVdx8zezvsWCO91S80571pnbwQEUbKcA8R1b9+8Uv3CcvyjEo8Oi/XrtrQxJ+NpmgbK2h7GaaX 3554EW94M64DmLTeV+PNX7aObgbodMhFZahMNMoXg3zysIb3cHGxA89rBW0A== X-Developer-Key: i=ribalda@chromium.org; a=openpgp; fpr=9EC3BB66E2FC129A6F90B39556A0D81F9F782DA9 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org From: Hans Verkuil Check for inactive controls in uvc_ctrl_is_accessible(). Use the new value for the master_id controls if present, otherwise use the existing value to determine if it is OK to set the control. Doing this here avoids attempting to set an inactive control, which will return an error from the USB device, which returns an invalid errorcode. This fixes: warn: v4l2-test-controls.cpp(483): s_ctrl returned EIO   warn: v4l2-test-controls.cpp(483): s_ctrl returned EIO test VIDIOC_G/S_CTRL: OK   warn: v4l2-test-controls.cpp(739): s_ext_ctrls returned EIO   warn: v4l2-test-controls.cpp(739): s_ext_ctrls returned EIO   warn: v4l2-test-controls.cpp(816): s_ext_ctrls returned EIO test VIDIOC_G/S/TRY_EXT_CTRLS: OK Tested with: v4l2-ctl -c auto_exposure=1 OK v4l2-ctl -c exposure_time_absolute=251 OK v4l2-ctl -c auto_exposure=3 OK v4l2-ctl -c exposure_time_absolute=251 VIDIOC_S_EXT_CTRLS: failed: Input/output error exposure_time_absolute: Input/output error ERROR v4l2-ctl -c auto_exposure=3,exposure_time_absolute=251,auto_exposure=1 v4l2-ctl -C auto_exposure,exposure_time_absolute   auto_exposure: 1 exposure_time_absolute: 251 Reviewed-by: Ricardo Ribalda Signed-off-by: Hans Verkuil --- drivers/media/usb/uvc/uvc_ctrl.c | 47 +++++++++++++++++++++++++++++++++++++++- drivers/media/usb/uvc/uvc_v4l2.c | 4 ++-- drivers/media/usb/uvc/uvcvideo.h | 3 ++- 3 files changed, 50 insertions(+), 4 deletions(-) diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c index 8c208db9600b..7153ee5aabb1 100644 --- a/drivers/media/usb/uvc/uvc_ctrl.c +++ b/drivers/media/usb/uvc/uvc_ctrl.c @@ -1064,11 +1064,33 @@ static int uvc_query_v4l2_class(struct uvc_video_chain *chain, u32 req_id, return 0; } +/** + * uvc_ctrl_is_accessible() - Check if a control can be read/writen/tried. + * @chain: uvc_video_chain that the controls belong to. + * @v4l2_id: video4linux id of the control. + * @ctrl: Other controls that will be accessed in the ioctl. + * @ioctl: ioctl used to access the control. + * + * Check if a control can be accessed by a specicific ioctl operation, + * assuming that other controls are also going to be accessed by that ioctl. + * We need to check the value of the other controls, to support operations + * where a master value is changed with a slave value. Eg. + * auto_exposure=1,exposure_time_absolute=251 + * + */ int uvc_ctrl_is_accessible(struct uvc_video_chain *chain, u32 v4l2_id, - bool read) + const struct v4l2_ext_controls *ctrls, + unsigned long ioctl) { + struct uvc_control_mapping *master_map = NULL; + struct uvc_control *master_ctrl = NULL; struct uvc_control_mapping *mapping; struct uvc_control *ctrl; + bool read = ioctl == VIDIOC_G_EXT_CTRLS; + bool try = ioctl == VIDIOC_TRY_EXT_CTRLS; + s32 val; + int ret; + int i; if (__uvc_query_v4l2_class(chain, v4l2_id, 0) >= 0) return -EACCES; @@ -1083,6 +1105,29 @@ int uvc_ctrl_is_accessible(struct uvc_video_chain *chain, u32 v4l2_id, if (!(ctrl->info.flags & UVC_CTRL_FLAG_SET_CUR) && !read) return -EACCES; + if (read || try || !mapping->master_id) + return 0; + + /* + * Iterate backwards in cases where the master control is accessed + * multiple times in the same ioctl. We want the last value. + */ + for (i = ctrls->count - 1; i >= 0; i--) { + if (ctrls->controls[i].id == mapping->master_id) + return ctrls->controls[i].value == + mapping->master_manual ? 0 : -EACCES; + } + + __uvc_find_control(ctrl->entity, mapping->master_id, &master_map, + &master_ctrl, 0); + + if (!master_ctrl || !(master_ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR)) + return 0; + + ret = __uvc_ctrl_get(chain, master_ctrl, master_map, &val); + if (ret >= 0 && val != mapping->master_manual) + return -EACCES; + return 0; } diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c index 4cc3fa6b8c98..d95168cdc2d1 100644 --- a/drivers/media/usb/uvc/uvc_v4l2.c +++ b/drivers/media/usb/uvc/uvc_v4l2.c @@ -1020,8 +1020,8 @@ static int uvc_ctrl_check_access(struct uvc_video_chain *chain, int ret = 0; for (i = 0; i < ctrls->count; ++ctrl, ++i) { - ret = uvc_ctrl_is_accessible(chain, ctrl->id, - ioctl == VIDIOC_G_EXT_CTRLS); + ret = uvc_ctrl_is_accessible(chain, ctrl->id, ctrls, + ioctl); if (ret) break; } diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h index 24c911aeebce..644d5fcf2eef 100644 --- a/drivers/media/usb/uvc/uvcvideo.h +++ b/drivers/media/usb/uvc/uvcvideo.h @@ -905,7 +905,8 @@ static inline int uvc_ctrl_rollback(struct uvc_fh *handle) int uvc_ctrl_get(struct uvc_video_chain *chain, struct v4l2_ext_control *xctrl); int uvc_ctrl_set(struct uvc_fh *handle, struct v4l2_ext_control *xctrl); int uvc_ctrl_is_accessible(struct uvc_video_chain *chain, u32 v4l2_id, - bool read); + const struct v4l2_ext_controls *ctrls, + unsigned long ioctl); int uvc_xu_ctrl_query(struct uvc_video_chain *chain, struct uvc_xu_control_query *xqry); From patchwork Fri Dec 2 17:21:39 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ricardo Ribalda X-Patchwork-Id: 630494 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3E4CDC4321E for ; Fri, 2 Dec 2022 17:22:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233799AbiLBRV6 (ORCPT ); Fri, 2 Dec 2022 12:21:58 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33198 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233907AbiLBRVz (ORCPT ); Fri, 2 Dec 2022 12:21:55 -0500 Received: from mail-ej1-x62a.google.com (mail-ej1-x62a.google.com [IPv6:2a00:1450:4864:20::62a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 672F36F0F6 for ; Fri, 2 Dec 2022 09:21:54 -0800 (PST) Received: by mail-ej1-x62a.google.com with SMTP id bj12so13035028ejb.13 for ; Fri, 02 Dec 2022 09:21:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=1TOCYbcSDGYo9uBDae2YM90jdMCkFXFL9pKLx8gH8lk=; b=Rv8G+gUWpIQ0RpbmMyAexFTzcwXByWUGtbzZhNjQV34dWvYdqMGVOyV2zgXVLnStUI JreWZrXYPkvYSMfX3iLfHq8zfjqx+7nFjRu1T6UvpwfVUHXcrrefkFAztT2nA9iV1aBf 9PKgvJcAuYoIrWWM1bdOOwvDxl6pCt6GEzHVw= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=1TOCYbcSDGYo9uBDae2YM90jdMCkFXFL9pKLx8gH8lk=; b=D+/SnYqWR66dNcYiOAQVeMoLvpKd0NHY67g6Zr72D5ZFKj607DUh7hwwXh1rtQ6MUy Yk1X6/YEeanz2BWBTId8BWn/+iJ18lgAT0p85WkUhYMte1kRnDwdr/7rsBbPMKvknfwN o1hbxyuA5pqhszVrX2HcsgPcqkck4CQBzQdTIo5Z/OL/ZTRAuycwDdIydFoJ45jUitey M3he4IZbqYQBkAf4LveIzwX/G2qK2Qm42B/f7yboynbEZpu5EjMeYywYHz4wdjdezPDu Wy7U2HRt67RuatT9mbUgQMl44FW3ja9OTTlEn1w+4o9no5ba6TKJNUEhnrzxi/KJS7XO Lm0w== X-Gm-Message-State: ANoB5pkKy/T3SFA2UcsnMGlb74vTZMFWRaQhICljZdIhlCBccBufjLuC oGnoh9EDQ4Mnc4Q1fyOqHym9JQ== X-Google-Smtp-Source: AA0mqf4YI5O/1Q0etPueEfxbOhCrWpfHsgxQYe97PVIfsp7yScExzeZqmoEDXX7hwm2eGhImyXPRwA== X-Received: by 2002:a17:906:a387:b0:7bc:2ad:7c1e with SMTP id k7-20020a170906a38700b007bc02ad7c1emr34567522ejz.588.1670001713981; Fri, 02 Dec 2022 09:21:53 -0800 (PST) Received: from alco.roam.corp.google.com (80.71.134.83.ipv4.parknet.dk. [80.71.134.83]) by smtp.gmail.com with ESMTPSA id fe17-20020a1709072a5100b007be301a1d51sm3206685ejc.211.2022.12.02.09.21.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 02 Dec 2022 09:21:53 -0800 (PST) From: Ricardo Ribalda Date: Fri, 02 Dec 2022 18:21:39 +0100 Subject: [PATCH RESEND v2 5/7] media: uvcvideo: Fix handling on Bitmask controls MIME-Version: 1.0 Message-Id: <20220920-resend-v4l2-compliance-v2-5-b0ceb15353ac@chromium.org> References: <20220920-resend-v4l2-compliance-v2-0-b0ceb15353ac@chromium.org> In-Reply-To: <20220920-resend-v4l2-compliance-v2-0-b0ceb15353ac@chromium.org> To: Mauro Carvalho Chehab , Laurent Pinchart Cc: Hans Verkuil , Hans Verkuil , linux-media@vger.kernel.org, Ricardo Ribalda , linux-kernel@vger.kernel.org, Hans Verkuil X-Mailer: b4 0.11.0-dev-696ae X-Developer-Signature: v=1; a=openpgp-sha256; l=4061; i=ribalda@chromium.org; h=from:subject:message-id; bh=Q6Ty28eEyDWUJosEKd4UTXCsSOQeb3Aa2fdI+JNxN3I=; b=owEBbQKS/ZANAwAKAdE30T7POsSIAcsmYgBjijQpN+Gp11+KJtyf2NqCaonYO3z4AG74/0P4ktMz X+9mnGyJAjMEAAEKAB0WIQREDzjr+/4oCDLSsx7RN9E+zzrEiAUCY4o0KQAKCRDRN9E+zzrEiDabD/ 4hdednARo9vIZ63cZE6rj/LqS7zBcNbf4ARBjcT0uoLqLwPIoOBReqPeG7oJyDA7hLjdCVFOvjQpLp C2Cskx1EE/9OoCEVpnh8KpSiqv4vOdkh9MrXErvEs3ftBp4ygmFnC1epjDrjn7R5YzQAyMdNdew04S qOmrIGTuDkPpo0rwg+zjuwMuPSUwmAuHr21BHWQpCEp10jfllYv8bc5Wpnh7c3u+36ri8mTD5ACwva EcWSQjHA1/krvk24Rm/78XqJWJ/l6ocDc+1vLfspiPYs/jzKO1UxAJwHY6FpYWeQLVApg2KyVPVuaf Ha6Xc5oFzZOZKJdzbjtNtIt5ds5L5zpUS6TtQEWdoWHsLZneng1Md9yh7PuCSmDq2dCSLBqxCP6Ujw kw+qmFX5Y550YZ+alIAdvaqxkIrWNB1jR962Mxg7bD4Zm+FOHlFlA/O7EO5TXGB+Kj+7DVrARWAXxL d/x8eUeFbdqXGhxDtt/FPH64Qz5pIrgElhgSfQplbJo2XSkCyArPy8d3C5bAHQk0AbW0A59U9+P6DX 9Xn0B6UzUIwaxA89+K7Md2aTY/wxc5bQ4ZlUOJw+tKmbb1PtGpDGNrn+vwm4SVXjR5JNBgV9xqHJ5N J1RsVk6vooHSyqNZPxJ888bSHIsN3xBVxlQG7/n8vad5+q4YuseFYRFGI4iQ== X-Developer-Key: i=ribalda@chromium.org; a=openpgp; fpr=9EC3BB66E2FC129A6F90B39556A0D81F9F782DA9 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Minimum and step values for V4L2_CTRL_TYPE_BITMASK controls should be 0. There is no need to query the camera firmware about this and maybe get invalid results. Also value should be masked to the max value advertised by the hardware. Finally, handle uvc 1.5 mask controls that use MAX instead of RES to describe the valid bits. Fixes v4l2-compliane: Control ioctls (Input 0): fail: v4l2-test-controls.cpp(97): minimum must be 0 for a bitmask control test VIDIOC_QUERY_EXT_CTRL/QUERYMENU: FAIL Signed-off-by: Ricardo Ribalda --- drivers/media/usb/uvc/uvc_ctrl.c | 53 +++++++++++++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 12 deletions(-) diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c index 7153ee5aabb1..526572044e82 100644 --- a/drivers/media/usb/uvc/uvc_ctrl.c +++ b/drivers/media/usb/uvc/uvc_ctrl.c @@ -1145,6 +1145,25 @@ static const char *uvc_map_get_name(const struct uvc_control_mapping *map) return "Unknown Control"; } +static u32 uvc_get_ctrl_bitmap(struct uvc_control *ctrl, + struct uvc_control_mapping *mapping) +{ + /* + * Some controls, like CT_AE_MODE_CONTROL use GET_RES to + * represent the number of bits supported, those controls + * do not list GET_MAX as supported. + */ + if (ctrl->info.flags & UVC_CTRL_FLAG_GET_MAX) + return mapping->get(mapping, UVC_GET_MAX, + uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX)); + + if (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES) + return mapping->get(mapping, UVC_GET_RES, + uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES)); + + return ~0; +} + static int __uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, struct uvc_control *ctrl, struct uvc_control_mapping *mapping, @@ -1219,6 +1238,12 @@ static int __uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, v4l2_ctrl->step = 0; return 0; + case V4L2_CTRL_TYPE_BITMASK: + v4l2_ctrl->minimum = 0; + v4l2_ctrl->maximum = uvc_get_ctrl_bitmap(ctrl, mapping); + v4l2_ctrl->step = 0; + return 0; + default: break; } @@ -1320,19 +1345,14 @@ int uvc_query_v4l2_menu(struct uvc_video_chain *chain, menu_info = &mapping->menu_info[query_menu->index]; - if (mapping->data_type == UVC_CTRL_DATA_TYPE_BITMASK && - (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES)) { - s32 bitmap; - + if (mapping->data_type == UVC_CTRL_DATA_TYPE_BITMASK) { if (!ctrl->cached) { ret = uvc_ctrl_populate_cache(chain, ctrl); if (ret < 0) goto done; } - bitmap = mapping->get(mapping, UVC_GET_RES, - uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES)); - if (!(bitmap & menu_info->value)) { + if (!(uvc_get_ctrl_bitmap(ctrl, mapping) & menu_info->value)) { ret = -EINVAL; goto done; } @@ -1815,6 +1835,18 @@ int uvc_ctrl_set(struct uvc_fh *handle, value = xctrl->value; break; + case V4L2_CTRL_TYPE_BITMASK: + if (!ctrl->cached) { + ret = uvc_ctrl_populate_cache(chain, ctrl); + if (ret < 0) + return ret; + } + + xctrl->value = max(0, xctrl->value); + xctrl->value &= uvc_get_ctrl_bitmap(ctrl, mapping); + value = xctrl->value; + break; + case V4L2_CTRL_TYPE_BOOLEAN: xctrl->value = clamp(xctrl->value, 0, 1); value = xctrl->value; @@ -1829,17 +1861,14 @@ int uvc_ctrl_set(struct uvc_fh *handle, * Valid menu indices are reported by the GET_RES request for * UVC controls that support it. */ - if (mapping->data_type == UVC_CTRL_DATA_TYPE_BITMASK && - (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES)) { + if (mapping->data_type == UVC_CTRL_DATA_TYPE_BITMASK) { if (!ctrl->cached) { ret = uvc_ctrl_populate_cache(chain, ctrl); if (ret < 0) return ret; } - step = mapping->get(mapping, UVC_GET_RES, - uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES)); - if (!(step & value)) + if (!(uvc_get_ctrl_bitmap(ctrl, mapping) & value)) return -EINVAL; } From patchwork Fri Dec 2 17:21:41 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ricardo Ribalda X-Patchwork-Id: 630493 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 64029C4321E for ; Fri, 2 Dec 2022 17:22:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234247AbiLBRWP (ORCPT ); Fri, 2 Dec 2022 12:22:15 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33286 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231470AbiLBRV7 (ORCPT ); Fri, 2 Dec 2022 12:21:59 -0500 Received: from mail-ej1-x631.google.com (mail-ej1-x631.google.com [IPv6:2a00:1450:4864:20::631]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1F6307F8AD for ; Fri, 2 Dec 2022 09:21:57 -0800 (PST) Received: by mail-ej1-x631.google.com with SMTP id vv4so13044452ejc.2 for ; Fri, 02 Dec 2022 09:21:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=EjhL47z9Nl+DaAg29fxcGxhmqEDsIaNpB1QWBqLjg58=; b=gUybeRSnsTC0aPYHfRkd5QF9Nu44JbnujAhiWe8zqjr0Na8yfDqSl4ugB+81lmz0qV EZHYcR0O8pfYxb5qaPjjJsyKJNE9VIWMvCr+dNxSTLpvwo73ZLiqppnhEl+gvTftUMUT gMLacG2c4ujg6pOGC7I1P9mR8FUnfz3GEtZLM= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=EjhL47z9Nl+DaAg29fxcGxhmqEDsIaNpB1QWBqLjg58=; b=quUYYp5Ngez1pP3h7xtQbD6Clf43kfvlS/MfJ0iz8mZZbLpKUOXTPMHe8F/hGQdaKe 8QZjvanyNC+5gL9OmfvkP7uetcLaqjSwmGkOZ/Ghs+CYc642X6oEY9fKB+UusiH4laA9 roa8onDkHCj8nj1FpKLwzbdUFvkPKkd1SceMNrIoxekbSh/Mt+uZorKBviuftajb6wnb aTckrV0bLZY3LZygHiCldShyegVGDmvGvvEkkm4i+2ZxaPCYFGBuhd83SRuWFVW2bWjD DiTKe71fpkhwdEcXAk8plX6JMYRks/0iYe0UrnSZXQkre3znI3KXmlOZp3Yz7dV8v4YT FgOg== X-Gm-Message-State: ANoB5pkgK3TvnWzcZ4Uc5MBJKUHtqPr58vkzY1A1NYvHEXR2JBplmnJq bpDnjkS58S9vtTNBFjEjnGn1Iw== X-Google-Smtp-Source: AA0mqf5PKE8Pht6Z/r4N0ReXRIVBfmjamBnYSYrpzoEcdDOrUxewhHkjUzYLXu23ZB3eNAlGoPZWMA== X-Received: by 2002:a17:907:986b:b0:7ad:b7c2:a2f7 with SMTP id ko11-20020a170907986b00b007adb7c2a2f7mr45617347ejc.227.1670001715642; Fri, 02 Dec 2022 09:21:55 -0800 (PST) Received: from alco.roam.corp.google.com (80.71.134.83.ipv4.parknet.dk. [80.71.134.83]) by smtp.gmail.com with ESMTPSA id fe17-20020a1709072a5100b007be301a1d51sm3206685ejc.211.2022.12.02.09.21.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 02 Dec 2022 09:21:55 -0800 (PST) From: Ricardo Ribalda Date: Fri, 02 Dec 2022 18:21:41 +0100 Subject: [PATCH RESEND v2 7/7] media: uvcvideo: Use standard names for menus MIME-Version: 1.0 Message-Id: <20220920-resend-v4l2-compliance-v2-7-b0ceb15353ac@chromium.org> References: <20220920-resend-v4l2-compliance-v2-0-b0ceb15353ac@chromium.org> In-Reply-To: <20220920-resend-v4l2-compliance-v2-0-b0ceb15353ac@chromium.org> To: Mauro Carvalho Chehab , Laurent Pinchart Cc: Hans Verkuil , Hans Verkuil , linux-media@vger.kernel.org, Ricardo Ribalda , linux-kernel@vger.kernel.org, Hans Verkuil X-Mailer: b4 0.11.0-dev-696ae X-Developer-Signature: v=1; a=openpgp-sha256; l=12904; i=ribalda@chromium.org; h=from:subject:message-id; bh=CQ0Q3iEnjgF/RdatrIffgvHt8KgiNN9Adkhd3ymwRxg=; b=owEBbQKS/ZANAwAKAdE30T7POsSIAcsmYgBjijQsHCyx0OPBe0KIY2MAlct06a6Z8vNSFlgl59Ra dYmEr3CJAjMEAAEKAB0WIQREDzjr+/4oCDLSsx7RN9E+zzrEiAUCY4o0LAAKCRDRN9E+zzrEiLsDEA CbR5VB6GomNQ5k9uB94p/hQJV0SIQWBUa1L1ZtyRc0ovxw0Baysc6YVnr/xgxS7zexj467+n+mEHXB ppsw/DtQnuiJa/vv4/XcCYbwTG0kM/KiS5vTLznCfHnToC/DLQTQvytS+s70W8fv6cy8KwGOOtVUAg 4HwFFbT2DT1RKEs87bqcBOZtBPKHM+913oSyL8iPB3/663JNjJFhVtjTOD1EPuupo92WfcTUT5Jeno U66lZpxDDF1AElyCvOTeoBW3/FsE6i17nNLGGzuk96+0NhyKvvFmmBY2p8K8BhX5v/7lsISQze3kfR JdqNgcUcQ9a6ruuuUdVOPPEQPsnhcb04xB094umEdomMsa+FiD6ELNnnQ+CDhKcSGIH+Nkv2LIJGbo 60tCcPqk5K5LmUmqOAFov5EJUW6fO0DIHIjQ3xgccJhb57+c3yz1+rycQNueAGvQD32EdQqb0SVVFI ZsLOqP5i1ZBju9p79IeytwsmP+sBZBtp33Dr2vNz4v9Y3eDK9DyYiMWx8j8xmI6cHsvtIET54rzBYH Rxbx49rc74D9Mbro2Bakfb1sHri+/WveUWyZopShstgiwCTxS11WoKLBNKX9HgwdcumFu66bJMzPYU 4Y/EFhHF9Cx0Wcpvht5clDthsQuavOLQi9B4dmYM3rxkYzPRt5X44KNJJh5A== X-Developer-Key: i=ribalda@chromium.org; a=openpgp; fpr=9EC3BB66E2FC129A6F90B39556A0D81F9F782DA9 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Instead of duplicating the menu info, use the one from the core. Also, do not use extra memory for 1:1 mappings. Signed-off-by: Ricardo Ribalda Suggested-by: Laurent Pinchart --- drivers/media/usb/uvc/uvc_ctrl.c | 116 +++++++++++++++++++++++++------------ drivers/media/usb/uvc/uvc_driver.c | 9 +-- drivers/media/usb/uvc/uvc_v4l2.c | 81 ++++++++++++++++++++------ drivers/media/usb/uvc/uvcvideo.h | 3 +- include/uapi/linux/uvcvideo.h | 3 +- 5 files changed, 146 insertions(+), 66 deletions(-) diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c index df273b829961..5c28d8aace37 100644 --- a/drivers/media/usb/uvc/uvc_ctrl.c +++ b/drivers/media/usb/uvc/uvc_ctrl.c @@ -363,19 +363,31 @@ static const u32 uvc_control_classes[] = { V4L2_CID_USER_CLASS, }; -static const struct uvc_menu_info power_line_frequency_controls[] = { - { 0, "Disabled" }, - { 1, "50 Hz" }, - { 2, "60 Hz" }, - { 3, "Auto" }, -}; +static const int exposure_auto_mapping[] = { 2, 1, 4, 8 }; -static const struct uvc_menu_info exposure_auto_controls[] = { - { 2, "Auto Mode" }, - { 1, "Manual Mode" }, - { 4, "Shutter Priority Mode" }, - { 8, "Aperture Priority Mode" }, -}; +static u32 uvc_mapping_get_menu_value(struct uvc_control_mapping *mapping, + u32 idx) +{ + if (!test_bit(idx, &mapping->menu_mask)) + return 0; + + if (mapping->menu_mapping) + return mapping->menu_mapping[idx]; + + return idx; +} + +static const char +*uvc_mapping_get_menu_name(struct uvc_control_mapping *mapping, u32 idx) +{ + if (!test_bit(idx, &mapping->menu_mask)) + return NULL; + + if (mapping->menu_names) + return mapping->menu_names[idx]; + + return v4l2_ctrl_get_menu(mapping->id)[idx]; +} static s32 uvc_ctrl_get_zoom(struct uvc_control_mapping *mapping, u8 query, const u8 *data) @@ -524,8 +536,8 @@ static const struct uvc_control_mapping uvc_ctrl_mappings[] = { .offset = 0, .v4l2_type = V4L2_CTRL_TYPE_MENU, .data_type = UVC_CTRL_DATA_TYPE_BITMASK, - .menu_info = exposure_auto_controls, - .menu_mask = BIT_MASK(ARRAY_SIZE(exposure_auto_controls)), + .menu_mapping = exposure_auto_mapping, + .menu_mask = GENMASK(ARRAY_SIZE(exposure_auto_mapping) - 1, 0), .slave_ids = { V4L2_CID_EXPOSURE_ABSOLUTE, }, }, { @@ -730,8 +742,7 @@ static const struct uvc_control_mapping uvc_ctrl_mappings_uvc11[] = { .offset = 0, .v4l2_type = V4L2_CTRL_TYPE_MENU, .data_type = UVC_CTRL_DATA_TYPE_ENUM, - .menu_info = power_line_frequency_controls, - .menu_mask = BIT_MASK(ARRAY_SIZE(power_line_frequency_controls) - 1), + .menu_mask = GENMASK(V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0), }, }; @@ -744,8 +755,7 @@ static const struct uvc_control_mapping uvc_ctrl_mappings_uvc15[] = { .offset = 0, .v4l2_type = V4L2_CTRL_TYPE_MENU, .data_type = UVC_CTRL_DATA_TYPE_ENUM, - .menu_info = power_line_frequency_controls, - .menu_mask = BIT_MASK(ARRAY_SIZE(power_line_frequency_controls)), + .menu_mask = GENMASK(V4L2_CID_POWER_LINE_FREQUENCY_AUTO, 0), }, }; @@ -972,13 +982,17 @@ static s32 __uvc_ctrl_get_value(struct uvc_control_mapping *mapping, s32 value = mapping->get(mapping, UVC_GET_CUR, data); if (mapping->v4l2_type == V4L2_CTRL_TYPE_MENU) { - const struct uvc_menu_info *menu = mapping->menu_info; unsigned int i; - for (i = 0; BIT(i) <= mapping->menu_mask; ++i, ++menu) { + for (i = 0; BIT(i) <= mapping->menu_mask; ++i) { + u32 menu_value; + if (!test_bit(i, &mapping->menu_mask)) continue; - if (menu->value == value) { + + menu_value = uvc_mapping_get_menu_value(mapping, i); + + if (menu_value == value) { value = i; break; } @@ -1174,7 +1188,6 @@ static int __uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, { struct uvc_control_mapping *master_map = NULL; struct uvc_control *master_ctrl = NULL; - const struct uvc_menu_info *menu; unsigned int i; memset(v4l2_ctrl, 0, sizeof(*v4l2_ctrl)); @@ -1219,11 +1232,15 @@ static int __uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, v4l2_ctrl->maximum = fls(mapping->menu_mask) - 1; v4l2_ctrl->step = 1; - menu = mapping->menu_info; - for (i = 0; BIT(i) <= mapping->menu_mask; ++i, ++menu) { + for (i = 0; BIT(i) <= mapping->menu_mask; ++i) { + u32 menu_value; + if (!test_bit(i, &mapping->menu_mask)) continue; - if (menu->value == v4l2_ctrl->default_value) { + + menu_value = uvc_mapping_get_menu_value(mapping, i); + + if (menu_value == v4l2_ctrl->default_value) { v4l2_ctrl->default_value = i; break; } @@ -1322,11 +1339,11 @@ int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, int uvc_query_v4l2_menu(struct uvc_video_chain *chain, struct v4l2_querymenu *query_menu) { - const struct uvc_menu_info *menu_info; struct uvc_control_mapping *mapping; struct uvc_control *ctrl; u32 index = query_menu->index; u32 id = query_menu->id; + const char *name; int ret; memset(query_menu, 0, sizeof(*query_menu)); @@ -1348,22 +1365,28 @@ int uvc_query_v4l2_menu(struct uvc_video_chain *chain, goto done; } - menu_info = &mapping->menu_info[query_menu->index]; - if (mapping->data_type == UVC_CTRL_DATA_TYPE_BITMASK) { + u32 menu_value; + if (!ctrl->cached) { ret = uvc_ctrl_populate_cache(chain, ctrl); if (ret < 0) goto done; } - if (!(uvc_get_ctrl_bitmap(ctrl, mapping) & menu_info->value)) { + menu_value = uvc_mapping_get_menu_value(mapping, + query_menu->index); + if (!(uvc_get_ctrl_bitmap(ctrl, mapping) & menu_value)) { ret = -EINVAL; goto done; } } - strscpy(query_menu->name, menu_info->name, sizeof(query_menu->name)); + name = uvc_mapping_get_menu_name(mapping, query_menu->index); + if (name) + strscpy(query_menu->name, name, sizeof(query_menu->name)); + else + ret = -EINVAL; done: mutex_unlock(&chain->ctrl_mutex); @@ -1865,7 +1888,7 @@ int uvc_ctrl_set(struct uvc_fh *handle, if (!test_bit(xctrl->value, &mapping->menu_mask)) return -EINVAL; - value = mapping->menu_info[xctrl->value].value; + value = uvc_mapping_get_menu_value(mapping, xctrl->value); /* * Valid menu indices are reported by the GET_RES request for @@ -2311,12 +2334,28 @@ static int __uvc_ctrl_add_mapping(struct uvc_video_chain *chain, INIT_LIST_HEAD(&map->ev_subs); - size = sizeof(*mapping->menu_info) * fls(mapping->menu_mask); - map->menu_info = kmemdup(mapping->menu_info, size, GFP_KERNEL); - if (map->menu_info == NULL) { - kfree(map->name); - kfree(map); - return -ENOMEM; + if (mapping->menu_mapping && mapping->menu_mask) { + size = sizeof(mapping->menu_mapping[0]) * + fls(mapping->menu_mask); + map->menu_mapping = kmemdup(mapping->menu_mapping, size, + GFP_KERNEL); + if (!map->menu_mapping) { + kfree(map->name); + kfree(map); + return -ENOMEM; + } + } + if (mapping->menu_names && mapping->menu_mask) { + size = sizeof(mapping->menu_names[0]) * + fls(mapping->menu_mask); + map->menu_names = kmemdup(mapping->menu_names, size, + GFP_KERNEL); + if (!map->menu_names) { + kfree(map->menu_mapping); + kfree(map->name); + kfree(map); + return -ENOMEM; + } } if (map->get == NULL) @@ -2661,7 +2700,8 @@ static void uvc_ctrl_cleanup_mappings(struct uvc_device *dev, list_for_each_entry_safe(mapping, nm, &ctrl->info.mappings, list) { list_del(&mapping->list); - kfree(mapping->menu_info); + kfree(mapping->menu_names); + kfree(mapping->menu_mapping); kfree(mapping->name); kfree(mapping); } diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c index abdb9ca7eed6..97c267e75fa4 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c @@ -2661,11 +2661,6 @@ MODULE_PARM_DESC(timeout, "Streaming control requests timeout"); * Driver initialization and cleanup */ -static const struct uvc_menu_info power_line_frequency_controls_limited[] = { - { 1, "50 Hz" }, - { 2, "60 Hz" }, -}; - static const struct uvc_control_mapping uvc_ctrl_power_line_mapping_limited = { .id = V4L2_CID_POWER_LINE_FREQUENCY, .entity = UVC_GUID_UVC_PROCESSING, @@ -2674,8 +2669,8 @@ static const struct uvc_control_mapping uvc_ctrl_power_line_mapping_limited = { .offset = 0, .v4l2_type = V4L2_CTRL_TYPE_MENU, .data_type = UVC_CTRL_DATA_TYPE_ENUM, - .menu_info = power_line_frequency_controls_limited, - .menu_mask = BIT_MASK(ARRAY_SIZE(power_line_frequency_controls_limited)), + .menu_mask = GENMASK(V4L2_CID_POWER_LINE_FREQUENCY_60HZ, + V4L2_CID_POWER_LINE_FREQUENCY_50HZ), }; static const struct uvc_device_info uvc_ctrl_power_line_limited = { diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c index e6792fd46bf5..89581c1559df 100644 --- a/drivers/media/usb/uvc/uvc_v4l2.c +++ b/drivers/media/usb/uvc/uvc_v4l2.c @@ -25,6 +25,64 @@ #include "uvcvideo.h" +static int uvc_control_xu_2_mapping(struct uvc_control_mapping *map, + struct uvc_xu_control_mapping *xmap) +{ + char (*names)[UVC_MENU_NAME_LEN]; + unsigned int i; + u32 *mapping; + size_t size; + + /* Prevent excessive memory consumption, as well as integer + * overflows. + */ + if (xmap->menu_count == 0 || + xmap->menu_count > UVC_MAX_CONTROL_MENU_ENTRIES) + return -EINVAL; + + map->menu_mask = BIT_MASK(xmap->menu_count); + + size = xmap->menu_count * sizeof(*map->menu_mapping); + mapping = kzalloc(size, GFP_KERNEL); + if (!mapping) + return -ENOMEM; + + for (i = 0; i < xmap->menu_count ; i++) + if (copy_from_user(&mapping[i], &xmap->menu_info[i].value, + sizeof(mapping[i]))) { + kfree(mapping); + return -ENOMEM; + } + + map->menu_mapping = mapping; + + /* + * Always use the standard naming if available. + */ + if (v4l2_ctrl_get_menu(map->id)) + return 0; + + size = xmap->menu_count * sizeof(map->menu_names[0]); + names = kzalloc(size, GFP_KERNEL); + if (!names) { + kfree(mapping); + return -ENOMEM; + } + + for (i = 0; i < xmap->menu_count ; i++) { + /* sizeof(names[i]) - 1: to take care of \0 */ + if (copy_from_user(&names[i], &xmap->menu_info[i].name, + sizeof(names[i]) - 1)) { + kfree(names); + kfree(mapping); + return -ENOMEM; + } + } + map->menu_names = names; + + return 0; +} + /* ------------------------------------------------------------------------ * UVC ioctls */ @@ -32,7 +90,6 @@ static int uvc_ioctl_ctrl_map(struct uvc_video_chain *chain, struct uvc_xu_control_mapping *xmap) { struct uvc_control_mapping *map; - unsigned int size; int ret; map = kzalloc(sizeof(*map), GFP_KERNEL); @@ -63,24 +120,9 @@ static int uvc_ioctl_ctrl_map(struct uvc_video_chain *chain, break; case V4L2_CTRL_TYPE_MENU: - /* - * Prevent excessive memory consumption, as well as integer - * overflows. - */ - if (xmap->menu_count == 0 || - xmap->menu_count > UVC_MAX_CONTROL_MENU_ENTRIES) { - ret = -EINVAL; - goto free_map; - } - - size = xmap->menu_count * sizeof(*map->menu_info); - map->menu_info = memdup_user(xmap->menu_info, size); - if (IS_ERR(map->menu_info)) { - ret = PTR_ERR(map->menu_info); + ret = uvc_control_xu_2_mapping(map, xmap); + if (ret) goto free_map; - } - - map->menu_mask = BIT_MASK(xmap->menu_count); break; default: @@ -92,7 +134,8 @@ static int uvc_ioctl_ctrl_map(struct uvc_video_chain *chain, ret = uvc_ctrl_add_mapping(chain, map); - kfree(map->menu_info); + kfree(map->menu_names); + kfree(map->menu_mapping); free_map: kfree(map); diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h index 7e2339fc256e..8ebd7ee2934d 100644 --- a/drivers/media/usb/uvc/uvcvideo.h +++ b/drivers/media/usb/uvc/uvcvideo.h @@ -254,7 +254,8 @@ struct uvc_control_mapping { enum v4l2_ctrl_type v4l2_type; u32 data_type; - const struct uvc_menu_info *menu_info; + const u32 *menu_mapping; + const char (*menu_names)[UVC_MENU_NAME_LEN]; unsigned long menu_mask; u32 master_id; diff --git a/include/uapi/linux/uvcvideo.h b/include/uapi/linux/uvcvideo.h index 8288137387c0..1b64b6aa40b5 100644 --- a/include/uapi/linux/uvcvideo.h +++ b/include/uapi/linux/uvcvideo.h @@ -36,9 +36,10 @@ UVC_CTRL_FLAG_GET_MAX | UVC_CTRL_FLAG_GET_RES | \ UVC_CTRL_FLAG_GET_DEF) +#define UVC_MENU_NAME_LEN 32 struct uvc_menu_info { __u32 value; - __u8 name[32]; + __u8 name[UVC_MENU_NAME_LEN]; }; struct uvc_xu_control_mapping {