]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBus.c
MdeModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdeModulePkg / Bus / Scsi / ScsiBusDxe / ScsiBus.c
index d09d76a279c983a0fb217b4d453ad757bc380728..c4069aec0f1335850601f9c66f6149f23eae07d8 100644 (file)
@@ -2,39 +2,15 @@
   SCSI Bus driver that layers on every SCSI Pass Thru and\r
   Extended SCSI Pass Thru protocol in the system.\r
 \r
-Copyright (c) 2006 - 2008, Intel Corporation. <BR>\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 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
 \r
-#include <Uefi.h>\r
-\r
-\r
-#include <Protocol/ScsiPassThru.h>\r
-#include <Protocol/ScsiPassThruExt.h>\r
-#include <Protocol/ScsiIo.h>\r
-#include <Protocol/ComponentName.h>\r
-#include <Protocol/DriverBinding.h>\r
-#include <Protocol/DevicePath.h>\r
-\r
-#include <Library/DebugLib.h>\r
-#include <Library/UefiDriverEntryPoint.h>\r
-#include <Library/UefiLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/MemoryAllocationLib.h>\r
-#include <Library/ScsiLib.h>\r
-#include <Library/UefiBootServicesTableLib.h>\r
-#include <Library/DevicePathLib.h>\r
-\r
 #include "ScsiBus.h"\r
 \r
+\r
 EFI_DRIVER_BINDING_PROTOCOL gSCSIBusDriverBinding = {\r
   SCSIBusDriverBindingSupported,\r
   SCSIBusDriverBindingStart,\r
@@ -44,51 +20,102 @@ EFI_DRIVER_BINDING_PROTOCOL gSCSIBusDriverBinding = {
   NULL\r
 };\r
 \r
+VOID  *mWorkingBuffer;\r
 \r
-//\r
-// The ScsiBusProtocol is just used to locate ScsiBusDev\r
-// structure in the SCSIBusDriverBindingStop(). Then we can\r
-// Close all opened protocols and release this structure.\r
-//\r
-STATIC EFI_GUID  mScsiBusProtocolGuid = EFI_SCSI_BUS_PROTOCOL_GUID;\r
+/**\r
+  Convert EFI_SCSI_IO_SCSI_REQUEST_PACKET packet to EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET packet.\r
 \r
-STATIC VOID  *WorkingBuffer;\r
+  @param  Packet         The pointer of EFI_SCSI_IO_SCSI_REQUEST_PACKET\r
+  @param  CommandPacket  The pointer of EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET\r
 \r
-STATIC\r
+**/\r
 EFI_STATUS\r
 EFIAPI\r
 ScsiioToPassThruPacket (\r
   IN      EFI_SCSI_IO_SCSI_REQUEST_PACKET         *Packet,\r
-  IN OUT  EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET  *CommandPacket\r
-  )\r
-;\r
+  OUT     EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET  *CommandPacket\r
+  );\r
+\r
+/**\r
+  Convert EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET packet to EFI_SCSI_IO_SCSI_REQUEST_PACKET packet.\r
 \r
+  @param  ScsiPacket  The pointer of EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET\r
+  @param  Packet      The pointer of EFI_SCSI_IO_SCSI_REQUEST_PACKET\r
 \r
-STATIC\r
+**/\r
 EFI_STATUS\r
 EFIAPI\r
 PassThruToScsiioPacket (\r
   IN     EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET  *ScsiPacket,\r
-  IN OUT EFI_SCSI_IO_SCSI_REQUEST_PACKET         *Packet\r
-  )\r
-;\r
-STATIC\r
+  OUT    EFI_SCSI_IO_SCSI_REQUEST_PACKET         *Packet\r
+  );\r
+\r
+/**\r
+  Notify Function in which convert EFI1.0 PassThru Packet back to UEF2.0\r
+  SCSI IO Packet.\r
+\r
+  @param  Event    The instance of EFI_EVENT.\r
+  @param  Context  The parameter passed in.\r
+\r
+**/\r
 VOID\r
 EFIAPI\r
 NotifyFunction (\r
-  EFI_EVENT  Event,\r
-  VOID       *Context\r
+  IN  EFI_EVENT  Event,\r
+  IN  VOID       *Context\r
+  );\r
+\r
+/**\r
+  Allocates an aligned buffer for SCSI device.\r
+\r
+  This function allocates an aligned buffer for the SCSI device to perform\r
+  SCSI pass through operations. The alignment requirement is from SCSI pass\r
+  through interface.\r
+\r
+  @param  ScsiIoDevice      The SCSI child device involved for the operation.\r
+  @param  BufferSize        The request buffer size.\r
+\r
+  @return A pointer to the aligned buffer or NULL if the allocation fails.\r
+\r
+**/\r
+VOID *\r
+AllocateAlignedBuffer (\r
+  IN SCSI_IO_DEV              *ScsiIoDevice,\r
+  IN UINTN                    BufferSize\r
   )\r
-;\r
+{\r
+  return AllocateAlignedPages (EFI_SIZE_TO_PAGES (BufferSize), ScsiIoDevice->ScsiIo.IoAlign);\r
+}\r
+\r
+/**\r
+  Frees an aligned buffer for SCSI device.\r
+\r
+  This function frees an aligned buffer for the SCSI device to perform\r
+  SCSI pass through operations.\r
+\r
+  @param  Buffer            The aligned buffer to be freed.\r
+  @param  BufferSize        The request buffer size.\r
+\r
+**/\r
+VOID\r
+FreeAlignedBuffer (\r
+  IN VOID                     *Buffer,\r
+  IN UINTN                    BufferSize\r
+  )\r
+{\r
+  if (Buffer != NULL) {\r
+    FreeAlignedPages (Buffer, EFI_SIZE_TO_PAGES (BufferSize));\r
+  }\r
+}\r
 \r
 /**\r
   The user Entry Point for module ScsiBus. The user code starts with this function.\r
 \r
-  @param[in] ImageHandle    The firmware allocated handle for the EFI image.\r
-  @param[in] SystemTable    A pointer to the EFI System Table.\r
+  @param  ImageHandle    The firmware allocated handle for the EFI image.\r
+  @param  SystemTable    A pointer to the EFI System Table.\r
 \r
-  @retval EFI_SUCCESS       The entry point is executed successfully.\r
-  @retval other             Some error occurs when executing this entry point.\r
+  @retval EFI_SUCCESS    The entry point is executed successfully.\r
+  @retval other          Some error occurs when executing this entry point.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -116,6 +143,26 @@ InitializeScsiBus(
   return Status;\r
 }\r
 \r
+\r
+/**\r
+  Test to see if this driver supports ControllerHandle.\r
+\r
+  This service is called by the EFI boot service ConnectController(). In order\r
+  to make drivers as small as possible, there are a few calling restrictions for\r
+  this service. ConnectController() must follow these calling restrictions. If\r
+  any other agent wishes to call Supported() it must also follow these calling\r
+  restrictions.\r
+\r
+  @param  This                Protocol instance pointer.\r
+  @param  ControllerHandle    Handle of device to test\r
+  @param  RemainingDevicePath Optional parameter use to pick a specific child\r
+                              device to start.\r
+\r
+  @retval EFI_SUCCESS         This driver supports this device\r
+  @retval EFI_ALREADY_STARTED This driver is already running on this device\r
+  @retval other               This driver does not support this device\r
+\r
+**/\r
 EFI_STATUS\r
 EFIAPI\r
 SCSIBusDriverBindingSupported (\r
@@ -123,32 +170,21 @@ SCSIBusDriverBindingSupported (
   IN EFI_HANDLE                   Controller,\r
   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath\r
   )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Test to see if this driver supports ControllerHandle. Any ControllerHandle\r
-  that has ExtScsiPassThruProtocol/ScsiPassThruProtocol installed will be supported.\r
-\r
-Arguments:\r
-\r
-  This                - Protocol instance pointer.\r
-  Controller          - Handle of device to test\r
-  RemainingDevicePath - Not used\r
-\r
-Returns:\r
-\r
-  EFI_SUCCESS         - This driver supports this device.\r
-  EFI_UNSUPPORTED     - This driver does not support this device.\r
-\r
---*/\r
-\r
 {\r
-  EFI_STATUS  Status;\r
-  EFI_SCSI_PASS_THRU_PROTOCOL *PassThru;\r
+  EFI_STATUS                      Status;\r
+  EFI_SCSI_PASS_THRU_PROTOCOL     *PassThru;\r
   EFI_EXT_SCSI_PASS_THRU_PROTOCOL *ExtPassThru;\r
+  UINT64                          Lun;\r
+  UINT8                           *TargetId;\r
+  SCSI_TARGET_ID                  ScsiTargetId;\r
+\r
+  TargetId = &ScsiTargetId.ScsiId.ExtScsi[0];\r
+  SetMem (TargetId, TARGET_MAX_BYTES, 0xFF);\r
+\r
   //\r
-  // Check for the existence of Extended SCSI Pass Thru Protocol and SCSI Pass Thru Protocol\r
+  // To keep backward compatibility, UEFI ExtPassThru Protocol is supported as well as\r
+  // EFI PassThru Protocol. From priority perspective, ExtPassThru Protocol is firstly\r
+  // tried to open on host controller handle. If fails, then PassThru Protocol is tried instead.\r
   //\r
   Status = gBS->OpenProtocol (\r
                   Controller,\r
@@ -161,45 +197,100 @@ Returns:
 \r
   if (Status == EFI_ALREADY_STARTED) {\r
     return EFI_SUCCESS;\r
-  }\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    Status = gBS->OpenProtocol (\r
-                    Controller,\r
-                    &gEfiScsiPassThruProtocolGuid,\r
-                    (VOID **)&PassThru,\r
-                    This->DriverBindingHandle,\r
-                    Controller,\r
-                    EFI_OPEN_PROTOCOL_BY_DRIVER\r
-                    );\r
-\r
-    if (Status == EFI_ALREADY_STARTED) {\r
+  } else if (!EFI_ERROR(Status)) {\r
+    //\r
+    // Check if RemainingDevicePath is NULL or the End of Device Path Node,\r
+    // if yes, return EFI_SUCCESS.\r
+    //\r
+    if ((RemainingDevicePath == NULL) || IsDevicePathEnd (RemainingDevicePath)) {\r
+      //\r
+      // Close protocol regardless of RemainingDevicePath validation\r
+      //\r
+      gBS->CloseProtocol (\r
+             Controller,\r
+             &gEfiExtScsiPassThruProtocolGuid,\r
+             This->DriverBindingHandle,\r
+             Controller\r
+             );\r
       return EFI_SUCCESS;\r
+    } else {\r
+      //\r
+      // If RemainingDevicePath isn't the End of Device Path Node, check its validation\r
+      //\r
+      Status = ExtPassThru->GetTargetLun (ExtPassThru, RemainingDevicePath, &TargetId, &Lun);\r
+      //\r
+      // Close protocol regardless of RemainingDevicePath validation\r
+      //\r
+      gBS->CloseProtocol (\r
+             Controller,\r
+             &gEfiExtScsiPassThruProtocolGuid,\r
+             This->DriverBindingHandle,\r
+             Controller\r
+             );\r
+      if (!EFI_ERROR(Status)) {\r
+        return EFI_SUCCESS;\r
+      }\r
     }\r
+  }\r
 \r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    }\r
+  //\r
+  // Come here in 2 condition:\r
+  // 1. ExtPassThru doesn't exist.\r
+  // 2. ExtPassThru exists but RemainingDevicePath is invalid.\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                  Controller,\r
+                  &gEfiScsiPassThruProtocolGuid,\r
+                  (VOID **)&PassThru,\r
+                  This->DriverBindingHandle,\r
+                  Controller,\r
+                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
+                  );\r
 \r
-    gBS->CloseProtocol (\r
-      Controller,\r
-      &gEfiScsiPassThruProtocolGuid,\r
-      This->DriverBindingHandle,\r
-      Controller\r
-      );\r
+  if (Status == EFI_ALREADY_STARTED) {\r
     return EFI_SUCCESS;\r
   }\r
 \r
-  gBS->CloseProtocol (\r
-    Controller,\r
-    &gEfiExtScsiPassThruProtocolGuid,\r
-    This->DriverBindingHandle,\r
-    Controller\r
-    );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
 \r
-  return EFI_SUCCESS;\r
+  //\r
+  // Test RemainingDevicePath is valid or not.\r
+  //\r
+  if ((RemainingDevicePath != NULL) && !IsDevicePathEnd (RemainingDevicePath)) {\r
+    Status = PassThru->GetTargetLun (PassThru, RemainingDevicePath, &ScsiTargetId.ScsiId.Scsi, &Lun);\r
+  }\r
+\r
+  gBS->CloseProtocol (\r
+         Controller,\r
+         &gEfiScsiPassThruProtocolGuid,\r
+         This->DriverBindingHandle,\r
+         Controller\r
+         );\r
+  return Status;\r
 }\r
 \r
+\r
+/**\r
+  Start this driver on ControllerHandle.\r
+\r
+  This service is called by the EFI boot service ConnectController(). In order\r
+  to make drivers as small as possible, there are a few calling restrictions for\r
+  this service. ConnectController() must follow these calling restrictions. If\r
+  any other agent wishes to call Start() it must also follow these calling\r
+  restrictions.\r
+\r
+  @param  This                 Protocol instance pointer.\r
+  @param  ControllerHandle     Handle of device to bind driver to\r
+  @param  RemainingDevicePath  Optional parameter use to pick a specific child\r
+                               device to start.\r
+\r
+  @retval EFI_SUCCESS          This driver is added to ControllerHandle\r
+  @retval EFI_ALREADY_STARTED  This driver is already running on ControllerHandle\r
+  @retval other                This driver does not support this device\r
+\r
+**/\r
 EFI_STATUS\r
 EFIAPI\r
 SCSIBusDriverBindingStart (\r
@@ -207,22 +298,6 @@ SCSIBusDriverBindingStart (
   IN EFI_HANDLE                   Controller,\r
   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath\r
   )\r
-/*++\r
-\r
-Routine Description:\r
-  Starting the SCSI Bus Driver\r
-\r
-Arguments:\r
-  This                - Protocol instance pointer.\r
-  Controller          - Handle of device to test\r
-  RemainingDevicePath - Not used\r
-\r
-Returns:\r
-  EFI_SUCCESS         - This driver supports this device.\r
-  EFI_UNSUPPORTED     - This driver does not support this device.\r
-  EFI_DEVICE_ERROR    - This driver cannot be started due to device Error\r
-\r
---*/\r
 {\r
   UINT64                                Lun;\r
   UINT8                                 *TargetId;\r
@@ -233,26 +308,21 @@ Returns:
   EFI_STATUS                            DevicePathStatus;\r
   EFI_STATUS                            PassThruStatus;\r
   SCSI_BUS_DEVICE                       *ScsiBusDev;\r
-  SCSI_TARGET_ID                        *ScsiTargetId;\r
+  SCSI_TARGET_ID                        ScsiTargetId;\r
   EFI_DEVICE_PATH_PROTOCOL              *ParentDevicePath;\r
   EFI_SCSI_PASS_THRU_PROTOCOL           *ScsiInterface;\r
   EFI_EXT_SCSI_PASS_THRU_PROTOCOL       *ExtScsiInterface;\r
   EFI_SCSI_BUS_PROTOCOL                 *BusIdentify;\r
 \r
   TargetId        = NULL;\r
-  ScsiTargetId    = NULL;\r
   ScanOtherPuns   = TRUE;\r
   FromFirstTarget = FALSE;\r
   ExtScsiSupport  = FALSE;\r
   PassThruStatus  = EFI_SUCCESS;\r
-    \r
-  ScsiTargetId = AllocateZeroPool(sizeof(SCSI_TARGET_ID));\r
-  if (ScsiTargetId == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
 \r
-  TargetId = &ScsiTargetId->ScsiId.ExtScsi[0];\r
-  \r
+  TargetId = &ScsiTargetId.ScsiId.ExtScsi[0];\r
+  SetMem (TargetId, TARGET_MAX_BYTES, 0xFF);\r
+\r
   DevicePathStatus = gBS->OpenProtocol (\r
                             Controller,\r
                             &gEfiDevicePathProtocolGuid,\r
@@ -266,7 +336,16 @@ Returns:
   }\r
 \r
   //\r
-  // To keep backward compatibility, UEFI ExtPassThru Protocol is supported as well as \r
+  // Report Status Code to indicate SCSI bus starts\r
+  //\r
+  REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+    EFI_PROGRESS_CODE,\r
+    (EFI_IO_BUS_SCSI | EFI_IOB_PC_INIT),\r
+    ParentDevicePath\r
+    );\r
+\r
+  //\r
+  // To keep backward compatibility, UEFI ExtPassThru Protocol is supported as well as\r
   // EFI PassThru Protocol. From priority perspective, ExtPassThru Protocol is firstly\r
   // tried to open on host controller handle. If fails, then PassThru Protocol is tried instead.\r
   //\r
@@ -301,13 +380,13 @@ Returns:
                This->DriverBindingHandle,\r
                Controller\r
                );\r
-      } \r
+      }\r
       return Status;\r
-    } \r
+    }\r
   } else {\r
     //\r
-    // Succeed to open ExtPassThru Protocol, and meanwhile open PassThru Protocol \r
-    // with BY_DRIVER if it is also present on the handle. The intent is to prevent \r
+    // Succeed to open ExtPassThru Protocol, and meanwhile open PassThru Protocol\r
+    // with BY_DRIVER if it is also present on the handle. The intent is to prevent\r
     // another SCSI Bus Driver to work on the same host handle.\r
     //\r
     ExtScsiSupport = TRUE;\r
@@ -320,7 +399,7 @@ Returns:
                             EFI_OPEN_PROTOCOL_BY_DRIVER\r
                             );\r
   }\r
-    \r
+\r
   if (Status != EFI_ALREADY_STARTED) {\r
     //\r
     // Go through here means either ExtPassThru or PassThru Protocol is successfully opened\r
@@ -338,17 +417,17 @@ Returns:
     if (ScsiBusDev->ExtScsiSupport) {\r
       ScsiBusDev->ExtScsiInterface = ExtScsiInterface;\r
     } else {\r
-      ScsiBusDev->ScsiInterface    = ScsiInterface;    \r
+      ScsiBusDev->ScsiInterface    = ScsiInterface;\r
     }\r
 \r
     //\r
     // Install EFI_SCSI_BUS_PROTOCOL to the controller handle, So ScsiBusDev could be\r
     // retrieved on this controller handle. With ScsiBusDev, we can know which PassThru\r
     // Protocol is present on the handle, UEFI ExtPassThru Protocol or EFI PassThru Protocol.\r
-    // \r
+    //\r
     Status = gBS->InstallProtocolInterface (\r
                     &Controller,\r
-                    &mScsiBusProtocolGuid,\r
+                    &gEfiCallerIdGuid,\r
                     EFI_NATIVE_INTERFACE,\r
                     &ScsiBusDev->BusIdentify\r
                     );\r
@@ -362,7 +441,7 @@ Returns:
     //\r
     Status = gBS->OpenProtocol (\r
                     Controller,\r
-                    &mScsiBusProtocolGuid,\r
+                    &gEfiCallerIdGuid,\r
                     (VOID **) &BusIdentify,\r
                     This->DriverBindingHandle,\r
                     Controller,\r
@@ -375,16 +454,42 @@ Returns:
     ScsiBusDev = SCSI_BUS_CONTROLLER_DEVICE_FROM_THIS (BusIdentify);\r
   }\r
 \r
+  //\r
+  // Report Status Code to indicate detecting devices on bus\r
+  //\r
+  REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+    EFI_PROGRESS_CODE,\r
+    (EFI_IO_BUS_SCSI | EFI_IOB_PC_DETECT),\r
+    ParentDevicePath\r
+    );\r
+\r
+  Lun  = 0;\r
   if (RemainingDevicePath == NULL) {\r
-    SetMem (ScsiTargetId, TARGET_MAX_BYTES,0xFF);\r
-    Lun  = 0;\r
+    //\r
+    // If RemainingDevicePath is NULL,\r
+    // must enumerate all SCSI devices anyway\r
+    //\r
     FromFirstTarget = TRUE;\r
-  } else {\r
+  } else if (!IsDevicePathEnd (RemainingDevicePath)) {\r
+    //\r
+    // If RemainingDevicePath isn't the End of Device Path Node,\r
+    // only scan the specified device by RemainingDevicePath\r
+    //\r
     if (ScsiBusDev->ExtScsiSupport) {\r
-      ScsiBusDev->ExtScsiInterface->GetTargetLun (ScsiBusDev->ExtScsiInterface, RemainingDevicePath, &TargetId, &Lun);  \r
+      Status = ScsiBusDev->ExtScsiInterface->GetTargetLun (ScsiBusDev->ExtScsiInterface, RemainingDevicePath, &TargetId, &Lun);\r
     } else {\r
-      ScsiBusDev->ScsiInterface->GetTargetLun (ScsiBusDev->ScsiInterface, RemainingDevicePath, &ScsiTargetId->ScsiId.Scsi, &Lun);\r
+      Status = ScsiBusDev->ScsiInterface->GetTargetLun (ScsiBusDev->ScsiInterface, RemainingDevicePath, &ScsiTargetId.ScsiId.Scsi, &Lun);\r
+    }\r
+\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
     }\r
+  } else {\r
+    //\r
+    // If RemainingDevicePath is the End of Device Path Node,\r
+    // skip enumerate any device and return EFI_SUCESSS\r
+    //\r
+    ScanOtherPuns = FALSE;\r
   }\r
 \r
   while(ScanOtherPuns) {\r
@@ -396,7 +501,7 @@ Returns:
       if (ScsiBusDev->ExtScsiSupport) {\r
         Status = ScsiBusDev->ExtScsiInterface->GetNextTargetLun (ScsiBusDev->ExtScsiInterface, &TargetId, &Lun);\r
       } else {\r
-        Status = ScsiBusDev->ScsiInterface->GetNextDevice (ScsiBusDev->ScsiInterface, &ScsiTargetId->ScsiId.Scsi, &Lun);\r
+        Status = ScsiBusDev->ScsiInterface->GetNextDevice (ScsiBusDev->ScsiInterface, &ScsiTargetId.ScsiId.Scsi, &Lun);\r
       }\r
       if (EFI_ERROR (Status)) {\r
         //\r
@@ -411,11 +516,11 @@ Returns:
     // Avoid creating handle for the host adapter.\r
     //\r
     if (ScsiBusDev->ExtScsiSupport) {\r
-      if ((ScsiTargetId->ScsiId.Scsi) == ScsiBusDev->ExtScsiInterface->Mode->AdapterId) {\r
+      if ((ScsiTargetId.ScsiId.Scsi) == ScsiBusDev->ExtScsiInterface->Mode->AdapterId) {\r
         continue;\r
       }\r
     } else {\r
-      if ((ScsiTargetId->ScsiId.Scsi) == ScsiBusDev->ScsiInterface->Mode->AdapterId) {\r
+      if ((ScsiTargetId.ScsiId.Scsi) == ScsiBusDev->ScsiInterface->Mode->AdapterId) {\r
         continue;\r
       }\r
     }\r
@@ -423,17 +528,16 @@ Returns:
     // Scan for the scsi device, if it attaches to the scsi bus,\r
     // then create handle and install scsi i/o protocol.\r
     //\r
-    Status = ScsiScanCreateDevice (This, Controller, ScsiTargetId, Lun, ScsiBusDev);\r
+    Status = ScsiScanCreateDevice (This, Controller, &ScsiTargetId, Lun, ScsiBusDev);\r
   }\r
-  gBS->FreePool (ScsiTargetId);\r
   return EFI_SUCCESS;\r
-  \r
+\r
 ErrorExit:\r
-  \r
+\r
   if (ScsiBusDev != NULL) {\r
-    gBS->FreePool (ScsiBusDev);\r
+    FreePool (ScsiBusDev);\r
   }\r
-  \r
+\r
   if (ExtScsiSupport) {\r
     gBS->CloseProtocol (\r
            Controller,\r
@@ -460,6 +564,25 @@ ErrorExit:
   return Status;\r
 }\r
 \r
+/**\r
+  Stop this driver on ControllerHandle.\r
+\r
+  This service is called by the EFI boot service DisconnectController().\r
+  In order to make drivers as small as possible, there are a few calling\r
+  restrictions for this service. DisconnectController() must follow these\r
+  calling restrictions. If any other agent wishes to call Stop() it must also\r
+  follow these calling restrictions.\r
+\r
+  @param  This              Protocol instance pointer.\r
+  @param  ControllerHandle  Handle of device to stop driver on\r
+  @param  NumberOfChildren  Number of Handles in ChildHandleBuffer. If number of\r
+                            children is zero stop the entire bus driver.\r
+  @param  ChildHandleBuffer List of Child Handles to Stop.\r
+\r
+  @retval EFI_SUCCESS       This driver is removed ControllerHandle\r
+  @retval other             This driver was not removed from this device\r
+\r
+**/\r
 EFI_STATUS\r
 EFIAPI\r
 SCSIBusDriverBindingStop (\r
@@ -468,25 +591,6 @@ SCSIBusDriverBindingStop (
   IN  UINTN                           NumberOfChildren,\r
   IN  EFI_HANDLE                      *ChildHandleBuffer\r
   )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Stop this driver on ControllerHandle. Support stoping any child handles\r
-  created by this driver.\r
-\r
-Arguments:\r
-\r
-  This              - Protocol instance pointer.\r
-  Controller        - Handle of device to stop driver on\r
-  NumberOfChildren  - Number of Children in the ChildHandleBuffer\r
-  ChildHandleBuffer - List of handles for the children we need to stop.\r
-\r
-Returns:\r
-\r
-  EFI_SUCCESS\r
-  Others\r
---*/\r
 {\r
   EFI_STATUS                  Status;\r
   BOOLEAN                     AllChildrenStopped;\r
@@ -503,7 +607,7 @@ Returns:
     //\r
     Status = gBS->OpenProtocol (\r
                     Controller,\r
-                    &mScsiBusProtocolGuid,\r
+                    &gEfiCallerIdGuid,\r
                     (VOID **) &Scsidentifier,\r
                     This->DriverBindingHandle,\r
                     Controller,\r
@@ -521,7 +625,7 @@ Returns:
     //\r
     gBS->UninstallProtocolInterface (\r
            Controller,\r
-           &mScsiBusProtocolGuid,\r
+           &gEfiCallerIdGuid,\r
            &ScsiBusDev->BusIdentify\r
            );\r
 \r
@@ -529,12 +633,26 @@ Returns:
     // Close the bus driver\r
     //\r
     if (ScsiBusDev->ExtScsiSupport) {\r
+      //\r
+      // Close ExtPassThru Protocol from this controller handle\r
+      //\r
       gBS->CloseProtocol (\r
              Controller,\r
              &gEfiExtScsiPassThruProtocolGuid,\r
              This->DriverBindingHandle,\r
              Controller\r
              );\r
+      //\r
+      // When Start() succeeds to open ExtPassThru, it always tries to open PassThru BY_DRIVER.\r
+      // Its intent is to prevent another SCSI Bus Driver from woking on the same host handle.\r
+      // So Stop() needs to try to close PassThru if present here.\r
+      //\r
+      gBS->CloseProtocol (\r
+             Controller,\r
+             &gEfiScsiPassThruProtocolGuid,\r
+             This->DriverBindingHandle,\r
+             Controller\r
+             );\r
     } else {\r
       gBS->CloseProtocol (\r
              Controller,\r
@@ -550,7 +668,7 @@ Returns:
            This->DriverBindingHandle,\r
            Controller\r
            );\r
-    gBS->FreePool (ScsiBusDev);\r
+    FreePool (ScsiBusDev);\r
     return EFI_SUCCESS;\r
   }\r
 \r
@@ -622,7 +740,7 @@ Returns:
                );\r
       }\r
     } else {\r
-      gBS->FreePool (ScsiIoDevice);\r
+      FreePool (ScsiIoDevice);\r
     }\r
   }\r
 \r
@@ -633,30 +751,24 @@ Returns:
   return EFI_SUCCESS;\r
 }\r
 \r
+\r
+/**\r
+  Retrieves the device type information of the SCSI Controller.\r
+\r
+  @param  This          Protocol instance pointer.\r
+  @param  DeviceType    A pointer to the device type information retrieved from\r
+                        the SCSI Controller.\r
+\r
+  @retval EFI_SUCCESS             Retrieves the device type information successfully.\r
+  @retval EFI_INVALID_PARAMETER   The DeviceType is NULL.\r
+\r
+**/\r
 EFI_STATUS\r
 EFIAPI\r
 ScsiGetDeviceType (\r
   IN  EFI_SCSI_IO_PROTOCOL     *This,\r
   OUT UINT8                    *DeviceType\r
   )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Retrieves the device type information of the SCSI Controller.\r
-    \r
-Arguments:\r
-\r
-  This                  - Protocol instance pointer.\r
-  DeviceType            - A pointer to the device type information\r
-                            retrieved from the SCSI Controller. \r
-\r
-Returns:\r
-\r
-  EFI_SUCCESS           - Retrieves the device type information successfully.\r
-  EFI_INVALID_PARAMETER - The DeviceType is NULL.\r
-  \r
---*/\r
 {\r
   SCSI_IO_DEV *ScsiIoDevice;\r
 \r
@@ -669,6 +781,20 @@ Returns:
   return EFI_SUCCESS;\r
 }\r
 \r
+\r
+/**\r
+  Retrieves the device location in the SCSI channel.\r
+\r
+  @param  This   Protocol instance pointer.\r
+  @param  Target A pointer to the Target ID of a SCSI device\r
+                 on the SCSI channel.\r
+  @param  Lun    A pointer to the LUN of the SCSI device on\r
+                 the SCSI channel.\r
+\r
+  @retval EFI_SUCCESS           Retrieves the device location successfully.\r
+  @retval EFI_INVALID_PARAMETER The Target or Lun is NULL.\r
+\r
+**/\r
 EFI_STATUS\r
 EFIAPI\r
 ScsiGetDeviceLocation (\r
@@ -676,26 +802,6 @@ ScsiGetDeviceLocation (
   IN OUT UINT8                **Target,\r
   OUT UINT64                  *Lun\r
   )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Retrieves the device location in the SCSI channel.\r
-    \r
-Arguments:\r
-\r
-  This                  - Protocol instance pointer.\r
-  Target                - A pointer to the Target Array which represents ID of a SCSI device \r
-                          on the SCSI channel. \r
-  Lun                   - A pointer to the LUN of the SCSI device on \r
-                          the SCSI channel.\r
-\r
-Returns:\r
-\r
-  EFI_SUCCESS           - Retrieves the device location successfully.\r
-  EFI_INVALID_PARAMETER - The Target or Lun is NULL.\r
-\r
---*/\r
 {\r
   SCSI_IO_DEV *ScsiIoDevice;\r
 \r
@@ -712,35 +818,37 @@ Returns:
   return EFI_SUCCESS;\r
 }\r
 \r
+/**\r
+  Resets the SCSI Bus that the SCSI Controller is attached to.\r
+\r
+  @param  This  Protocol instance pointer.\r
+\r
+  @retval  EFI_SUCCESS       The SCSI bus is reset successfully.\r
+  @retval  EFI_DEVICE_ERROR  Errors encountered when resetting the SCSI bus.\r
+  @retval  EFI_UNSUPPORTED   The bus reset operation is not supported by the\r
+                             SCSI Host Controller.\r
+  @retval  EFI_TIMEOUT       A timeout occurred while attempting to reset\r
+                             the SCSI bus.\r
+**/\r
 EFI_STATUS\r
 EFIAPI\r
 ScsiResetBus (\r
   IN  EFI_SCSI_IO_PROTOCOL     *This\r
   )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Resets the SCSI Bus that the SCSI Controller is attached to.\r
-    \r
-Arguments:\r
-\r
-  This                  - Protocol instance pointer.\r
-\r
-Returns:\r
-\r
-  EFI_SUCCESS           - The SCSI bus is reset successfully.\r
-  EFI_DEVICE_ERROR      - Errors encountered when resetting the SCSI bus.\r
-  EFI_UNSUPPORTED       - The bus reset operation is not supported by the\r
-                          SCSI Host Controller.\r
-  EFI_TIMEOUT           - A timeout occurred while attempting to reset \r
-                          the SCSI bus.\r
---*/\r
 {\r
   SCSI_IO_DEV *ScsiIoDevice;\r
 \r
   ScsiIoDevice = SCSI_IO_DEV_FROM_THIS (This);\r
 \r
+  //\r
+  // Report Status Code to indicate reset happens\r
+  //\r
+  REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+    EFI_PROGRESS_CODE,\r
+    (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_PC_RESET),\r
+    ScsiIoDevice->ScsiBusDeviceData->DevicePath\r
+    );\r
+\r
   if (ScsiIoDevice->ExtScsiSupport){\r
     return ScsiIoDevice->ExtScsiPassThru->ResetChannel (ScsiIoDevice->ExtScsiPassThru);\r
   } else {\r
@@ -748,36 +856,38 @@ Returns:
   }\r
 }\r
 \r
+\r
+/**\r
+  Resets the SCSI Controller that the device handle specifies.\r
+\r
+  @param  This  Protocol instance pointer.\r
+\r
+  @retval  EFI_SUCCESS       Reset the SCSI controller successfully.\r
+  @retval  EFI_DEVICE_ERROR  Errors are encountered when resetting the SCSI Controller.\r
+  @retval  EFI_UNSUPPORTED   The SCSI bus does not support a device reset operation.\r
+  @retval  EFI_TIMEOUT       A timeout occurred while attempting to reset the\r
+                             SCSI Controller.\r
+**/\r
 EFI_STATUS\r
 EFIAPI\r
 ScsiResetDevice (\r
   IN  EFI_SCSI_IO_PROTOCOL     *This\r
   )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Resets the SCSI Controller that the device handle specifies.\r
-    \r
-Arguments:\r
-\r
-  This                  - Protocol instance pointer.\r
-    \r
-Returns:\r
-\r
-  EFI_SUCCESS           - Reset the SCSI controller successfully.\r
-  EFI_DEVICE_ERROR      - Errors are encountered when resetting the\r
-                          SCSI Controller.\r
-  EFI_UNSUPPORTED       - The SCSI bus does not support a device \r
-                          reset operation.\r
-  EFI_TIMEOUT           - A timeout occurred while attempting to \r
-                          reset the SCSI Controller.\r
---*/\r
 {\r
   SCSI_IO_DEV  *ScsiIoDevice;\r
   UINT8        Target[TARGET_MAX_BYTES];\r
 \r
   ScsiIoDevice = SCSI_IO_DEV_FROM_THIS (This);\r
+\r
+  //\r
+  // Report Status Code to indicate reset happens\r
+  //\r
+  REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+    EFI_PROGRESS_CODE,\r
+    (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_PC_RESET),\r
+    ScsiIoDevice->ScsiBusDeviceData->DevicePath\r
+    );\r
+\r
   CopyMem (Target,&ScsiIoDevice->Pun, TARGET_MAX_BYTES);\r
 \r
 \r
@@ -796,76 +906,71 @@ Returns:
   }\r
 }\r
 \r
-EFI_STATUS\r
-EFIAPI\r
-ScsiExecuteSCSICommand (\r
-  IN  EFI_SCSI_IO_PROTOCOL                         *This,\r
-  IN OUT  EFI_SCSI_IO_SCSI_REQUEST_PACKET          *Packet,\r
-  IN EFI_EVENT                                     Event  OPTIONAL\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
 \r
+/**\r
   Sends a SCSI Request Packet to the SCSI Controller for execution.\r
-    \r
-Arguments:\r
 \r
-  This                  - Protocol instance pointer.\r
-  Packet                - The SCSI request packet to send to the SCSI \r
+  @param  This            Protocol instance pointer.\r
+  @param  CommandPacket   The SCSI request packet to send to the SCSI\r
                           Controller specified by the device handle.\r
-  Event                 - If the SCSI bus where the SCSI device is attached\r
-                          does not support non-blocking I/O, then Event is \r
-                          ignored, and blocking I/O is performed.  \r
+  @param  Event           If the SCSI bus where the SCSI device is attached\r
+                          does not support non-blocking I/O, then Event is\r
+                          ignored, and blocking I/O is performed.\r
                           If Event is NULL, then blocking I/O is performed.\r
-                          If Event is not NULL and non-blocking I/O is \r
+                          If Event is not NULL and non-blocking I/O is\r
                           supported, then non-blocking I/O is performed,\r
                           and Event will be signaled when the SCSI Request\r
                           Packet completes.\r
-Returns:\r
-\r
-  EFI_SUCCESS           - The SCSI Request Packet was sent by the host \r
-                          successfully, and TransferLength bytes were \r
-                          transferred to/from DataBuffer.See \r
-                          HostAdapterStatus, TargetStatus, \r
-                          SenseDataLength, and SenseData in that order\r
-                          for additional status information.\r
-  EFI_BAD_BUFFER_SIZE  - The SCSI Request Packet was executed, \r
-                          but the entire DataBuffer could not be transferred.\r
-                          The actual number of bytes transferred is returned\r
-                          in TransferLength. See HostAdapterStatus, \r
-                          TargetStatus, SenseDataLength, and SenseData in \r
-                          that order for additional status information.\r
-  EFI_NOT_READY         - The SCSI Request Packet could not be sent because \r
-                          there are too many SCSI Command Packets already \r
-                          queued.The caller may retry again later.\r
-  EFI_DEVICE_ERROR      - A device error occurred while attempting to send \r
-                          the SCSI Request Packet. See HostAdapterStatus, \r
-                          TargetStatus, SenseDataLength, and SenseData in \r
-                          that order for additional status information.\r
-  EFI_INVALID_PARAMETER - The contents of CommandPacket are invalid.  \r
-                          The SCSI Request Packet was not sent, so no \r
-                          additional status information is available.\r
-  EFI_UNSUPPORTED       - The command described by the SCSI Request Packet\r
-                          is not supported by the SCSI initiator(i.e., SCSI \r
-                          Host Controller). The SCSI Request Packet was not\r
-                          sent, so no additional status information is \r
-                          available.\r
-  EFI_TIMEOUT           - A timeout occurred while waiting for the SCSI \r
-                          Request Packet to execute. See HostAdapterStatus,\r
-                          TargetStatus, SenseDataLength, and SenseData in \r
-                          that order for additional status information.\r
---*/\r
+\r
+  @retval EFI_SUCCESS         The SCSI Request Packet was sent by the host\r
+                              successfully, and TransferLength bytes were\r
+                              transferred to/from DataBuffer.See\r
+                              HostAdapterStatus, TargetStatus,\r
+                              SenseDataLength, and SenseData in that order\r
+                              for additional status information.\r
+  @retval EFI_BAD_BUFFER_SIZE The SCSI Request Packet was executed,\r
+                              but the entire DataBuffer could not be transferred.\r
+                              The actual number of bytes transferred is returned\r
+                              in TransferLength. See HostAdapterStatus,\r
+                              TargetStatus, SenseDataLength, and SenseData in\r
+                              that order for additional status information.\r
+  @retval EFI_NOT_READY       The SCSI Request Packet could not be sent because\r
+                              there are too many SCSI Command Packets already\r
+                              queued.The caller may retry again later.\r
+  @retval EFI_DEVICE_ERROR    A device error occurred while attempting to send\r
+                              the SCSI Request Packet. See HostAdapterStatus,\r
+                              TargetStatus, SenseDataLength, and SenseData in\r
+                              that order for additional status information.\r
+  @retval EFI_INVALID_PARAMETER  The contents of CommandPacket are invalid.\r
+                                 The SCSI Request Packet was not sent, so no\r
+                                 additional status information is available.\r
+  @retval EFI_UNSUPPORTED     The command described by the SCSI Request Packet\r
+                              is not supported by the SCSI initiator(i.e., SCSI\r
+                              Host Controller). The SCSI Request Packet was not\r
+                              sent, so no additional status information is\r
+                              available.\r
+  @retval EFI_TIMEOUT         A timeout occurred while waiting for the SCSI\r
+                              Request Packet to execute. See HostAdapterStatus,\r
+                              TargetStatus, SenseDataLength, and SenseData in\r
+                              that order for additional status information.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ScsiExecuteSCSICommand (\r
+  IN     EFI_SCSI_IO_PROTOCOL                     *This,\r
+  IN OUT EFI_SCSI_IO_SCSI_REQUEST_PACKET          *Packet,\r
+  IN     EFI_EVENT                                Event  OPTIONAL\r
+  )\r
 {\r
   SCSI_IO_DEV                                 *ScsiIoDevice;\r
   EFI_STATUS                                  Status;\r
   UINT8                                       Target[TARGET_MAX_BYTES];\r
   EFI_EVENT                                   PacketEvent;\r
   EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET  *ExtRequestPacket;\r
-  SCSI_EVENT_DATA                             EventData;                                     \r
+  SCSI_EVENT_DATA                             EventData;\r
 \r
   PacketEvent = NULL;\r
-  \r
+\r
   if (Packet == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
@@ -875,35 +980,53 @@ Returns:
 \r
   if (ScsiIoDevice->ExtScsiSupport) {\r
     ExtRequestPacket = (EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *) Packet;\r
-    Status = ScsiIoDevice->ExtScsiPassThru->PassThru (\r
-                                          ScsiIoDevice->ExtScsiPassThru,\r
-                                          Target,\r
-                                          ScsiIoDevice->Lun,\r
-                                          ExtRequestPacket,\r
-                                          Event\r
-                                          );\r
+\r
+    if (((ScsiIoDevice->ExtScsiPassThru->Mode->Attributes & EFI_SCSI_PASS_THRU_ATTRIBUTES_NONBLOCKIO) != 0) && (Event !=  NULL)) {\r
+      Status = ScsiIoDevice->ExtScsiPassThru->PassThru (\r
+                                                ScsiIoDevice->ExtScsiPassThru,\r
+                                                Target,\r
+                                                ScsiIoDevice->Lun,\r
+                                                ExtRequestPacket,\r
+                                                Event\r
+                                                );\r
+    } else {\r
+      //\r
+      // If there's no event or the SCSI Device doesn't support NON-BLOCKING,\r
+      // let the 'Event' parameter for PassThru() be NULL.\r
+      //\r
+      Status = ScsiIoDevice->ExtScsiPassThru->PassThru (\r
+                                                ScsiIoDevice->ExtScsiPassThru,\r
+                                                Target,\r
+                                                ScsiIoDevice->Lun,\r
+                                                ExtRequestPacket,\r
+                                                NULL\r
+                                                );\r
+      if ((!EFI_ERROR(Status)) && (Event != NULL)) {\r
+        //\r
+        // Signal Event to tell caller to pick up the SCSI IO packet if the\r
+        // PassThru() succeeds.\r
+        //\r
+        gBS->SignalEvent (Event);\r
+      }\r
+    }\r
   } else {\r
 \r
-    Status = gBS->AllocatePool (\r
-                     EfiBootServicesData,\r
-                     sizeof(EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET),\r
-                     (VOID**)&WorkingBuffer\r
-                     );\r
+    mWorkingBuffer = AllocatePool (sizeof(EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET));\r
 \r
-    if (EFI_ERROR (Status)) {\r
+    if (mWorkingBuffer == NULL) {\r
       return EFI_DEVICE_ERROR;\r
     }\r
 \r
     //\r
     // Convert package into EFI1.0, EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET.\r
     //\r
-    Status = ScsiioToPassThruPacket(Packet, (EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET*)WorkingBuffer);\r
+    Status = ScsiioToPassThruPacket(Packet, (EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET*)mWorkingBuffer);\r
     if (EFI_ERROR(Status)) {\r
-      gBS->FreePool(WorkingBuffer);\r
+      FreePool(mWorkingBuffer);\r
       return Status;\r
     }\r
 \r
-    if ((ScsiIoDevice->ScsiPassThru->Mode->Attributes & EFI_SCSI_PASS_THRU_ATTRIBUTES_NONBLOCKIO) && (Event !=  NULL)) {\r
+    if (((ScsiIoDevice->ScsiPassThru->Mode->Attributes & EFI_SCSI_PASS_THRU_ATTRIBUTES_NONBLOCKIO) != 0) && (Event !=  NULL)) {\r
       EventData.Data1 = (VOID*)Packet;\r
       EventData.Data2 = Event;\r
       //\r
@@ -911,13 +1034,13 @@ Returns:
       //\r
       Status = gBS->CreateEvent (\r
                        EVT_NOTIFY_SIGNAL,\r
-                       TPL_CALLBACK,\r
+                       TPL_NOTIFY,\r
                        NotifyFunction,\r
                        &EventData,\r
                        &PacketEvent\r
                        );\r
       if (EFI_ERROR(Status)) {\r
-        gBS->FreePool(WorkingBuffer);\r
+        FreePool(mWorkingBuffer);\r
         return Status;\r
       }\r
 \r
@@ -925,12 +1048,12 @@ Returns:
                                           ScsiIoDevice->ScsiPassThru,\r
                                           ScsiIoDevice->Pun.ScsiId.Scsi,\r
                                           ScsiIoDevice->Lun,\r
-                                          WorkingBuffer,\r
+                                          mWorkingBuffer,\r
                                           PacketEvent\r
                                           );\r
 \r
       if (EFI_ERROR(Status)) {\r
-        gBS->FreePool(WorkingBuffer);\r
+        FreePool(mWorkingBuffer);\r
         gBS->CloseEvent(PacketEvent);\r
         return Status;\r
       }\r
@@ -944,71 +1067,121 @@ Returns:
                                           ScsiIoDevice->ScsiPassThru,\r
                                           ScsiIoDevice->Pun.ScsiId.Scsi,\r
                                           ScsiIoDevice->Lun,\r
-                                          WorkingBuffer,\r
-                                          Event\r
+                                          mWorkingBuffer,\r
+                                          NULL\r
                                           );\r
       if (EFI_ERROR(Status)) {\r
-        gBS->FreePool(WorkingBuffer);\r
+        FreePool(mWorkingBuffer);\r
         return Status;\r
       }\r
 \r
-      PassThruToScsiioPacket((EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET*)WorkingBuffer,Packet);\r
+      PassThruToScsiioPacket((EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET*)mWorkingBuffer,Packet);\r
       //\r
       // After converting EFI1.0 PassThru Packet back to UEFI2.0 SCSI IO Packet,\r
-      // free WorkingBuffer.\r
+      // free mWorkingBuffer.\r
+      //\r
+      FreePool(mWorkingBuffer);\r
+\r
       //\r
-      gBS->FreePool(WorkingBuffer);\r
+      // Signal Event to tell caller to pick up the SCSI IO Packet.\r
+      //\r
+      if (Event != NULL) {\r
+        gBS->SignalEvent (Event);\r
+      }\r
     }\r
   }\r
   return Status;\r
 }\r
 \r
-EFI_STATUS\r
-EFIAPI\r
-ScsiScanCreateDevice (\r
-  EFI_DRIVER_BINDING_PROTOCOL   *This,\r
-  EFI_HANDLE                    Controller,\r
-  SCSI_TARGET_ID                *TargetId,\r
-  UINT64                        Lun,\r
-  SCSI_BUS_DEVICE               *ScsiBusDev\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
 \r
+/**\r
   Scan SCSI Bus to discover the device, and attach ScsiIoProtocol to it.\r
 \r
-Arguments:\r
-\r
-  This              - Protocol instance pointer\r
-  Controller        - Controller handle\r
-  Pun               - The Pun of the SCSI device on the SCSI channel.\r
-  Lun               - The Lun of the SCSI device on the SCSI channel.\r
-  ScsiBusDev        - The pointer of SCSI_BUS_DEVICE\r
-\r
-Returns:\r
+  @param  This           Protocol instance pointer\r
+  @param  Controller     Controller handle\r
+  @param  TargetId       Tartget to be scanned\r
+  @param  Lun            The Lun of the SCSI device on the SCSI channel.\r
+  @param  ScsiBusDev     The pointer of SCSI_BUS_DEVICE\r
 \r
-  EFI_SUCCESS       - Successfully to discover the device and attach ScsiIoProtocol to it.\r
-  EFI_OUT_OF_RESOURCES - Fail to discover the device.\r
+  @retval EFI_SUCCESS           Successfully to discover the device and attach\r
+                                ScsiIoProtocol to it.\r
+  @retval EFI_OUT_OF_RESOURCES  Fail to discover the device.\r
 \r
---*/\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ScsiScanCreateDevice (\r
+  IN     EFI_DRIVER_BINDING_PROTOCOL   *This,\r
+  IN     EFI_HANDLE                    Controller,\r
+  IN     SCSI_TARGET_ID                *TargetId,\r
+  IN     UINT64                        Lun,\r
+  IN OUT SCSI_BUS_DEVICE               *ScsiBusDev\r
+  )\r
 {\r
   EFI_STATUS                Status;\r
   SCSI_IO_DEV               *ScsiIoDevice;\r
   EFI_DEVICE_PATH_PROTOCOL  *ScsiDevicePath;\r
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;\r
+  EFI_DEVICE_PATH_PROTOCOL  *RemainingDevicePath;\r
+  EFI_HANDLE                 DeviceHandle;\r
 \r
-  Status = gBS->AllocatePool (\r
-                  EfiBootServicesData,\r
-                  sizeof (SCSI_IO_DEV),\r
-                  (VOID **) &ScsiIoDevice\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
+  DevicePath          = NULL;\r
+  RemainingDevicePath = NULL;\r
+  ScsiDevicePath      = NULL;\r
+  ScsiIoDevice        = NULL;\r
+\r
+  //\r
+  // Build Device Path\r
+  //\r
+  if (ScsiBusDev->ExtScsiSupport){\r
+    Status = ScsiBusDev->ExtScsiInterface->BuildDevicePath (\r
+                                             ScsiBusDev->ExtScsiInterface,\r
+                                             &TargetId->ScsiId.ExtScsi[0],\r
+                                             Lun,\r
+                                             &ScsiDevicePath\r
+                                             );\r
+  } else {\r
+    Status = ScsiBusDev->ScsiInterface->BuildDevicePath (\r
+                                          ScsiBusDev->ScsiInterface,\r
+                                          TargetId->ScsiId.Scsi,\r
+                                          Lun,\r
+                                          &ScsiDevicePath\r
+                                          );\r
+  }\r
+\r
+  if (EFI_ERROR(Status)) {\r
     return Status;\r
   }\r
 \r
-  ZeroMem (ScsiIoDevice, sizeof (SCSI_IO_DEV));\r
+  DevicePath = AppendDevicePathNode (\r
+                 ScsiBusDev->DevicePath,\r
+                 ScsiDevicePath\r
+                 );\r
+\r
+  if (DevicePath == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto ErrorExit;\r
+  }\r
+\r
+  DeviceHandle = NULL;\r
+  RemainingDevicePath = DevicePath;\r
+  Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &RemainingDevicePath, &DeviceHandle);\r
+  if (!EFI_ERROR (Status) && (DeviceHandle != NULL) && IsDevicePathEnd(RemainingDevicePath)) {\r
+    //\r
+    // The device has been started, directly return to fast boot.\r
+    //\r
+    Status = EFI_ALREADY_STARTED;\r
+    goto ErrorExit;\r
+  }\r
+\r
+  ScsiIoDevice = AllocateZeroPool (sizeof (SCSI_IO_DEV));\r
+  if (ScsiIoDevice == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto ErrorExit;\r
+  }\r
 \r
   ScsiIoDevice->Signature                 = SCSI_IO_DEV_SIGNATURE;\r
+  ScsiIoDevice->ScsiBusDeviceData         = ScsiBusDev;\r
   CopyMem(&ScsiIoDevice->Pun, TargetId, TARGET_MAX_BYTES);\r
   ScsiIoDevice->Lun                       = Lun;\r
 \r
@@ -1029,55 +1202,22 @@ Returns:
   ScsiIoDevice->ScsiIo.ResetDevice        = ScsiResetDevice;\r
   ScsiIoDevice->ScsiIo.ExecuteScsiCommand = ScsiExecuteSCSICommand;\r
 \r
-\r
-  if (!DiscoverScsiDevice (ScsiIoDevice)) {\r
-    gBS->FreePool (ScsiIoDevice);\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
   //\r
-  // Set Device Path\r
+  // Report Status Code here since the new SCSI device will be discovered\r
   //\r
-  if (ScsiIoDevice->ExtScsiSupport){\r
-    Status = ScsiIoDevice->ExtScsiPassThru->BuildDevicePath (\r
-                                          ScsiIoDevice->ExtScsiPassThru,\r
-                                          &ScsiIoDevice->Pun.ScsiId.ExtScsi[0],\r
-                                          ScsiIoDevice->Lun,\r
-                                          &ScsiDevicePath\r
-                                          );\r
-    if (Status == EFI_OUT_OF_RESOURCES) {\r
-      gBS->FreePool (ScsiIoDevice);\r
-      return Status;\r
-    }\r
-  } else {\r
-    Status = ScsiIoDevice->ScsiPassThru->BuildDevicePath (\r
-                                          ScsiIoDevice->ScsiPassThru,\r
-                                          ScsiIoDevice->Pun.ScsiId.Scsi,\r
-                                          ScsiIoDevice->Lun,\r
-                                          &ScsiDevicePath\r
-                                          );\r
-    if (Status == EFI_OUT_OF_RESOURCES) {\r
-      gBS->FreePool (ScsiIoDevice);\r
-      return Status;\r
-    }\r
-  }\r
-\r
-  ScsiIoDevice->DevicePath = AppendDevicePathNode (\r
-                              ScsiBusDev->DevicePath,\r
-                              ScsiDevicePath\r
-                              );\r
-  //\r
-  // The memory space for ScsiDevicePath is allocated in\r
-  // ScsiPassThru->BuildDevicePath() function; It is no longer used\r
-  // after EfiAppendDevicePathNode,so free the memory it occupies.\r
-  //\r
-  gBS->FreePool (ScsiDevicePath);\r
+  REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+    EFI_PROGRESS_CODE,\r
+    (EFI_IO_BUS_SCSI | EFI_IOB_PC_ENABLE),\r
+    ScsiBusDev->DevicePath\r
+    );\r
 \r
-  if (ScsiIoDevice->DevicePath == NULL) {\r
-    gBS->FreePool (ScsiIoDevice);\r
-    return EFI_OUT_OF_RESOURCES;\r
+  if (!DiscoverScsiDevice (ScsiIoDevice)) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto ErrorExit;\r
   }\r
 \r
+  ScsiIoDevice->DevicePath = DevicePath;\r
+\r
   Status = gBS->InstallMultipleProtocolInterfaces (\r
                   &ScsiIoDevice->Handle,\r
                   &gEfiDevicePathProtocolGuid,\r
@@ -1087,147 +1227,189 @@ Returns:
                   NULL\r
                   );\r
   if (EFI_ERROR (Status)) {\r
-    gBS->FreePool (ScsiIoDevice);\r
-    return EFI_OUT_OF_RESOURCES;\r
+    goto ErrorExit;\r
   } else {\r
     if (ScsiBusDev->ExtScsiSupport) {\r
       gBS->OpenProtocol (\r
-            Controller,\r
-            &gEfiExtScsiPassThruProtocolGuid,\r
-            (VOID **) &(ScsiBusDev->ExtScsiInterface),\r
-            This->DriverBindingHandle,\r
-            ScsiIoDevice->Handle,\r
-            EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
-            );\r
+             Controller,\r
+             &gEfiExtScsiPassThruProtocolGuid,\r
+             (VOID **) &(ScsiBusDev->ExtScsiInterface),\r
+             This->DriverBindingHandle,\r
+             ScsiIoDevice->Handle,\r
+             EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
+             );\r
      } else {\r
       gBS->OpenProtocol (\r
-            Controller,\r
-            &gEfiScsiPassThruProtocolGuid,\r
-            (VOID **) &(ScsiBusDev->ScsiInterface),\r
-            This->DriverBindingHandle,\r
-            ScsiIoDevice->Handle,\r
-            EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
-            );\r
+             Controller,\r
+             &gEfiScsiPassThruProtocolGuid,\r
+             (VOID **) &(ScsiBusDev->ScsiInterface),\r
+             This->DriverBindingHandle,\r
+             ScsiIoDevice->Handle,\r
+             EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
+             );\r
      }\r
   }\r
   return EFI_SUCCESS;\r
-}\r
 \r
-BOOLEAN\r
-EFIAPI\r
-DiscoverScsiDevice (\r
-  SCSI_IO_DEV   *ScsiIoDevice\r
-  )\r
-/*++\r
+ErrorExit:\r
 \r
-Routine Description:\r
+  //\r
+  // The memory space for ScsiDevicePath is allocated in\r
+  // ScsiPassThru->BuildDevicePath() function; It is no longer used\r
+  // after AppendDevicePathNode,so free the memory it occupies.\r
+  //\r
+  FreePool (ScsiDevicePath);\r
 \r
-  Discovery SCSI Device\r
+  if (DevicePath != NULL) {\r
+    FreePool (DevicePath);\r
+  }\r
 \r
-Arguments:\r
+  if (ScsiIoDevice != NULL) {\r
+    FreePool (ScsiIoDevice);\r
+  }\r
 \r
-  ScsiIoDevice    - The pointer of SCSI_IO_DEV\r
+  return Status;\r
+}\r
 \r
-Returns:\r
 \r
-  TRUE            - Find SCSI Device and verify it.\r
-  FALSE           - Unable to find SCSI Device.\r
+/**\r
+  Discovery SCSI Device\r
+\r
+  @param  ScsiIoDevice    The pointer of SCSI_IO_DEV\r
 \r
---*/\r
+  @retval  TRUE   Find SCSI Device and verify it.\r
+  @retval  FALSE  Unable to find SCSI Device.\r
+\r
+**/\r
+BOOLEAN\r
+DiscoverScsiDevice (\r
+  IN OUT  SCSI_IO_DEV   *ScsiIoDevice\r
+  )\r
 {\r
   EFI_STATUS            Status;\r
   UINT32                InquiryDataLength;\r
   UINT8                 SenseDataLength;\r
   UINT8                 HostAdapterStatus;\r
   UINT8                 TargetStatus;\r
-  EFI_SCSI_SENSE_DATA   SenseData;\r
-  EFI_SCSI_INQUIRY_DATA InquiryData;\r
+  EFI_SCSI_INQUIRY_DATA *InquiryData;\r
+  EFI_SCSI_SENSE_DATA   *SenseData;\r
+  UINT8                 MaxRetry;\r
+  UINT8                 Index;\r
+  BOOLEAN               ScsiDeviceFound;\r
 \r
   HostAdapterStatus = 0;\r
   TargetStatus      = 0;\r
+  SenseData         = NULL;\r
+\r
+  InquiryData = AllocateAlignedBuffer (ScsiIoDevice, sizeof (EFI_SCSI_INQUIRY_DATA));\r
+  if (InquiryData == NULL) {\r
+    ScsiDeviceFound = FALSE;\r
+    goto Done;\r
+  }\r
+\r
+  SenseData = AllocateAlignedBuffer (\r
+                ScsiIoDevice,\r
+                sizeof (EFI_SCSI_SENSE_DATA)\r
+                );\r
+  if (SenseData == NULL) {\r
+    ScsiDeviceFound = FALSE;\r
+    goto Done;\r
+  }\r
+\r
   //\r
   // Using Inquiry command to scan for the device\r
   //\r
   InquiryDataLength = sizeof (EFI_SCSI_INQUIRY_DATA);\r
   SenseDataLength   = sizeof (EFI_SCSI_SENSE_DATA);\r
+  ZeroMem (InquiryData, InquiryDataLength);\r
+  ZeroMem (SenseData, SenseDataLength);\r
+\r
+  MaxRetry = 2;\r
+  for (Index = 0; Index < MaxRetry; Index++) {\r
+    Status = ScsiInquiryCommand (\r
+              &ScsiIoDevice->ScsiIo,\r
+              SCSI_BUS_TIMEOUT,\r
+              SenseData,\r
+              &SenseDataLength,\r
+              &HostAdapterStatus,\r
+              &TargetStatus,\r
+              (VOID *) InquiryData,\r
+              &InquiryDataLength,\r
+              FALSE\r
+              );\r
+    if (!EFI_ERROR (Status)) {\r
+      if ((HostAdapterStatus == EFI_SCSI_IO_STATUS_HOST_ADAPTER_OK) &&\r
+          (TargetStatus == EFI_SCSI_IO_STATUS_TARGET_CHECK_CONDITION) &&\r
+          (SenseData->Error_Code == 0x70) &&\r
+          (SenseData->Sense_Key == EFI_SCSI_SK_ILLEGAL_REQUEST)) {\r
+        ScsiDeviceFound = FALSE;\r
+        goto Done;\r
+      }\r
+      break;\r
+    }\r
+    if ((Status == EFI_BAD_BUFFER_SIZE) ||\r
+        (Status == EFI_INVALID_PARAMETER) ||\r
+        (Status == EFI_UNSUPPORTED)) {\r
+      ScsiDeviceFound = FALSE;\r
+      goto Done;\r
+    }\r
+  }\r
 \r
-  Status = ScsiInquiryCommand (\r
-            &ScsiIoDevice->ScsiIo,\r
-            EfiScsiStallSeconds (1),\r
-            (VOID *) &SenseData,\r
-            &SenseDataLength,\r
-            &HostAdapterStatus,\r
-            &TargetStatus,\r
-            (VOID *) &InquiryData,\r
-            &InquiryDataLength,\r
-            FALSE\r
-            );\r
-  if (EFI_ERROR (Status)) {\r
-    //\r
-    //    ParseSenseData (&SenseData,SenseDataLength);\r
-    //\r
-    return FALSE;\r
+  if (Index == MaxRetry) {\r
+    ScsiDeviceFound = FALSE;\r
+    goto Done;\r
   }\r
+\r
   //\r
   // Retrieved inquiry data successfully\r
   //\r
-  if ((InquiryData.Peripheral_Qualifier != 0) &&\r
-      (InquiryData.Peripheral_Qualifier != 3)) {\r
-    return FALSE;\r
-  }\r
-\r
-  if (InquiryData.Peripheral_Qualifier == 3) {\r
-    if (InquiryData.Peripheral_Type != 0x1f) {\r
-      return FALSE;\r
-    }\r
+  if (InquiryData->Peripheral_Qualifier != 0) {\r
+    ScsiDeviceFound = FALSE;\r
+    goto Done;\r
   }\r
 \r
-  if (0x1e >= InquiryData.Peripheral_Type && InquiryData.Peripheral_Type >= 0xa) {\r
-    return FALSE;\r
+  if (0x1e >= InquiryData->Peripheral_Type && InquiryData->Peripheral_Type >= 0xa) {\r
+    ScsiDeviceFound = FALSE;\r
+    goto Done;\r
   }\r
 \r
   //\r
   // valid device type and peripheral qualifier combination.\r
   //\r
-  ScsiIoDevice->ScsiDeviceType  = InquiryData.Peripheral_Type;\r
-  ScsiIoDevice->RemovableDevice = InquiryData.RMB;\r
-  if (InquiryData.Version == 0) {\r
+  ScsiIoDevice->ScsiDeviceType  = InquiryData->Peripheral_Type;\r
+  ScsiIoDevice->RemovableDevice = InquiryData->Rmb;\r
+  if (InquiryData->Version == 0) {\r
     ScsiIoDevice->ScsiVersion = 0;\r
   } else {\r
     //\r
     // ANSI-approved version\r
     //\r
-    ScsiIoDevice->ScsiVersion = (UINT8) (InquiryData.Version & 0x03);\r
+    ScsiIoDevice->ScsiVersion = (UINT8) (InquiryData->Version & 0x07);\r
   }\r
 \r
-  return TRUE;\r
+  ScsiDeviceFound = TRUE;\r
+\r
+Done:\r
+  FreeAlignedBuffer (SenseData, sizeof (EFI_SCSI_SENSE_DATA));\r
+  FreeAlignedBuffer (InquiryData, sizeof (EFI_SCSI_INQUIRY_DATA));\r
+\r
+  return ScsiDeviceFound;\r
 }\r
 \r
 \r
-STATIC\r
+/**\r
+  Convert EFI_SCSI_IO_SCSI_REQUEST_PACKET packet to EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET packet.\r
+\r
+  @param  Packet         The pointer of EFI_SCSI_IO_SCSI_REQUEST_PACKET\r
+  @param  CommandPacket  The pointer of EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET\r
+\r
+**/\r
 EFI_STATUS\r
 EFIAPI\r
 ScsiioToPassThruPacket (\r
   IN      EFI_SCSI_IO_SCSI_REQUEST_PACKET         *Packet,\r
-  IN OUT  EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET  *CommandPacket\r
+  OUT     EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET  *CommandPacket\r
   )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Convert EFI_SCSI_IO_SCSI_REQUEST_PACKET packet to\r
-  EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET packet\r
-\r
-Arguments:\r
-\r
-  Packet            - The pointer of EFI_SCSI_IO_SCSI_REQUEST_PACKET\r
-  CommandPacket     - The pointer of EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET\r
-\r
-Returns:\r
-\r
-  NONE\r
-\r
---*/\r
 {\r
   //\r
   //EFI 1.10 doesn't support Bi-Direction Command.\r
@@ -1258,30 +1440,19 @@ Returns:
 }\r
 \r
 \r
-STATIC\r
+/**\r
+  Convert EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET packet to EFI_SCSI_IO_SCSI_REQUEST_PACKET packet.\r
+\r
+  @param  ScsiPacket  The pointer of EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET\r
+  @param  Packet      The pointer of EFI_SCSI_IO_SCSI_REQUEST_PACKET\r
+\r
+**/\r
 EFI_STATUS\r
 EFIAPI\r
 PassThruToScsiioPacket (\r
   IN     EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET  *ScsiPacket,\r
-  IN OUT EFI_SCSI_IO_SCSI_REQUEST_PACKET         *Packet\r
+  OUT    EFI_SCSI_IO_SCSI_REQUEST_PACKET         *Packet\r
   )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Convert EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET packet to\r
-  EFI_SCSI_IO_SCSI_REQUEST_PACKET packet\r
-\r
-Arguments:\r
-\r
-  ScsiPacket        - The pointer of EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET\r
-  Packet            - The pointer of EFI_SCSI_IO_SCSI_REQUEST_PACKET\r
-\r
-Returns:\r
-\r
-  NONE\r
-\r
---*/\r
 {\r
   Packet->Timeout           = ScsiPacket->Timeout;\r
   Packet->Cdb               = ScsiPacket->Cdb;\r
@@ -1303,32 +1474,20 @@ Returns:
   return EFI_SUCCESS;\r
 }\r
 \r
+/**\r
+  Notify Function in which convert EFI1.0 PassThru Packet back to UEF2.0\r
+  SCSI IO Packet.\r
 \r
+  @param  Event    The instance of EFI_EVENT.\r
+  @param  Context  The parameter passed in.\r
 \r
-STATIC\r
+**/\r
 VOID\r
 EFIAPI\r
 NotifyFunction (\r
-  EFI_EVENT  Event,\r
-  VOID       *Context\r
+  IN  EFI_EVENT  Event,\r
+  IN  VOID       *Context\r
   )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  Notify Function in which convert EFI1.0 PassThru Packet back to UEF2.0\r
-  SCSI IO Packet.\r
-\r
-Arguments:\r
-\r
-  Event          - The instance of EFI_EVENT.\r
-  Context        - The parameter passed in.\r
-\r
-Returns:\r
-\r
-  NONE\r
-\r
---*/\r
 {\r
   EFI_SCSI_IO_SCSI_REQUEST_PACKET          *Packet;\r
   EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET   *ScsiPacket;\r
@@ -1337,7 +1496,7 @@ Returns:
 \r
   PassData = (SCSI_EVENT_DATA*)Context;\r
   Packet  = (EFI_SCSI_IO_SCSI_REQUEST_PACKET *)PassData->Data1;\r
-  ScsiPacket =  (EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET*)WorkingBuffer;\r
+  ScsiPacket =  (EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET*)mWorkingBuffer;\r
 \r
   //\r
   // Convert EFI1.0 PassThru packet to UEFI2.0 SCSI IO Packet.\r
@@ -1346,9 +1505,9 @@ Returns:
 \r
   //\r
   // After converting EFI1.0 PassThru Packet back to UEFI2.0 SCSI IO Packet,\r
-  // free WorkingBuffer.\r
+  // free mWorkingBuffer.\r
   //\r
-  gBS->FreePool(WorkingBuffer);\r
+  gBS->FreePool(mWorkingBuffer);\r
 \r
   //\r
   // Signal Event to tell caller to pick up UEFI2.0 SCSI IO Packet.\r
@@ -1357,3 +1516,4 @@ Returns:
   gBS->CloseEvent(Event);\r
   gBS->SignalEvent(CallerEvent);\r
 }\r
+\r