[PATCH] USB: musb :gadget: fix ZLP handling in musb_g_tx

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Ming Lei <tom.leiming@xxxxxxxxx>

This patch fixes the problem reported by Sergei:

>how come? we need to send ZLP before giving back the request.
>Well, look at the code ionce again. We need to send ZLP *after*
>request->actual == request->length, but as the check is inserted
>after the ZLP send, ZLP *may* be sent once the first DMA completes,
>not the last.

The patch also has been discussed on the link below:

    http://marc.info/?t=128454814900001&r=1&w=2

Signed-off-by: Ming Lei <tom.leiming@xxxxxxxxx>
Reported-by:   Sergei Shtylyov <sshtylyov@xxxxxxxxxx>
Cc: Felipe Balbi <balbi@xxxxxx>
Cc: David Brownell <dbrownell@xxxxxxxxxxxxxxxxxxxxx>
Cc: Anand Gadiyar <gadiyar@xxxxxx>
Cc: Mike Frysinger <vapier@xxxxxxxxxx>
Cc: Sergei Shtylyov <sshtylyov@xxxxxxxxxxxxx>
---

This patch is against the "patch-2.6.36+" patchset
sent out by Felipe on Sept. 16.

---
 drivers/usb/musb/musb_gadget.c |   22 +++++++++++++---------
 1 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
index 46cf94a..36b6042 100644
--- a/drivers/usb/musb/musb_gadget.c
+++ b/drivers/usb/musb/musb_gadget.c
@@ -477,7 +477,13 @@ void musb_g_tx(struct musb *musb, u8 epnum)
 				epnum, csr, musb_ep->dma->actual_len, request);
 		}
 
-		if (is_dma || request->actual == request->length) {
+		/*
+		 * We should do the followings only if data transfer for
+		 * the 'request' is over:
+		 * 	- handle ZLP or short packet if meeting the conditions
+		 * 	- complete the request
+		 */
+		if (request->actual == request->length) {
 			/*
 			 * First, maybe a terminating short packet. Some DMA
 			 * engines might handle this by themselves.
@@ -503,14 +509,12 @@ void musb_g_tx(struct musb *musb, u8 epnum)
 				request->zero = 0;
 			}
 
-			if (request->actual == request->length) {
-				musb_g_giveback(musb_ep, request, 0);
-				request = musb_ep->desc ? next_request(musb_ep) : NULL;
-				if (!request) {
-					DBG(4, "%s idle now\n",
-						musb_ep->end_point.name);
-					return;
-				}
+			musb_g_giveback(musb_ep, request, 0);
+			request = musb_ep->desc ? next_request(musb_ep) : NULL;
+			if (!request) {
+				DBG(4, "%s idle now\n",
+					musb_ep->end_point.name);
+				return;
 			}
 		}
 
-- 
1.6.2.5

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux