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