|
Oliver Neukum |
eccafb |
From c96683798e272366866a5c0ce3073c0b5a256db7 Mon Sep 17 00:00:00 2001
|
|
Oliver Neukum |
eccafb |
From: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
|
|
Oliver Neukum |
eccafb |
Date: Thu, 21 Apr 2022 19:22:50 -0700
|
|
Oliver Neukum |
eccafb |
Subject: [PATCH] usb: dwc3: ep0: Don't prepare beyond Setup stage
|
|
Oliver Neukum |
eccafb |
Git-commit: c96683798e272366866a5c0ce3073c0b5a256db7
|
|
Oliver Neukum |
eccafb |
References: git-fixes
|
|
Oliver Neukum |
eccafb |
Patch-mainline: v5.19-rc1
|
|
Oliver Neukum |
eccafb |
|
|
Oliver Neukum |
eccafb |
Since we can't guarantee that the host won't send new Setup packet
|
|
Oliver Neukum |
eccafb |
before going through the device-initiated disconnect, don't prepare
|
|
Oliver Neukum |
eccafb |
beyond the Setup stage and keep the device in EP0_SETUP_PHASE. This
|
|
Oliver Neukum |
eccafb |
ensures that the device-initated disconnect sequence can go through
|
|
Oliver Neukum |
eccafb |
gracefully. Note that the controller won't service the End Transfer
|
|
Oliver Neukum |
eccafb |
command if it can't DMA out the Setup packet.
|
|
Oliver Neukum |
eccafb |
|
|
Oliver Neukum |
eccafb |
Signed-off-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
|
|
Oliver Neukum |
eccafb |
Link: https://lore.kernel.org/r/6bacec56ecabb2c6e49a09cedfcac281fdc97de0.1650593829.git.Thinh.Nguyen@synopsys.com
|
|
Oliver Neukum |
eccafb |
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
Oliver Neukum |
eccafb |
Signed-off-by: Oliver Neukum <oneukum@suse.com>
|
|
Oliver Neukum |
eccafb |
---
|
|
Oliver Neukum |
eccafb |
drivers/usb/dwc3/ep0.c | 2 +-
|
|
Oliver Neukum |
eccafb |
drivers/usb/dwc3/gadget.c | 29 +++++++++++++++++------------
|
|
Oliver Neukum |
eccafb |
2 files changed, 18 insertions(+), 13 deletions(-)
|
|
Oliver Neukum |
eccafb |
|
|
Oliver Neukum |
eccafb |
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
|
|
Oliver Neukum |
eccafb |
index aa8476da222d..6615f641b34f 100644
|
|
Oliver Neukum |
eccafb |
--- a/drivers/usb/dwc3/ep0.c
|
|
Oliver Neukum |
eccafb |
+++ b/drivers/usb/dwc3/ep0.c
|
|
Oliver Neukum |
eccafb |
@@ -813,7 +813,7 @@ static void dwc3_ep0_inspect_setup(struct dwc3 *dwc,
|
|
Oliver Neukum |
eccafb |
int ret = -EINVAL;
|
|
Oliver Neukum |
eccafb |
u32 len;
|
|
Oliver Neukum |
eccafb |
|
|
Oliver Neukum |
eccafb |
- if (!dwc->gadget_driver)
|
|
Oliver Neukum |
eccafb |
+ if (!dwc->gadget_driver || !dwc->connected)
|
|
Oliver Neukum |
eccafb |
goto out;
|
|
Oliver Neukum |
eccafb |
|
|
Oliver Neukum |
eccafb |
trace_dwc3_ctrl_req(ctrl);
|
|
Oliver Neukum |
eccafb |
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
|
|
Oliver Neukum |
eccafb |
index 3c0a6c83ea43..5e3311e3cc16 100644
|
|
Oliver Neukum |
eccafb |
--- a/drivers/usb/dwc3/gadget.c
|
|
Oliver Neukum |
eccafb |
+++ b/drivers/usb/dwc3/gadget.c
|
|
Oliver Neukum |
eccafb |
@@ -2514,6 +2514,23 @@ static int dwc3_gadget_soft_disconnect(struct dwc3 *dwc)
|
|
Oliver Neukum |
eccafb |
spin_lock_irqsave(&dwc->lock, flags);
|
|
Oliver Neukum |
eccafb |
dwc->connected = false;
|
|
Oliver Neukum |
eccafb |
|
|
Oliver Neukum |
eccafb |
+ /*
|
|
Oliver Neukum |
eccafb |
+ * Per databook, when we want to stop the gadget, if a control transfer
|
|
Oliver Neukum |
eccafb |
+ * is still in process, complete it and get the core into setup phase.
|
|
Oliver Neukum |
eccafb |
+ */
|
|
Oliver Neukum |
eccafb |
+ if (dwc->ep0state != EP0_SETUP_PHASE) {
|
|
Oliver Neukum |
eccafb |
+ int ret;
|
|
Oliver Neukum |
eccafb |
+
|
|
Oliver Neukum |
eccafb |
+ reinit_completion(&dwc->ep0_in_setup);
|
|
Oliver Neukum |
eccafb |
+
|
|
Oliver Neukum |
eccafb |
+ spin_unlock_irqrestore(&dwc->lock, flags);
|
|
Oliver Neukum |
eccafb |
+ ret = wait_for_completion_timeout(&dwc->ep0_in_setup,
|
|
Oliver Neukum |
eccafb |
+ msecs_to_jiffies(DWC3_PULL_UP_TIMEOUT));
|
|
Oliver Neukum |
eccafb |
+ spin_lock_irqsave(&dwc->lock, flags);
|
|
Oliver Neukum |
eccafb |
+ if (ret == 0)
|
|
Oliver Neukum |
eccafb |
+ dev_warn(dwc->dev, "timed out waiting for SETUP phase\n");
|
|
Oliver Neukum |
eccafb |
+ }
|
|
Oliver Neukum |
eccafb |
+
|
|
Oliver Neukum |
eccafb |
/*
|
|
Oliver Neukum |
eccafb |
* In the Synopsys DesignWare Cores USB3 Databook Rev. 3.30a
|
|
Oliver Neukum |
eccafb |
* Section 4.1.8 Table 4-7, it states that for a device-initiated
|
|
Oliver Neukum |
eccafb |
@@ -2546,18 +2563,6 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on)
|
|
Oliver Neukum |
eccafb |
return 0;
|
|
Oliver Neukum |
eccafb |
|
|
Oliver Neukum |
eccafb |
dwc->softconnect = is_on;
|
|
Oliver Neukum |
eccafb |
- /*
|
|
Oliver Neukum |
eccafb |
- * Per databook, when we want to stop the gadget, if a control transfer
|
|
Oliver Neukum |
eccafb |
- * is still in process, complete it and get the core into setup phase.
|
|
Oliver Neukum |
eccafb |
- */
|
|
Oliver Neukum |
eccafb |
- if (!is_on && dwc->ep0state != EP0_SETUP_PHASE) {
|
|
Oliver Neukum |
eccafb |
- reinit_completion(&dwc->ep0_in_setup);
|
|
Oliver Neukum |
eccafb |
-
|
|
Oliver Neukum |
eccafb |
- ret = wait_for_completion_timeout(&dwc->ep0_in_setup,
|
|
Oliver Neukum |
eccafb |
- msecs_to_jiffies(DWC3_PULL_UP_TIMEOUT));
|
|
Oliver Neukum |
eccafb |
- if (ret == 0)
|
|
Oliver Neukum |
eccafb |
- dev_warn(dwc->dev, "timed out waiting for SETUP phase\n");
|
|
Oliver Neukum |
eccafb |
- }
|
|
Oliver Neukum |
eccafb |
|
|
Oliver Neukum |
eccafb |
/*
|
|
Oliver Neukum |
eccafb |
* Avoid issuing a runtime resume if the device is already in the
|
|
Oliver Neukum |
eccafb |
--
|
|
Oliver Neukum |
eccafb |
2.40.1
|
|
Oliver Neukum |
eccafb |
|