From patchwork Tue Oct 4 08:42:26 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "\(Exiting\) Baolin Wang" X-Patchwork-Id: 77237 Delivered-To: patch@linaro.org Received: by 10.140.106.72 with SMTP id d66csp2097094qgf; Tue, 4 Oct 2016 01:43:17 -0700 (PDT) X-Received: by 10.98.5.133 with SMTP id 127mr4052735pff.40.1475570597719; Tue, 04 Oct 2016 01:43:17 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id l85si41601676pfk.122.2016.10.04.01.43.17; Tue, 04 Oct 2016 01:43:17 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-usb-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; spf=pass (google.com: best guess record for domain of linux-usb-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-usb-owner@vger.kernel.org; dmarc=fail (p=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754006AbcJDIm7 (ORCPT + 4 others); Tue, 4 Oct 2016 04:42:59 -0400 Received: from mail-pf0-f180.google.com ([209.85.192.180]:35892 "EHLO mail-pf0-f180.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753618AbcJDIm6 (ORCPT ); Tue, 4 Oct 2016 04:42:58 -0400 Received: by mail-pf0-f180.google.com with SMTP id i85so22176699pfa.3 for ; Tue, 04 Oct 2016 01:42:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=sA7Dy9rvnRUS4x2aXZM7BvWSP4o9TtlL3aDt30838rM=; b=faOl/vJvbtt0wkJbPWJtHDY/x9l/SYI214vMkTKiJqP0svRa7XOh8HxRChkx01xzwl 823k9si3RpAz/gmaD9odRYMW2ikiieEH59ze3gsoWBvQoyS8Eh5bsrb9qFCTKIEyjTic bPIam2qGM96tpTOYlxm9zYXetg0dSRJk3mRs0= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=sA7Dy9rvnRUS4x2aXZM7BvWSP4o9TtlL3aDt30838rM=; b=DgX5128hWLZ4EHLhDAUmk0VPW4LRMo8ypI3sYxVKCvFZxdQ7DiYqlVzDyUK9CtgV43 pp172Gy+qLI9W1YuBcECTW5WJfS/x79Z1T7fcw9HqIWXggh2nnJc7UP/+rKbWLPFIdXB tQkIAut1NBe5n8D+GcQgRos1qfdlbxSszRB56lcaSVX+ZpZJv/+GmX7rRn3YjsqOxTD+ FE1IlM/o7kPTwAQCUCOCDrj0vlikaWMzof73ilevYWxuEdKy1nebhwByWVkO+ctcpmty UOTsoqXmdgxSdrcdJud7KW9ABfpUGF/Rz+FWDRJpFfNMh1tHZ1PEd3s6NjiIVKuS1KpY NU/w== X-Gm-Message-State: AA6/9Rl4muWG0B1/OdT38XQMy7y/uKbjKitl9O2Hwt/BAidKTFBI3QYycUaObOv3W4VSP4yy X-Received: by 10.98.53.65 with SMTP id c62mr4059133pfa.66.1475570577107; Tue, 04 Oct 2016 01:42:57 -0700 (PDT) Received: from baolinwangubtpc.spreadtrum.com ([175.111.195.49]) by smtp.gmail.com with ESMTPSA id p128sm52953419pfg.38.2016.10.04.01.42.54 (version=TLS1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 04 Oct 2016 01:42:56 -0700 (PDT) From: Baolin Wang To: balbi@kernel.org Cc: gregkh@linuxfoundation.org, broonie@kernel.org, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, baolin.wang@linaro.org Subject: [RESEND PATCH v3 2/2] usb: dwc3: Wait for control tranfer completed when stopping gadget Date: Tue, 4 Oct 2016 16:42:26 +0800 Message-Id: <0e1e7e00e3e2aacf0fe0ee91854e6a0ee81cc320.1475570367.git.baolin.wang@linaro.org> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <521625dd7f5e335e2a681ec65ebffc5832207e5f.1475570367.git.baolin.wang@linaro.org> References: <521625dd7f5e335e2a681ec65ebffc5832207e5f.1475570367.git.baolin.wang@linaro.org> In-Reply-To: <521625dd7f5e335e2a681ec65ebffc5832207e5f.1475570367.git.baolin.wang@linaro.org> References: <521625dd7f5e335e2a681ec65ebffc5832207e5f.1475570367.git.baolin.wang@linaro.org> Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org When we change the USB function with configfs dynamically, we possibly met this situation: one core is doing the control transfer, another core is trying to unregister the USB gadget from userspace, we must wait for completing this control tranfer, or it will hang the controller to set the DEVCTRLHLT flag. Signed-off-by: Baolin Wang --- drivers/usb/dwc3/core.h | 2 ++ drivers/usb/dwc3/ep0.c | 2 ++ drivers/usb/dwc3/gadget.c | 23 +++++++++++++++++++++++ 3 files changed, 27 insertions(+) -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index b2317e7..9128725 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -745,6 +745,7 @@ struct dwc3_scratchpad_array { * @ep0_usb_req: dummy req used while handling STD USB requests * @ep0_bounce_addr: dma address of ep0_bounce * @scratch_addr: dma address of scratchbuf + * @ep0_in_setup: One control transfer is completed and enter setup phase * @lock: for synchronizing * @dev: pointer to our struct device * @xhci: pointer to our xHCI child @@ -843,6 +844,7 @@ struct dwc3 { dma_addr_t ep0_bounce_addr; dma_addr_t scratch_addr; struct dwc3_request ep0_usb_req; + struct completion ep0_in_setup; /* device lock */ spinlock_t lock; diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index fe79d77..06c167a 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -311,6 +311,8 @@ void dwc3_ep0_out_start(struct dwc3 *dwc) ret = dwc3_ep0_start_trans(dwc, 0, dwc->ctrl_req_addr, 8, DWC3_TRBCTL_CONTROL_SETUP, false); WARN_ON(ret < 0); + + complete(&dwc->ep0_in_setup); } 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 ca2ae5b..fef023a 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1437,6 +1437,15 @@ static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on, int suspend) if (pm_runtime_suspended(dwc->dev)) return 0; + /* + * Per databook, when we want to stop the gadget, if a control transfer + * is still in process, complete it and get the core into setup phase. + */ + if (!is_on && dwc->ep0state != EP0_SETUP_PHASE) { + reinit_completion(&dwc->ep0_in_setup); + return -EBUSY; + } + reg = dwc3_readl(dwc->regs, DWC3_DCTL); if (is_on) { if (dwc->revision <= DWC3_REVISION_187A) { @@ -1487,10 +1496,22 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on) is_on = !!is_on; +try_again: spin_lock_irqsave(&dwc->lock, flags); ret = dwc3_gadget_run_stop(dwc, is_on, false); spin_unlock_irqrestore(&dwc->lock, flags); + if (ret == -EBUSY) { + ret = wait_for_completion_timeout(&dwc->ep0_in_setup, + msecs_to_jiffies(500)); + if (ret == 0) { + dev_err(dwc->dev, "timeout to stop gadget.\n"); + ret = -ETIMEDOUT; + } else { + goto try_again; + } + } + return ret; } @@ -2914,6 +2935,8 @@ int dwc3_gadget_init(struct dwc3 *dwc) goto err4; } + init_completion(&dwc->ep0_in_setup); + dwc->gadget.ops = &dwc3_gadget_ops; dwc->gadget.speed = USB_SPEED_UNKNOWN; dwc->gadget.sg_supported = true;