From patchwork Tue Oct 18 21:50:39 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dan Vacura X-Patchwork-Id: 616420 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 93790C4167D for ; Tue, 18 Oct 2022 21:51:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229935AbiJRVv3 (ORCPT ); Tue, 18 Oct 2022 17:51:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35186 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229861AbiJRVv1 (ORCPT ); Tue, 18 Oct 2022 17:51:27 -0400 Received: from mail1.bemta35.messagelabs.com (mail1.bemta35.messagelabs.com [67.219.250.114]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7AFC9BE2FA; Tue, 18 Oct 2022 14:51:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=motorola.com; s=Selector; t=1666129886; i=@motorola.com; bh=sfQAryD/xBgH6Xtqc/fcYqWHp7Ikn2PFWWAT/anYcbM=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Transfer-Encoding; b=aXiY4dEGkp/dNiF7l4HrWCrfgbEP/IqiSPH15ayVN/gcz93V3SIUcFSvjI52RRP70 vGC1S2ysDOyy/JEv884apnHB2b0RsTTqNV6cqnkX70cNAG239aLyBRhsu+tMTsNoF2 2NjUunMi9W0McB89Nnea5ofCuzXRouspWTA8R9O4hDTUwRAQ90cncQfCGOZ6RZwQJj bZ8atdeRvhyoj1qu9/KOSMDPXtFW2hHGw8VXZA6GrhCvnuAmPXCdUqsTvnrDH58+k4 G92VIchE73JE8M6ORTrTVmvi5u4ya3nQudpiAx8NlOriEwGCOig4woQrmIWH8IYQzd ZmSOiXe5rxFcw== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFvrMIsWRWlGSWpSXmKPExsWS8eKJhO4def9 kgyePDCyOtT1ht3hyoJ3RonfZHjaL5sXr2Sw6Jy5ht1jYtoTF4vKuOWwWi5a1MltsabvCZPHj Tx+zxYKNjxgtVi04wO7A4zG7Yyarx6ZVnWwe++euYfdY3DeZ1aP/r4HHlv2fGT0+b5ILYI9iz cxLyq9IYM3Y9/IgY8E7pYqGi29YGxgvynYxcnEICUxnkjjwqYkFwlnHJDHx0Q0gh5ODTUBNYs HrVcwgtoiArMThK7/BbGaBBhaJzdeCQWxhAXeJS70Tgeo5OFgEVCV2dRqAhHkFLCWWvWllBbE lBOQl9h88C9bKKWAl0fWwDWy8EFDN49YrrBD1ghInZz5hgRgvL9G8dTbzBEbeWUhSs5CkFjAy rWI0LU4tKkst0jXSSyrKTM8oyU3MzNFLrNJN1Cst1i1PLS4ByiSWF+ulFhfrFVfmJuek6OWll mxiBIZ/SlHC/B2MU5f+0TvEKMnBpCTKO+ebX7IQX1J+SmVGYnFGfFFpTmrxIUYZDg4lCV5OKf 9kIcGi1PTUirTMHGAswqQlOHiURHjTZIDSvMUFibnFmekQqVOMuhyd+7sOMAux5OXnpUqJ83L LAhUJgBRllObBjYClhUuMslLCvIwMDAxCPAWpRbmZJajyrxjFORiVhHkPgKziycwrgdv0CugI JqAjTLf4gRxRkoiQkmpg6uJmX9uk/uOQ4am/sUsuH3GukV14R0X+/Zut387cZUo6dnNmHFPVX x9/ia9nk85VSHBoMR3bdks/7XO0RflbTc/u8vkSu092pEyZKm6eK8Ia9KNUdkbhSoH1n01FbB fe0mV//NJf+rhqvEySb9j51M07OubHsT01mDxjoafJWd6WAkPuM8cLuBu4X51eFb2nZ/XRbZL 2O0+UbKh+Ly/LdIQ5YuuW3Qz8lewibaVbXevyIszk/2xc51l+zu3ERYFPeT3lMZZXrzi8F5Od /uSyio/llG+OlZ8WBnXdfDbTZemDQm/JK5mtl3/cZuesLWZgkd+zkqFLb5ptl9jMyXXPmNmMA xmmbN04yftfvVK8EktxRqKhFnNRcSIATuoq6oYDAAA= X-Env-Sender: w36195@motorola.com X-Msg-Ref: server-18.tower-636.messagelabs.com!1666129883!642373!1 X-Originating-IP: [104.232.228.24] X-SYMC-ESS-Client-Auth: outbound-route-from=pass X-StarScan-Received: X-StarScan-Version: 9.87.3; banners=-,-,- X-VirusChecked: Checked Received: (qmail 30411 invoked from network); 18 Oct 2022 21:51:24 -0000 Received: from unknown (HELO va32lpfpp04.lenovo.com) (104.232.228.24) by server-18.tower-636.messagelabs.com with ECDHE-RSA-AES256-GCM-SHA384 encrypted SMTP; 18 Oct 2022 21:51:24 -0000 Received: from va32lmmrp02.lenovo.com (va32lmmrp02.mot.com [10.62.176.191]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by va32lpfpp04.lenovo.com (Postfix) with ESMTPS id 4MsSHH5HK9zgK7f; Tue, 18 Oct 2022 21:51:23 +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 va32lmmrp02.lenovo.com (Postfix) with ESMTPSA id 4MsSHH3S9Jzf6WS; Tue, 18 Oct 2022 21:51:23 +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 , Michael Grzeschik , Paul Elder , linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org Subject: [PATCH v4 3/6] usb: gadget: uvc: fix sg handling in error case Date: Tue, 18 Oct 2022 16:50:39 -0500 Message-Id: <20221018215044.765044-4-w36195@motorola.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20221018215044.765044-1-w36195@motorola.com> References: <20221018215044.765044-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: Signed-off-by: Dan Vacura --- V1 -> V2: - undo error rename - change uvcg_info to uvcg_dbg V2 -> V3: - no changes V3 -> V4: - drop extra cc stable cherry-picks, as a request was made to stable 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 323977716f5a..5993e083819c 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 Tue Oct 18 21:50: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: 616419 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 C0DD2C433FE for ; Tue, 18 Oct 2022 21:51:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230073AbiJRVvo (ORCPT ); Tue, 18 Oct 2022 17:51:44 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35344 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230009AbiJRVvc (ORCPT ); Tue, 18 Oct 2022 17:51:32 -0400 Received: from mail1.bemta33.messagelabs.com (mail1.bemta33.messagelabs.com [67.219.247.6]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A7B47CAE55; Tue, 18 Oct 2022 14:51:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=motorola.com; s=Selector; t=1666129889; i=@motorola.com; bh=8C4mpLzfAGmUvqoBtRBj2oPSMTlDzsJxu1HgUPQnxFc=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Transfer-Encoding; b=qX84A6D9CB5ogQPXoUAJL4ECeD6qUMTDh7ABwIrIdel4AhXNiJaqt8/O/tpWT/EfJ 7acGYcMF1G6FRTzLvR2BTZQf2Rar6sy4vBtmiCBkhbA4ZuNU5CTzMeGguDGLQ3yBJZ SbdL5cx3FDq0yNMOquGW8O7aht9QB1oUfWR9BEhg0uWBvKfV290Eg55wzCrSRe/Qxz xljd5T4nzlYnVKPwwc+xGYQsvBW96btMR80Q+Yy875EI9wpX8OckkfvxqjCuFQYnD3 hlu2nBBOS98xc2F1p67PG/QPgzDywcf/qzfKoWmcK8iIjYcZ4jWPmtADkmxbZ9yytj kR/iDfrGizpkw== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFvrIIsWRWlGSWpSXmKPExsWS8eKJuO4Def9 kg7cPhC2OtT1ht3hyoJ3RonfZHjaL5sXr2Sw6Jy5ht1jYtoTF4vKuOWwWi5a1MltsabvCZPHj Tx+zxaoFB9gduD1md8xk9di0qpPNY//cNewei/sms3r0/zXw2LL/M6PH501yAexRrJl5SfkVC awZDQdfsRTcNaiY/PgWcwPjN80uRi4OIYEZTBLT1z5ghHDWMUlMfXiQvYuRk4NNQE1iwetVzC C2iICsxOErv5lBipgFnjNLHP60DiwhLBAgcebTazYQm0VAVeLXoueMIDavgKXE1d13wQZJCMh L7D94FqyeU8BKouthGwuILQRU87j1CitEvaDEyZlPwOLMQPXNW2czT2DknYUkNQtJagEj0ypG s+LUorLUIl1DS72kosz0jJLcxMwcvcQq3US90mLd1MTiEl0jvcTyYr3U4mK94src5JwUvbzUk k2MwNBPKXL/uYNx/rI/eocYJTmYlER553zzSxbiS8pPqcxILM6ILyrNSS0+xCjDwaEkwcsp5Z 8sJFiUmp5akZaZA4xDmLQEB4+SCG+aDFCat7ggMbc4Mx0idYpRl6Nzf9cBZiGWvPy8VClxXm5 ZoCIBkKKM0jy4EbCUcIlRVkqYl5GBgUGIpyC1KDezBFX+FaM4B6OSMO8BkFU8mXklcJteAR3B BHSE6RY/kCNKEhFSUg1MM3iy9x158saluiVWxXOZZNvmLT/ffZrqeNBn4WWTun1fvRuuVefMu zajbtWLv+sb3lqKb5DaJvfnbuyvlVHl82S1s5e/zd9Y5uj1T0RFbIHc0133l7FULp7hP+fp4S 81U7SuXpupP5XlyNbZWtpyRT+slzJc8Bb/sk5Y8MA11U1v4jOic3eZ7FzELn+TxfDGhuaz6i/ 8T8keOjrPmeXJ96Rt/lfOW3b0SqoW5zyaKdp4XXOxTs6Vpv+qqTPi9sfL5P8Tr5z84fi81lfc wWapNh6n9r65KtXH7Vdqca8iXUlL7Z0X6+k6n8yXIhMZ7/P3eFyYdq/JhEO91z703fd7bV+Ek zbPli0LeK4rM5FhjRJLcUaioRZzUXEiAIYJe2KEAwAA X-Env-Sender: w36195@motorola.com X-Msg-Ref: server-12.tower-715.messagelabs.com!1666129888!57532!1 X-Originating-IP: [104.232.228.23] X-SYMC-ESS-Client-Auth: outbound-route-from=pass X-StarScan-Received: X-StarScan-Version: 9.100.1; banners=-,-,- X-VirusChecked: Checked Received: (qmail 20118 invoked from network); 18 Oct 2022 21:51:28 -0000 Received: from unknown (HELO va32lpfpp03.lenovo.com) (104.232.228.23) by server-12.tower-715.messagelabs.com with ECDHE-RSA-AES256-GCM-SHA384 encrypted SMTP; 18 Oct 2022 21:51:28 -0000 Received: from va32lmmrp02.lenovo.com (va32lmmrp02.mot.com [10.62.176.191]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by va32lpfpp03.lenovo.com (Postfix) with ESMTPS id 4MsSHM6xjrz50WfM; Tue, 18 Oct 2022 21:51: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 va32lmmrp02.lenovo.com (Postfix) with ESMTPSA id 4MsSHM5G9Mzf6WS; Tue, 18 Oct 2022 21:51:27 +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 , Paul Elder , Michael Grzeschik , linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org Subject: [PATCH v4 5/6] usb: gadget: uvc: make interrupt skip logic configurable Date: Tue, 18 Oct 2022 16:50:41 -0500 Message-Id: <20221018215044.765044-6-w36195@motorola.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20221018215044.765044-1-w36195@motorola.com> References: <20221018215044.765044-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 V3 -> V4: - no change 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 dd1c6b2ca7c6..c1a80c5d1f63 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 {