From patchwork Mon Oct 17 20:54:41 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dan Vacura X-Patchwork-Id: 616008 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 48555C43217 for ; Mon, 17 Oct 2022 20:55:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230394AbiJQUzi (ORCPT ); Mon, 17 Oct 2022 16:55:38 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41162 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230370AbiJQUzg (ORCPT ); Mon, 17 Oct 2022 16:55:36 -0400 Received: from mail1.bemta31.messagelabs.com (mail1.bemta31.messagelabs.com [67.219.246.114]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0185E6C975; Mon, 17 Oct 2022 13:55:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=motorola.com; s=Selector; t=1666040129; i=@motorola.com; bh=NOhktsFLmQtBuXz/JYn15RmVV9EK16MqKyqGXNDWM9M=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Transfer-Encoding; b=RSSb7hRksdVVjg4v9ib36feuf8bmLyMaOTJDGUVnqz2Oh3/8ZRm7HmBG2z62K8Gpf d8eHiGwRly6MJ6S0j2id3ZRdhbpsNXB/FuGjan3h5OT+LCcfQ5hJNrA+fVrdSVikuu GyaHLClH1DU58D8aZNmJXoMxEHvq/Dz1hSWr0WZnPRIkAluMu9txaHFnGRd1butFSD MnsxsZyP83KFlAD+qwAniisvlQ/z+NJmtF9ypIFWjIDrQC+eoZUy9tmc1/op7CdX/h iK4PfGh6bK/ms2ZX3P1lHWuvxP0I8t+EJD5Ctie7DVO4OZw7emrcN1iWPL9hOOIfo7 F/vMxuBsQEXFg== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFvrEIsWRWlGSWpSXmKPExsWS8eKJmK7DQd9 kg7/7OC2OtT1ht3hyoJ3RonfZHjaL5sXr2Sw6Jy5ht1jYtoTF4vKuOWwWi5a1MltsabvCZPHj Tx+zxYKNjxgtVi04wO7A4zG7Yyarx6ZVnWwe++euYfdY3DeZ1aP/r4HHlv2fGT0+b5ILYI9iz cxLyq9IYM24NOs+W8FytYrLzy6xNTDeVehi5OIQEpjGJPF9+l9mCGctk0Tz78nsXYycHGwCah ILXq9iBrFFBGQlDl/5DVbELNDAIrFy2nlWkISwgLvE/PtTWLoYOThYBFQl5rSkgZi8ApYSM3Y EglRICMhL7D94lhkkzClgJbFhqjpIWAioYvOBLWBDeAUEJU7OfMICYjMDlTdvnc08gZF3FpLU LCSpBYxMqxhNi1OLylKLdE31kooy0zNKchMzc/QSq3QT9UqLdVMTi0t0DfUSy4v1UouL9Yorc 5NzUvTyUks2MQKDP6WIccUOxknL/ugdYpTkYFIS5e2Y4ZssxJeUn1KZkVicEV9UmpNafIhRho NDSYL35w6gnGBRanpqRVpmDjASYdISHDxKIryd24DSvMUFibnFmekQqVOMuhyd+7sOMAux5OX npUqJ8/7YB1QkAFKUUZoHNwKWFC4xykoJ8zIyMDAI8RSkFuVmlqDKv2IU52BUEua9vx9oCk9m XgncpldARzABHZGx3wvkiJJEhJRUA1PxzISXEgeEznz4rvecNVG+8aztNO/1vyQsTHQafebVB q7bW6Gxagmb2JnaqGX/Oy7wXD6vx/8uWcRh1t67J9adOnhy9jWhnOO+J3pS+VZ/ieqcO/0OY7 mulviMJ6fTd1xgeJ9+wZB31RLWu992MrmVdBlsltt3cpcYf5VSu3+RTLypjZnjl9JDiuk/bO9 zZvpOdd+qwuC/8mbxTZ009x9sveeCXy+7zWL59MIm7n0d1hxrWNoUy2dua95YwXq39NZD77na UTWCxxVE+1vspW97/r0pPH9ltO6hkPaqb8HbC9NdP5hyHrYtVVC/mH5Bo6957vl3Dq+s40qfN htv2nvmLsNnW4av0he9b3Rz2SqxFGckGmoxFxUnAgCBF8NrhQMAAA== X-Env-Sender: w36195@motorola.com X-Msg-Ref: server-26.tower-686.messagelabs.com!1666040127!469899!1 X-Originating-IP: [104.232.228.22] X-SYMC-ESS-Client-Auth: outbound-route-from=pass X-StarScan-Received: X-StarScan-Version: 9.87.3; banners=-,-,- X-VirusChecked: Checked Received: (qmail 11647 invoked from network); 17 Oct 2022 20:55:28 -0000 Received: from unknown (HELO va32lpfpp02.lenovo.com) (104.232.228.22) by server-26.tower-686.messagelabs.com with ECDHE-RSA-AES256-GCM-SHA384 encrypted SMTP; 17 Oct 2022 20:55:28 -0000 Received: from ilclmmrp01.lenovo.com (ilclmmrp01.mot.com [100.65.83.165]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by va32lpfpp02.lenovo.com (Postfix) with ESMTPS id 4Mrq5C5wk0z50GGl; Mon, 17 Oct 2022 20:55:27 +0000 (UTC) Received: from p1g3.mot.com (unknown [100.64.172.121]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: w36195) by ilclmmrp01.lenovo.com (Postfix) with ESMTPSA id 4Mrq5C4N2Nzbpxx; Mon, 17 Oct 2022 20:55:27 +0000 (UTC) From: Dan Vacura To: linux-usb@vger.kernel.org Cc: Daniel Scally , Thinh Nguyen , Jeff Vanhoof , Dan Vacura , stable@vger.kernel.org, Greg Kroah-Hartman , Jonathan Corbet , Laurent Pinchart , Felipe Balbi , Paul Elder , Michael Grzeschik , linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org Subject: [PATCH v3 3/6] usb: gadget: uvc: fix sg handling in error case Date: Mon, 17 Oct 2022 15:54:41 -0500 Message-Id: <20221017205446.523796-4-w36195@motorola.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20221017205446.523796-1-w36195@motorola.com> References: <20221017205446.523796-1-w36195@motorola.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org If there is a transmission error the buffer will be returned too early, causing a memory fault as subsequent requests for that buffer are still queued up to be sent. Refactor the error handling to wait for the final request to come in before reporting back the buffer to userspace for all transfer types (bulk/isoc/isoc_sg). This ensures userspace knows if the frame was successfully sent. Fixes: e81e7f9a0eb9 ("usb: gadget: uvc: add scatter gather support") Cc: # 859c675d84d4: usb: gadget: uvc: consistently use define for headerlen Cc: # f262ce66d40c: usb: gadget: uvc: use on returned header len in video_encode_isoc_sg Cc: # 61aa709ca58a: usb: gadget: uvc: rework uvcg_queue_next_buffer to uvcg_complete_buffer Cc: # 9b969f93bcef: usb: gadget: uvc: giveback vb2 buffer on req complete Cc: # aef11279888c: usb: gadget: uvc: improve sg exit condition Cc: Signed-off-by: Dan Vacura --- V1 -> V2: - undo error rename - change uvcg_info to uvcg_dbg V2 -> V3: - no changes drivers/usb/gadget/function/uvc_queue.c | 8 +++++--- drivers/usb/gadget/function/uvc_video.c | 18 ++++++++++++++---- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/drivers/usb/gadget/function/uvc_queue.c b/drivers/usb/gadget/function/uvc_queue.c index ec500ee499ee..0aa3d7e1f3cc 100644 --- a/drivers/usb/gadget/function/uvc_queue.c +++ b/drivers/usb/gadget/function/uvc_queue.c @@ -304,6 +304,7 @@ int uvcg_queue_enable(struct uvc_video_queue *queue, int enable) queue->sequence = 0; queue->buf_used = 0; + queue->flags &= ~UVC_QUEUE_DROP_INCOMPLETE; } else { ret = vb2_streamoff(&queue->queue, queue->queue.type); if (ret < 0) @@ -329,10 +330,11 @@ int uvcg_queue_enable(struct uvc_video_queue *queue, int enable) void uvcg_complete_buffer(struct uvc_video_queue *queue, struct uvc_buffer *buf) { - if ((queue->flags & UVC_QUEUE_DROP_INCOMPLETE) && - buf->length != buf->bytesused) { - buf->state = UVC_BUF_STATE_QUEUED; + if (queue->flags & UVC_QUEUE_DROP_INCOMPLETE) { + queue->flags &= ~UVC_QUEUE_DROP_INCOMPLETE; + buf->state = UVC_BUF_STATE_ERROR; vb2_set_plane_payload(&buf->buf.vb2_buf, 0, 0); + vb2_buffer_done(&buf->buf.vb2_buf, VB2_BUF_STATE_ERROR); return; } diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c index 91a58567beac..dd54841b0b3e 100644 --- a/drivers/usb/gadget/function/uvc_video.c +++ b/drivers/usb/gadget/function/uvc_video.c @@ -88,6 +88,7 @@ uvc_video_encode_bulk(struct usb_request *req, struct uvc_video *video, struct uvc_buffer *buf) { void *mem = req->buf; + struct uvc_request *ureq = req->context; int len = video->req_size; int ret; @@ -113,13 +114,14 @@ uvc_video_encode_bulk(struct usb_request *req, struct uvc_video *video, video->queue.buf_used = 0; buf->state = UVC_BUF_STATE_DONE; list_del(&buf->queue); - uvcg_complete_buffer(&video->queue, buf); video->fid ^= UVC_STREAM_FID; + ureq->last_buf = buf; video->payload_size = 0; } if (video->payload_size == video->max_payload_size || + video->queue.flags & UVC_QUEUE_DROP_INCOMPLETE || buf->bytesused == video->queue.buf_used) video->payload_size = 0; } @@ -180,7 +182,8 @@ uvc_video_encode_isoc_sg(struct usb_request *req, struct uvc_video *video, req->length -= len; video->queue.buf_used += req->length - header_len; - if (buf->bytesused == video->queue.buf_used || !buf->sg) { + if (buf->bytesused == video->queue.buf_used || !buf->sg || + video->queue.flags & UVC_QUEUE_DROP_INCOMPLETE) { video->queue.buf_used = 0; buf->state = UVC_BUF_STATE_DONE; buf->offset = 0; @@ -195,6 +198,7 @@ uvc_video_encode_isoc(struct usb_request *req, struct uvc_video *video, struct uvc_buffer *buf) { void *mem = req->buf; + struct uvc_request *ureq = req->context; int len = video->req_size; int ret; @@ -209,12 +213,13 @@ uvc_video_encode_isoc(struct usb_request *req, struct uvc_video *video, req->length = video->req_size - len; - if (buf->bytesused == video->queue.buf_used) { + if (buf->bytesused == video->queue.buf_used || + video->queue.flags & UVC_QUEUE_DROP_INCOMPLETE) { video->queue.buf_used = 0; buf->state = UVC_BUF_STATE_DONE; list_del(&buf->queue); - uvcg_complete_buffer(&video->queue, buf); video->fid ^= UVC_STREAM_FID; + ureq->last_buf = buf; } } @@ -255,6 +260,11 @@ uvc_video_complete(struct usb_ep *ep, struct usb_request *req) case 0: break; + case -EXDEV: + uvcg_dbg(&video->uvc->func, "VS request missed xfer.\n"); + queue->flags |= UVC_QUEUE_DROP_INCOMPLETE; + break; + case -ESHUTDOWN: /* disconnect from host. */ uvcg_dbg(&video->uvc->func, "VS request cancelled.\n"); uvcg_queue_cancel(queue, 1); From patchwork Mon Oct 17 20:54:43 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dan Vacura X-Patchwork-Id: 616007 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 62881C433FE for ; Mon, 17 Oct 2022 20:55:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230452AbiJQUzt (ORCPT ); Mon, 17 Oct 2022 16:55:49 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41384 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230404AbiJQUzl (ORCPT ); Mon, 17 Oct 2022 16:55:41 -0400 Received: from mail1.bemta33.messagelabs.com (mail1.bemta33.messagelabs.com [67.219.247.1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9767577E83; Mon, 17 Oct 2022 13:55:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=motorola.com; s=Selector; t=1666040132; i=@motorola.com; bh=jaIOs9fk+1VScGcZnnxQOBf6SfBAGDU0JdmzRh0R7V4=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Transfer-Encoding; b=YnN7GTPKMzYCrtFCLa+vnZNyGa8wYL+GRS9aUdlh/f+/VBTkDvORcFaImevdNwfAq WVYA3xGNgnEiQ3GTxUhayP9+iAbGXwbOgrSrB+QTZNK+OQyCuSq9oiTwPYLuDSAS9j Aj9R/QtRLxL+4yXMqoBZEniEkRmuh2qYZqEAv5r3XSQRhLE3RYz8YfJKhBUw7DDtWg 0lwm19jiVcOyv3P3BAF+evbrraBa2IgprjoShMtEmM+Blj76hknxR2oQ7UqS4dju3s zosTwLGUvq5nqixBJlE774e6r34946Wk4jv8SFSGXzob000Xnu+ZCPd+nLBHExAd+A Moun16z8P07MA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFvrAIsWRWlGSWpSXmKPExsUyYU+Di67zQd9 kg1n7LS2OtT1ht3hyoJ3RonfZHjaL5sXr2Sw6Jy5ht1jYtoTF4vKuOWwWi5a1MltsabvCZPHj Tx+zxaoFB9gduD1md8xk9di0qpPNY//cNewei/sms3r0/zXw2LL/M6PH501yAexRrJl5SfkVC awZF3/PZCw4blCx7MYR9gbGZ5pdjFwcQgJTmCRmP2lnh3DWMknM6+hk7GLk5GATUJNY8HoVM4 gtIiArcfjKb2aQImaB58wS03beYgJJCAsESDxq+wRWxCKgKvHs5jQWEJtXwFLiyMJvYHEJAXm J/QfPAtkcHJwCVhIbpqqDhIWASjYf2MIKUS4ocXLmE7BWZqDy5q2zmScw8s5CkpqFJLWAkWkV o1lxalFZapGukYFeUlFmekZJbmJmjl5ilW6iXmmxbmpicYmukV5iebFeanGxXnFlbnJOil5ea skmRmDgpxQ5WO5gnLjsj94hRkkOJiVR3o4ZvslCfEn5KZUZicUZ8UWlOanFhxhlODiUJHh/7g DKCRalpqdWpGXmAKMQJi3BwaMkwtu5DSjNW1yQmFucmQ6ROsWoy9G5v+sAsxBLXn5eqpQ4749 9QEUCIEUZpXlwI2AJ4RKjrJQwLyMDA4MQT0FqUW5mCar8K0ZxDkYlYd77+4Gm8GTmlcBtegV0 BBPQERn7vUCOKElESEk1MEkeOflseZmOQr3q9rPeS5nE7hUk3+v57FXw8voF3e8zlj+T+aGj0 tXTF2ZlKiixWNg71M9b3emQnIN+wsTnfsdOnSs133CE9fuVt48Wl51+U1zZPuPgz4X7WQ/vjh YMTXSNcIq5nbI29s5BYYfbaorBeW6sP/w68mRWd9fb7bBPmpsWcGOnhEB2SLnz96j8w7reYTL pOwzC4he+ChGM+cYX/LH9UFAhqzTf3y37JnYekZ/faBQf+m+t5bENy5+oixw4IB1+dWuJxwum wpM+Zw/906vZUr+nzCt5+scnChf0N+ed7W9L4itapGC6RHbbnNRpB+1D5eLve3pEBuTaL9tTc Li6IF5rjfpkZ9sQJZbijERDLeai4kQAWZeUOoMDAAA= X-Env-Sender: w36195@motorola.com X-Msg-Ref: server-8.tower-635.messagelabs.com!1666040131!17541!1 X-Originating-IP: [144.188.128.68] X-SYMC-ESS-Client-Auth: outbound-route-from=pass X-StarScan-Received: X-StarScan-Version: 9.100.1; banners=-,-,- X-VirusChecked: Checked Received: (qmail 729 invoked from network); 17 Oct 2022 20:55:31 -0000 Received: from unknown (HELO ilclpfpp02.lenovo.com) (144.188.128.68) by server-8.tower-635.messagelabs.com with ECDHE-RSA-AES256-GCM-SHA384 encrypted SMTP; 17 Oct 2022 20:55:31 -0000 Received: from ilclmmrp01.lenovo.com (ilclmmrp01.mot.com [100.65.83.165]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ilclpfpp02.lenovo.com (Postfix) with ESMTPS id 4Mrq5H3V4RzfBb2; Mon, 17 Oct 2022 20:55:31 +0000 (UTC) Received: from p1g3.mot.com (unknown [100.64.172.121]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: w36195) by ilclmmrp01.lenovo.com (Postfix) with ESMTPSA id 4Mrq5H3GPhzbpxx; Mon, 17 Oct 2022 20:55:31 +0000 (UTC) From: Dan Vacura To: linux-usb@vger.kernel.org Cc: Daniel Scally , Thinh Nguyen , Jeff Vanhoof , Dan Vacura , Greg Kroah-Hartman , Jonathan Corbet , Laurent Pinchart , Felipe Balbi , Michael Grzeschik , Paul Elder , linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org Subject: [PATCH v3 5/6] usb: gadget: uvc: make interrupt skip logic configurable Date: Mon, 17 Oct 2022 15:54:43 -0500 Message-Id: <20221017205446.523796-6-w36195@motorola.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20221017205446.523796-1-w36195@motorola.com> References: <20221017205446.523796-1-w36195@motorola.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org Some UDC hw may not support skipping interrupts, but still support the request. Allow the interrupt frequency to be configurable to the user. Signed-off-by: Dan Vacura --- V1 -> V2: - no change, new patch in series V2 -> V3: - default to baseline value of 4, fix storing the initial value Documentation/ABI/testing/configfs-usb-gadget-uvc | 1 + Documentation/usb/gadget-testing.rst | 2 ++ drivers/usb/gadget/function/f_uvc.c | 3 +++ drivers/usb/gadget/function/u_uvc.h | 1 + drivers/usb/gadget/function/uvc.h | 2 ++ drivers/usb/gadget/function/uvc_configfs.c | 2 ++ drivers/usb/gadget/function/uvc_queue.c | 6 ++++++ drivers/usb/gadget/function/uvc_video.c | 3 ++- 8 files changed, 19 insertions(+), 1 deletion(-) diff --git a/Documentation/ABI/testing/configfs-usb-gadget-uvc b/Documentation/ABI/testing/configfs-usb-gadget-uvc index 611b23e6488d..5dfaa3f7f6a4 100644 --- a/Documentation/ABI/testing/configfs-usb-gadget-uvc +++ b/Documentation/ABI/testing/configfs-usb-gadget-uvc @@ -8,6 +8,7 @@ Description: UVC function directory streaming_maxpacket 1..1023 (fs), 1..3072 (hs/ss) streaming_interval 1..16 function_name string [32] + req_int_skip_div unsigned int =================== ============================= What: /config/usb-gadget/gadget/functions/uvc.name/control diff --git a/Documentation/usb/gadget-testing.rst b/Documentation/usb/gadget-testing.rst index 2278c9ffb74a..f9b5a09be1f4 100644 --- a/Documentation/usb/gadget-testing.rst +++ b/Documentation/usb/gadget-testing.rst @@ -794,6 +794,8 @@ The uvc function provides these attributes in its function directory: sending or receiving when this configuration is selected function_name name of the interface + req_int_skip_div divisor of total requests to aid in calculating + interrupt frequency, 0 indicates all interrupt =================== ================================================ There are also "control" and "streaming" subdirectories, each of which contain diff --git a/drivers/usb/gadget/function/f_uvc.c b/drivers/usb/gadget/function/f_uvc.c index 6e196e06181e..e40ca26b9c55 100644 --- a/drivers/usb/gadget/function/f_uvc.c +++ b/drivers/usb/gadget/function/f_uvc.c @@ -655,6 +655,8 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f) cpu_to_le16(max_packet_size * max_packet_mult * (opts->streaming_maxburst + 1)); + uvc->config_skip_int_div = opts->req_int_skip_div; + /* Allocate endpoints. */ ep = usb_ep_autoconfig(cdev->gadget, &uvc_control_ep); if (!ep) { @@ -872,6 +874,7 @@ static struct usb_function_instance *uvc_alloc_inst(void) opts->streaming_interval = 1; opts->streaming_maxpacket = 1024; + opts->req_int_skip_div = 4; snprintf(opts->function_name, sizeof(opts->function_name), "UVC Camera"); ret = uvcg_attach_configfs(opts); diff --git a/drivers/usb/gadget/function/u_uvc.h b/drivers/usb/gadget/function/u_uvc.h index 24b8681b0d6f..6f73bd5638ed 100644 --- a/drivers/usb/gadget/function/u_uvc.h +++ b/drivers/usb/gadget/function/u_uvc.h @@ -24,6 +24,7 @@ struct f_uvc_opts { unsigned int streaming_interval; unsigned int streaming_maxpacket; unsigned int streaming_maxburst; + unsigned int req_int_skip_div; unsigned int control_interface; unsigned int streaming_interface; diff --git a/drivers/usb/gadget/function/uvc.h b/drivers/usb/gadget/function/uvc.h index 40226b1f7e14..29f9477c92cc 100644 --- a/drivers/usb/gadget/function/uvc.h +++ b/drivers/usb/gadget/function/uvc.h @@ -107,6 +107,7 @@ struct uvc_video { spinlock_t req_lock; unsigned int req_int_count; + unsigned int req_int_skip_div; void (*encode) (struct usb_request *req, struct uvc_video *video, struct uvc_buffer *buf); @@ -155,6 +156,7 @@ struct uvc_device { /* Events */ unsigned int event_length; unsigned int event_setup_out : 1; + unsigned int config_skip_int_div; }; static inline struct uvc_device *to_uvc(struct usb_function *f) diff --git a/drivers/usb/gadget/function/uvc_configfs.c b/drivers/usb/gadget/function/uvc_configfs.c index 4303a3283ba0..419e926ab57e 100644 --- a/drivers/usb/gadget/function/uvc_configfs.c +++ b/drivers/usb/gadget/function/uvc_configfs.c @@ -2350,6 +2350,7 @@ UVC_ATTR(f_uvc_opts_, cname, cname) UVCG_OPTS_ATTR(streaming_interval, streaming_interval, 16); UVCG_OPTS_ATTR(streaming_maxpacket, streaming_maxpacket, 3072); UVCG_OPTS_ATTR(streaming_maxburst, streaming_maxburst, 15); +UVCG_OPTS_ATTR(req_int_skip_div, req_int_skip_div, UINT_MAX); #undef UVCG_OPTS_ATTR @@ -2399,6 +2400,7 @@ static struct configfs_attribute *uvc_attrs[] = { &f_uvc_opts_attr_streaming_interval, &f_uvc_opts_attr_streaming_maxpacket, &f_uvc_opts_attr_streaming_maxburst, + &f_uvc_opts_attr_req_int_skip_div, &f_uvc_opts_string_attr_function_name, NULL, }; diff --git a/drivers/usb/gadget/function/uvc_queue.c b/drivers/usb/gadget/function/uvc_queue.c index 0aa3d7e1f3cc..02559906a55a 100644 --- a/drivers/usb/gadget/function/uvc_queue.c +++ b/drivers/usb/gadget/function/uvc_queue.c @@ -63,6 +63,12 @@ static int uvc_queue_setup(struct vb2_queue *vq, */ nreq = DIV_ROUND_UP(DIV_ROUND_UP(sizes[0], 2), req_size); nreq = clamp(nreq, 4U, 64U); + if (0 == video->uvc->config_skip_int_div) { + video->req_int_skip_div = nreq; + } else { + video->req_int_skip_div = min_t(unsigned int, nreq, + video->uvc->config_skip_int_div); + } video->uvc_num_requests = nreq; return 0; diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c index 7d4508a83d5d..9ff02691b6a4 100644 --- a/drivers/usb/gadget/function/uvc_video.c +++ b/drivers/usb/gadget/function/uvc_video.c @@ -423,7 +423,8 @@ static void uvcg_video_pump(struct work_struct *work) if (list_empty(&video->req_free) || buf->state == UVC_BUF_STATE_DONE || !(video->req_int_count % - DIV_ROUND_UP(video->uvc_num_requests, 4))) { + DIV_ROUND_UP(video->uvc_num_requests, + video->req_int_skip_div))) { video->req_int_count = 0; req->no_interrupt = 0; } else {