ath79/mikrotik: use routerbootpart partitions
[oweals/openwrt.git] / target / linux / layerscape / patches-5.4 / 820-usb-0014-MLK-17380-3-usb-move-EH-SINGLE_STEP_SET_FEATURE-impl.patch
1 From d4806e4f103895387dc679fe53e1f4a5d41391bf Mon Sep 17 00:00:00 2001
2 From: Peter Chen <peter.chen@nxp.com>
3 Date: Thu, 18 Jan 2018 11:03:24 +0800
4 Subject: [PATCH] MLK-17380-3 usb: move EH SINGLE_STEP_SET_FEATURE implement to
5  core
6
7 Since other USB 2.0 host may need it, like USB2 for XHCI. We move
8 this design to HCD core.
9
10 Acked-by: Jun Li <jun.li@nxp.com>
11 Signed-off-by: Peter Chen <peter.chen@nxp.com>
12 (cherry picked from commit 035a27e1a3088261f40f77534aaccfe5825c2f96)
13 ---
14  drivers/usb/core/hcd.c      | 134 ++++++++++++++++++++++++++++++++++++++++++
15  drivers/usb/host/ehci-hcd.c |   4 ++
16  drivers/usb/host/ehci-hub.c | 139 --------------------------------------------
17  drivers/usb/host/ehci-q.c   |   2 +-
18  include/linux/usb/hcd.h     |  13 ++++-
19  5 files changed, 151 insertions(+), 141 deletions(-)
20
21 --- a/drivers/usb/core/hcd.c
22 +++ b/drivers/usb/core/hcd.c
23 @@ -2104,6 +2104,140 @@ int usb_hcd_get_frame_number (struct usb
24  }
25  
26  /*-------------------------------------------------------------------------*/
27 +#ifdef CONFIG_USB_HCD_TEST_MODE
28 +
29 +static void usb_ehset_completion(struct urb *urb)
30 +{
31 +       struct completion  *done = urb->context;
32 +
33 +       complete(done);
34 +}
35 +/*
36 + * Allocate and initialize a control URB. This request will be used by the
37 + * EHSET SINGLE_STEP_SET_FEATURE test in which the DATA and STATUS stages
38 + * of the GetDescriptor request are sent 15 seconds after the SETUP stage.
39 + * Return NULL if failed.
40 + */
41 +static struct urb *request_single_step_set_feature_urb(
42 +       struct usb_device       *udev,
43 +       void                    *dr,
44 +       void                    *buf,
45 +       struct completion       *done
46 +) {
47 +       struct urb *urb;
48 +       struct usb_hcd *hcd = bus_to_hcd(udev->bus);
49 +       struct usb_host_endpoint *ep;
50 +
51 +       urb = usb_alloc_urb(0, GFP_KERNEL);
52 +       if (!urb)
53 +               return NULL;
54 +
55 +       urb->pipe = usb_rcvctrlpipe(udev, 0);
56 +       ep = (usb_pipein(urb->pipe) ? udev->ep_in : udev->ep_out)
57 +                               [usb_pipeendpoint(urb->pipe)];
58 +       if (!ep) {
59 +               usb_free_urb(urb);
60 +               return NULL;
61 +       }
62 +
63 +       urb->ep = ep;
64 +       urb->dev = udev;
65 +       urb->setup_packet = (void *)dr;
66 +       urb->transfer_buffer = buf;
67 +       urb->transfer_buffer_length = USB_DT_DEVICE_SIZE;
68 +       urb->complete = usb_ehset_completion;
69 +       urb->status = -EINPROGRESS;
70 +       urb->actual_length = 0;
71 +       urb->transfer_flags = URB_DIR_IN;
72 +       usb_get_urb(urb);
73 +       atomic_inc(&urb->use_count);
74 +       atomic_inc(&urb->dev->urbnum);
75 +       urb->setup_dma = dma_map_single(
76 +                       hcd->self.sysdev,
77 +                       urb->setup_packet,
78 +                       sizeof(struct usb_ctrlrequest),
79 +                       DMA_TO_DEVICE);
80 +       urb->transfer_dma = dma_map_single(
81 +                       hcd->self.sysdev,
82 +                       urb->transfer_buffer,
83 +                       urb->transfer_buffer_length,
84 +                       DMA_FROM_DEVICE);
85 +       urb->context = done;
86 +       return urb;
87 +}
88 +
89 +int ehset_single_step_set_feature(struct usb_hcd *hcd, int port)
90 +{
91 +       int retval = -ENOMEM;
92 +       struct usb_ctrlrequest *dr;
93 +       struct urb *urb;
94 +       struct usb_device *udev;
95 +       struct usb_device_descriptor *buf;
96 +       DECLARE_COMPLETION_ONSTACK(done);
97 +
98 +       /* Obtain udev of the rhub's child port */
99 +       udev = usb_hub_find_child(hcd->self.root_hub, port);
100 +       if (!udev) {
101 +               dev_err(hcd->self.controller, "No device attached to the RootHub\n");
102 +               return -ENODEV;
103 +       }
104 +       buf = kmalloc(USB_DT_DEVICE_SIZE, GFP_KERNEL);
105 +       if (!buf)
106 +               return -ENOMEM;
107 +
108 +       dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL);
109 +       if (!dr) {
110 +               kfree(buf);
111 +               return -ENOMEM;
112 +       }
113 +
114 +       /* Fill Setup packet for GetDescriptor */
115 +       dr->bRequestType = USB_DIR_IN;
116 +       dr->bRequest = USB_REQ_GET_DESCRIPTOR;
117 +       dr->wValue = cpu_to_le16(USB_DT_DEVICE << 8);
118 +       dr->wIndex = 0;
119 +       dr->wLength = cpu_to_le16(USB_DT_DEVICE_SIZE);
120 +       urb = request_single_step_set_feature_urb(udev, dr, buf, &done);
121 +       if (!urb)
122 +               goto cleanup;
123 +
124 +       /* Submit just the SETUP stage */
125 +       retval = hcd->driver->submit_single_step_set_feature(hcd, urb, 1);
126 +       if (retval)
127 +               goto out1;
128 +       if (!wait_for_completion_timeout(&done, msecs_to_jiffies(2000))) {
129 +               usb_kill_urb(urb);
130 +               retval = -ETIMEDOUT;
131 +               dev_err(hcd->self.controller,
132 +                       "%s SETUP stage timed out on ep0\n", __func__);
133 +               goto out1;
134 +       }
135 +       msleep(15 * 1000);
136 +
137 +       /* Complete remaining DATA and STATUS stages using the same URB */
138 +       urb->status = -EINPROGRESS;
139 +       usb_get_urb(urb);
140 +       atomic_inc(&urb->use_count);
141 +       atomic_inc(&urb->dev->urbnum);
142 +       retval = hcd->driver->submit_single_step_set_feature(hcd, urb, 0);
143 +       if (!retval && !wait_for_completion_timeout(&done,
144 +                                               msecs_to_jiffies(2000))) {
145 +               usb_kill_urb(urb);
146 +               retval = -ETIMEDOUT;
147 +               dev_err(hcd->self.controller,
148 +                       "%s IN stage timed out on ep0\n", __func__);
149 +       }
150 +out1:
151 +       usb_free_urb(urb);
152 +cleanup:
153 +       kfree(dr);
154 +       kfree(buf);
155 +       return retval;
156 +}
157 +EXPORT_SYMBOL_GPL(ehset_single_step_set_feature);
158 +#endif /* CONFIG_USB_HCD_TEST_MODE */
159 +
160 +/*-------------------------------------------------------------------------*/
161  
162  #ifdef CONFIG_PM
163  
164 --- a/drivers/usb/host/ehci-hcd.c
165 +++ b/drivers/usb/host/ehci-hcd.c
166 @@ -1232,6 +1232,10 @@ static const struct hc_driver ehci_hc_dr
167          * device support
168          */
169         .free_dev =             ehci_remove_device,
170 +#ifdef CONFIG_USB_HCD_TEST_MODE
171 +       /* EH SINGLE_STEP_SET_FEATURE test support */
172 +       .submit_single_step_set_feature = ehci_submit_single_step_set_feature,
173 +#endif
174  };
175  
176  void ehci_init_driver(struct hc_driver *drv,
177 --- a/drivers/usb/host/ehci-hub.c
178 +++ b/drivers/usb/host/ehci-hub.c
179 @@ -725,145 +725,6 @@ ehci_hub_descriptor (
180  }
181  
182  /*-------------------------------------------------------------------------*/
183 -#ifdef CONFIG_USB_HCD_TEST_MODE
184 -
185 -#define EHSET_TEST_SINGLE_STEP_SET_FEATURE 0x06
186 -
187 -static void usb_ehset_completion(struct urb *urb)
188 -{
189 -       struct completion  *done = urb->context;
190 -
191 -       complete(done);
192 -}
193 -static int submit_single_step_set_feature(
194 -       struct usb_hcd  *hcd,
195 -       struct urb      *urb,
196 -       int             is_setup
197 -);
198 -
199 -/*
200 - * Allocate and initialize a control URB. This request will be used by the
201 - * EHSET SINGLE_STEP_SET_FEATURE test in which the DATA and STATUS stages
202 - * of the GetDescriptor request are sent 15 seconds after the SETUP stage.
203 - * Return NULL if failed.
204 - */
205 -static struct urb *request_single_step_set_feature_urb(
206 -       struct usb_device       *udev,
207 -       void                    *dr,
208 -       void                    *buf,
209 -       struct completion       *done
210 -) {
211 -       struct urb *urb;
212 -       struct usb_hcd *hcd = bus_to_hcd(udev->bus);
213 -       struct usb_host_endpoint *ep;
214 -
215 -       urb = usb_alloc_urb(0, GFP_KERNEL);
216 -       if (!urb)
217 -               return NULL;
218 -
219 -       urb->pipe = usb_rcvctrlpipe(udev, 0);
220 -       ep = (usb_pipein(urb->pipe) ? udev->ep_in : udev->ep_out)
221 -                               [usb_pipeendpoint(urb->pipe)];
222 -       if (!ep) {
223 -               usb_free_urb(urb);
224 -               return NULL;
225 -       }
226 -
227 -       urb->ep = ep;
228 -       urb->dev = udev;
229 -       urb->setup_packet = (void *)dr;
230 -       urb->transfer_buffer = buf;
231 -       urb->transfer_buffer_length = USB_DT_DEVICE_SIZE;
232 -       urb->complete = usb_ehset_completion;
233 -       urb->status = -EINPROGRESS;
234 -       urb->actual_length = 0;
235 -       urb->transfer_flags = URB_DIR_IN;
236 -       usb_get_urb(urb);
237 -       atomic_inc(&urb->use_count);
238 -       atomic_inc(&urb->dev->urbnum);
239 -       urb->setup_dma = dma_map_single(
240 -                       hcd->self.sysdev,
241 -                       urb->setup_packet,
242 -                       sizeof(struct usb_ctrlrequest),
243 -                       DMA_TO_DEVICE);
244 -       urb->transfer_dma = dma_map_single(
245 -                       hcd->self.sysdev,
246 -                       urb->transfer_buffer,
247 -                       urb->transfer_buffer_length,
248 -                       DMA_FROM_DEVICE);
249 -       urb->context = done;
250 -       return urb;
251 -}
252 -
253 -static int ehset_single_step_set_feature(struct usb_hcd *hcd, int port)
254 -{
255 -       int retval = -ENOMEM;
256 -       struct usb_ctrlrequest *dr;
257 -       struct urb *urb;
258 -       struct usb_device *udev;
259 -       struct ehci_hcd *ehci = hcd_to_ehci(hcd);
260 -       struct usb_device_descriptor *buf;
261 -       DECLARE_COMPLETION_ONSTACK(done);
262 -
263 -       /* Obtain udev of the rhub's child port */
264 -       udev = usb_hub_find_child(hcd->self.root_hub, port);
265 -       if (!udev) {
266 -               ehci_err(ehci, "No device attached to the RootHub\n");
267 -               return -ENODEV;
268 -       }
269 -       buf = kmalloc(USB_DT_DEVICE_SIZE, GFP_KERNEL);
270 -       if (!buf)
271 -               return -ENOMEM;
272 -
273 -       dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL);
274 -       if (!dr) {
275 -               kfree(buf);
276 -               return -ENOMEM;
277 -       }
278 -
279 -       /* Fill Setup packet for GetDescriptor */
280 -       dr->bRequestType = USB_DIR_IN;
281 -       dr->bRequest = USB_REQ_GET_DESCRIPTOR;
282 -       dr->wValue = cpu_to_le16(USB_DT_DEVICE << 8);
283 -       dr->wIndex = 0;
284 -       dr->wLength = cpu_to_le16(USB_DT_DEVICE_SIZE);
285 -       urb = request_single_step_set_feature_urb(udev, dr, buf, &done);
286 -       if (!urb)
287 -               goto cleanup;
288 -
289 -       /* Submit just the SETUP stage */
290 -       retval = submit_single_step_set_feature(hcd, urb, 1);
291 -       if (retval)
292 -               goto out1;
293 -       if (!wait_for_completion_timeout(&done, msecs_to_jiffies(2000))) {
294 -               usb_kill_urb(urb);
295 -               retval = -ETIMEDOUT;
296 -               ehci_err(ehci, "%s SETUP stage timed out on ep0\n", __func__);
297 -               goto out1;
298 -       }
299 -       msleep(15 * 1000);
300 -
301 -       /* Complete remaining DATA and STATUS stages using the same URB */
302 -       urb->status = -EINPROGRESS;
303 -       usb_get_urb(urb);
304 -       atomic_inc(&urb->use_count);
305 -       atomic_inc(&urb->dev->urbnum);
306 -       retval = submit_single_step_set_feature(hcd, urb, 0);
307 -       if (!retval && !wait_for_completion_timeout(&done,
308 -                                               msecs_to_jiffies(2000))) {
309 -               usb_kill_urb(urb);
310 -               retval = -ETIMEDOUT;
311 -               ehci_err(ehci, "%s IN stage timed out on ep0\n", __func__);
312 -       }
313 -out1:
314 -       usb_free_urb(urb);
315 -cleanup:
316 -       kfree(dr);
317 -       kfree(buf);
318 -       return retval;
319 -}
320 -#endif /* CONFIG_USB_HCD_TEST_MODE */
321 -/*-------------------------------------------------------------------------*/
322  
323  int ehci_hub_control(
324         struct usb_hcd  *hcd,
325 --- a/drivers/usb/host/ehci-q.c
326 +++ b/drivers/usb/host/ehci-q.c
327 @@ -1165,7 +1165,7 @@ submit_async (
328   * performed; TRUE - SETUP and FALSE - IN+STATUS
329   * Returns 0 if success
330   */
331 -static int submit_single_step_set_feature(
332 +static int ehci_submit_single_step_set_feature(
333         struct usb_hcd  *hcd,
334         struct urb      *urb,
335         int             is_setup
336 --- a/include/linux/usb/hcd.h
337 +++ b/include/linux/usb/hcd.h
338 @@ -409,7 +409,10 @@ struct hc_driver {
339         int     (*find_raw_port_number)(struct usb_hcd *, int);
340         /* Call for power on/off the port if necessary */
341         int     (*port_power)(struct usb_hcd *hcd, int portnum, bool enable);
342 -
343 +       /* Call for SINGLE_STEP_SET_FEATURE Test for USB2 EH certification */
344 +#define EHSET_TEST_SINGLE_STEP_SET_FEATURE 0x06
345 +       int     (*submit_single_step_set_feature)(struct usb_hcd *,
346 +                       struct urb *, int);
347  };
348  
349  static inline int hcd_giveback_urb_in_bh(struct usb_hcd *hcd)
350 @@ -474,6 +477,14 @@ int usb_hcd_setup_local_mem(struct usb_h
351  
352  struct platform_device;
353  extern void usb_hcd_platform_shutdown(struct platform_device *dev);
354 +#ifdef CONFIG_USB_HCD_TEST_MODE
355 +extern int ehset_single_step_set_feature(struct usb_hcd *hcd, int port);
356 +#else
357 +static inline int ehset_single_step_set_feature(struct usb_hcd *hcd, int port)
358 +{
359 +       return 0;
360 +}
361 +#endif /* CONFIG_USB_HCD_TEST_MODE */
362  
363  #ifdef CONFIG_USB_PCI
364  struct pci_dev;