]>
Commit | Line | Data |
---|---|---|
f723613a GKH |
1 | From a666e3e6098a9f56310e4ec2705f1dad124a34b5 Mon Sep 17 00:00:00 2001 |
2 | From: Sergei Shtylyov <sshtylyov@ru.mvista.com> | |
3 | Date: Sat, 11 Sep 2010 13:23:12 -0500 | |
4 | Subject: usb: musb: gadget: restart request on clearing endpoint halt | |
5 | ||
6 | From: Sergei Shtylyov <sshtylyov@ru.mvista.com> | |
7 | ||
8 | commit a666e3e6098a9f56310e4ec2705f1dad124a34b5 upstream. | |
9 | ||
10 | Commit 46034dca515bc4ddca0399ae58106d1f5f0d809f (USB: musb_gadget_ep0: stop | |
11 | abusing musb_gadget_set_halt()) forgot to restart a queued request after | |
12 | clearing the endpoint halt feature. This results in a couple of USB resets | |
13 | while enumerating the file-backed storage gadget due to CSW packet not being | |
14 | sent for the MODE SENSE(10) command. | |
15 | ||
16 | Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com> | |
17 | Signed-off-by: Felipe Balbi <balbi@ti.com> | |
18 | Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> | |
19 | ||
20 | --- | |
21 | drivers/usb/musb/musb_gadget.c | 2 +- | |
22 | drivers/usb/musb/musb_gadget.h | 2 ++ | |
23 | drivers/usb/musb/musb_gadget_ep0.c | 9 +++++++++ | |
24 | 3 files changed, 12 insertions(+), 1 deletion(-) | |
25 | ||
26 | --- a/drivers/usb/musb/musb_gadget.c | |
27 | +++ b/drivers/usb/musb/musb_gadget.c | |
28 | @@ -1095,7 +1095,7 @@ struct free_record { | |
29 | /* | |
30 | * Context: controller locked, IRQs blocked. | |
31 | */ | |
32 | -static void musb_ep_restart(struct musb *musb, struct musb_request *req) | |
33 | +void musb_ep_restart(struct musb *musb, struct musb_request *req) | |
34 | { | |
35 | DBG(3, "<== %s request %p len %u on hw_ep%d\n", | |
36 | req->tx ? "TX/IN" : "RX/OUT", | |
37 | --- a/drivers/usb/musb/musb_gadget.h | |
38 | +++ b/drivers/usb/musb/musb_gadget.h | |
39 | @@ -105,4 +105,6 @@ extern void musb_gadget_cleanup(struct m | |
40 | ||
41 | extern void musb_g_giveback(struct musb_ep *, struct usb_request *, int); | |
42 | ||
43 | +extern void musb_ep_restart(struct musb *, struct musb_request *); | |
44 | + | |
45 | #endif /* __MUSB_GADGET_H */ | |
46 | --- a/drivers/usb/musb/musb_gadget_ep0.c | |
47 | +++ b/drivers/usb/musb/musb_gadget_ep0.c | |
48 | @@ -261,6 +261,7 @@ __acquires(musb->lock) | |
49 | ctrlrequest->wIndex & 0x0f; | |
50 | struct musb_ep *musb_ep; | |
51 | struct musb_hw_ep *ep; | |
52 | + struct musb_request *request; | |
53 | void __iomem *regs; | |
54 | int is_in; | |
55 | u16 csr; | |
56 | @@ -302,6 +303,14 @@ __acquires(musb->lock) | |
57 | musb_writew(regs, MUSB_RXCSR, csr); | |
58 | } | |
59 | ||
60 | + /* Maybe start the first request in the queue */ | |
61 | + request = to_musb_request( | |
62 | + next_request(musb_ep)); | |
63 | + if (!musb_ep->busy && request) { | |
64 | + DBG(3, "restarting the request\n"); | |
65 | + musb_ep_restart(musb, request); | |
66 | + } | |
67 | + | |
68 | /* select ep0 again */ | |
69 | musb_ep_select(mbase, 0); | |
70 | } break; |