1 /*
2 *******************************************************************************
3 *                                              usb host module
4 *
5 *                             Copyright(C), 2006-2008, SoftWinners Co., Ltd.
6 *                                                  All Rights Reserved
7 *
8 * File Name :
9 *
10 * Author : GLHuang(HoLiGun)
11 *
12 * Version : 1.0
13 *
14 * Date : 2008.07.xx
15 *
16 * Description :
17 *
18 * History :
19 *******************************************************************************
20 */
21 //#include "usb_host_config.h"
22 
23 //#include <usb/usb_os_platform.h>
24 //#include "usb_host_base_types.h"
25 #include <ctype.h>
26 #include <usb_list.h>
27 
28 #include <usb_host_common.h>
29 #include <usb_host_hub.h>
30 #include "usb_core_base.h"
31 #include "usb_gen_hub.h"
32 #include "usb_msg.h"
33 #include "usb_gen_hub.h"
34 #include "usb_virt_bus.h"
35 
36 #include "urb.h"
37 #include <log.h>
38 
39 #define USB_OS_EPDK_TRUE 0
40 #define USB_OS_EPDK_FALSE 1
41 
42 /* 被urb的消费者调用,如hcd的finish函数通知core该urb被执行完毕 */
_urb_done_complete_callback(struct urb * urb)43 static void _urb_done_complete_callback(struct urb *urb)
44 {
45     // USB_OS_COMPLETE_POST((USB_OS_KERNEL_EVENT *)(urb->context));
46     hal_sem_post((hal_sem_t)(urb->context));//akira 20202020
47 }
48 
49 /* urb timeout 处理函数, 其实就是在queue的过程中出现了问题,
50    通过unqueue来并行的做一下,别的地方都是复用的。 */
_urb_timeout_process(void * data)51 static void _urb_timeout_process(void *data)
52 {
53     struct urb *urb = (struct urb *)data;
54 
55     if (urb == NULL)
56     {
57         __err("PANIC : _urb_timeout_process() urb = %x \n", urb);
58         return ;
59     }
60 
61     __inf("ERR: _urb_timeout_process: urb time out %x\n", urb);
62     usb_unlink_urb(urb);
63     return;
64 }
65 
66 // Starts urb and waits for completion or timeout
67 // note that this call is NOT interruptible, while
68 // many device driver i/o requests should be interruptible
69 //timeout   :   != 0时表示有timeout,单位为ms
70 
71 /*  内部函数--发送urb,并等待其完成,或timeout
72     本函数要求可以重入,所以semi和timer得时时分配
73     虽然epos的semi带有timeout 功能,
74     但是为了提高本代码的可移植性
75     将不利用该特性,
76     但是将来为了优化,可以考虑该特性
77 */
usb_start_wait_urb(struct urb * urb,int timeout_ms,int * actual_length)78 static int usb_start_wait_urb(struct urb *urb, int timeout_ms, int *actual_length)
79 {
80     uint8_t err = 0;
81     uint32_t ret = 0;
82     int32_t status = 0;
83     // USB_OS_KERNEL_EVENT         *wait_urb_complete_semi = NULL;
84     // USB_OS_KERNEL_SOFT_TIMER    *wait_urb_timer = NULL;
85     hal_sem_t wait_urb_complete_semi;
86     osal_timer_t wait_urb_timer = NULL;
87 
88     /* check input */
89     if (urb == NULL)
90     {
91         hal_log_err("ERR: usb_start_wait_urb: input error\n");
92         return -1;
93     }
94 
95     /* initialize urb */
96     wait_urb_complete_semi = hal_sem_create(0);
97 
98     if (wait_urb_complete_semi == NULL)
99     {
100         hal_log_err("ERR: create complete semi false\n");
101         return -1;
102     }
103 
104     urb->context = (void *)wait_urb_complete_semi;
105     urb->transfer_flags |= URB_ASYNC_UNLINK;
106     urb->actual_length = 0;
107     /* submit urb */
108     status = usb_submit_urb(urb, 0);
109 
110     if (status == 0)
111     {
112 
113         if (timeout_ms > 0) //akira 20202020
114         {
115             // wait_urb_timer = USB_esKRNL_TmrCreate(timeout_ms,
116             //                                       USB_TIMER_PERIOD_ONE,
117             //                                       (USB_TIMER_CALLBACK)_urb_timeout_process,
118             //                                       urb);
119             // unsigned long time_interval = rt_tick_from_millisecond(timeout_ms);
120             wait_urb_timer = osal_timer_create("wait_urb_timer",
121                                                (timeout_func)_urb_timeout_process,
122                                                (void *)urb,
123                                                timeout_ms / (1000 / CONFIG_HZ),
124                                                OSAL_TIMER_FLAG_ONE_SHOT);
125             if (wait_urb_timer == NULL)
126             {
127                    __err("PANIC : create timer for urb false\n");
128                 return -1;
129             }
130 
131             urb->wait_urb_timer = wait_urb_timer;
132             // ret = USB_esKRNL_TmrStart(wait_urb_timer);
133             ret = osal_timer_start(wait_urb_timer);
134 
135             if (ret)
136             {
137                 // USB_esKRNL_TmrDel(wait_urb_timer);
138                 osal_timer_delete(wait_urb_timer);
139                 __err("PANIC : usb_start_wait_urb,start timer fail\n");
140                 return -1;
141             }
142         }
143 
144         //USB_OS_COMPLETE_PEND(wait_urb_complete_semi, 0, &err);
145         hal_sem_timedwait(wait_urb_complete_semi, timeout_ms / (1000 / CONFIG_HZ));
146         status = urb->status;
147 
148         /* note:  HCDs return ETIMEDOUT for other reasons too */
149         if (status == -ECONNRESET)
150         {
151             hal_log_err("ERR: timed out on ep%d%s len=%d/%d\n",
152                         usb_pipeendpoint(urb->pipe),
153                         usb_pipein(urb->pipe) ? "in" : "out",
154                         urb->actual_length,
155                         urb->transfer_buffer_length);
156 
157             if (urb->actual_length > 0)
158             {
159                 status = 0;
160             }
161             else
162             {
163                 status = -ETIMEDOUT;
164             }
165         }
166 
167         // stop timer
168         if (wait_urb_timer != 0) //akira 20202020
169         {
170             // ret = USB_esKRNL_TmrStop(wait_urb_timer);
171             ret = osal_timer_stop(wait_urb_timer);
172 
173             if (ret != USB_OS_EPDK_TRUE)
174             {
175                 __err("PANIC : usb_start_wait_urb, timer stop error code = %x\n", ret);
176                 return -1;
177             }
178 
179             // ret = USB_esKRNL_TmrDel(wait_urb_timer);
180             ret = osal_timer_delete(wait_urb_timer);
181 
182             if (ret)
183             {
184                  __err("PANIC : usb_start_wait_urb, timer del error code = %x\n", ret);
185                 return -1;
186             }
187         }
188 
189         urb->wait_urb_timer = NULL;
190     }
191 
192     if (actual_length)
193     {
194         *actual_length = urb->actual_length;
195     }
196 
197     //free complete
198     if (wait_urb_complete_semi)
199     {
200         //USB_OS_COMPLETE_DELETE(wait_urb_complete_semi, &err);
201         hal_sem_delete(wait_urb_complete_semi);
202     }
203 
204     //free urb
205     usb_free_urb(urb);
206     return status;
207 }
208 
209 //returns
210 //  <0  :   失败
211 //  >=0 :   返回的长度
_usb_internal_ctrll_msg(struct usb_host_virt_dev * usb_dev,uint32_t pipe,struct usb_ctrlrequest * cmd,void * data,int32_t len,int32_t timeout)212 int _usb_internal_ctrll_msg(struct usb_host_virt_dev *usb_dev,
213                             uint32_t pipe,
214                             struct usb_ctrlrequest *cmd,
215                             void *data,
216                             int32_t len,
217                             int32_t timeout)
218 {
219     struct urb *urb;
220     int retv;
221     int length;
222     //--<1>--malloc urb
223     urb = usb_alloc_urb(0);
224 
225     if (!urb)
226     {
227         hal_log_err("ERR: usb_alloc_urb failed\n");
228         return -ENOMEM;
229     }
230 
231     //--<2>--填充urb
232     usb_fill_control_urb(urb,
233                          usb_dev,
234                          pipe,
235                          (unsigned char *)cmd,
236                          data,
237                          len,
238                          _urb_done_complete_callback,
239                          NULL);
240     //--<3>--发送并等待urb完成或timeout
241     retv = usb_start_wait_urb(urb, timeout, &length);
242 
243     if (retv < 0)
244     {
245         return retv;
246     }
247     else
248     {
249         return length;
250     }
251 }
252 
253 
254 
_usb_internal_bulk_msg(struct usb_host_virt_dev * usb_dev,unsigned int pipe,void * data,int len,int * actual_length,int timeout)255 int _usb_internal_bulk_msg(struct usb_host_virt_dev *usb_dev,
256                            unsigned int pipe,
257                            void *data,
258                            int len,
259                            int *actual_length,
260                            int timeout)
261 {
262     struct urb *urb = NULL;
263     //--<1>--分配一个urb
264     urb = usb_alloc_urb(0);
265 
266     if (!urb)
267     {
268         return -ENOMEM;
269     }
270 
271     //--<2>--填充一个urb
272     usb_fill_bulk_urb(urb,
273                       usb_dev,
274                       pipe,
275                       data,
276                       len,
277                       _urb_done_complete_callback,
278                       NULL);
279     //--<3>--发送urb并等待其完成或timeout
280     return usb_start_wait_urb(urb, timeout, actual_length);
281 }
282 
283 
284 /**
285  * usb_get_string - gets a string descriptor
286  * @dev: the device whose string descriptor is being retrieved
287  * @langid: code for language chosen (from string descriptor zero)
288  * @index: the number of the descriptor
289  * @buf: where to put the string
290  * @size: how big is "buf"?
291  * Context: !in_interrupt ()
292  *
293  * Retrieves a string, encoded using UTF-16LE (Unicode, 16 bits per character,
294  * in little-endian byte order).
295  * The usb_string() function will often be a convenient way to turn
296  * these strings into kernel-printable form.
297  *
298  * Strings may be referenced in device, configuration, interface, or other
299  * descriptors, and could also be used in vendor-specific ways.
300  *
301  * This call is synchronous, and may not be used in an interrupt context.
302  *
303  * Returns the number of bytes received on success, or else the status code
304  * returned by the underlying usb_control_msg() call.
305  */
usb_get_string(struct usb_host_virt_dev * dev,u16 langid,uint8_t index,void * buf,int32_t size)306 int usb_get_string(struct usb_host_virt_dev  *dev,
307                    u16 langid,
308                    uint8_t  index,
309                    void *buf,
310                    int32_t size)
311 {
312     int i;
313     int result;
314 
315     for (i = 0; i < 3; ++i)
316     {
317         /* retry on length 0 or stall; some devices are flakey */
318         result = usb_control_msg(dev,
319                                  usb_rcvctrlpipe(dev, 0),
320                                  USB_REQ_GET_DESCRIPTOR,
321                                  USB_DIR_IN,
322                                  (USB_DT_STRING << 8) + index,
323                                  langid,
324                                  buf,
325                                  size,
326                                  USB_CTRL_GET_TIMEOUT);
327 
328         if (!(result == 0 || result == -EPIPE))
329         {
330             break;
331         }
332     }
333 
334     return result;
335 }
336 
usb_try_string_workarounds(uint8_t * buf,int32_t * length)337 static void usb_try_string_workarounds(uint8_t  *buf, int32_t *length)
338 {
339     int32_t newlength, oldlength = *length;
340 
341     for (newlength = 2; newlength + 1 < oldlength; newlength += 2)
342     {
343         if (!isprint(buf[newlength]) || buf[newlength + 1])
344         {
345             break;
346         }
347     }
348 
349     if (newlength > 2)
350     {
351         buf[0] = newlength;
352         *length = newlength;
353     }
354 }
355 
_usb_string_sub(struct usb_host_virt_dev * dev,uint32_t langid,uint32_t index,uint8_t * buf)356 int _usb_string_sub(struct usb_host_virt_dev  *dev,  uint32_t langid, uint32_t index, uint8_t *buf)
357 {
358     int32_t rc;
359     /* Try to read the string descriptor by asking for the maximum
360      * possible number of bytes */
361     rc = usb_get_string(dev, langid, index, buf, 255);
362 
363     /* If that failed try to read the descriptor length, then
364      * ask for just that many bytes */
365     if (rc < 2)
366     {
367         rc = usb_get_string(dev, langid, index, buf, 2);
368 
369         if (rc == 2)
370         {
371             rc = usb_get_string(dev, langid, index, buf, buf[0]);
372         }
373     }
374 
375     if (rc >= 2)
376     {
377         if (!buf[0] && !buf[1])
378         {
379             usb_try_string_workarounds(buf, &rc);
380         }
381 
382         /* There might be extra junk at the end of the descriptor */
383         if (buf[0] < rc)
384         {
385             rc = buf[0];
386         }
387 
388         rc = rc - (rc & 1); /* force a multiple of two */
389     }
390 
391     if (rc < 2)
392     {
393         rc = (rc < 0 ? rc : -EINVAL);
394     }
395 
396     return rc;
397 }
398 
399 
400 
401 
402