From patchwork Thu Oct 1 00:44:19 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thinh Nguyen X-Patchwork-Id: 258329 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-10.1 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B9EE3C4741F for ; Thu, 1 Oct 2020 00:44:22 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 733362137B for ; Thu, 1 Oct 2020 00:44:22 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=synopsys.com header.i=@synopsys.com header.b="ElCDQP5A" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731620AbgJAAoW (ORCPT ); Wed, 30 Sep 2020 20:44:22 -0400 Received: from smtprelay-out1.synopsys.com ([149.117.87.133]:55872 "EHLO smtprelay-out1.synopsys.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731339AbgJAAoV (ORCPT ); Wed, 30 Sep 2020 20:44:21 -0400 Received: from mailhost.synopsys.com (sv1-mailhost1.synopsys.com [10.205.2.131]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by smtprelay-out1.synopsys.com (Postfix) with ESMTPS id 2433FC07AC; Thu, 1 Oct 2020 00:44:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=synopsys.com; s=mail; t=1601513061; bh=C1i18HhTqcOBBY5KMc2PThgsWna5b6k9srAXBCru+pU=; h=Date:In-Reply-To:References:From:Subject:To:Cc:From; b=ElCDQP5ACojZOGUjmM5SIwdaxsgWpw7lWiB8XXnG/MhYtB8xkVajZmwZs5QP8Petu /1XUiLdbyhZ2wBwXFQ/vyfuUAySN5a+aBwmCjg/d62uYlI/I7EfLQCatDoQHIsj88G 6uTpIAPVVy4a2HTp5lwt6Wpe6RIRCTwcyujMOOoIQD8eMXXgtLXGfFark9JtzkqeUV wzsSWjblIR45KSKIGbqDF4on6evkekoEFu+5I6XWumGectk2MBEubkndvFKiGuzgyt +p6uPkOpqcH3RaajO5UJqtzSidGY6oTFhYVUq/xRdOJdoo6XE/I7z63hJ2f7s15NSB brMzF0UYs3Tag== Received: from te-lab16 (nanobot.internal.synopsys.com [10.10.186.99]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mailhost.synopsys.com (Postfix) with ESMTPSA id B00D0A01F1; Thu, 1 Oct 2020 00:44:19 +0000 (UTC) Received: by te-lab16 (sSMTP sendmail emulation); Wed, 30 Sep 2020 17:44:19 -0700 Date: Wed, 30 Sep 2020 17:44:19 -0700 Message-Id: <47c8050ffbf1f7747969a46ef7f04babbc736c29.1601511883.git.Thinh.Nguyen@synopsys.com> In-Reply-To: References: X-SNPS-Relay: synopsys.com From: Thinh Nguyen Subject: [PATCH 1/4] usb: dwc3: gadget: Look ahead when setting IOC To: Felipe Balbi , Greg Kroah-Hartman , Thinh.Nguyen@synopsys.com, linux-usb@vger.kernel.org Cc: John Youn Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org Previously if we run out of TRBs for the last SG entry that requires an extra TRB, we set interrupt-on-completion (IOC) bit to an already prepared TRB (i.e. HWO=1). This logic is not clean, and it's not a typical way to prepare TRB. Also, this prevents showing IOC setup in tracepoint when __dwc3_prepare_one_trb() is executed. Instead, let's look ahead when preparing TRB to know whether to set the IOC bit before the last SG entry. This requires adding a new parameter "must_interrupt" to dwc3_prepare_one_trb(). Signed-off-by: Thinh Nguyen --- drivers/usb/dwc3/gadget.c | 72 +++++++++++++++++++++------------------ 1 file changed, 39 insertions(+), 33 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 76c383eecfd3..0387b94b8f94 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -947,7 +947,7 @@ static void __dwc3_prepare_one_trb(struct dwc3_ep *dep, struct dwc3_trb *trb, dma_addr_t dma, unsigned int length, unsigned int chain, unsigned int node, unsigned int stream_id, unsigned int short_not_ok, unsigned int no_interrupt, - unsigned int is_last) + unsigned int is_last, bool must_interrupt) { struct dwc3 *dwc = dep->dwc; struct usb_gadget *gadget = dwc->gadget; @@ -1034,7 +1034,7 @@ static void __dwc3_prepare_one_trb(struct dwc3_ep *dep, struct dwc3_trb *trb, trb->ctrl |= DWC3_TRB_CTRL_ISP_IMI; } - if ((!no_interrupt && !chain) || + if ((!no_interrupt && !chain) || must_interrupt || (dwc3_calc_trbs_left(dep) == 1)) trb->ctrl |= DWC3_TRB_CTRL_IOC; @@ -1061,10 +1061,12 @@ static void __dwc3_prepare_one_trb(struct dwc3_ep *dep, struct dwc3_trb *trb, * @chain: should this TRB be chained to the next? * @node: only for isochronous endpoints. First TRB needs different type. * @use_bounce_buffer: set to use bounce buffer + * @must_interrupt: set to interrupt on TRB completion */ static void dwc3_prepare_one_trb(struct dwc3_ep *dep, struct dwc3_request *req, unsigned int trb_length, - unsigned int chain, unsigned int node, bool use_bounce_buffer) + unsigned int chain, unsigned int node, bool use_bounce_buffer, + bool must_interrupt) { struct dwc3_trb *trb; dma_addr_t dma; @@ -1091,7 +1093,21 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep, req->num_trbs++; __dwc3_prepare_one_trb(dep, trb, dma, trb_length, chain, node, - stream_id, short_not_ok, no_interrupt, is_last); + stream_id, short_not_ok, no_interrupt, is_last, + must_interrupt); +} + +static bool dwc3_needs_extra_trb(struct dwc3_ep *dep, struct dwc3_request *req) +{ + unsigned int maxp = usb_endpoint_maxp(dep->endpoint.desc); + unsigned int rem = req->request.length % maxp; + + if ((req->request.length && req->request.zero && !rem && + !usb_endpoint_xfer_isoc(dep->endpoint.desc)) || + (!req->direction && rem)) + return true; + + return false; } /** @@ -1111,9 +1127,7 @@ static int dwc3_prepare_last_sg(struct dwc3_ep *dep, unsigned int rem = req->request.length % maxp; unsigned int num_trbs = 1; - if ((req->request.length && req->request.zero && !rem && - !usb_endpoint_xfer_isoc(dep->endpoint.desc)) || - (!req->direction && rem)) + if (dwc3_needs_extra_trb(dep, req)) num_trbs++; if (dwc3_calc_trbs_left(dep) < num_trbs) @@ -1124,13 +1138,13 @@ static int dwc3_prepare_last_sg(struct dwc3_ep *dep, /* Prepare a normal TRB */ if (req->direction || req->request.length) dwc3_prepare_one_trb(dep, req, entry_length, - req->needs_extra_trb, node, false); + req->needs_extra_trb, node, false, false); /* Prepare extra TRBs for ZLP and MPS OUT transfer alignment */ if ((!req->direction && !req->request.length) || req->needs_extra_trb) dwc3_prepare_one_trb(dep, req, req->direction ? 0 : maxp - rem, - false, 1, true); + false, 1, true, false); return num_trbs; } @@ -1145,6 +1159,7 @@ static int dwc3_prepare_trbs_sg(struct dwc3_ep *dep, unsigned int remaining = req->request.num_mapped_sgs - req->num_queued_sgs; unsigned int num_trbs = req->num_trbs; + bool needs_extra_trb = dwc3_needs_extra_trb(dep, req); /* * If we resume preparing the request, then get the remaining length of @@ -1155,6 +1170,7 @@ static int dwc3_prepare_trbs_sg(struct dwc3_ep *dep, for_each_sg(sg, s, remaining, i) { unsigned int trb_length; + bool must_interrupt = false; bool last_sg = false; trb_length = min_t(unsigned int, length, sg_dma_len(s)); @@ -1176,9 +1192,20 @@ static int dwc3_prepare_trbs_sg(struct dwc3_ep *dep, if (last_sg) { if (!dwc3_prepare_last_sg(dep, req, trb_length, i)) - goto out; + break; } else { - dwc3_prepare_one_trb(dep, req, trb_length, 1, i, false); + /* + * Look ahead to check if we have enough TRBs for the + * last SG entry. If not, set interrupt on this TRB to + * resume preparing the last SG entry when more TRBs are + * free. + */ + if (needs_extra_trb && dwc3_calc_trbs_left(dep) <= 2 && + sg_dma_len(sg_next(s)) >= length) + must_interrupt = true; + + dwc3_prepare_one_trb(dep, req, trb_length, 1, i, false, + must_interrupt); } /* @@ -1203,31 +1230,10 @@ static int dwc3_prepare_trbs_sg(struct dwc3_ep *dep, break; } - if (!dwc3_calc_trbs_left(dep)) + if (!dwc3_calc_trbs_left(dep) || must_interrupt) break; } - return req->num_trbs - num_trbs; - -out: - /* - * If we run out of TRBs for MPS alignment setup, then set IOC on the - * previous TRB to get notified for TRB completion to resume when more - * TRBs are available. - * - * Note: normally we shouldn't update the TRB after the HWO bit is set. - * However, the controller doesn't update its internal cache to handle - * the newly prepared TRBs until UPDATE_TRANSFER or START_TRANSFER - * command is executed. At this point, it doesn't happen yet, so we - * should be fine modifying it here. - */ - if (i) { - struct dwc3_trb *trb; - - trb = dwc3_ep_prev_trb(dep, dep->trb_enqueue); - trb->ctrl |= DWC3_TRB_CTRL_IOC; - } - return req->num_trbs - num_trbs; } From patchwork Thu Oct 1 00:44:25 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thinh Nguyen X-Patchwork-Id: 297408 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-10.1 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 69541C4363D for ; Thu, 1 Oct 2020 00:44:29 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2C83F2137B for ; Thu, 1 Oct 2020 00:44:29 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=synopsys.com header.i=@synopsys.com header.b="d5MFxWpO" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732230AbgJAAo2 (ORCPT ); Wed, 30 Sep 2020 20:44:28 -0400 Received: from smtprelay-out1.synopsys.com ([149.117.73.133]:33818 "EHLO smtprelay-out1.synopsys.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731339AbgJAAo2 (ORCPT ); Wed, 30 Sep 2020 20:44:28 -0400 Received: from mailhost.synopsys.com (sv2-mailhost2.synopsys.com [10.205.2.134]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by smtprelay-out1.synopsys.com (Postfix) with ESMTPS id 03E24408D3; Thu, 1 Oct 2020 00:44:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=synopsys.com; s=mail; t=1601513068; bh=Gp/V/Rxv1oGXxmEF9zjzSd06Qw/fgwbCaO7kJLELq6c=; h=Date:In-Reply-To:References:From:Subject:To:Cc:From; b=d5MFxWpON6xNdhxq/4/26G6B53lsxipAs2pT8pZKyrzVdhhL9+VFr7+jlvZMS5zQ6 oGXFkZE+vAa7c6a9I4kzC15EUabLnVjLkOeNBKfr8/5UZljr2tSF8jEmtW9D5rUWOO Bwykw2WIW3c4JciZmiNjxR3F2SDd1O+Qco64gTkkLGgs0JLiWiozf+5Q1zd+cW+Dmr jCwUJWCBTdbL8bxOdQGoRH177nvTtGzZVZE7N4OP+aSYjdjvIFpFWcuGTNrApeWlM2 vIqgVlLhe9+C0AwM6ydOwFeS2MoW7uLmT/DZyoyz5ayCbqrUswT2rWfk6PEah2hsEH LvzwdB+5QGYeA== Received: from te-lab16 (nanobot.internal.synopsys.com [10.10.186.99]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mailhost.synopsys.com (Postfix) with ESMTPSA id 5BB76A0099; Thu, 1 Oct 2020 00:44:26 +0000 (UTC) Received: by te-lab16 (sSMTP sendmail emulation); Wed, 30 Sep 2020 17:44:25 -0700 Date: Wed, 30 Sep 2020 17:44:25 -0700 Message-Id: <91107f27d4d8bd3514eb2bafb46ac7905e276644.1601511883.git.Thinh.Nguyen@synopsys.com> In-Reply-To: References: X-SNPS-Relay: synopsys.com From: Thinh Nguyen Subject: [PATCH 2/4] usb: dwc3: gadget: Revise setting IOC when no TRB left To: Felipe Balbi , Greg Kroah-Hartman , Thinh.Nguyen@synopsys.com, linux-usb@vger.kernel.org Cc: John Youn Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org To keep the setting of interrupt-on-completion (IOC) when out of TRBs consistent and easier to read, the caller of dwc3_prepare_one_trb() will determine if the TRB must have IOC bit set. This also reduces the number of times we need to call dwc3_calc_trbs_left(). Note that we only care about setting IOC from insufficient number of TRBs for SG and not linear requests (because we don't need to split linear requests). Signed-off-by: Thinh Nguyen --- drivers/usb/dwc3/gadget.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 0387b94b8f94..327cd556e8db 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1034,8 +1034,7 @@ static void __dwc3_prepare_one_trb(struct dwc3_ep *dep, struct dwc3_trb *trb, trb->ctrl |= DWC3_TRB_CTRL_ISP_IMI; } - if ((!no_interrupt && !chain) || must_interrupt || - (dwc3_calc_trbs_left(dep) == 1)) + if ((!no_interrupt && !chain) || must_interrupt) trb->ctrl |= DWC3_TRB_CTRL_IOC; if (chain) @@ -1169,6 +1168,7 @@ static int dwc3_prepare_trbs_sg(struct dwc3_ep *dep, length -= sg_dma_len(s); for_each_sg(sg, s, remaining, i) { + unsigned int num_trbs_left = dwc3_calc_trbs_left(dep); unsigned int trb_length; bool must_interrupt = false; bool last_sg = false; @@ -1187,7 +1187,7 @@ static int dwc3_prepare_trbs_sg(struct dwc3_ep *dep, if ((i == remaining - 1) || !length) last_sg = true; - if (!dwc3_calc_trbs_left(dep)) + if (!num_trbs_left) break; if (last_sg) { @@ -1196,12 +1196,13 @@ static int dwc3_prepare_trbs_sg(struct dwc3_ep *dep, } else { /* * Look ahead to check if we have enough TRBs for the - * last SG entry. If not, set interrupt on this TRB to - * resume preparing the last SG entry when more TRBs are + * next SG entry. If not, set interrupt on this TRB to + * resume preparing the next SG entry when more TRBs are * free. */ - if (needs_extra_trb && dwc3_calc_trbs_left(dep) <= 2 && - sg_dma_len(sg_next(s)) >= length) + if (num_trbs_left == 1 || (needs_extra_trb && + num_trbs_left <= 2 && + sg_dma_len(sg_next(s)) >= length)) must_interrupt = true; dwc3_prepare_one_trb(dep, req, trb_length, 1, i, false, @@ -1230,7 +1231,7 @@ static int dwc3_prepare_trbs_sg(struct dwc3_ep *dep, break; } - if (!dwc3_calc_trbs_left(dep) || must_interrupt) + if (must_interrupt) break; } From patchwork Thu Oct 1 00:44:32 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thinh Nguyen X-Patchwork-Id: 258328 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-10.1 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 99A62C4363D for ; Thu, 1 Oct 2020 00:44:35 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 49A2F2085B for ; Thu, 1 Oct 2020 00:44:35 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=synopsys.com header.i=@synopsys.com header.b="Q9LIkBBk" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731339AbgJAAoe (ORCPT ); Wed, 30 Sep 2020 20:44:34 -0400 Received: from smtprelay-out1.synopsys.com ([149.117.73.133]:33832 "EHLO smtprelay-out1.synopsys.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730155AbgJAAoe (ORCPT ); Wed, 30 Sep 2020 20:44:34 -0400 Received: from mailhost.synopsys.com (sv2-mailhost2.synopsys.com [10.205.2.134]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by smtprelay-out1.synopsys.com (Postfix) with ESMTPS id 15CF1408D3; Thu, 1 Oct 2020 00:44:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=synopsys.com; s=mail; t=1601513074; bh=H8pvtbzYvnHhzhJEWU7eLnvcq6Ah9qf2Mytq96+2LhE=; h=Date:In-Reply-To:References:From:Subject:To:Cc:From; b=Q9LIkBBkuxTl+tb3wh8AwEEjo6HMvNRckfRUjZqp38/tnBCJOJNQZ8K6wbFOF+w5Z xrgt+d4hyUAG0MywMKFuinH4BPMFTrrLZHMq90HAA/1DWEI0qoswl+51DhRUJ0j3nf zCsPgoQR7cDnd+h92SRUzIS4ImX3zGROEx2NIF6PBsNFUKeinyS5p0dbgqc3OXbxyX WxZKs5ATs6eDadt1vxsVTqzDBMvjPUSGlDAG8VHivtwMoxfxxL/MXXMGNZXBaVs/jv c5tN8LGTAsljLyeghJfBMdTOcMcBH1I/P9MqPPXhFaF3JsMJGgLIHs8R+SG0hmI7NP WBoYndJfiuCQQ== Received: from te-lab16 (nanobot.internal.synopsys.com [10.10.186.99]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mailhost.synopsys.com (Postfix) with ESMTPSA id CE918A0099; Thu, 1 Oct 2020 00:44:32 +0000 (UTC) Received: by te-lab16 (sSMTP sendmail emulation); Wed, 30 Sep 2020 17:44:32 -0700 Date: Wed, 30 Sep 2020 17:44:32 -0700 Message-Id: In-Reply-To: References: X-SNPS-Relay: synopsys.com From: Thinh Nguyen Subject: [PATCH 3/4] usb: dwc3: gadget: Keep TRBs in request order To: Felipe Balbi , Greg Kroah-Hartman , Thinh.Nguyen@synopsys.com, linux-usb@vger.kernel.org Cc: John Youn Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org If we couldn't finish preparing all the TRBs of a request, don't prepare the next request. Otherwise, the TRBs order will be mixed up and the controller will process the wrong TRB. This is a corner case where there's not enough TRBs for a request that needs the extra TRB but there's still 1 available TRB in the pool. Signed-off-by: Thinh Nguyen --- drivers/usb/dwc3/gadget.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 327cd556e8db..ff924656f690 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1274,7 +1274,7 @@ static int dwc3_prepare_trbs(struct dwc3_ep *dep) list_for_each_entry(req, &dep->started_list, list) { if (req->num_pending_sgs > 0) { ret = dwc3_prepare_trbs_sg(dep, req); - if (!ret) + if (!ret || req->num_pending_sgs) return ret; } @@ -1303,10 +1303,13 @@ static int dwc3_prepare_trbs(struct dwc3_ep *dep) req->num_queued_sgs = 0; req->num_pending_sgs = req->request.num_mapped_sgs; - if (req->num_pending_sgs > 0) + if (req->num_pending_sgs > 0) { ret = dwc3_prepare_trbs_sg(dep, req); - else + if (req->num_pending_sgs) + return ret; + } else { ret = dwc3_prepare_trbs_linear(dep, req); + } if (!ret || !dwc3_calc_trbs_left(dep)) return ret; From patchwork Thu Oct 1 00:44:38 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thinh Nguyen X-Patchwork-Id: 297407 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-10.1 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6EB45C4363D for ; Thu, 1 Oct 2020 00:44:42 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 286EC2137B for ; Thu, 1 Oct 2020 00:44:42 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=synopsys.com header.i=@synopsys.com header.b="RGPOXfy4" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732234AbgJAAol (ORCPT ); Wed, 30 Sep 2020 20:44:41 -0400 Received: from smtprelay-out1.synopsys.com ([149.117.87.133]:55904 "EHLO smtprelay-out1.synopsys.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730155AbgJAAok (ORCPT ); Wed, 30 Sep 2020 20:44:40 -0400 Received: from mailhost.synopsys.com (sv2-mailhost1.synopsys.com [10.205.2.133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by smtprelay-out1.synopsys.com (Postfix) with ESMTPS id 1EEDFC08E7; Thu, 1 Oct 2020 00:44:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=synopsys.com; s=mail; t=1601513080; bh=w4bQMMPMytV5Fqto2kYUq5ZP20jsNlOdXC9UuB1FQB0=; h=Date:In-Reply-To:References:From:Subject:To:Cc:From; b=RGPOXfy4J/jJXe6W4dWXKAMEfi41122rh2B+GmsSpuXW8whbAinNxPoVs+rwy5agz 9pd55FtMs9/A/KElJ8ahN0WDMthhwzvwSJfw11XaGVNGSyay7X3UFP7BiP9xq+Uum3 29F5A2aRWs5nSEVtVJBiNzIvlH+aWAVbeOL1W1s/XhbxZQJUbhak5orMriYSklxYH6 ocmwuFHC4sRDaEhJQsRNFwzHt852jOILzAyLkDiAsdX2G22u5S5A0p8ZZegM6dErgb qXTvs0cYqwuR3kQlrVynSn5est6CKIUZU3iqm1fRNd/5Xkc7GdFg/Nv40oxOkQ3RfS paoUzEUsPhB8A== Received: from te-lab16 (nanobot.internal.synopsys.com [10.10.186.99]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mailhost.synopsys.com (Postfix) with ESMTPSA id E1949A00A0; Thu, 1 Oct 2020 00:44:38 +0000 (UTC) Received: by te-lab16 (sSMTP sendmail emulation); Wed, 30 Sep 2020 17:44:38 -0700 Date: Wed, 30 Sep 2020 17:44:38 -0700 Message-Id: In-Reply-To: References: X-SNPS-Relay: synopsys.com From: Thinh Nguyen Subject: [PATCH 4/4] usb: dwc3: gadget: Return early if no TRB update To: Felipe Balbi , Greg Kroah-Hartman , Thinh.Nguyen@synopsys.com, linux-usb@vger.kernel.org Cc: John Youn Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org If the transfer had already started and there's no TRB to update, then there's no need to go through __dwc3_gadget_kick_transfer(). There is no problem reissuing UPDATE_TRANSFER command. This change just saves the driver from doing a few operations. This happens when we run out of TRB and function driver still queues for more requests. Signed-off-by: Thinh Nguyen --- drivers/usb/dwc3/gadget.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index ff924656f690..da1f2ad2ad90 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1347,6 +1347,13 @@ static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep) starting = !(dep->flags & DWC3_EP_TRANSFER_STARTED); + /* + * If there's no new TRB prepared and we don't need to restart a + * transfer, there's no need to update the transfer. + */ + if (!ret && !starting) + return ret; + req = next_request(&dep->started_list); if (!req) { dep->flags |= DWC3_EP_PENDING_REQUEST;