Received: by 2002:a05:6a10:413:0:0:0:0 with SMTP id 19csp3588403pxp; Tue, 8 Mar 2022 18:11:39 -0800 (PST) X-Google-Smtp-Source: ABdhPJw+pXVsETswLNP7+zsX5XXwW2jQXBVQ1Dik1XovmtmCCYAMafPMEXtP2bzl8iVxYKHjt4sS X-Received: by 2002:a05:6a00:148b:b0:4f7:2acc:7851 with SMTP id v11-20020a056a00148b00b004f72acc7851mr7227988pfu.43.1646791899606; Tue, 08 Mar 2022 18:11:39 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1646791899; cv=none; d=google.com; s=arc-20160816; b=x34j2pUefbca+o4HEz+F6AAuWLsQfp81eV8c/6TyGWt11pstVwVHh3ZytrfqLsyYEt aUTkQGjOWihqF0NhkniYx0/0OI/GpeX/O/sGWh2a94nHWP1WcKqvF8L7hX5w9Q4UXKmL NtEenwdQJXK8i80s3IuikFhKZgWwnn9S4k+R7oJyKNOtcorLXNQHz+go1GU9T8Ll5Cgn riE7jgptUgW8gtq1bBf/glcb+QkuWLDqhKE8gvpvfG5zywwtgIwhOgtY0nIS7I/KsLot 5ELnslsAQO6y/OmNJs798IVIgB4N0zMoLYH3DGelyr3HR7xAB3g22MZ2FhYMYHPX4Yav UugA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from:dkim-signature; bh=uVYTo3zmAFmOrPCTNEi6PNR2yQWPKzEW4c6l7/SRtPU=; b=MyFqvDAtCAiSiZjHXCt69kSc7/lY9UzMhpNc48TCGYf7wOZBEhg4VywpKgCMTXKire +1eZm9fHm/zSbm/OYVpprVNGQFJ5rmZeeSXfDjWjp8tU4pBHRjbrlhhQpgxodtVVTdZr +lGQxMKN5MlBaNcRE6jgqo8IoNQdbr95SzBT2fDDdxanqTyvxGAskNyXSK6GkJETFkTs NDLs9klHQxkpYYybwiZhmFNygkZQpRud4Z6Ujpo4VJMuVPiywiHF2T4+Sa6rC90LBKl+ qD7fvYgNjTW4cQA+SzftHQVDsqcK6k/0WmUR3l2HVlGL0BJwi7mFUxOneEauSZZMI9xX 7g2g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@quicinc.com header.s=qcdkim header.b=C6R0hZnW; spf=softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=quicinc.com Return-Path: Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net. [23.128.96.19]) by mx.google.com with ESMTPS id f33-20020a635121000000b0037264ef5f8bsi504076pgb.859.2022.03.08.18.11.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 08 Mar 2022 18:11:39 -0800 (PST) Received-SPF: softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 as permitted sender) client-ip=23.128.96.19; Authentication-Results: mx.google.com; dkim=pass header.i=@quicinc.com header.s=qcdkim header.b=C6R0hZnW; spf=softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=quicinc.com Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id B7852131F70; Tue, 8 Mar 2022 17:04:04 -0800 (PST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229714AbiCIBEv (ORCPT + 99 others); Tue, 8 Mar 2022 20:04:51 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44558 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229687AbiCIBEj (ORCPT ); Tue, 8 Mar 2022 20:04:39 -0500 Received: from alexa-out-sd-02.qualcomm.com (alexa-out-sd-02.qualcomm.com [199.106.114.39]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 730B42BB0D; Tue, 8 Mar 2022 16:42:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1646786524; x=1678322524; h=from:to:cc:subject:date:message-id:mime-version: content-transfer-encoding; bh=uVYTo3zmAFmOrPCTNEi6PNR2yQWPKzEW4c6l7/SRtPU=; b=C6R0hZnW0JUw4WHzQLhrEeG207YWcNnEixm1LXeiPW/9N2B3/W6Gq63d uCR7bpW5nWY4p7c4Ffe2AVgk80zP1Dy6vOnmMu9m2+JkggC1XSgCVOiaM ANpE06qq0P2ggqWYJrlgBN8zkEViiOVVBPPaalQHSAFXYJko9Frjcjv0v U=; Received: from unknown (HELO ironmsg04-sd.qualcomm.com) ([10.53.140.144]) by alexa-out-sd-02.qualcomm.com with ESMTP; 08 Mar 2022 16:42:04 -0800 X-QCInternal: smtphost Received: from nasanex01c.na.qualcomm.com ([10.47.97.222]) by ironmsg04-sd.qualcomm.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 Mar 2022 16:42:03 -0800 Received: from nalasex01b.na.qualcomm.com (10.47.209.197) by nasanex01c.na.qualcomm.com (10.47.97.222) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.15; Tue, 8 Mar 2022 16:42:02 -0800 Received: from wcheng-linux.qualcomm.com (10.80.80.8) by nalasex01b.na.qualcomm.com (10.47.209.197) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.15; Tue, 8 Mar 2022 16:42:02 -0800 From: Wesley Cheng To: , CC: , , , , Wesley Cheng Subject: [PATCH] usb: dwc3: gadget: Wait for ep0 xfers to complete during dequeue Date: Tue, 8 Mar 2022 16:41:48 -0800 Message-ID: <20220309004148.12061-1-quic_wcheng@quicinc.com> X-Mailer: git-send-email 2.33.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nalasex01b.na.qualcomm.com (10.47.209.197) X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,RDNS_NONE,SPF_HELO_NONE,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Thinh Nguyen If the request being dequeued is currently active, then the current logic is to issue a stop transfer command, and allow the command completion to cleanup the cancelled list. The DWC3 controller will run into an end transfer command timeout if there is an ongoing EP0 transaction. If this is the case, wait for the EP0 completion event before proceeding to retry the endxfer command again. Co-developed-by: Wesley Cheng Signed-off-by: Wesley Cheng Signed-off-by: Thinh Nguyen --- Patch discussion below: https://lore.kernel.org/linux-usb/1644836933-141376-1-git-send-email-dh10.jung@samsung.com/T/#t drivers/usb/dwc3/core.h | 2 +- drivers/usb/dwc3/ep0.c | 14 ++++++++++++++ drivers/usb/dwc3/gadget.c | 13 ++++++++----- drivers/usb/dwc3/gadget.h | 1 + 4 files changed, 24 insertions(+), 6 deletions(-) diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index eb9c1efced05..f557f5f36a7f 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -736,7 +736,7 @@ struct dwc3_ep { #define DWC3_EP_FIRST_STREAM_PRIMED BIT(10) #define DWC3_EP_PENDING_CLEAR_STALL BIT(11) #define DWC3_EP_TXFIFO_RESIZED BIT(12) - +#define DWC3_EP_DELAY_STOP BIT(13) /* This last one is specific to EP0 */ #define DWC3_EP0_DIR_IN BIT(31) diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 658739410992..1064be5518f6 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -271,6 +271,7 @@ void dwc3_ep0_out_start(struct dwc3 *dwc) { struct dwc3_ep *dep; int ret; + int i; complete(&dwc->ep0_in_setup); @@ -279,6 +280,19 @@ void dwc3_ep0_out_start(struct dwc3 *dwc) DWC3_TRBCTL_CONTROL_SETUP, false); ret = dwc3_ep0_start_trans(dep); WARN_ON(ret < 0); + for (i = 2; i < DWC3_ENDPOINTS_NUM; i++) { + struct dwc3_ep *dwc3_ep; + + dwc3_ep = dwc->eps[i]; + if (!dwc3_ep) + continue; + + if (!(dwc3_ep->flags & DWC3_EP_DELAY_STOP)) + continue; + + dwc3_ep->flags &= ~DWC3_EP_DELAY_STOP; + dwc3_stop_active_transfer(dwc3_ep, true, true); + } } static struct dwc3_ep *dwc3_wIndex_to_dep(struct dwc3 *dwc, __le16 wIndex_le) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index a0c883f19a41..ccef508b1296 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -654,9 +654,6 @@ static int dwc3_gadget_set_ep_config(struct dwc3_ep *dep, unsigned int action) return dwc3_send_gadget_ep_cmd(dep, DWC3_DEPCMD_SETEPCONFIG, ¶ms); } -static void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force, - bool interrupt); - /** * dwc3_gadget_calc_tx_fifo_size - calculates the txfifo size value * @dwc: pointer to the DWC3 context @@ -1899,6 +1896,7 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) */ if ((dep->flags & DWC3_EP_END_TRANSFER_PENDING) || (dep->flags & DWC3_EP_WEDGE) || + (dep->flags & DWC3_EP_DELAY_STOP) || (dep->flags & DWC3_EP_STALL)) { dep->flags |= DWC3_EP_DELAY_START; return 0; @@ -2033,6 +2031,9 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep, if (r == req) { struct dwc3_request *t; + if (dwc->ep0state != EP0_SETUP_PHASE && !dwc->delayed_status) + dep->flags |= DWC3_EP_DELAY_STOP; + /* wait until it is processed */ dwc3_stop_active_transfer(dep, true, true); @@ -2116,7 +2117,8 @@ int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value, int protocol) list_for_each_entry_safe(req, tmp, &dep->started_list, list) dwc3_gadget_move_cancelled_request(req, DWC3_REQUEST_STATUS_STALLED); - if (dep->flags & DWC3_EP_END_TRANSFER_PENDING) { + if (dep->flags & DWC3_EP_END_TRANSFER_PENDING || + (dep->flags & DWC3_EP_DELAY_STOP)) { dep->flags |= DWC3_EP_PENDING_CLEAR_STALL; return 0; } @@ -3596,7 +3598,7 @@ static void dwc3_reset_gadget(struct dwc3 *dwc) } } -static void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force, +void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force, bool interrupt) { struct dwc3_gadget_ep_cmd_params params; @@ -3604,6 +3606,7 @@ static void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force, int ret; if (!(dep->flags & DWC3_EP_TRANSFER_STARTED) || + (dep->flags & DWC3_EP_DELAY_STOP) || (dep->flags & DWC3_EP_END_TRANSFER_PENDING)) return; diff --git a/drivers/usb/dwc3/gadget.h b/drivers/usb/dwc3/gadget.h index 77df4b6d6c13..f763380e672e 100644 --- a/drivers/usb/dwc3/gadget.h +++ b/drivers/usb/dwc3/gadget.h @@ -116,6 +116,7 @@ int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct usb_request *request, gfp_t gfp_flags); int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value, int protocol); void dwc3_ep0_send_delayed_status(struct dwc3 *dwc); +void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force, bool interrupt); /** * dwc3_gadget_ep_get_transfer_index - Gets transfer index from HW