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