1 /*
2 ********************************************************************************************************************
3 * usb host driver
4 *
5 * (c) Copyright 2007-2010, javen.China
6 * All Rights Reserved
7 *
8 * File Name : mscTransport.c
9 *
10 * Author : javen
11 *
12 * Version : 2.0
13 *
14 * Date : 2010.03.02
15 *
16 * Description :
17 *
18 * History :
19 *
20 ********************************************************************************************************************
21 */
22 #include "usb_os_platform.h"
23 #include "error.h"
24 #include "usb_host_common.h"
25 #include "urb.h"
26 #include "usb_gen_hub.h"
27 #include "usb_msc_i.h"
28 #include "mscTransport.h"
29 #include "Scsi2.h"
30
31 /*
32 *******************************************************************************
33 * mscUrbCallBack
34 *
35 * Description:
36 * urb call back函数
37 *
38 * Parameters:
39 * urb : input. 需要提交的URB
40 *
41 * Return value:
42 * 无
43 *
44 * note:
45 *
46 *
47 *******************************************************************************
48 */
mscUrbCallBack(struct urb * urb)49 static void mscUrbCallBack(struct urb *urb)
50 {
51 hal_sem_t urb_done = (hal_sem_t)urb->context;
52
53 if (urb_done != NULL)
54 {
55 hal_sem_post(urb_done);
56 }
57 else
58 {
59 hal_log_err("ERR: mscUrbCallBack: urb_done == NULL");
60 }
61 }
62
63 /*
64 *******************************************************************************
65 * mscTimeOut
66 *
67 * Description:
68 *
69 *
70 * Parameters:
71 *
72 *
73 * Return value:
74 *
75 *
76 * note:
77 *
78 *
79 *******************************************************************************
80 */
mscTimeOut(void * parg)81 static void mscTimeOut(void *parg)
82 {
83 __mscDev_t *mscDev = (__mscDev_t *)parg;
84
85 if (mscDev == NULL)
86 {
87 hal_log_err("ERR: mscTimeOut: mscDev == NULL");
88 return;
89 }
90
91 hal_log_info("ERR: mscTimeOut: CurrentUrb = %x", (unsigned int)mscDev->CurrentUrb);
92
93 if (mscDev->ScsiCmnd)
94 {
95 hal_log_err("ERR: mscTimeOut, Cmnd = %x, Timeout = %dms, retries = %d, allowed = %d",
96 ((__u8 *)(mscDev->ScsiCmnd->cmnd.CommandBlock))[0],
97 mscDev->ScsiCmnd->cmnd.Timeout,
98 mscDev->ScsiCmnd->retries,
99 mscDev->ScsiCmnd->allowed);
100 }
101
102 if (mscDev->busy)
103 {
104 usb_unlink_urb(mscDev->CurrentUrb);
105 mscDev->CurrentUrb->status = -ETIMEDOUT;
106 }
107
108 return;
109 }
110
111 /*
112 *******************************************************************************
113 * mscUsbTransport
114 *
115 * Description:
116 * 发送URB
117 *
118 * Parameters:
119 * mscDev : input. 目标设备
120 * TimeOut : input. 超时时间
121 *
122 * Return value:
123 * 返回URB状态
124 *
125 * note:
126 *
127 *
128 *******************************************************************************
129 */
mscUsbTransport(__mscDev_t * mscDev,unsigned int TimeOut)130 static int mscUsbTransport(__mscDev_t *mscDev, unsigned int TimeOut)
131 {
132 int ret = 0;
133 __u8 err = 0;
134
135 if (mscDev == NULL)
136 {
137 hal_log_err("ERR: mscUSBTransport: input error, mscDev = %x", mscDev);
138 return -EINVAL;
139 }
140
141 if (mscDev->state != MSC_DEV_ONLINE)
142 {
143 hal_log_err("ERR: mscUSBTransport: Can't transport for device is not online");
144 return -EINVAL;
145 }
146
147 /* fill URB */
148 mscDev->CurrentUrb->context = (void *)mscDev->UrbWait;
149 mscDev->CurrentUrb->actual_length = 0;
150 mscDev->CurrentUrb->error_count = 0;
151 mscDev->CurrentUrb->status = 0;
152 /* 设置buffer传输方式, 如果使用msc的buff,则不使用DMA,需要palloc分配内存 */
153 mscDev->CurrentUrb->transfer_flags = URB_ASYNC_UNLINK;
154 // mscDev->CurrentUrb->transfer_flags = URB_ASYNC_UNLINK | URB_NO_SETUP_DMA_MAP;
155
156 // if (mscDev->CurrentUrb->transfer_buffer == mscDev->iobuf)
157 // {
158 // mscDev->CurrentUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
159 // }
160
161
162 mscDev->CurrentUrb->transfer_dma = 0;
163 mscDev->CurrentUrb->setup_dma = 0;
164
165 /* create timer */
166 if (TimeOut)
167 {
168 // unsigned long time_interval = rt_tick_from_millisecond(TimeOut);
169 mscDev->TimerHdle = osal_timer_create("mscTime_timer",
170 (timeout_func)mscTimeOut,
171 (void *)mscDev,
172 TimeOut / (1000 / CONFIG_HZ),
173 OSAL_TIMER_FLAG_ONE_SHOT);
174 if (mscDev->TimerHdle == NULL)
175 {
176 hal_log_err("PANIC : create timer for urb false\n");
177 return -1;
178 }
179 }
180 /* set mscDev busy */
181 mscDev->busy = 1;
182 /* submit urb */
183 ret = usb_submit_urb(mscDev->CurrentUrb, 0);
184 if (ret != 0)
185 {
186 hal_log_err("ERR: submit urb failed. ret = %d", ret);
187 if (mscDev->TimerHdle)
188 {
189 osal_timer_delete(mscDev->TimerHdle);
190 mscDev->TimerHdle = NULL;
191 }
192
193 mscDev->busy = 0;
194 return -EINVAL;
195 }
196
197 /* start timer */
198 if (mscDev->TimerHdle)
199 {
200 osal_timer_start(mscDev->TimerHdle);
201 }
202
203 /* wait urb done */
204 hal_sem_timedwait(mscDev->UrbWait, TimeOut / (1000 / CONFIG_HZ));
205 /* urb is done, then set mscDev free */
206 mscDev->busy = 0;
207
208 /* kill timer */
209 if (mscDev->TimerHdle)
210 {
211 osal_timer_stop(mscDev->TimerHdle);
212 osal_timer_delete(mscDev->TimerHdle);
213 mscDev->TimerHdle = NULL;
214 }
215
216 return mscDev->CurrentUrb->status;
217 }
218
219 /*
220 *******************************************************************************
221 * mscCtrlMsg
222 *
223 * Description:
224 * USB控制消息函数
225 *
226 * Parameters:
227 * mscDev : input. 目标设备
228 * Pipe : input. URB通道
229 * Request : input. 请求类型
230 * RequestType : input. 请求方向(读/写)和请求类型
231 * Value : input. 值
232 * Index : input. 索引
233 * Buffer : input. 输入/输出缓存区
234 * BufferLen : input. 输入/输出缓存区大小
235 * TimeOut : input. URB超时时间
236 *
237 * Return value:
238 * 返回URB状态
239 *
240 * note:
241 *
242 *
243 *******************************************************************************
244 */
mscSendCtrlReq(__mscDev_t * mscDev,int Pipe,__u8 Request,__u8 RequestType,__u16 Value,__u16 Index,void * Buffer,__u16 BufferLen,unsigned int TimeOut)245 static int mscSendCtrlReq(__mscDev_t *mscDev,
246 int Pipe,
247 __u8 Request,
248 __u8 RequestType,
249 __u16 Value,
250 __u16 Index,
251 void *Buffer,
252 __u16 BufferLen,
253 unsigned int TimeOut)
254 {
255 if (mscDev == NULL)
256 {
257 hal_log_err("ERR: USBStorageCtrlMsg : mscDev = %x", mscDev);
258 return USB_ERR_BAD_ARGUMENTS;
259 }
260
261 /* 填充控制请求结构体 */
262 mscDev->CtrlReq->bRequest = Request; // 请求类型
263 mscDev->CtrlReq->bRequestType = RequestType; // 请求方向(读/写)和请求类型
264 mscDev->CtrlReq->wValue = cpu_to_le16(Value); // 值, 使用小端字节序
265 mscDev->CtrlReq->wIndex = cpu_to_le16(Index); // 索引, 使用小端字节序
266 mscDev->CtrlReq->wLength = cpu_to_le16(BufferLen); // 缓冲区大小, 使用小端字节序
267 /* 填充并提交Urb */
268 memset(mscDev->CurrentUrb, 0x00, sizeof(struct urb));
269 usb_fill_control_urb(mscDev->CurrentUrb,
270 mscDev->pusb_dev,
271 Pipe,
272 (unsigned char *)mscDev->CtrlReq,
273 Buffer,
274 BufferLen,
275 mscUrbCallBack,
276 NULL);
277 /* 发送请求并等待响应 */
278 return mscUsbTransport(mscDev, TimeOut);
279 }
280
281 /*
282 *******************************************************************************
283 * mscClearHalt
284 *
285 * Description:
286 * 清除端点状态
287 *
288 * Parameters:
289 * mscDev : input. 目标设备
290 * Pipe : input. urb的pipe
291 *
292 * Return value:
293 * 返回URB执行结果
294 *
295 * note:
296 *
297 *
298 *******************************************************************************
299 */
mscClearHalt(__mscDev_t * mscDev,unsigned int Pipe)300 static int mscClearHalt(__mscDev_t *mscDev, unsigned int Pipe)
301 {
302 int Result = 0;
303 unsigned int endp = usb_pipeendpoint(Pipe);
304
305 if (usb_pipein(Pipe))
306 {
307 endp |= USB_DIR_IN;
308 }
309
310 Result = mscSendCtrlReq(mscDev,
311 mscDev->CtrlOut,
312 USB_REQ_CLEAR_FEATURE,
313 USB_RECIP_ENDPOINT,
314 USB_ENDPOINT_HALT,
315 (__u16)endp,
316 NULL,
317 0,
318 USB_STOR_CTRL_MSG_TIME);
319
320 /* reset the endpoint toggle */
321 if (Result >= 0)
322 {
323 usb_settoggle(mscDev->pusb_dev, usb_pipeendpoint(Pipe), usb_pipeout(Pipe), 0);
324 }
325
326 if (Result == 0)
327 {
328 Result = USB_ERR_SUCCESS;
329 }
330 else
331 {
332 Result = USB_ERR_UNKOWN_ERROR;
333 }
334
335 return Result;
336 }
337
338 /*
339 *******************************************************************************
340 * AnalyseBlukUrbState
341 *
342 * Description:
343 * 分析Bulk Urb状态
344 *
345 * Parameters:
346 * mscDev : input. 目标设备
347 * UrbState : input. URB执行状态
348 * Pipe : input. urb的pipe
349 * WantLen : input. 原始要求传输数据长度
350 * ActLen : input. 实际传输数据长度
351 *
352 * Return value:
353 * 返回USB操作结果
354 *
355 * note:
356 *
357 *
358 *******************************************************************************
359 */
AnalyseBulkUrbState(__mscDev_t * mscDev,int UrbState,int Pipe,unsigned int WantLen,unsigned int ActLen)360 static int AnalyseBulkUrbState(__mscDev_t *mscDev,
361 int UrbState,
362 int Pipe,
363 unsigned int WantLen,
364 unsigned int ActLen)
365 {
366 switch (UrbState)
367 {
368 case 0: /* no error code; did we send all the data? */
369 if (WantLen != ActLen)
370 {
371 hal_log_err("Wrn: short transfer, urb_state(%d), want_len(%d), real_len(%d)",
372 UrbState, WantLen, ActLen);
373 return USB_STOR_XFER_SHORT;
374 }
375
376 return USB_STOR_XFER_GOOD;
377
378 case -EPIPE: /* stalled */
379 hal_log_err("ERR: ep stalled, need clear feature");
380
381 /* for control endpoints, (used by CB[I]) a stall indicates a failed command */
382 if (usb_pipecontrol(Pipe))
383 {
384 hal_log_err("stall on control pipe, urb_state(%d), want_len(%d), real_len(%d)",
385 UrbState, WantLen, ActLen);
386 return USB_STOR_XFER_STALLED;
387 }
388
389 /* for other sorts of endpoint, clear the stall */
390 if (mscClearHalt(mscDev, Pipe) != USB_ERR_SUCCESS)
391 {
392 hal_log_err("ERR: mscClearHalt ep failed, urb_state(%d), want_len(%d), real_len(%d)",
393 UrbState, WantLen, ActLen);
394 return USB_STOR_XFER_ERROR;
395 }
396
397 return USB_STOR_XFER_STALLED;
398
399 /* timeout or excessively long NAK */
400 case -ETIMEDOUT:
401 hal_log_err("ERR: timeout or NAK, urb_state(%d), want_len(%d), real_len(%d)",
402 UrbState, WantLen, ActLen);
403 return USB_STOR_XFER_TIME_OUT;
404
405 /* babble - the device tried to send more than we wanted to read */
406 case -EOVERFLOW:
407 hal_log_err("ERR: babble, data overflow, urb_state(%d), want_len(%d), real_len(%d)",
408 UrbState, WantLen, ActLen);
409 return USB_STOR_XFER_LONG;
410
411 /* the transfer was cancelled by abort, disconnect, or timeout */
412 case -ECONNRESET:
413 hal_log_err("ERR: transfer cancelled, urb_state(%d), want_len(%d), real_len(%d)",
414 UrbState, WantLen, ActLen);
415 return USB_STOR_XFER_ERROR;
416
417 /* short scatter-gather read transfer */
418 case -EREMOTEIO:
419 hal_log_err("ERR: short read transfer, urb_state(%d), want_len(%d), real_len(%d)",
420 UrbState, WantLen, ActLen);
421 return USB_STOR_XFER_SHORT;
422
423 /* abort or disconnect in progress */
424 case -EIO:
425 hal_log_err("ERR: abort or disconnect in progress, urb_state(%d), want_len(%d), real_len(%d)",
426 UrbState, WantLen, ActLen);
427 return USB_STOR_XFER_ERROR;
428
429 default:
430 hal_log_err("ERR: unkown urb state, urb_state(%d), want_len(%d), real_len(%d)",
431 UrbState, WantLen, ActLen);
432 return USB_STOR_XFER_ERROR;
433 }
434 }
435
436 /*
437 *******************************************************************************
438 * mscSendBlukReq
439 *
440 * Description:
441 * 发送bulk请求
442 *
443 * Parameters:
444 * mscDev : input. 目标设备
445 * Pipe : input. urb的pipe
446 * Buffer : input. 数据缓冲区
447 * BufferLen : input. 数据缓冲区大小
448 * ActLen : input. 实际传输数据长度
449 * TimeOut : input. URB超时时间
450 *
451 * Return value:
452 * 返回USB操作结果
453 *
454 * note:
455 *
456 *
457 *******************************************************************************
458 */
mscSendBulkReq(__mscDev_t * mscDev,int Pipe,void * Buffer,unsigned int BufferLen,unsigned int * ActLen,unsigned int TimeOut)459 static int mscSendBulkReq(__mscDev_t *mscDev,
460 int Pipe,
461 void *Buffer,
462 unsigned int BufferLen,
463 unsigned int *ActLen,
464 unsigned int TimeOut)
465 {
466 /* fill urb */
467 memset(mscDev->CurrentUrb, 0x00, sizeof(struct urb));
468 usb_fill_bulk_urb(mscDev->CurrentUrb,
469 mscDev->pusb_dev,
470 Pipe,
471 Buffer,
472 BufferLen,
473 mscUrbCallBack,
474 NULL);
475 /* submit urb */
476 mscUsbTransport(mscDev, TimeOut);
477
478 if (ActLen)
479 {
480 *ActLen = (unsigned int)(mscDev->CurrentUrb->actual_length);
481 }
482
483 return AnalyseBulkUrbState(mscDev,
484 mscDev->CurrentUrb->status,
485 Pipe,
486 BufferLen,
487 (unsigned int)(mscDev->CurrentUrb->actual_length));
488 }
489
490 /*
491 *******************************************************************************
492 * GetMaxLun
493 *
494 * Description:
495 * 获取当前设备的最大Lun编号,如果获取失败,则默认设备只有1个Lun
496 *
497 * Parameters:
498 * mscDev : input. 目标设备
499 *
500 * Return value:
501 * Lun 编号
502 *
503 * note:
504 *
505 *
506 *******************************************************************************
507 */
mscGetMaxLun(__mscDev_t * mscDev)508 unsigned int mscGetMaxLun(__mscDev_t *mscDev)
509 {
510 int ret = 0;
511 unsigned int MaxLun = 0;
512
513 if (mscDev == NULL)
514 {
515 hal_log_err("ERR: GetMaxLun: input error, mscDev = %x", mscDev);
516 return 0;
517 }
518
519 hal_sem_wait(mscDev->DevLock);
520 /* issue the command */
521 ret = mscSendCtrlReq(mscDev,
522 mscDev->CtrlIn,
523 USB_BULK_GET_MAX_LUN,
524 USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
525 0,
526 mscDev->InterfaceNo,
527 mscDev->iobuf,
528 1,
529 USB_STOR_CTRL_MSG_TIME);
530
531 if (ret == 0)
532 {
533 hal_log_info("[msc]: GetMaxLUN successful, max lun is %d", mscDev->iobuf[0]);
534 MaxLun = mscDev->iobuf[0];
535 }
536 else
537 {
538 hal_log_info("[msc]: GetMaxLUN failed, max lun is zero");
539 MaxLun = 0;
540
541 if (ret == -EPIPE)
542 {
543 mscClearHalt(mscDev, mscDev->BulkIn);
544 mscClearHalt(mscDev, mscDev->BulkOut);
545 }
546 }
547
548 hal_sem_post(mscDev->DevLock);
549 return MaxLun;
550 }
551
552 /*
553 *******************************************************************************
554 * mscBoReset
555 *
556 * Description:
557 *
558 *
559 * Parameters:
560 *
561 *
562 * Return value:
563 *
564 *
565 * note:
566 *
567 *
568 *******************************************************************************
569 */
570 #if 0
571 static int mscBoReset(__mscDev_t *mscDev)
572 {
573 int ret = 0;
574
575 if (mscDev == NULL)
576 {
577 printf("ERR: mscBoReset: input error, mscDev = %x", mscDev);
578 return USB_ERR_BAD_ARGUMENTS;
579 }
580
581 /* send reset request */
582 ret = mscSendCtrlReq(mscDev,
583 mscDev->CtrlOut,
584 USB_BULK_RESET_REQUEST,
585 USB_TYPE_CLASS | USB_RECIP_INTERFACE,
586 0,
587 mscDev->InterfaceNo,
588 NULL,
589 0,
590 USB_STOR_CTRL_MSG_TIME);
591
592 if (ret != USB_ERR_SUCCESS)
593 {
594 printf("ERR: Soft reset failed 1");
595 return ret;
596 }
597
598 /* clear ep status */
599 ret = mscClearHalt(mscDev, mscDev->BulkIn);
600
601 if (ret != USB_ERR_SUCCESS)
602 {
603 printf("ERR: Soft reset failed 2");
604 return ret;
605 }
606
607 ret = mscClearHalt(mscDev, mscDev->BulkOut);
608
609 if (ret != USB_ERR_SUCCESS)
610 {
611 printf("ERR: Soft reset failed 3");
612 return ret;
613 }
614
615 return ret;
616 }
617 #endif
618
619 /*
620 *******************************************************************************
621 * mscPortReset
622 *
623 * Description:
624 * 重置设备
625 *
626 * Parameters:
627 * mscDev : input. 目标设备
628 *
629 * Return value:
630 * 返回成功或失败
631 *
632 * note:
633 *
634 *
635 *******************************************************************************
636 */
mscPortReset(__mscDev_t * mscDev)637 static int mscPortReset(__mscDev_t *mscDev)
638 {
639 int ret = 0;
640
641 if (mscDev == NULL)
642 {
643 hal_log_err("ERR: mscPortReset: input error, mscDev = %x", mscDev);
644 return USB_ERR_BAD_ARGUMENTS;
645 }
646
647 /* device online? */
648 if (mscDev->state == MSC_DEV_OFFLINE)
649 {
650 hal_log_err("ERR: mscPortReset: device is offline");
651 return USB_ERR_IO_DEVICE_OFFLINE;
652 }
653
654 /* reset a multi-interface device must be wariness */
655 if (mscDev->pusb_dev->actconfig->desc.bNumInterfaces != 1)
656 {
657 hal_log_err("ERR: Refusing to reset a multi-interface device");
658 return USB_ERR_IO_DEVICE_BUSY;
659 }
660
661 /* reset device */
662 ret = usb_reset_device(mscDev->pusb_dev);
663
664 if (ret != 0)
665 {
666 hal_log_err("ERR: reset device failed");
667 return USB_ERR_RESET_POERT_FAILED;
668 }
669
670 return USB_ERR_SUCCESS;
671 }
672
mscResetRecovery(__mscDev_t * mscDev)673 int mscResetRecovery(__mscDev_t *mscDev)
674 {
675 return mscPortReset(mscDev);
676 }
677
678 /*
679 *******************************************************************************
680 * mscBoTransport
681 *
682 * Description:
683 *
684 *
685 * Parameters:
686 *
687 *
688 * Return value:
689 *
690 *
691 * note:
692 *
693 *
694 *******************************************************************************
695 */
mscBoTransport(__mscDev_t * mscDev,__ScsiCmnd_t * ScsiCmnd)696 int mscBoTransport(__mscDev_t *mscDev, __ScsiCmnd_t *ScsiCmnd)
697 {
698 __CBW_t *CBW = NULL;
699 __CSW_t *CSW = NULL;
700 unsigned int ActLen = 0;
701 unsigned int TimeOut = 0;
702 unsigned int CSWRepeat = 0;
703 int Pipe = 0;
704 int ret = 0;
705
706 if (mscDev == NULL || ScsiCmnd == NULL)
707 {
708 hal_log_err("ERR: mscBoTransport: input error, mscDev = %x,ScsiCmnd = %x", mscDev, ScsiCmnd);
709 return USB_STOR_TRANSPORT_ERROR;
710 }
711
712 /* is scsi command valid */
713 if (ScsiCmnd->DataTransferLength)
714 {
715 switch (ScsiCmnd->cmnd.data_direction)
716 {
717 case DATA_FROM_DEVICE:
718 Pipe = mscDev->BulkIn;
719 break;
720
721 case DATA_TO_DEVICE:
722 Pipe = mscDev->BulkOut;
723 break;
724
725 default:
726 Pipe = 0;
727 hal_log_err("ERR: data phase do not kwon data direction");
728 return USB_STOR_TRANSPORT_ERROR;
729 }
730 }
731
732 hal_sem_wait(mscDev->DevLock);
733 mscDev->ScsiCmnd = ScsiCmnd;
734 //----------------------------------------------------
735 // Command Block Transport (CBW)
736 //----------------------------------------------------
737 /* build the active CBW */
738 CBW = (__CBW_t *)mscDev->iobuf;
739 memset(CBW, 0, sizeof(__CBW_t));
740 mscDev->Tag++;
741 TimeOut = USB_STOR_CBW_CSW_TIME;
742 CBW->dCBWSignature = CBW_SIGNATURE;
743 CBW->dCBWTag = mscDev->Tag;
744 CBW->dCBWDataTransferLength = ScsiCmnd->DataTransferLength;
745 CBW->bmCBWFlags = (ScsiCmnd->cmnd.data_direction == DATA_FROM_DEVICE)
746 ? CBW_FLAGS_DATA_IN : CBW_FLAGS_DATA_OUT;
747 CBW->bCBWLUN = ScsiCmnd->cmnd.dwLun;
748 CBW->bCBWCBLength = ScsiCmnd->cmnd.CBLen;
749 memcpy((void *)CBW->CBWCB, ScsiCmnd->cmnd.CommandBlock, CBW->bCBWCBLength);
750 /* Command Block Transport */
751 ret = mscSendBulkReq(mscDev,
752 mscDev->BulkOut,
753 CBW,
754 sizeof(__CBW_t),
755 NULL,
756 TimeOut);
757
758 if (ret != USB_STOR_XFER_GOOD)
759 {
760 hal_log_err("ERR: mscBoTransport: Command Block Transport failed, reset");
761 mscDev->ResetRecovery(mscDev);
762 ret = USB_STOR_TRANSPORT_ERROR;
763 goto TransportDone;
764 }
765
766 //----------------------------------------------------
767 // Data Transport
768 //----------------------------------------------------
769 if (ScsiCmnd->DataTransferLength)
770 {
771 TimeOut = ScsiCmnd->cmnd.Timeout;
772 ret = mscSendBulkReq(mscDev,
773 Pipe,
774 ScsiCmnd->buffer,
775 ScsiCmnd->DataTransferLength,
776 &ActLen,
777 TimeOut);
778
779 /* 有些设备在read/write数据时会发生endpoint stall的情况,
780 解除stall可能需要进行clear feature操作,所以需要进行重试
781 */
782 if (ret == USB_STOR_XFER_STALLED)
783 {
784 __u8 Command = 0;
785 Command = ((__u8 *)(ScsiCmnd->cmnd.CommandBlock))[0];
786
787 if (Command == SCSI_READ6 || Command == SCSI_READ10 || Command == SCSI_READ16
788 || Command == SCSI_WRITE6 || Command == SCSI_WRITE10 || Command == SCSI_WRITE16)
789 {
790 hal_log_err("ERR: Command(%x) execute failed, for ep stall, need retry", Command);
791 mscDev->ResetRecovery(mscDev);
792 ret = USB_STOR_TRANSPORT_ERROR;
793 goto TransportDone;
794 }
795 }
796
797 if (ret == USB_STOR_XFER_ERROR)
798 {
799 hal_log_err("ERR: mscBoTransport: Data Transport failed, reset");
800 mscDev->ResetRecovery(mscDev);
801 ret = USB_STOR_TRANSPORT_ERROR;
802 goto TransportDone;
803 }
804
805 ScsiCmnd->ActualLength = ActLen;
806 }
807
808 //----------------------------------------------------
809 // Command Status Transport (CSW)
810 //----------------------------------------------------
811 RETRY_CSW:
812
813 if (ScsiCmnd->DataTransferLength)
814 {
815 TimeOut = USB_STOR_CBW_CSW_TIME;
816 }
817 else
818 {
819 TimeOut = ScsiCmnd->cmnd.Timeout;
820 }
821
822 CSW = (__CSW_t *)mscDev->iobuf;
823 memset(CSW, 0, sizeof(__CSW_t));
824 ret = mscSendBulkReq(mscDev,
825 mscDev->BulkIn,
826 CSW,
827 sizeof(__CSW_t),
828 &ActLen,
829 TimeOut);
830
831 if (ret == USB_STOR_XFER_SHORT && ActLen == 0 && ++CSWRepeat < MAX_BOT_CSW_REPEAT)
832 {
833 hal_log_err("ERR: Received 0-length CSW, must Receive the CSW again");
834 goto RETRY_CSW;
835 }
836
837 if (ret == USB_STOR_XFER_STALLED && ++CSWRepeat < MAX_BOT_CSW_REPEAT)
838 {
839 hal_log_err("ERR: EP stall, must Receive the CSW again");
840 goto RETRY_CSW;
841 }
842
843 if (ret != USB_STOR_XFER_GOOD)
844 {
845 hal_log_err("ERR: unkown error happen during receive cmd(%x)'s CSW, must reset",
846 ((__u8 *)(ScsiCmnd->cmnd.CommandBlock))[0]);
847 mscDev->ResetRecovery(mscDev);
848 ret = USB_STOR_TRANSPORT_ERROR;
849 goto TransportDone;
850 }
851
852 /* check CSW size */
853 if (sizeof(__CSW_t) != ActLen)
854 {
855 hal_log_err("ERR: Invalid Csw size: (%d, %d), must reset", sizeof(__CSW_t), ActLen);
856 mscDev->ResetRecovery(mscDev);
857 ret = USB_STOR_TRANSPORT_ERROR;
858 goto TransportDone;
859 }
860
861 /* check CSW Signature */
862 if (CSW->dCSWSignature != CSW_SIGNATURE)
863 {
864 hal_log_err("ERR: Invalid Csw Signature: %x, must reset", CSW->dCSWSignature);
865 mscDev->ResetRecovery(mscDev);
866 ret = USB_STOR_TRANSPORT_ERROR;
867 goto TransportDone;
868 }
869
870 /* check CSW Tags */
871 if (CSW->dCSWTag != mscDev->Tag)
872 {
873 hal_log_err("ERR: Invalid Csw Tags: (%x, %x), must reset", mscDev->Tag, CSW->dCSWTag);
874 mscDev->ResetRecovery(mscDev);
875 ret = USB_STOR_TRANSPORT_ERROR;
876 goto TransportDone;
877 }
878
879 /* check CSW Status, command failed, need sense */
880 if (CSW->bCSWStatus == 1)
881 {
882 hal_log_err("WRN: command(%x) failed, need sense", ((__u8 *)(ScsiCmnd->cmnd.CommandBlock))[0]);
883 ret = USB_STOR_TRANSPORT_FAILED;
884 goto TransportDone;
885 }
886
887 /* check CSW Status, Phase Error */
888 if (CSW->bCSWStatus == 2)
889 {
890 hal_log_err("ERR: command Phase Error, must reset");
891 ret = USB_STOR_TRANSPORT_ERROR;
892 goto TransportDone;
893 }
894
895 mscDev->ScsiCmnd = NULL;
896 hal_sem_post(mscDev->DevLock);
897 return USB_STOR_TRANSPORT_GOOD;
898 TransportDone:
899 mscDev->ScsiCmnd = NULL;
900 hal_sem_post(mscDev->DevLock);
901 return ret;
902 }
903
904
905 /*
906 *******************************************************************************
907 * mscBoStopTransport
908 *
909 * Description:
910 *
911 *
912 * Parameters:
913 *
914 *
915 * Return value:
916 *
917 *
918 * note:
919 *
920 *
921 *******************************************************************************
922 */
mscBoStopTransport(__mscDev_t * mscDev)923 int mscBoStopTransport(__mscDev_t *mscDev)
924 {
925 if (mscDev == NULL)
926 {
927 hal_log_err("ERR: mscBoStopTransport: input error, mscDev = %x", mscDev);
928 return USB_ERR_BAD_ARGUMENTS;
929 }
930
931 if (mscDev->TimerHdle)
932 {
933 osal_timer_stop(mscDev->TimerHdle);
934 osal_timer_delete(mscDev->TimerHdle);
935 mscDev->TimerHdle = NULL;
936 }
937
938 if (mscDev->busy)
939 {
940 usb_unlink_urb(mscDev->CurrentUrb);
941 mscDev->CurrentUrb->status = -ESHUTDOWN;
942 }
943
944 return USB_ERR_SUCCESS;
945 }
946
947
948
949