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

    usb: gadget: fsl_udc_core: dTD's next dtd pointer need to be updated

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 will 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 4d0947dec4db1224354e2f6f00ae22ce38e62a43 Mon Sep 17 00:00:00 2001
From: Peter Chen <[email protected]>
Date: Sun, 1 Apr 2012 15:17:16 +0800
Subject: usb: gadget: fsl_udc_core: dTD's next dtd pointer need to be updated
 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: <[email protected]>
Signed-off-by: Peter Chen <[email protected]>
Acked-by: Li Yang <[email protected]>
Signed-off-by: Felipe Balbi <[email protected]>
---
 drivers/usb/gadget/fsl_udc_core.c |    2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/usb/gadget/fsl_udc_core.c 
b/drivers/usb/gadget/fsl_udc_core.c
index 8f6fc70..5a52d42 100644
--- a/drivers/usb/gadget/fsl_udc_core.c
+++ b/drivers/usb/gadget/fsl_udc_core.c
@@ -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;
-- 
1.7.10.1.362.g242cab3


--
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