1 /*
2 ********************************************************************************
3 * USB Hid Driver
4 *
5 * (c) Copyright 2006-2010, All winners Co,Ld.
6 * All Right Reserved
7 *
8 * FileName : HidTransport.c
9 *
10 * Author : Javen
11 *
12 * Date : 2010/06/02
13 *
14 * Description : Hid 传输
15 *
16 * Others : NULL
17 *
18 * History:
19 * <time> <author> <version > <desc>
20 * 2010.06.02 Javen 1.0 build this file
21 *
22 ********************************************************************************
23 */
24
25 //#include "usb_host_config.h"
26 //#include "usb_host_base_types.h"
27 #include "usb_os_platform.h"
28 #include "error.h"
29
30 #include "usb_host_common.h"
31 #include "urb.h"
32 #include "usb_gen_hub.h"
33
34 #include "HidSpec.h"
35 #include "Hid_i.h"
36 #include "HidProtocol.h"
37 #include "HidTransport.h"
38
39 /*
40 *******************************************************************************
41 * HidTransportDone
42 *
43 * Description:
44 *
45 *
46 * Parameters:
47 *
48 *
49 * Return value:
50 *
51 *
52 * note:
53 * 无
54 *
55 *******************************************************************************
56 */
HidTransportDone(struct urb * urb)57 static void HidTransportDone(struct urb *urb)
58 {
59 hal_sem_t urb_done = (hal_sem_t)urb->context;
60
61 if(urb_done){
62 hal_sem_post(urb_done);
63 }else{
64 hal_log_err("ERR: mscUrbCallBack: urb_done == NULL\n");
65 }
66 }
67
68 /*
69 *******************************************************************************
70 * HidUsbTransport
71 *
72 * Description:
73 *
74 *
75 * Parameters:
76 *
77 *
78 * Return value:
79 *
80 *
81 * note:
82 * 无
83 *
84 *******************************************************************************
85 */
HidUsbTransport(HidDev_t * HidDev)86 static int HidUsbTransport(HidDev_t *HidDev)
87 {
88 int ret = 0;
89 unsigned char err = 0;
90
91 if(HidDev == NULL){
92 hal_log_err("ERR: HidUsbTransport: input error\n");
93 return USB_ERR_BAD_ARGUMENTS;
94 }
95
96 if(HidDev->State != HID_DEV_ONLINE){
97 hal_log_err("ERR: mscUSBTransport: Can't transport for device is not online\n");
98 return USB_ERR_BAD_ARGUMENTS;
99 }
100
101 /* fill URB */
102 HidDev->CurrentUrb->context = (void *)HidDev->UrbWait;
103 HidDev->CurrentUrb->actual_length = 0;
104 HidDev->CurrentUrb->error_count = 0;
105 HidDev->CurrentUrb->status = 0;
106 HidDev->CurrentUrb->transfer_dma = 0;
107 HidDev->CurrentUrb->setup_dma = 0;
108
109 /* set HidDev busy */
110 HidDev->busy = 1;
111
112 /* submit urb */
113 ret = usb_submit_urb(HidDev->CurrentUrb, 0);
114 if(ret == 0){
115 /* nothing to do */
116 }else if(ret == -ENODEV){
117 hal_log_err("ERR: device is not present, CurrentUrb = %d\n", HidDev->CurrentUrb);
118 HidDev->busy = 0;
119
120 return USB_ERR_IO_DEVICE_OFFLINE;
121 }else{
122 hal_log_err("ERR: submit urb failed. ret = %d, CurrentUrb = %d\n", ret, HidDev->CurrentUrb);
123 HidDev->busy = 0;
124
125 return USB_ERR_COMMAND_SEND_FAILED;
126 }
127
128 /* wait urb done */
129 // USB_OS_SemPend(HidDev->UrbWait, 0, &err);
130 hal_sem_wait(HidDev->UrbWait);
131
132 /* urb is done, then set mscDev free */
133 HidDev->busy = 0;
134
135 return USB_ERR_SUCCESS;
136 }
137
138 /*
139 *******************************************************************************
140 * HidSoftReset
141 *
142 * Description:
143 *
144 *
145 * Parameters:
146 *
147 *
148 * Return value:
149 *
150 *
151 * note:
152 * 无
153 *
154 *******************************************************************************
155 */
HidSoftReset(HidDev_t * HidDev)156 int HidSoftReset(HidDev_t *HidDev)
157 {
158 if(HidDev == NULL){
159 hal_log_err("ERR: HidSoftReset: input error\n");
160 return USB_ERR_BAD_ARGUMENTS;
161 }
162
163 /* device online? */
164 if(HidDev->State == HID_DEV_OFFLINE){
165 hal_log_err("ERR: HidPortReset: device is offline\n");
166 return USB_ERR_IO_DEVICE_OFFLINE;
167 }
168
169 return HidSetIlde(HidDev, HidDev->InterfaceNo, 0, 0);
170 }
171
172 /*
173 *******************************************************************************
174 * HidPortReset
175 *
176 * Description:
177 * reset 设备
178 *
179 * Parameters:
180 * mscDev : input. 目标设备
181 *
182 * Return value:
183 * 返回成功或者失败
184 *
185 * note:
186 *
187 *
188 *******************************************************************************
189 */
HidPortReset(HidDev_t * HidDev)190 static int HidPortReset(HidDev_t *HidDev)
191 {
192 int ret = 0;
193
194 if(HidDev == NULL){
195 hal_log_err("ERR: HidPortReset: input error, mscDev = %x\n", HidDev);
196 return USB_ERR_BAD_ARGUMENTS;
197 }
198
199 /* device online? */
200 if(HidDev->State == HID_DEV_OFFLINE){
201 hal_log_err("ERR: HidPortReset: device is offline\n");
202 return USB_ERR_IO_DEVICE_OFFLINE;
203 }
204
205 /* reset a multi-interface device must be wariness */
206 if(HidDev->pusb_dev->actconfig->desc.bNumInterfaces != 1){
207 hal_log_err("ERR: Refusing to reset a multi-interface device\n");
208 return USB_ERR_IO_DEVICE_BUSY;
209 }
210
211 /* reset device */
212 ret = usb_reset_device(HidDev->pusb_dev);
213 if(ret != 0){
214 hal_log_err("ERR: reset device failed\n");
215 return USB_ERR_RESET_POERT_FAILED;
216 }
217
218 return USB_ERR_SUCCESS;
219 }
220
221 /*
222 *******************************************************************************
223 * HidResetRecovery
224 *
225 * Description:
226 *
227 *
228 * Parameters:
229 *
230 *
231 * Return value:
232 *
233 *
234 * note:
235 * 无
236 *
237 *******************************************************************************
238 */
HidResetRecovery(HidDev_t * HidDev)239 int HidResetRecovery(HidDev_t *HidDev)
240 {
241 int ret = 0;
242
243 ret = HidPortReset(HidDev);
244 if(ret != USB_ERR_SUCCESS){
245 hal_log_err("ERR: HidPortReset failed\n");
246 return USB_ERR_RESET_POERT_FAILED;
247 }
248
249 ret = HidSoftReset(HidDev);
250 if(ret != USB_ERR_SUCCESS){
251 hal_log_err("ERR: HidSoftReset failed\n");
252 return USB_ERR_RESET_POERT_FAILED;
253 }
254
255 return USB_ERR_SUCCESS;
256 }
257
258
259 /*
260 *******************************************************************************
261 * HidTransport
262 *
263 * Description:
264 *
265 *
266 * Parameters:
267 *
268 *
269 * Return value:
270 *
271 *
272 * note:
273 * 无
274 *
275 *******************************************************************************
276 */
277 #if 0 /* reset 多次 */
278 int HidTransport(HidDev_t *HidDev, HidRequest_t *HidReq)
279 {
280 int ret = 0;
281 __u32 retries = 3;
282
283 /* fill urb */
284 usb_fill_int_urb( HidDev->CurrentUrb,
285 HidDev->pusb_dev,
286 HidDev->IntIn,
287 HidReq->buffer,
288 HidReq->DataTransferLength,
289 HidTransportDone,
290 NULL,
291 HidDev->EpInterval);
292
293 HidRetry:
294 /* summit urb */
295 ret = HidUsbTransport(HidDev);
296 if(ret != USB_ERR_SUCCESS){
297 hal_log_err("ERR: HidUsbTransport failed\n");
298 return USB_HID_TRANSPORT_PIPE_HALT;
299 }
300
301 if(HidDev->CurrentUrb->status == -ESHUTDOWN){
302 hal_log_err("ERR: device is shut down\n");
303 return USB_HID_TRANSPORT_CANCEL_CMD;
304 }
305
306 if(HidDev->CurrentUrb->status != 0 && retries--){
307 hal_log_err("ERR: HidTransport failed(%d), need retry %d\n",
308 HidDev->CurrentUrb->status, retries);
309 ret = HidDev->ResetRecovery(HidDev);
310 if(ret != USB_ERR_SUCCESS){
311 hal_log_err("ERR: HidResetRecovery failed\n");
312 return USB_HID_TRANSPORT_DEVICE_DISCONNECT;
313 }
314
315 goto HidRetry;
316 }
317
318 /* retry的最后一次成功,不算其中 */
319 if(retries == 0 && HidDev->CurrentUrb->status != 0){
320 hal_log_err("ERR: HidTransport failed\n");
321 return USB_HID_TRANSPORT_DEVICE_DISCONNECT;
322 }
323
324 return USB_HID_TRANSPORT_SUCCESS;
325 }
326 #else /* 不reset */
HidTransport(HidDev_t * HidDev,HidRequest_t * HidReq)327 int HidTransport(HidDev_t *HidDev, HidRequest_t *HidReq)
328 {
329 int ret = 0;
330
331 /* fill urb */
332 usb_fill_int_urb( HidDev->CurrentUrb,
333 HidDev->pusb_dev,
334 HidDev->IntIn,
335 HidReq->buffer,
336 HidReq->DataTransferLength,
337 HidTransportDone,
338 NULL,
339 HidDev->EpInterval);
340
341 /* summit urb */
342 ret = HidUsbTransport(HidDev);
343 if(ret == USB_ERR_SUCCESS){
344 /* nothing to do */
345 }else if(ret == USB_ERR_IO_DEVICE_OFFLINE){
346 hal_log_err("ERR: deivce is offline\n");
347 return USB_HID_TRANSPORT_DEVICE_DISCONNECT;
348 }else{
349 hal_log_err("ERR: HidUsbTransport failed, ret = %d\n", ret);
350 return USB_HID_TRANSPORT_PIPE_HALT;
351 }
352
353 /* check urb status */
354 if(HidDev->CurrentUrb->status != 0){
355 hal_log_err("ERR: HidTransport failed(%d)\n", HidDev->CurrentUrb->status);
356
357 /* driver取消了本次传输 */
358 if(HidDev->CurrentUrb->status == -ESHUTDOWN){
359 hal_log_err("ERR: HidTransport: device is shut down\n");
360 return USB_HID_TRANSPORT_CANCEL_CMD;
361 }
362
363 if(HidDev->State == HID_DEV_OFFLINE){
364 hal_log_err("ERR: HidTransport: device is offline\n");
365 return USB_HID_TRANSPORT_DEVICE_DISCONNECT;
366 }
367
368 /*
369 ret = HidDev->ResetRecovery(HidDev);
370 if(ret != USB_ERR_SUCCESS){
371 hal_log_err("ERR: HidResetRecovery failed\n");
372 return USB_HID_TRANSPORT_DEVICE_DISCONNECT;
373 }
374 */
375 }
376
377 return USB_HID_TRANSPORT_SUCCESS;
378 }
379 #endif
380
381 /*
382 *******************************************************************************
383 * HidStopTransport
384 *
385 * Description:
386 *
387 *
388 * Parameters:
389 *
390 *
391 * Return value:
392 *
393 *
394 * note:
395 * 无
396 *
397 *******************************************************************************
398 */
HidStopTransport(HidDev_t * HidDev)399 int HidStopTransport(HidDev_t *HidDev)
400 {
401 if(HidDev == NULL){
402 hal_log_err("ERR: HidStopTransport: input error, HidDev = %x\n", HidDev);
403 return USB_ERR_BAD_ARGUMENTS;
404 }
405
406 if(HidDev->busy){
407 usb_unlink_urb(HidDev->CurrentUrb);
408 HidDev->CurrentUrb->status = -ESHUTDOWN;
409 }
410
411 return USB_ERR_SUCCESS;
412 }
413
414
415