Skip to content

Commit

Permalink
usb: gadget: fsl_udc_core: dTD's next dtd pointer need to be updated …
Browse files Browse the repository at this point in the history
…once written

dTD's next dtd pointer need to be updated once CPU writes it, or this
request may not be handled by controller, then host will get NAK from
device forever.

This problem occurs when there is a request is handling, we need to add
a new request to dTD list, if this new request is added before the current
one is finished, the new request is intended to added as next dtd pointer
at current dTD, but without wmb(), the dTD's next dtd pointer may not be
updated when the controller reads it. In that case, the controller will
still get Terminate Bit is 1 at dTD's next dtd pointer, that means there is
no next request, then this new request is missed by controller.

CC: <stable@vger.kernel.org>
Signed-off-by: Peter Chen <peter.chen@freescale.com>
Acked-by: Li Yang <leoli@freescale.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
  • Loading branch information
Peter Chen authored and Felipe Balbi committed May 4, 2012
1 parent 124ef38 commit 4d0947d
Showing 1 changed file with 2 additions and 0 deletions.
2 changes: 2 additions & 0 deletions drivers/usb/gadget/fsl_udc_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -735,6 +735,8 @@ static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req)
lastreq = list_entry(ep->queue.prev, struct fsl_req, queue);
lastreq->tail->next_td_ptr =
cpu_to_hc32(req->head->td_dma & DTD_ADDR_MASK);
/* Ensure dTD's next dtd pointer to be updated */
wmb();
/* Read prime bit, if 1 goto done */
if (fsl_readl(&dr_regs->endpointprime) & bitmask)
return;
Expand Down

0 comments on commit 4d0947d

Please sign in to comment.