summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Chen <peter.chen@freescale.com>2011-11-21 14:10:49 +0800
committerFrank Li <Frank.Li@freescale.com>2011-11-21 15:39:23 +0800
commit37ccc1e6b64f0c26ddaf3638a297242bd7e564cf (patch)
treec76e395a97d33b101e7501ee60c42523439829f7
parent3f094c8cdeec0ccbd324f5b986fcf95de2383090 (diff)
ENGR00161644 usb-gadget: prime directly for status dTD of ep0
During the setup transfer, if prime status just after prime the data, but before the data completes, there is a potential problem: The device's qTD has NO direction bit, If the IN request(Status Stage) is added to qTD list while the OUT (Data Stage) is priming, then the IN will not prime by software, it will prime automatically by controller as OUT. We met one usb hang issue during repeat plug in/out test at i.mx6q that the data status has finished but status has never finished, it is most likely above issue. After this fix, the repeat plug in/out test passes successfully. Signed-off-by: Peter Chen <peter.chen@freescale.com>
-rw-r--r--drivers/usb/gadget/arcotg_udc.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/drivers/usb/gadget/arcotg_udc.c b/drivers/usb/gadget/arcotg_udc.c
index 91f99391fb58..391ba5820527 100644
--- a/drivers/usb/gadget/arcotg_udc.c
+++ b/drivers/usb/gadget/arcotg_udc.c
@@ -865,8 +865,13 @@ static int fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req)
? (1 << (ep_index(ep) + 16))
: (1 << (ep_index(ep)));
- /* check if the pipe is empty */
- if (!(list_empty(&ep->queue))) {
+ /*
+ * check if
+ * - the request is empty, and
+ * - the request is not the status request for ep0
+ */
+ if (!(list_empty(&ep->queue)) &&
+ !((ep_index(ep) == 0) && (req->req.length == 0))) {
/* Add td to the end */
struct fsl_req *lastreq;
lastreq = list_entry(ep->queue.prev, struct fsl_req, queue);