When system has stpped the gadget, we should avoid queuing any requests
which will cause tranfer failed. Thus adding some disconnect checking to
avoid this situation.

Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
---
Changes since v1:
 - Split into 2 separate ptaches.
 - Choose complete mechanism instead of polling.
---
 drivers/usb/dwc3/ep0.c    |    8 ++++++++
 drivers/usb/dwc3/gadget.c |   12 +++++++++---
 2 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index fe79d77..632e5a4 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -228,6 +228,14 @@ int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct 
usb_request *request,
        int                             ret;
 
        spin_lock_irqsave(&dwc->lock, flags);
+       if (!dwc->pullups_connected) {
+               dwc3_trace(trace_dwc3_ep0,
+                       "queuing request %p to %s when gadget is disconnected",
+                       request, dep->name);
+               ret = -ESHUTDOWN;
+               goto out;
+       }
+
        if (!dep->endpoint.desc) {
                dwc3_trace(trace_dwc3_ep0,
                                "trying to queue request %p to disabled %s",
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 1783406..1a33308 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -1040,6 +1040,13 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, 
struct dwc3_request *req)
        struct dwc3             *dwc = dep->dwc;
        int                     ret;
 
+       if (!dwc->pullups_connected) {
+               dwc3_trace(trace_dwc3_gadget,
+                       "queuing request %p to %s when gadget is disconnected",
+                       &req->request, dep->endpoint.name);
+               return -ESHUTDOWN;
+       }
+
        if (!dep->endpoint.desc) {
                dwc3_trace(trace_dwc3_gadget,
                                "trying to queue request %p to disabled %s",
@@ -1984,13 +1991,12 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, 
struct dwc3_ep *dep,
                if (ret)
                        break;
        }
-
        /*
         * Our endpoint might get disabled by another thread during
         * dwc3_gadget_giveback(). If that happens, we're just gonna return 1
         * early on so DWC3_EP_BUSY flag gets cleared
         */
-       if (!dep->endpoint.desc)
+       if (!dep->endpoint.desc || !dwc->pullups_connected)
                return 1;
 
        if (usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
@@ -2064,7 +2070,7 @@ static void dwc3_endpoint_transfer_complete(struct dwc3 
*dwc,
         * dwc3_gadget_giveback(). If that happens, we're just gonna return 1
         * early on so DWC3_EP_BUSY flag gets cleared
         */
-       if (!dep->endpoint.desc)
+       if (!dep->endpoint.desc || !dwc->pullups_connected)
                return;
 
        if (!usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
-- 
1.7.9.5

Reply via email to