]>
Commit | Line | Data |
---|---|---|
7c360069 GKH |
1 | From a535d81c92615b8ffb99b7e1fd1fb01effaed1af Mon Sep 17 00:00:00 2001 |
2 | From: Alan Stern <stern@rowland.harvard.edu> | |
3 | Date: Fri, 1 Nov 2013 12:05:12 -0400 | |
4 | Subject: usb: dwc3: fix implementation of endpoint wedge | |
5 | ||
6 | From: Alan Stern <stern@rowland.harvard.edu> | |
7 | ||
8 | commit a535d81c92615b8ffb99b7e1fd1fb01effaed1af upstream. | |
9 | ||
10 | The dwc3 UDC driver doesn't implement endpoint wedging correctly. | |
11 | When an endpoint is wedged, the gadget driver should be allowed to | |
12 | clear the wedge by calling usb_ep_clear_halt(). Only the host is | |
13 | prevented from resetting the endpoint. | |
14 | ||
15 | This patch fixes the implementation. | |
16 | ||
17 | Signed-off-by: Alan Stern <stern@rowland.harvard.edu> | |
18 | Tested-by: Pratyush Anand <pratyush.anand@st.com> | |
19 | Signed-off-by: Felipe Balbi <balbi@ti.com> | |
20 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
21 | ||
22 | --- | |
23 | drivers/usb/dwc3/ep0.c | 2 ++ | |
24 | drivers/usb/dwc3/gadget.c | 5 +---- | |
25 | 2 files changed, 3 insertions(+), 4 deletions(-) | |
26 | ||
27 | --- a/drivers/usb/dwc3/ep0.c | |
28 | +++ b/drivers/usb/dwc3/ep0.c | |
29 | @@ -380,6 +380,8 @@ static int dwc3_ep0_handle_feature(struc | |
30 | dep = dwc3_wIndex_to_dep(dwc, wIndex); | |
31 | if (!dep) | |
32 | return -EINVAL; | |
33 | + if (set == 0 && (dep->flags & DWC3_EP_WEDGE)) | |
34 | + break; | |
35 | ret = __dwc3_gadget_ep_set_halt(dep, set); | |
36 | if (ret) | |
37 | return -EINVAL; | |
38 | --- a/drivers/usb/dwc3/gadget.c | |
39 | +++ b/drivers/usb/dwc3/gadget.c | |
40 | @@ -1101,9 +1101,6 @@ int __dwc3_gadget_ep_set_halt(struct dwc | |
41 | else | |
42 | dep->flags |= DWC3_EP_STALL; | |
43 | } else { | |
44 | - if (dep->flags & DWC3_EP_WEDGE) | |
45 | - return 0; | |
46 | - | |
47 | ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, | |
48 | DWC3_DEPCMD_CLEARSTALL, ¶ms); | |
49 | if (ret) | |
50 | @@ -1111,7 +1108,7 @@ int __dwc3_gadget_ep_set_halt(struct dwc | |
51 | value ? "set" : "clear", | |
52 | dep->name); | |
53 | else | |
54 | - dep->flags &= ~DWC3_EP_STALL; | |
55 | + dep->flags &= ~(DWC3_EP_STALL | DWC3_EP_WEDGE); | |
56 | } | |
57 | ||
58 | return ret; |