This is a note to let you know that I've just added the patch titled

    usb: dwc3: gadget: fix isoc END TRANSFER Condition

to my usb git tree which can be found at
    git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git
in the usb-next branch.

The patch will show up in the next release of the linux-next tree
(usually sometime within the next 24 hours during the week.)

The patch will also be merged in the next major kernel release
during the merge window.

If you have any questions about this process, please let me know.


>From cdc359dd87ab6c39a67dab724fd0b61c16e6f08b Mon Sep 17 00:00:00 2001
From: Pratyush Anand <[email protected]>
Date: Mon, 14 Jan 2013 15:59:34 +0530
Subject: usb: dwc3: gadget: fix isoc END TRANSFER Condition

There were still some corner cases where isoc transfer was not able to
restart, specially when missed isoc does not happen , and in fact gadget does
not queue any new request during giveback.

Cleanup function calls giveback first, which provides a way to queue
another request to gadget. But gadget did not had any data. So , it did
not call ep_queue. To twist it further, gadget did not queue till
cleanup for last queued TRB is called. If we ever reach this scenario,
we must call END TRANSFER, so that we receive a new  xfernotready with
information about current microframe number.

Also insure that there is no request submitted to core when issuing END
TRANSFER.

Cc: <[email protected]> # v3.8
Signed-off-by: Pratyush Anand <[email protected]>
Signed-off-by: Felipe Balbi <[email protected]>
---
 drivers/usb/dwc3/gadget.c | 23 ++++++++++++++++++-----
 1 file changed, 18 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index c4ffb35..e60e72c 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -1089,7 +1089,10 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, 
struct dwc3_request *req)
                 * notion of current microframe.
                 */
                if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
-                       dwc3_stop_active_transfer(dwc, dep->number);
+                       if (list_empty(&dep->req_queued)) {
+                               dwc3_stop_active_transfer(dwc, dep->number);
+                               dep->flags = DWC3_EP_ENABLED;
+                       }
                        return 0;
                }
 
@@ -1727,10 +1730,20 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, 
struct dwc3_ep *dep,
                        break;
        } while (1);
 
-       if (list_empty(&dep->req_queued) &&
-                       (dep->flags & DWC3_EP_MISSED_ISOC)) {
-               dwc3_stop_active_transfer(dwc, dep->number);
-               dep->flags &= ~DWC3_EP_MISSED_ISOC;
+       if (usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
+                       list_empty(&dep->req_queued)) {
+               if (list_empty(&dep->request_list)) {
+                       /*
+                        * If there is no entry in request list then do
+                        * not issue END TRANSFER now. Just set PENDING
+                        * flag, so that END TRANSFER is issued when an
+                        * entry is added into request list.
+                        */
+                       dep->flags = DWC3_EP_PENDING_REQUEST;
+               } else {
+                       dwc3_stop_active_transfer(dwc, dep->number);
+                       dep->flags = DWC3_EP_ENABLED;
+               }
                return 1;
        }
 
-- 
1.8.1.rc1.5.g7e0651a


--
To unsubscribe from this list: send the line "unsubscribe stable" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to