]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/3.0.33/usb-gadget-fsl_udc_core-dtd-s-next-dtd-pointer-need-to-be-updated-once-written.patch
drop queue-4.14/mips-make-sure-dt-memory-regions-are-valid.patch
[thirdparty/kernel/stable-queue.git] / releases / 3.0.33 / usb-gadget-fsl_udc_core-dtd-s-next-dtd-pointer-need-to-be-updated-once-written.patch
CommitLineData
a13f3828
GKH
1From 4d0947dec4db1224354e2f6f00ae22ce38e62a43 Mon Sep 17 00:00:00 2001
2From: Peter Chen <peter.chen@freescale.com>
3Date: Sun, 1 Apr 2012 15:17:16 +0800
4Subject: usb: gadget: fsl_udc_core: dTD's next dtd pointer need to be updated once written
5
6From: Peter Chen <peter.chen@freescale.com>
7
8commit 4d0947dec4db1224354e2f6f00ae22ce38e62a43 upstream.
9
10dTD's next dtd pointer need to be updated once CPU writes it, or this
11request may not be handled by controller, then host will get NAK from
12device forever.
13
14This problem occurs when there is a request is handling, we need to add
15a new request to dTD list, if this new request is added before the current
16one is finished, the new request is intended to added as next dtd pointer
17at current dTD, but without wmb(), the dTD's next dtd pointer may not be
18updated when the controller reads it. In that case, the controller will
19still get Terminate Bit is 1 at dTD's next dtd pointer, that means there is
20no next request, then this new request is missed by controller.
21
22Signed-off-by: Peter Chen <peter.chen@freescale.com>
23Acked-by: Li Yang <leoli@freescale.com>
24Signed-off-by: Felipe Balbi <balbi@ti.com>
25Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
26
27---
28 drivers/usb/gadget/fsl_udc_core.c | 2 ++
29 1 file changed, 2 insertions(+)
30
31--- a/drivers/usb/gadget/fsl_udc_core.c
32+++ b/drivers/usb/gadget/fsl_udc_core.c
33@@ -717,6 +717,8 @@ static void fsl_queue_td(struct fsl_ep *
34 lastreq = list_entry(ep->queue.prev, struct fsl_req, queue);
35 lastreq->tail->next_td_ptr =
36 cpu_to_hc32(req->head->td_dma & DTD_ADDR_MASK);
37+ /* Ensure dTD's next dtd pointer to be updated */
38+ wmb();
39 /* Read prime bit, if 1 goto done */
40 if (fsl_readl(&dr_regs->endpointprime) & bitmask)
41 goto out;