]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EdkModulePkg/Bus/Usb/UsbBot/Dxe/bot.c
1. Sync definition of EFI_DEBUG_IMAGE_INFO with UEFI spec
[mirror_edk2.git] / EdkModulePkg / Bus / Usb / UsbBot / Dxe / bot.c
index acba154842dc24047047665867ca3d49a65fa73f..fef5de9387124b68b8f999a54c03574d073de3c3 100644 (file)
@@ -1,13 +1,13 @@
 /*++\r
 \r
-Copyright (c) 2006, Intel Corporation                                                         \r
-All rights reserved. This program and the accompanying materials                          \r
-are licensed and made available under the terms and conditions of the BSD License         \r
-which accompanies this distribution.  The full text of the license may be found at        \r
-http://opensource.org/licenses/bsd-license.php                                            \r
-                                                                                          \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+Copyright (c) 2006, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
 \r
 Module Name:\r
 \r
@@ -19,44 +19,8 @@ Abstract:
 \r
 #include "bot.h"\r
 \r
-//\r
-// Function prototypes\r
-//\r
-EFI_STATUS\r
-EFIAPI\r
-UsbBotDriverEntryPoint (\r
-  IN EFI_HANDLE           ImageHandle,\r
-  IN EFI_SYSTEM_TABLE     *SystemTable\r
-  );\r
-\r
-//\r
-// Bot Driver Binding Protocol\r
-//\r
-EFI_STATUS\r
-EFIAPI\r
-BotDriverBindingSupported (\r
-  IN EFI_DRIVER_BINDING_PROTOCOL    *This,\r
-  IN EFI_HANDLE                     ControllerHandle,\r
-  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath\r
-  );\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-BotDriverBindingStart (\r
-  IN EFI_DRIVER_BINDING_PROTOCOL    *This,\r
-  IN EFI_HANDLE                     ControllerHandle,\r
-  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath\r
-  );\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-BotDriverBindingStop (\r
-  IN  EFI_DRIVER_BINDING_PROTOCOL    *This,\r
-  IN  EFI_HANDLE                     ControllerHandle,\r
-  IN  UINTN                          NumberOfChildren,\r
-  IN  EFI_HANDLE                     *ChildHandleBuffer\r
-  );\r
-\r
+GLOBAL_REMOVE_IF_UNREFERENCED UINT32     gBOTDebugLevel  = EFI_D_INFO;\r
+GLOBAL_REMOVE_IF_UNREFERENCED UINT32     gBOTErrorLevel  = EFI_D_INFO;\r
 \r
 EFI_DRIVER_BINDING_PROTOCOL   gUsbBotDriverBinding = {\r
   BotDriverBindingSupported,\r
@@ -85,7 +49,7 @@ STATIC
 EFI_STATUS\r
 BotDataPhase (\r
   IN     USB_BOT_DEVICE            *UsbBotDev,\r
-  IN     UINT32                    *DataSize,\r
+  IN     UINT                    *DataSize,\r
   IN OUT VOID                      *DataBuffer,\r
   IN     EFI_USB_DATA_DIRECTION    Direction,\r
   IN     UINT16                    Timeout\r
@@ -94,11 +58,10 @@ BotDataPhase (
 STATIC\r
 EFI_STATUS\r
 BotStatusPhase (\r
-  IN  USB_BOT_DEVICE      *UsbBotDev,\r
-  OUT UINT8               *TransferStatus,\r
-  IN  UINT16              Timeout\r
+  IN  USB_BOT_DEVICE          *UsbBotDev,\r
+  OUT UINT32                  *DataResidue, \r
+  IN  UINT16                  Timeout\r
   );\r
-\r
 //\r
 // USB Atapi protocol prototype\r
 //\r
@@ -123,6 +86,7 @@ BotMassStorageReset (
   IN  BOOLEAN                   ExtendedVerification\r
   );\r
 \r
+STATIC\r
 VOID\r
 BotReportStatusCode (\r
   IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath,\r
@@ -193,7 +157,7 @@ BotDriverBindingSupported (
   //\r
   // Check if it is a BOT type Mass Storage Device\r
   //\r
-  if ((InterfaceDescriptor.InterfaceClass    != 0x08) ||\r
+  if ((InterfaceDescriptor.InterfaceClass    != MASS_STORAGE_CLASS) ||\r
       (InterfaceDescriptor.InterfaceProtocol != BOT)) {\r
     Status = EFI_UNSUPPORTED;\r
     goto Exit;\r
@@ -431,7 +395,7 @@ BotDriverBindingStop (
 \r
   Returns:\r
     EFI_SUCCESS       - This driver is removed DeviceHandle\r
-    EFI_UNSUPPORTED   - Can't open the gEfiUsbAtapiProtocolGuid protocl  \r
+    EFI_UNSUPPORTED   - Can't open the gEfiUsbAtapiProtocolGuid protocl\r
     other             - This driver was not removed from this device\r
 \r
 --*/\r
@@ -440,8 +404,6 @@ BotDriverBindingStop (
   EFI_USB_ATAPI_PROTOCOL  *BotAtapiProtocol;\r
   USB_BOT_DEVICE          *UsbBotDev;\r
 \r
-  EFI_USB_IO_PROTOCOL     *UsbIo;\r
-\r
   //\r
   // Get our context back.\r
   //\r
@@ -463,7 +425,6 @@ BotDriverBindingStop (
   // After installing Usb-Atapi protocol onto this handle\r
   // it will be called by upper layer drivers such as Fat\r
   //\r
-  UsbIo = UsbBotDev->UsbIo;\r
 \r
   BotReportStatusCode (\r
     UsbBotDev->DevicePath,\r
@@ -513,6 +474,38 @@ BotDriverBindingStop (
   return Status;\r
 }\r
 \r
+\r
+\r
+STATIC\r
+EFI_STATUS\r
+ClearBulkInPipe (\r
+  IN  USB_BOT_DEVICE          *UsbBotDev\r
+  )\r
+{\r
+ UINT32   Result;\r
+\r
+ return UsbClearEndpointHalt (\r
+          UsbBotDev->UsbIo,\r
+          UsbBotDev->BulkInEndpointDescriptor->EndpointAddress,\r
+          &Result\r
+          );\r
+}\r
+\r
+\r
+STATIC\r
+EFI_STATUS\r
+ClearBulkOutPipe  (\r
+  IN  USB_BOT_DEVICE          *UsbBotDev\r
+  )\r
+{\r
+ UINT32   Result;\r
+ return UsbClearEndpointHalt (\r
+          UsbBotDev->UsbIo,\r
+          UsbBotDev->BulkOutEndpointDescriptor->EndpointAddress,\r
+          &Result\r
+          );\r
+}\r
+\r
 STATIC\r
 EFI_STATUS\r
 BotRecoveryReset (\r
@@ -530,17 +523,12 @@ Arguments:
 \r
 Returns:\r
   EFI_SUCCESS - Success the operation\r
-  \r
+\r
 --*/\r
 {\r
   EFI_STATUS              Status;\r
-  UINT32                  Result;\r
   EFI_USB_DEVICE_REQUEST  Request;\r
-  EFI_USB_IO_PROTOCOL     *UsbIo;\r
-  UINT8                   EndpointAddr;\r
-\r
-  UsbIo = UsbBotDev->UsbIo;\r
-\r
+  UINT32                  Result;\r
   BotReportStatusCode (\r
     UsbBotDev->DevicePath,\r
     EFI_PROGRESS_CODE,\r
@@ -555,43 +543,24 @@ Returns:
   Request.RequestType = 0x21;\r
   Request.Request     = 0xFF;\r
 \r
-  Status = UsbIo->UsbControlTransfer (\r
-                    UsbIo,\r
-                    &Request,\r
-                    EfiUsbNoData,\r
-                    TIMEOUT_VALUE,\r
-                    NULL,\r
-                    0,\r
-                    &Result\r
-                    );\r
+  Status = UsbBotDev->UsbIo->UsbControlTransfer (\r
+                               UsbBotDev->UsbIo,\r
+                               &Request,\r
+                               EfiUsbNoData,\r
+                               TIMEOUT_VALUE,\r
+                               NULL,\r
+                               0,\r
+                               &Result\r
+                               );\r
 \r
   gBS->Stall (100 * 1000);\r
 \r
-  if (!EFI_ERROR (Status)) {\r
-    //\r
-    // clear bulk in endpoint stall feature\r
-    //\r
-    EndpointAddr = UsbBotDev->BulkInEndpointDescriptor->EndpointAddress;\r
-\r
-    Status = UsbClearEndpointHalt (\r
-               UsbIo,\r
-               EndpointAddr,\r
-               &Result\r
-               );\r
-\r
-    //\r
-    // clear bulk out endpoint stall feature\r
-    //\r
-    EndpointAddr = UsbBotDev->BulkOutEndpointDescriptor->EndpointAddress;\r
-    Status = UsbClearEndpointHalt (\r
-               UsbIo,\r
-               EndpointAddr,\r
-               &Result\r
-               );\r
-  }\r
+  ClearBulkInPipe (UsbBotDev);\r
+  ClearBulkOutPipe (UsbBotDev);\r
 \r
   return Status;\r
 }\r
+\r
 //\r
 // Bot Protocol Implementation\r
 //\r
@@ -639,7 +608,7 @@ BotCommandPhase (
   cbw.dCBWSignature           = CBWSIG;\r
   cbw.dCBWTag                 = 0x01;\r
   cbw.dCBWDataTransferLength  = DataTransferLength;\r
-  cbw.bmCBWFlags              = (UINT8) (Direction << 7);\r
+  cbw.bmCBWFlags              = (UINT8) ((Direction == EfiUsbDataIn) ? 0x80 : 0);\r
   cbw.bCBWCBLength            = CommandSize;\r
 \r
   CopyMem (cbw.CBWCB, Command, CommandSize);\r
@@ -648,28 +617,20 @@ BotCommandPhase (
 \r
   Status = UsbIo->UsbBulkTransfer (\r
                     UsbIo,\r
-                    (UsbBotDev->BulkOutEndpointDescriptor)->EndpointAddress,\r
+                    UsbBotDev->BulkOutEndpointDescriptor->EndpointAddress,\r
                     &cbw,\r
                     &DataSize,\r
                     Timeout,\r
                     &Result\r
                     );\r
-  if (EFI_ERROR (Status)) {\r
-    //\r
-    // Command phase fail, we need to recovery reset this device\r
-    //\r
-    BotRecoveryReset (UsbBotDev);\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
+  return Status;\r
 }\r
 \r
 STATIC\r
 EFI_STATUS\r
 BotDataPhase (\r
   IN      USB_BOT_DEVICE            *UsbBotDev,\r
-  IN      UINT32                    *DataSize,\r
+  IN      UINT                    *DataSize,\r
   IN  OUT VOID                      *DataBuffer,\r
   IN      EFI_USB_DATA_DIRECTION    Direction,\r
   IN      UINT16                    Timeout\r
@@ -695,125 +656,52 @@ BotDataPhase (
   UINT32              Result;\r
   EFI_USB_IO_PROTOCOL *UsbIo;\r
   UINT8               EndpointAddr;\r
-  UINTN               Remain;\r
-  UINTN               Increment;\r
-  UINT32              MaxPacketLen;\r
   UINT8               *BufferPtr;\r
-  UINTN               TransferredSize;\r
-  UINTN               RetryTimes;\r
-  UINTN               MaxRetry;\r
-  UINTN               BlockSize;\r
-  UINTN               PackageNum;\r
 \r
   UsbIo           = UsbBotDev->UsbIo;\r
-  Remain          = *DataSize;\r
   BufferPtr       = (UINT8 *) DataBuffer;\r
-  TransferredSize = 0;\r
-  MaxRetry        = 10;\r
-  PackageNum      = 128;\r
 \r
   //\r
   // retrieve the the max packet length of the given endpoint\r
   //\r
   if (Direction == EfiUsbDataIn) {\r
-    MaxPacketLen  = (UsbBotDev->BulkInEndpointDescriptor)->MaxPacketSize;\r
-    EndpointAddr  = (UsbBotDev->BulkInEndpointDescriptor)->EndpointAddress;\r
+    EndpointAddr  = UsbBotDev->BulkInEndpointDescriptor->EndpointAddress;\r
   } else {\r
-    MaxPacketLen  = (UsbBotDev->BulkOutEndpointDescriptor)->MaxPacketSize;\r
-    EndpointAddr  = (UsbBotDev->BulkOutEndpointDescriptor)->EndpointAddress;\r
+    EndpointAddr  = UsbBotDev->BulkOutEndpointDescriptor->EndpointAddress;\r
   }\r
 \r
-  RetryTimes  = MaxRetry;\r
-  BlockSize   = PackageNum * MaxPacketLen;\r
-  while (Remain > 0) {\r
-    //\r
-    // Using 15 packets to aVOID Bitstuff error\r
-    //\r
-    if (Remain > PackageNum * MaxPacketLen) {\r
-      Increment = BlockSize;\r
-    } else {\r
-      Increment = Remain;\r
-    }\r
-\r
     Status = UsbIo->UsbBulkTransfer (\r
                       UsbIo,\r
                       EndpointAddr,\r
                       BufferPtr,\r
-                      &Increment,\r
-                      Timeout,\r
+                      DataSize,\r
+                      (UINT16)(Timeout),\r
                       &Result\r
                       );\r
 \r
-    TransferredSize += Increment;\r
-\r
     if (EFI_ERROR (Status)) {\r
-      RetryTimes--;\r
-      if ((RetryTimes == 0) || ((Result & EFI_USB_ERR_TIMEOUT) == 0)) {\r
-        goto ErrorExit;\r
+      if ((Result & EFI_USB_ERR_STALL) == EFI_USB_ERR_STALL) {\r
+        if (Direction == EfiUsbDataIn) {\r
+          DEBUG((gBOTErrorLevel, "BOT: Data IN Stall, ClearBulkInPipe\n"));\r
+          ClearBulkInPipe (UsbBotDev);\r
+        } else {\r
+          DEBUG((gBOTErrorLevel, "BOT: Data OUT Stall, ClearBulkInPipe\n"));\r
+          ClearBulkOutPipe (UsbBotDev);\r
+        }\r
       }\r
+     // BotRecoveryReset (UsbBotDev);\r
+   }\r
 \r
-      TransferredSize -= Increment;\r
-      continue;\r
-    } else {\r
-      //\r
-      // we try MaxTetry times for every bulk transfer\r
-      //\r
-      RetryTimes = MaxRetry;\r
-    }\r
-\r
-    BufferPtr += Increment;\r
-    Remain -= Increment;\r
-    if (Increment < BlockSize && TransferredSize <= *DataSize) {\r
-      //\r
-      // we get to the end of transter and transter size is\r
-      // less than requriedsize\r
-      //\r
-      break;\r
-    }\r
-  }\r
-\r
-  *DataSize = (UINT32) TransferredSize;\r
-\r
-  return EFI_SUCCESS;\r
-\r
-ErrorExit:\r
-  if (Direction == EfiUsbDataIn) {\r
-    BotReportStatusCode (\r
-      UsbBotDev->DevicePath,\r
-      EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
-      (EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_EC_INPUT_ERROR)\r
-      );\r
-  } else {\r
-    BotReportStatusCode (\r
-      UsbBotDev->DevicePath,\r
-      EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
-      (EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_EC_OUTPUT_ERROR)\r
-      );\r
-  }\r
-\r
-  if ((Result & EFI_USB_ERR_STALL) == EFI_USB_ERR_STALL) {\r
-    //\r
-    // just endpoint stall happens\r
-    //\r
-    UsbClearEndpointHalt (\r
-      UsbIo,\r
-      EndpointAddr,\r
-      &Result\r
-      );\r
-  }\r
-\r
-  *DataSize = (UINT32) TransferredSize;\r
 \r
   return Status;\r
-\r
 }\r
 \r
 STATIC\r
 EFI_STATUS\r
 BotStatusPhase (\r
-  IN  USB_BOT_DEVICE        *UsbBotDev,\r
-  OUT UINT8                 *TransferStatus,\r
-  IN  UINT16                Timeout\r
+  IN  USB_BOT_DEVICE          *UsbBotDev,\r
+  OUT UINT32                  *DataResidue,\r
+  IN  UINT16                  Timeout\r
   )\r
 /*++\r
 \r
@@ -822,7 +710,6 @@ BotStatusPhase (
 \r
   Parameters:\r
     UsbBotDev       -  USB_BOT_DEVICE pointer\r
-    TransferStatus  -  TransferStatus\r
     Timeout         -  Time out value in milliseconds\r
   Return Value:\r
     EFI_SUCCESS\r
@@ -832,47 +719,21 @@ BotStatusPhase (
 {\r
   CSW                 csw;\r
   EFI_STATUS          Status;\r
-  UINT32              Result;\r
   EFI_USB_IO_PROTOCOL *UsbIo;\r
   UINT8               EndpointAddr;\r
   UINTN               DataSize;\r
+  UINT32              Result;\r
+  UINT8               Index;\r
 \r
   UsbIo = UsbBotDev->UsbIo;\r
+  EndpointAddr  = UsbBotDev->BulkInEndpointDescriptor->EndpointAddress;\r
 \r
-  ZeroMem (&csw, sizeof (CSW));\r
-\r
-  EndpointAddr  = (UsbBotDev->BulkInEndpointDescriptor)->EndpointAddress;\r
-\r
-  DataSize      = sizeof (CSW);\r
-\r
-  //\r
-  // Get the status field from bulk transfer\r
-  //\r
-  Status = UsbIo->UsbBulkTransfer (\r
-                    UsbIo,\r
-                    EndpointAddr,\r
-                    &csw,\r
-                    &DataSize,\r
-                    Timeout,\r
-                    &Result\r
-                    );\r
-  if (EFI_ERROR (Status)) {\r
-    if ((Result & EFI_USB_ERR_STALL) == EFI_USB_ERR_STALL) {\r
-      //\r
-      // just endpoint stall happens\r
-      //\r
-      UsbClearEndpointHalt (\r
-        UsbIo,\r
-        EndpointAddr,\r
-        &Result\r
-        );\r
-    }\r
 \r
+  for (Index = 0; Index < 3; Index ++) {\r
     ZeroMem (&csw, sizeof (CSW));\r
+    DataSize    = sizeof (CSW);\r
+    Result      = 0;\r
 \r
-    EndpointAddr  = (UsbBotDev->BulkInEndpointDescriptor)->EndpointAddress;\r
-\r
-    DataSize      = sizeof (CSW);\r
     Status = UsbIo->UsbBulkTransfer (\r
                       UsbIo,\r
                       EndpointAddr,\r
@@ -883,25 +744,36 @@ BotStatusPhase (
                       );\r
     if (EFI_ERROR (Status)) {\r
       if ((Result & EFI_USB_ERR_STALL) == EFI_USB_ERR_STALL) {\r
-        UsbClearEndpointHalt (\r
-          UsbIo,\r
-          EndpointAddr,\r
-          &Result\r
-          );\r
+        DEBUG((gBOTDebugLevel, "BOT: CSW Stall, ClearBulkInPipe\n"));\r
+        ClearBulkInPipe (UsbBotDev);\r
+        continue;\r
+      }\r
+    }\r
+\r
+    if (csw.dCSWSignature == CSWSIG) {\r
+      if (csw.bCSWStatus == 0 || csw.bCSWStatus  == 0x01) {\r
+        if (DataResidue != NULL) {\r
+          *DataResidue = csw.dCSWDataResidue;\r
+        }\r
+        if (csw.bCSWStatus  == 0x01) {\r
+          return EFI_DEVICE_ERROR;\r
+        }\r
+        break;\r
+      } else if (csw.bCSWStatus == 0x02) {\r
+        DEBUG((gBOTErrorLevel, "BOT: Bot Phase error\n"));\r
+        BotRecoveryReset (UsbBotDev);\r
       }\r
 \r
-      return Status;\r
     }\r
   }\r
 \r
-  if (csw.dCSWSignature == CSWSIG) {\r
-    *TransferStatus = csw.bCSWStatus;\r
-  } else {\r
+  if (Index == 3) {\r
     return EFI_DEVICE_ERROR;\r
   }\r
 \r
   return EFI_SUCCESS;\r
 }\r
+\r
 //\r
 // Usb Atapi Protocol implementation\r
 //\r
@@ -938,81 +810,82 @@ BotAtapiCommand (
 {\r
   EFI_STATUS      Status;\r
   EFI_STATUS      BotDataStatus;\r
-  UINT8           TransferStatus;\r
   USB_BOT_DEVICE  *UsbBotDev;\r
-  UINT32          BufferSize;\r
-\r
-  BotDataStatus = EFI_SUCCESS;\r
-  TransferStatus = 0;\r
+  UINTN           BufferSize;\r
+  UINT8           Index;\r
+  UINT32          DataResidue;\r
 \r
   //\r
   // Get the context\r
   //\r
-  UsbBotDev = USB_BOT_DEVICE_FROM_THIS (This);\r
+  UsbBotDev     = USB_BOT_DEVICE_FROM_THIS (This);\r
+  BotDataStatus = EFI_SUCCESS;\r
+  BufferSize    = 0;\r
 \r
-  //\r
-  // First send ATAPI command through Bot\r
-  //\r
-  Status = BotCommandPhase (\r
-            UsbBotDev,\r
-            Command,\r
-            CommandSize,\r
-            BufferLength,\r
-            Direction,\r
-            TimeOutInMilliSeconds\r
-            );\r
+  for (Index = 0; Index < 3; Index ++) {\r
+    //\r
+    // First send ATAPI command through Bot\r
+    //\r
+    Status = BotCommandPhase (\r
+              UsbBotDev,\r
+              Command,\r
+              CommandSize,\r
+              BufferLength,\r
+              Direction,\r
+              10 * 1000\r
+              );\r
 \r
-  if (EFI_ERROR (Status)) {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-  //\r
-  // Send/Get Data if there is a Data Stage\r
-  //\r
-  switch (Direction) {\r
-\r
-  case EfiUsbDataIn:\r
-  case EfiUsbDataOut:\r
-    BufferSize = BufferLength;\r
-\r
-    BotDataStatus = BotDataPhase (\r
-                      UsbBotDev,\r
-                      &BufferSize,\r
-                      DataBuffer,\r
-                      Direction,\r
-                      (UINT16) (TimeOutInMilliSeconds)\r
-                      );\r
+    if (EFI_ERROR (Status)) {\r
+       DEBUG((gBOTErrorLevel, "BotCommandPhase Fail\n"));\r
+       return Status;\r
+    }\r
+    //\r
+    // Send/Get Data if there is a Data Stage\r
+    //\r
+    switch (Direction) {\r
 \r
-    break;\r
+    case EfiUsbDataIn:\r
+    case EfiUsbDataOut:\r
+      BufferSize = BufferLength;\r
 \r
-  case EfiUsbNoData:\r
-    break;\r
-  }\r
-  \r
-  //\r
-  // Status Phase\r
-  //\r
-  Status = BotStatusPhase (\r
-            UsbBotDev,\r
-            &TransferStatus,\r
-            TimeOutInMilliSeconds\r
-            );\r
+      BotDataStatus = BotDataPhase (\r
+                        UsbBotDev,\r
+                        &BufferSize,\r
+                        DataBuffer,\r
+                        Direction,\r
+                        (UINT16) (TimeOutInMilliSeconds)\r
+                        );\r
 \r
-  if (EFI_ERROR (Status)) {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
 \r
-  if (TransferStatus == 0x02) {\r
+      if (EFI_ERROR (BotDataStatus)) {\r
+        DEBUG((gBOTErrorLevel, "BotDataPhase Fail\n"));\r
+      }\r
+      break;\r
+\r
+    case EfiUsbNoData:\r
+      break;\r
+   }\r
+\r
+    DataResidue = 0;\r
     //\r
-    // Phase error\r
+    // Status Phase\r
     //\r
-    BotRecoveryReset (UsbBotDev);\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
+    Status = BotStatusPhase (\r
+              UsbBotDev,\r
+              &DataResidue,\r
+              10 * 1000\r
+              );\r
 \r
-  if (TransferStatus == 0x01) {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
+    if (EFI_ERROR (Status)) {\r
+      DEBUG((gBOTErrorLevel, "BotStatusPhase Fail\n"));\r
+      return Status;\r
+    }\r
 \r
+    if (!EFI_ERROR (BotDataStatus)) {\r
+      break;\r
+    }\r
+\r
+  }\r
   return BotDataStatus;\r
 }\r
 \r
@@ -1059,6 +932,7 @@ BotMassStorageReset (
   return Status;\r
 }\r
 \r
+STATIC\r
 VOID\r
 BotReportStatusCode (\r
   IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath,\r