From patchwork Thu Sep 3 02:06:11 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thinh Nguyen X-Patchwork-Id: 258670 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 51B84C433E2 for ; Thu, 3 Sep 2020 02:06:15 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 283D820758 for ; Thu, 3 Sep 2020 02:06:15 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=synopsys.com header.i=@synopsys.com header.b="eJ8r94av" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726821AbgICCGO (ORCPT ); Wed, 2 Sep 2020 22:06:14 -0400 Received: from smtprelay-out1.synopsys.com ([149.117.87.133]:51382 "EHLO smtprelay-out1.synopsys.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726177AbgICCGO (ORCPT ); Wed, 2 Sep 2020 22:06:14 -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 3A579C00B2; Thu, 3 Sep 2020 02:06:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=synopsys.com; s=mail; t=1599098773; bh=tNW8jZz/kGzOBKWWSUwmqTQv7Rvj9rmxJwLME24QncM=; h=Date:In-Reply-To:References:From:Subject:To:Cc:From; b=eJ8r94avW1JWMTKWPjs5Z+yWXZdTLgakNaZIz79qm7kf20W7e8392mZGB9GoRLKse J6BN2/nFowN0Xzbxs4E1iWyKryIzV7vSM+xa4yCx0ImdiAmgt4L8TZCw/UYw4AMfsb e37ign3wM0qOO8Mypdkj6a02WNQ+sWqVx07xmANzMVzkfC98KuJaRu6hLA6UfN0t9+ anma17UxQ1lH+YWoBehO33aBCzI9fgEdFrL1gQ3QB3NzNcTU0V2Tcgx5653cj6hAUF B6JG1cO5ui6IYmr3FboQCntBCWBL8TU9w8iHcgyStpe5n9tZ8EZvdy1kO8vQXooWpp e2/GhNdQ2yGmg== 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 06088A007B; Thu, 3 Sep 2020 02:06:11 +0000 (UTC) Received: by te-lab16 (sSMTP sendmail emulation); Wed, 02 Sep 2020 19:06:11 -0700 Date: Wed, 02 Sep 2020 19:06:11 -0700 Message-Id: <66fa061307b6f4eff00fb279ae5130c3bd8720f7.1599098161.git.thinhn@synopsys.com> In-Reply-To: References: X-SNPS-Relay: synopsys.com From: Thinh Nguyen Subject: [PATCH v3 1/4] usb: dwc3: gadget: Refactor preparing TRBs To: Felipe Balbi , Greg Kroah-Hartman , Thinh Nguyen , linux-usb@vger.kernel.org Cc: John Youn Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org There are a lot of common codes for preparing SG and linear TRBs. Let's refactor them for easier read. No functional change here. Signed-off-by: Thinh Nguyen --- Changes in v3: - None Changes in v2: - Remove unused variables rem and maxp drivers/usb/dwc3/gadget.c | 178 ++++++++++++++------------------------ 1 file changed, 67 insertions(+), 111 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 13a187efb5b9..09810ca537bc 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1091,6 +1091,65 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep, stream_id, short_not_ok, no_interrupt, is_last); } +/** + * dwc3_prepare_last_sg - prepare TRBs for the last SG entry + * @dep: The endpoint that the request belongs to + * @req: The request to prepare + * @entry_length: The last SG entry size + * @node: Indicates whether this is not the first entry (for isoc only) + */ +static void dwc3_prepare_last_sg(struct dwc3_ep *dep, + struct dwc3_request *req, + unsigned int entry_length, + unsigned int node) +{ + unsigned int maxp = usb_endpoint_maxp(dep->endpoint.desc); + unsigned int rem = req->request.length % maxp; + unsigned int num_extra_trbs = 0; + unsigned int i; + bool do_zlp = false; + + if (!usb_endpoint_xfer_isoc(dep->endpoint.desc) && + req->request.zero && req->request.length && !rem) { + num_extra_trbs++; + do_zlp = true; + } + + if (!req->direction && (!req->request.length || rem || do_zlp)) + num_extra_trbs++; + + if (num_extra_trbs > 0) + req->needs_extra_trb = true; + + /* Prepare a normal TRB */ + dwc3_prepare_one_trb(dep, req, entry_length, req->needs_extra_trb, node); + + /* Prepare extra TRBs for ZLP and MPS OUT transfer alignment */ + for (i = 0; i < num_extra_trbs; i++) { + struct dwc3 *dwc = dep->dwc; + struct dwc3_trb *trb; + unsigned int extra_trb_length; + bool chain = true; + + if (do_zlp && !i) + extra_trb_length = 0; + else + extra_trb_length = maxp - rem; + + if (i == num_extra_trbs - 1) + chain = false; + + trb = &dep->trb_pool[dep->trb_enqueue]; + req->num_trbs++; + __dwc3_prepare_one_trb(dep, trb, dwc->bounce_addr, + extra_trb_length, chain, 1, + req->request.stream_id, + req->request.short_not_ok, + req->request.no_interrupt, + req->request.is_last); + } +} + static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep, struct dwc3_request *req) { @@ -1109,10 +1168,8 @@ static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep, length -= sg_dma_len(s); for_each_sg(sg, s, remaining, i) { - unsigned int maxp = usb_endpoint_maxp(dep->endpoint.desc); - unsigned int rem = length % maxp; unsigned int trb_length; - unsigned int chain = true; + bool last_sg = false; trb_length = min_t(unsigned int, length, sg_dma_len(s)); @@ -1126,60 +1183,12 @@ static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep, * mapped sg. */ if ((i == remaining - 1) || !length) - chain = false; + last_sg = true; - if (rem && usb_endpoint_dir_out(dep->endpoint.desc) && !chain) { - struct dwc3 *dwc = dep->dwc; - struct dwc3_trb *trb; - - req->needs_extra_trb = true; - - /* prepare normal TRB */ - dwc3_prepare_one_trb(dep, req, trb_length, true, i); - - /* Now prepare one extra TRB to align transfer size */ - trb = &dep->trb_pool[dep->trb_enqueue]; - req->num_trbs++; - __dwc3_prepare_one_trb(dep, trb, dwc->bounce_addr, - maxp - rem, false, 1, - req->request.stream_id, - req->request.short_not_ok, - req->request.no_interrupt, - req->request.is_last); - } else if (req->request.zero && req->request.length && - !usb_endpoint_xfer_isoc(dep->endpoint.desc) && - !rem && !chain) { - struct dwc3 *dwc = dep->dwc; - struct dwc3_trb *trb; - - req->needs_extra_trb = true; - - /* Prepare normal TRB */ - dwc3_prepare_one_trb(dep, req, trb_length, true, i); - - /* Prepare one extra TRB to handle ZLP */ - trb = &dep->trb_pool[dep->trb_enqueue]; - req->num_trbs++; - __dwc3_prepare_one_trb(dep, trb, dwc->bounce_addr, 0, - !req->direction, 1, - req->request.stream_id, - req->request.short_not_ok, - req->request.no_interrupt, - req->request.is_last); - - /* Prepare one more TRB to handle MPS alignment */ - if (!req->direction) { - trb = &dep->trb_pool[dep->trb_enqueue]; - req->num_trbs++; - __dwc3_prepare_one_trb(dep, trb, dwc->bounce_addr, maxp, - false, 1, req->request.stream_id, - req->request.short_not_ok, - req->request.no_interrupt, - req->request.is_last); - } - } else { - dwc3_prepare_one_trb(dep, req, trb_length, chain, i); - } + if (last_sg) + dwc3_prepare_last_sg(dep, req, trb_length, i); + else + dwc3_prepare_one_trb(dep, req, trb_length, 1, i); /* * There can be a situation where all sgs in sglist are not @@ -1188,7 +1197,7 @@ static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep, * we have free trbs we can continue queuing from where we * previously stopped */ - if (chain) + if (!last_sg) req->start_sg = sg_next(s); req->num_queued_sgs++; @@ -1211,60 +1220,7 @@ static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep, static void dwc3_prepare_one_trb_linear(struct dwc3_ep *dep, struct dwc3_request *req) { - unsigned int length = req->request.length; - unsigned int maxp = usb_endpoint_maxp(dep->endpoint.desc); - unsigned int rem = length % maxp; - - if ((!length || rem) && usb_endpoint_dir_out(dep->endpoint.desc)) { - struct dwc3 *dwc = dep->dwc; - struct dwc3_trb *trb; - - req->needs_extra_trb = true; - - /* prepare normal TRB */ - dwc3_prepare_one_trb(dep, req, length, true, 0); - - /* Now prepare one extra TRB to align transfer size */ - trb = &dep->trb_pool[dep->trb_enqueue]; - req->num_trbs++; - __dwc3_prepare_one_trb(dep, trb, dwc->bounce_addr, maxp - rem, - false, 1, req->request.stream_id, - req->request.short_not_ok, - req->request.no_interrupt, - req->request.is_last); - } else if (req->request.zero && req->request.length && - !usb_endpoint_xfer_isoc(dep->endpoint.desc) && - (IS_ALIGNED(req->request.length, maxp))) { - struct dwc3 *dwc = dep->dwc; - struct dwc3_trb *trb; - - req->needs_extra_trb = true; - - /* prepare normal TRB */ - dwc3_prepare_one_trb(dep, req, length, true, 0); - - /* Prepare one extra TRB to handle ZLP */ - trb = &dep->trb_pool[dep->trb_enqueue]; - req->num_trbs++; - __dwc3_prepare_one_trb(dep, trb, dwc->bounce_addr, 0, - !req->direction, 1, req->request.stream_id, - req->request.short_not_ok, - req->request.no_interrupt, - req->request.is_last); - - /* Prepare one more TRB to handle MPS alignment for OUT */ - if (!req->direction) { - trb = &dep->trb_pool[dep->trb_enqueue]; - req->num_trbs++; - __dwc3_prepare_one_trb(dep, trb, dwc->bounce_addr, maxp, - false, 1, req->request.stream_id, - req->request.short_not_ok, - req->request.no_interrupt, - req->request.is_last); - } - } else { - dwc3_prepare_one_trb(dep, req, length, false, 0); - } + dwc3_prepare_last_sg(dep, req, req->request.length, 0); } /* From patchwork Thu Sep 3 02:06:18 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thinh Nguyen X-Patchwork-Id: 297749 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 77844C433E2 for ; Thu, 3 Sep 2020 02:06:21 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4E68020786 for ; Thu, 3 Sep 2020 02:06:21 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=synopsys.com header.i=@synopsys.com header.b="aAlCmDd9" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727877AbgICCGU (ORCPT ); Wed, 2 Sep 2020 22:06:20 -0400 Received: from smtprelay-out1.synopsys.com ([149.117.87.133]:51392 "EHLO smtprelay-out1.synopsys.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726177AbgICCGU (ORCPT ); Wed, 2 Sep 2020 22:06:20 -0400 Received: from mailhost.synopsys.com (sv1-mailhost2.synopsys.com [10.205.2.132]) (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 4CE8CC00B2; Thu, 3 Sep 2020 02:06:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=synopsys.com; s=mail; t=1599098779; bh=lVUoTK2xo8L4aao3QiDjjis/Gwdvfpq5T1QFtk8eB7k=; h=Date:In-Reply-To:References:From:Subject:To:Cc:From; b=aAlCmDd9l+SfD5nAW7G6QvImwCn/PZV48IKx2xnDCvSjxbRy6bB5rvCdeIvvkCPll UUIBPdvigxvmjPLg0QG0Wga6sZWzBDwAt3hmzr1Q9j3ZG+vluNRGqRQoSI0XGttKtm t5RtW8teKipe2oxjoHMopDjhkjUXooMQlCyvkIdfgjUlOeTQ1hOQK7p3devB2lUf95 1XHQiK6XrSsRsP5PrgdfuLFBBxZ5x/TqWFUmsNMRGCo7MNDeCj5Sp620plOfucYzhY 7mtM1vuUIPp43vr/NDPF94qP1wr+xVgImMfDTcCFGENkE6V8wAiciIPOLN0z547ifh AorZ33yPwiCnw== 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 1F14AA006D; Thu, 3 Sep 2020 02:06:18 +0000 (UTC) Received: by te-lab16 (sSMTP sendmail emulation); Wed, 02 Sep 2020 19:06:18 -0700 Date: Wed, 02 Sep 2020 19:06:18 -0700 Message-Id: <3a914ab743485860aeffeb55d46b312491d7d811.1599098161.git.thinhn@synopsys.com> In-Reply-To: References: X-SNPS-Relay: synopsys.com From: Thinh Nguyen Subject: [PATCH v3 2/4] usb: dwc3: gadget: Account for extra TRB To: Felipe Balbi , Greg Kroah-Hartman , Thinh Nguyen , linux-usb@vger.kernel.org Cc: John Youn Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org When checking for how many TRB remaining, make sure to account for extra TRBs for ZLP or MPS alignment transfers. Since the dwc3_prepare_trb* functions should know if we need the extra TRBs, make those functions return a status code -EAGAIN if there isn't enough TRB. Check against those status when preparing TRB instead. Fixes: c6267a51639b ("usb: dwc3: gadget: align transfers to wMaxPacketSize") Signed-off-by: Thinh Nguyen --- Changes in v3: - None Changes in v2: - Add a missing "return 0" for dwc3_prepare_trbs() - Update doc indicate dwc3_prepare_trbs() can return other -errno drivers/usb/dwc3/gadget.c | 82 ++++++++++++++++++++++++--------------- 1 file changed, 51 insertions(+), 31 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 09810ca537bc..7c95ac3186be 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1060,8 +1060,10 @@ static void __dwc3_prepare_one_trb(struct dwc3_ep *dep, struct dwc3_trb *trb, * @trb_length: buffer size of the TRB * @chain: should this TRB be chained to the next? * @node: only for isochronous endpoints. First TRB needs different type. + * + * Return 0 on success or -EAGAIN if there is not enough TRBs. */ -static void dwc3_prepare_one_trb(struct dwc3_ep *dep, +static int dwc3_prepare_one_trb(struct dwc3_ep *dep, struct dwc3_request *req, unsigned int trb_length, unsigned int chain, unsigned int node) { @@ -1072,6 +1074,9 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep, unsigned int no_interrupt = req->request.no_interrupt; unsigned int is_last = req->request.is_last; + if (!dwc3_calc_trbs_left(dep)) + return -EAGAIN; + if (req->request.num_sgs > 0) dma = sg_dma_address(req->start_sg); else @@ -1089,6 +1094,8 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep, __dwc3_prepare_one_trb(dep, trb, dma, trb_length, chain, node, stream_id, short_not_ok, no_interrupt, is_last); + + return 0; } /** @@ -1097,11 +1104,13 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep, * @req: The request to prepare * @entry_length: The last SG entry size * @node: Indicates whether this is not the first entry (for isoc only) + * + * Returns 0 on success or -EAGAIN if there is not enough TRBs. */ -static void dwc3_prepare_last_sg(struct dwc3_ep *dep, - struct dwc3_request *req, - unsigned int entry_length, - unsigned int node) +static int dwc3_prepare_last_sg(struct dwc3_ep *dep, + struct dwc3_request *req, + unsigned int entry_length, + unsigned int node) { unsigned int maxp = usb_endpoint_maxp(dep->endpoint.desc); unsigned int rem = req->request.length % maxp; @@ -1121,6 +1130,9 @@ static void dwc3_prepare_last_sg(struct dwc3_ep *dep, if (num_extra_trbs > 0) req->needs_extra_trb = true; + if (dwc3_calc_trbs_left(dep) < num_extra_trbs + 1) + return -EAGAIN; + /* Prepare a normal TRB */ dwc3_prepare_one_trb(dep, req, entry_length, req->needs_extra_trb, node); @@ -1148,9 +1160,11 @@ static void dwc3_prepare_last_sg(struct dwc3_ep *dep, req->request.no_interrupt, req->request.is_last); } + + return 0; } -static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep, +static int dwc3_prepare_one_trb_sg(struct dwc3_ep *dep, struct dwc3_request *req) { struct scatterlist *sg = req->start_sg; @@ -1170,6 +1184,7 @@ static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep, for_each_sg(sg, s, remaining, i) { unsigned int trb_length; bool last_sg = false; + int ret; trb_length = min_t(unsigned int, length, sg_dma_len(s)); @@ -1186,9 +1201,13 @@ static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep, last_sg = true; if (last_sg) - dwc3_prepare_last_sg(dep, req, trb_length, i); + ret = dwc3_prepare_last_sg(dep, req, trb_length, i); else - dwc3_prepare_one_trb(dep, req, trb_length, 1, i); + ret = dwc3_prepare_one_trb(dep, req, trb_length, 1, i); + + /* Ran out of TRBs */ + if (ret) + return ret; /* * There can be a situation where all sgs in sglist are not @@ -1211,16 +1230,14 @@ static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep, req->num_pending_sgs -= req->request.num_mapped_sgs - req->num_queued_sgs; break; } - - if (!dwc3_calc_trbs_left(dep)) - break; } + return 0; } -static void dwc3_prepare_one_trb_linear(struct dwc3_ep *dep, +static int dwc3_prepare_one_trb_linear(struct dwc3_ep *dep, struct dwc3_request *req) { - dwc3_prepare_last_sg(dep, req, req->request.length, 0); + return dwc3_prepare_last_sg(dep, req, req->request.length, 0); } /* @@ -1230,10 +1247,13 @@ static void dwc3_prepare_one_trb_linear(struct dwc3_ep *dep, * The function goes through the requests list and sets up TRBs for the * transfers. The function returns once there are no more TRBs available or * it runs out of requests. + * + * Returns 0 on success or negative errno. */ -static void dwc3_prepare_trbs(struct dwc3_ep *dep) +static int dwc3_prepare_trbs(struct dwc3_ep *dep) { struct dwc3_request *req, *n; + int ret = 0; BUILD_BUG_ON_NOT_POWER_OF_2(DWC3_TRB_NUM); @@ -1248,11 +1268,11 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep) * break things. */ list_for_each_entry(req, &dep->started_list, list) { - if (req->num_pending_sgs > 0) - dwc3_prepare_one_trb_sg(dep, req); - - if (!dwc3_calc_trbs_left(dep)) - return; + if (req->num_pending_sgs > 0) { + ret = dwc3_prepare_one_trb_sg(dep, req); + if (ret) + return ret; + } /* * Don't prepare beyond a transfer. In DWC_usb32, its transfer @@ -1260,17 +1280,16 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep) * active transfer instead of stopping. */ if (dep->stream_capable && req->request.is_last) - return; + return 0; } list_for_each_entry_safe(req, n, &dep->pending_list, list) { struct dwc3 *dwc = dep->dwc; - int ret; ret = usb_gadget_map_request_by_dev(dwc->sysdev, &req->request, dep->direction); if (ret) - return; + return ret; req->sg = req->request.sg; req->start_sg = req->sg; @@ -1278,12 +1297,12 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep) req->num_pending_sgs = req->request.num_mapped_sgs; if (req->num_pending_sgs > 0) - dwc3_prepare_one_trb_sg(dep, req); + ret = dwc3_prepare_one_trb_sg(dep, req); else - dwc3_prepare_one_trb_linear(dep, req); + ret = dwc3_prepare_one_trb_linear(dep, req); - if (!dwc3_calc_trbs_left(dep)) - return; + if (ret) + return ret; /* * Don't prepare beyond a transfer. In DWC_usb32, its transfer @@ -1291,8 +1310,9 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep) * active transfer instead of stopping. */ if (dep->stream_capable && req->request.is_last) - return; + return 0; } + return 0; } static void dwc3_gadget_ep_cleanup_cancelled_requests(struct dwc3_ep *dep); @@ -1305,12 +1325,12 @@ static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep) int ret; u32 cmd; - if (!dwc3_calc_trbs_left(dep)) - return 0; - starting = !(dep->flags & DWC3_EP_TRANSFER_STARTED); - dwc3_prepare_trbs(dep); + ret = dwc3_prepare_trbs(dep); + if (ret) + return 0; + req = next_request(&dep->started_list); if (!req) { dep->flags |= DWC3_EP_PENDING_REQUEST; From patchwork Thu Sep 3 02:06:24 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thinh Nguyen X-Patchwork-Id: 258669 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 53932C433E7 for ; Thu, 3 Sep 2020 02:06:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3014820758 for ; Thu, 3 Sep 2020 02:06:27 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=synopsys.com header.i=@synopsys.com header.b="bqmL3dzQ" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727944AbgICCG0 (ORCPT ); Wed, 2 Sep 2020 22:06:26 -0400 Received: from smtprelay-out1.synopsys.com ([149.117.73.133]:54524 "EHLO smtprelay-out1.synopsys.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726177AbgICCGZ (ORCPT ); Wed, 2 Sep 2020 22:06:25 -0400 Received: from mailhost.synopsys.com (sv1-mailhost2.synopsys.com [10.205.2.132]) (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 56CC2404A2; Thu, 3 Sep 2020 02:06:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=synopsys.com; s=mail; t=1599098785; bh=oJP+qSVkgCcmEM2FmxEbfRW1vTg4mbEmuYw0mwqbQ6o=; h=Date:In-Reply-To:References:From:Subject:To:Cc:From; b=bqmL3dzQ055c9HV6dux6rRL4/hcgq59t0mQV7eUQoAt5Rem7/TaTMW1wFJpIyVh/D sgz0P0MdaxRtFtRkuku9H3x6Dx8cgwNlzNPNZiDN0piX274CpzuIS57sbK3LlMRlnP O/EigG/51veeMEFQpjDY+TCjIgU+DrhMFrqpkmkiUUry47KP7wK9+tPm4OkNPTx3/Q iDyxOUIRFXe6jRRqkLVdzqVSX4nrqfYviVVbf4/4ht+GQ0tf0v4Y4dH3ZgYJI1jRGl 3Ha5OrhOl5/jFTFifwZJlZH99MovTeExIP22A/hf2KcrCfoJs/liRqR214fNlBzKSX NTUPUZPzToY+w== 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 31D20A006D; Thu, 3 Sep 2020 02:06:24 +0000 (UTC) Received: by te-lab16 (sSMTP sendmail emulation); Wed, 02 Sep 2020 19:06:24 -0700 Date: Wed, 02 Sep 2020 19:06:24 -0700 Message-Id: <55d99f7e79667497cfbdd9e3d39b8e3668180aa9.1599098161.git.thinhn@synopsys.com> In-Reply-To: References: X-SNPS-Relay: synopsys.com From: Thinh Nguyen Subject: [PATCH v3 3/4] usb: dwc3: gadget: Rename misleading function names To: Felipe Balbi , Greg Kroah-Hartman , Thinh Nguyen , linux-usb@vger.kernel.org Cc: John Youn Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org The functions dwc3_prepare_one_trb_sg and dwc3_prepare_one_trb_linear are not necessarily preparing "one" TRB, it can prepare multiple TRBs. Rename these functions as follow: dwc3_prepare_one_trb_sg -> dwc3_prepare_trbs_sg dwc3_prepare_one_trb_linear -> dwc3_prepare_trbs_linear Signed-off-by: Thinh Nguyen --- Changes in v3: - None Changes in v2: - None drivers/usb/dwc3/gadget.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 7c95ac3186be..692b12367d8a 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1164,7 +1164,7 @@ static int dwc3_prepare_last_sg(struct dwc3_ep *dep, return 0; } -static int dwc3_prepare_one_trb_sg(struct dwc3_ep *dep, +static int dwc3_prepare_trbs_sg(struct dwc3_ep *dep, struct dwc3_request *req) { struct scatterlist *sg = req->start_sg; @@ -1234,7 +1234,7 @@ static int dwc3_prepare_one_trb_sg(struct dwc3_ep *dep, return 0; } -static int dwc3_prepare_one_trb_linear(struct dwc3_ep *dep, +static int dwc3_prepare_trbs_linear(struct dwc3_ep *dep, struct dwc3_request *req) { return dwc3_prepare_last_sg(dep, req, req->request.length, 0); @@ -1269,7 +1269,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_one_trb_sg(dep, req); + ret = dwc3_prepare_trbs_sg(dep, req); if (ret) return ret; } @@ -1297,9 +1297,9 @@ static int dwc3_prepare_trbs(struct dwc3_ep *dep) req->num_pending_sgs = req->request.num_mapped_sgs; if (req->num_pending_sgs > 0) - ret = dwc3_prepare_one_trb_sg(dep, req); + ret = dwc3_prepare_trbs_sg(dep, req); else - ret = dwc3_prepare_one_trb_linear(dep, req); + ret = dwc3_prepare_trbs_linear(dep, req); if (ret) return ret; From patchwork Thu Sep 3 02:06:30 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thinh Nguyen X-Patchwork-Id: 297748 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 E5B95C433E2 for ; Thu, 3 Sep 2020 02:06:33 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B6E1A20786 for ; Thu, 3 Sep 2020 02:06:33 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=synopsys.com header.i=@synopsys.com header.b="i0tFf0Bx" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727965AbgICCGc (ORCPT ); Wed, 2 Sep 2020 22:06:32 -0400 Received: from smtprelay-out1.synopsys.com ([149.117.87.133]:51396 "EHLO smtprelay-out1.synopsys.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726177AbgICCGc (ORCPT ); Wed, 2 Sep 2020 22:06:32 -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 73ED5C00B2; Thu, 3 Sep 2020 02:06:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=synopsys.com; s=mail; t=1599098791; bh=FAcdJ8pWFyDHfDki1U6x0jqoQZefGIeFFvsdKvw53pU=; h=Date:In-Reply-To:References:From:Subject:To:Cc:From; b=i0tFf0Bxtg6RsVE3HWDcSp9XoBuZqytW8Aoy7xuyqP13nyZkTXwtutw0EXzTw7EVs 3LTGdK0nYl0q+Gg7lhMU3JwzLYF/35VXp7eIVjY4plWQ7UkGQ4ecTMqUyaatHR8Vi8 He9n+5G4NVCknEk/nepWc18doGpOtS+IoM5lnmwKfB4tB0Zqc0e5r1W4KKO4C4rrUv fzx6ANWrYpYyFiFX8tykEqFIgKpU44UVU58TezAa+IzvFLh12RCvklX0pFKageRx2w IGJqmPFsOf4N+IfncD/mFeC1RKx18LdgaqWgKGPvQs4MpuQN24/MZ6dkZ/3FDq+sOq dsPOh9VemZG6Q== 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 4600DA007B; Thu, 3 Sep 2020 02:06:30 +0000 (UTC) Received: by te-lab16 (sSMTP sendmail emulation); Wed, 02 Sep 2020 19:06:30 -0700 Date: Wed, 02 Sep 2020 19:06:30 -0700 Message-Id: In-Reply-To: References: X-SNPS-Relay: synopsys.com From: Thinh Nguyen Subject: [PATCH v3 4/4] usb: dwc3: ep0: Skip ZLP setup for OUT To: Felipe Balbi , Greg Kroah-Hartman , Thinh Nguyen , linux-usb@vger.kernel.org Cc: John Youn Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org The current implementation for ZLP handling of usb_request->zero for ep0 is only for control IN requests. For OUT direction, DWC3 needs to check and set up for MPS boundary alignment, and it doesn't do that at the moment. Usually, control OUT requests can indicate its transfer size via the wLength field of the control message. So usb_request->zero is usually not needed for OUT direction. To handle ZLP OUT for control endpoint, we'd need to allocate at least 3 TRBs for control requests (we have 2 at the moment). For now, let's just make sure the current ZLP setup is only for IN direction. Signed-off-by: Thinh Nguyen --- Changes in v3: - None Changes in v2: - None drivers/usb/dwc3/ep0.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 5bb4327ae237..b531f63d19de 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -979,7 +979,7 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc, false); ret = dwc3_ep0_start_trans(dep); } else if (IS_ALIGNED(req->request.length, dep->endpoint.maxpacket) && - req->request.length && req->request.zero) { + req->request.length && req->request.zero && req->direction) { ret = usb_gadget_map_request_by_dev(dwc->sysdev, &req->request, dep->number);