]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBus.c
Clean up the private GUID definition in module Level.
[mirror_edk2.git] / MdeModulePkg / Bus / Scsi / ScsiBusDxe / ScsiBus.c
index 68f3683bb632cfc0cda7f1a700511c883309fdff..b1c4d207f9de8bf415b3b7a157906391dcba334e 100644 (file)
@@ -1,52 +1,22 @@
-/*++\r
+/** @file\r
+  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, 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 - 2010, Intel Corporation. All rights reserved.<BR>\r
+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
-Module Name:\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
-    scsibus.c\r
-    \r
-Abstract: \r
-    \r
+**/\r
 \r
-Revision History\r
---*/\r
-\r
-//\r
-// The package level header files this module uses\r
-//\r
-#include <PiDxe.h>\r
-\r
-//\r
-// The protocols, PPI and GUID defintions for this module\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
-// The Library classes this module consumes\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
@@ -56,51 +26,59 @@ 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
-  )\r
-;\r
+  IN  EFI_EVENT  Event,\r
+  IN  VOID       *Context\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
-  \r
-  @retval EFI_SUCCESS       The entry point is executed successfully.\r
-  @retval other             Some error occurs when executing this entry point.\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
 \r
 **/\r
 EFI_STATUS\r
@@ -115,21 +93,39 @@ InitializeScsiBus(
   //\r
   // Install driver model protocol(s).\r
   //\r
-  Status = EfiLibInstallAllDriverProtocols (\r
+  Status = EfiLibInstallDriverBindingComponentName2 (\r
              ImageHandle,\r
              SystemTable,\r
              &gSCSIBusDriverBinding,\r
              ImageHandle,\r
              &gScsiBusComponentName,\r
-             NULL,\r
-             NULL\r
+             &gScsiBusComponentName2\r
              );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
-\r
   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
@@ -137,32 +133,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
@@ -172,48 +157,103 @@ Returns:
                   Controller,\r
                   EFI_OPEN_PROTOCOL_BY_DRIVER\r
                   );\r
-  \r
+\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
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    }\r
+  }\r
 \r
-    gBS->CloseProtocol (\r
-      Controller,\r
-      &gEfiScsiPassThruProtocolGuid,\r
-      This->DriverBindingHandle,\r
-      Controller\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
+  if (Status == EFI_ALREADY_STARTED) {\r
     return EFI_SUCCESS;\r
   }\r
   \r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  \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
-    &gEfiExtScsiPassThruProtocolGuid,\r
-    This->DriverBindingHandle,\r
-    Controller\r
-    );\r
-\r
-  return EFI_SUCCESS;\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
@@ -221,152 +261,180 @@ 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
-// TODO:    This - add argument and description to function comment\r
-// TODO:    Controller - add argument and description to function comment\r
-// TODO:    RemainingDevicePath - add argument and description to function comment\r
 {\r
-  EFI_STATUS                  Status;\r
-  UINT64                      Lun;\r
-  BOOLEAN                     ScanOtherPuns;\r
-  SCSI_BUS_DEVICE             *ScsiBusDev;\r
-  BOOLEAN                     FromFirstTarget;\r
-  SCSI_TARGET_ID              *ScsiTargetId;\r
-  UINT8                       *TargetId;\r
-\r
-  TargetId = NULL;\r
-  ScanOtherPuns = TRUE;\r
+  UINT64                                Lun;\r
+  UINT8                                 *TargetId;\r
+  BOOLEAN                               ScanOtherPuns;\r
+  BOOLEAN                               FromFirstTarget;\r
+  BOOLEAN                               ExtScsiSupport;\r
+  EFI_STATUS                            Status;\r
+  EFI_STATUS                            DevicePathStatus;\r
+  EFI_STATUS                            PassThruStatus;\r
+  SCSI_BUS_DEVICE                       *ScsiBusDev;\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
+  ScanOtherPuns   = TRUE;\r
   FromFirstTarget = FALSE;\r
-  //\r
-  // Allocate SCSI_BUS_DEVICE structure\r
-  //\r
-  ScsiBusDev = NULL;\r
-  ScsiBusDev = AllocateZeroPool (sizeof (SCSI_BUS_DEVICE));\r
-  if (ScsiBusDev == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  ScsiTargetId = NULL;\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
+  ExtScsiSupport  = FALSE;\r
+  PassThruStatus  = EFI_SUCCESS;\r
   \r
-  Status = gBS->OpenProtocol (\r
-                  Controller,\r
-                  &gEfiDevicePathProtocolGuid,\r
-                  (VOID **) &(ScsiBusDev->DevicePath),\r
-                  This->DriverBindingHandle,\r
-                  Controller,\r
-                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
-                  );\r
-  if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {\r
-    gBS->FreePool (ScsiBusDev);\r
-    return Status;\r
+  TargetId = &ScsiTargetId.ScsiId.ExtScsi[0];\r
+  SetMem (TargetId, TARGET_MAX_BYTES, 0xFF);\r
+  \r
+  DevicePathStatus = gBS->OpenProtocol (\r
+                            Controller,\r
+                            &gEfiDevicePathProtocolGuid,\r
+                            (VOID **) &ParentDevicePath,\r
+                            This->DriverBindingHandle,\r
+                            Controller,\r
+                            EFI_OPEN_PROTOCOL_BY_DRIVER\r
+                            );\r
+  if (EFI_ERROR (DevicePathStatus) && (DevicePathStatus != EFI_ALREADY_STARTED)) {\r
+    return DevicePathStatus;\r
   }\r
 \r
   //\r
-  // First consume Extended SCSI Pass Thru protocol, if fail, then consume\r
-  // 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
                   &gEfiExtScsiPassThruProtocolGuid,\r
-                  (VOID **) &(ScsiBusDev->ExtScsiInterface),\r
+                  (VOID **) &ExtScsiInterface,\r
                   This->DriverBindingHandle,\r
                   Controller,\r
                   EFI_OPEN_PROTOCOL_BY_DRIVER\r
                   );\r
-  if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {\r
+  //\r
+  // Fail to open UEFI ExtendPassThru Protocol, then try to open EFI PassThru Protocol instead.\r
+  //\r
+  if (EFI_ERROR(Status) && (Status != EFI_ALREADY_STARTED)) {\r
     Status = gBS->OpenProtocol (\r
                     Controller,\r
                     &gEfiScsiPassThruProtocolGuid,\r
-                    (VOID **) &(ScsiBusDev->ScsiInterface),\r
+                    (VOID **) &ScsiInterface,\r
                     This->DriverBindingHandle,\r
                     Controller,\r
                     EFI_OPEN_PROTOCOL_BY_DRIVER\r
                     );\r
-    if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {\r
-      gBS->CloseProtocol (\r
-             Controller,\r
-             &gEfiDevicePathProtocolGuid,\r
-             This->DriverBindingHandle,\r
-             Controller\r
-             );\r
-      gBS->FreePool (ScsiBusDev);\r
+    //\r
+    // Fail to open EFI PassThru Protocol, Close the DevicePathProtocol if it is opened by this time.\r
+    //\r
+    if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {\r
+      if (!EFI_ERROR(DevicePathStatus)) {\r
+        gBS->CloseProtocol (\r
+               Controller,\r
+               &gEfiDevicePathProtocolGuid,\r
+               This->DriverBindingHandle,\r
+               Controller\r
+               );\r
+      } \r
       return Status;\r
     } \r
-    DEBUG ((EFI_D_INFO, "Open Scsi Pass Thrugh Protocol\n"));\r
-    ScsiBusDev->ExtScsiSupport  = FALSE;\r
   } else {\r
-    DEBUG ((EFI_D_INFO, "Open Extended Scsi Pass Thrugh Protocol\n"));\r
-    ScsiBusDev->ExtScsiSupport  = TRUE;\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
+    // another SCSI Bus Driver to work on the same host handle.\r
+    //\r
+    ExtScsiSupport = TRUE;\r
+    PassThruStatus = gBS->OpenProtocol (\r
+                            Controller,\r
+                            &gEfiScsiPassThruProtocolGuid,\r
+                            (VOID **) &ScsiInterface,\r
+                            This->DriverBindingHandle,\r
+                            Controller,\r
+                            EFI_OPEN_PROTOCOL_BY_DRIVER\r
+                            );\r
   }\r
-\r
-  ScsiBusDev->Signature = SCSI_BUS_DEVICE_SIGNATURE;\r
-  //\r
-  // Attach EFI_SCSI_BUS_PROTOCOL to controller handle\r
-  //\r
-  Status = gBS->InstallProtocolInterface (\r
-                  &Controller,\r
-                  &mScsiBusProtocolGuid,\r
-                  EFI_NATIVE_INTERFACE,\r
-                  &ScsiBusDev->BusIdentify\r
-                  );\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    gBS->CloseProtocol (\r
-           Controller,\r
-           &gEfiDevicePathProtocolGuid,\r
-           This->DriverBindingHandle,\r
-           Controller\r
-           );\r
+    \r
+  if (Status != EFI_ALREADY_STARTED) {\r
+    //\r
+    // Go through here means either ExtPassThru or PassThru Protocol is successfully opened\r
+    // on this handle for this time. Then construct Host controller private data.\r
+    //\r
+    ScsiBusDev = NULL;\r
+    ScsiBusDev = AllocateZeroPool(sizeof(SCSI_BUS_DEVICE));\r
+    if (ScsiBusDev == NULL) {\r
+      Status = EFI_OUT_OF_RESOURCES;\r
+      goto ErrorExit;\r
+    }\r
+    ScsiBusDev->Signature        = SCSI_BUS_DEVICE_SIGNATURE;\r
+    ScsiBusDev->ExtScsiSupport   = ExtScsiSupport;\r
+    ScsiBusDev->DevicePath       = ParentDevicePath;\r
     if (ScsiBusDev->ExtScsiSupport) {\r
-      gBS->CloseProtocol (\r
-             Controller,\r
-             &gEfiExtScsiPassThruProtocolGuid,\r
-             This->DriverBindingHandle,\r
-             Controller\r
-             );\r
+      ScsiBusDev->ExtScsiInterface = ExtScsiInterface;\r
     } else {\r
-      gBS->CloseProtocol (\r
-             Controller,\r
-             &gEfiScsiPassThruProtocolGuid,\r
-             This->DriverBindingHandle,\r
-             Controller\r
-             );\r
+      ScsiBusDev->ScsiInterface    = ScsiInterface;    \r
     }\r
-    gBS->FreePool (ScsiBusDev);\r
-    return Status;\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
+    Status = gBS->InstallProtocolInterface (\r
+                    &Controller,\r
+                    &gEfiCallerIdGuid,\r
+                    EFI_NATIVE_INTERFACE,\r
+                    &ScsiBusDev->BusIdentify\r
+                    );\r
+    if (EFI_ERROR (Status)) {\r
+      goto ErrorExit;\r
+    }\r
+  } else {\r
+    //\r
+    // Go through here means Start() is re-invoked again, nothing special is required to do except\r
+    // picking up Host controller private information.\r
+    //\r
+    Status = gBS->OpenProtocol (\r
+                    Controller,\r
+                    &gEfiCallerIdGuid,\r
+                    (VOID **) &BusIdentify,\r
+                    This->DriverBindingHandle,\r
+                    Controller,\r
+                    EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                    );\r
+\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+    ScsiBusDev = SCSI_BUS_CONTROLLER_DEVICE_FROM_THIS (BusIdentify);\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
@@ -378,7 +446,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
@@ -393,11 +461,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
@@ -405,11 +473,61 @@ 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
+  return EFI_SUCCESS;\r
+\r
+ErrorExit:\r
+  \r
+  if (ScsiBusDev != NULL) {\r
+    FreePool (ScsiBusDev);\r
+  }\r
+  \r
+  if (ExtScsiSupport) {\r
+    gBS->CloseProtocol (\r
+           Controller,\r
+           &gEfiExtScsiPassThruProtocolGuid,\r
+           This->DriverBindingHandle,\r
+           Controller\r
+           );\r
+    if (!EFI_ERROR (PassThruStatus)) {\r
+      gBS->CloseProtocol (\r
+             Controller,\r
+             &gEfiScsiPassThruProtocolGuid,\r
+             This->DriverBindingHandle,\r
+             Controller\r
+             );\r
+    }\r
+  } else {\r
+    gBS->CloseProtocol (\r
+           Controller,\r
+           &gEfiScsiPassThruProtocolGuid,\r
+           This->DriverBindingHandle,\r
+           Controller\r
+           );\r
   }\r
   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
@@ -418,22 +536,6 @@ SCSIBusDriverBindingStop (
   IN  UINTN                           NumberOfChildren,\r
   IN  EFI_HANDLE                      *ChildHandleBuffer\r
   )\r
-/*++\r
-  \r
-  Routine Description:\r
-  \r
-  Arguments:\r
-  \r
-  Returns:\r
-  \r
---*/\r
-// TODO:    This - add argument and description to function comment\r
-// TODO:    Controller - add argument and description to function comment\r
-// TODO:    NumberOfChildren - add argument and description to function comment\r
-// TODO:    ChildHandleBuffer - add argument and description to function comment\r
-// TODO:    EFI_SUCCESS - add return value to function comment\r
-// TODO:    EFI_DEVICE_ERROR - add return value to function comment\r
-// TODO:    EFI_SUCCESS - add return value to function comment\r
 {\r
   EFI_STATUS                  Status;\r
   BOOLEAN                     AllChildrenStopped;\r
@@ -450,13 +552,13 @@ SCSIBusDriverBindingStop (
     //\r
     Status = gBS->OpenProtocol (\r
                     Controller,\r
-                    &mScsiBusProtocolGuid,\r
+                    &gEfiCallerIdGuid,\r
                     (VOID **) &Scsidentifier,\r
                     This->DriverBindingHandle,\r
                     Controller,\r
                     EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
                     );\r
-  \r
+\r
     if (EFI_ERROR (Status)) {\r
       return EFI_DEVICE_ERROR;\r
     }\r
@@ -468,20 +570,34 @@ SCSIBusDriverBindingStop (
     //\r
     gBS->UninstallProtocolInterface (\r
            Controller,\r
-           &mScsiBusProtocolGuid,\r
+           &gEfiCallerIdGuid,\r
            &ScsiBusDev->BusIdentify\r
            );\r
-    \r
+\r
     //\r
     // 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
@@ -497,7 +613,7 @@ SCSIBusDriverBindingStop (
            This->DriverBindingHandle,\r
            Controller\r
            );\r
-    gBS->FreePool (ScsiBusDev);\r
+    FreePool (ScsiBusDev);\r
     return EFI_SUCCESS;\r
   }\r
 \r
@@ -553,7 +669,7 @@ SCSIBusDriverBindingStop (
         gBS->OpenProtocol (\r
                Controller,\r
                &gEfiExtScsiPassThruProtocolGuid,\r
-               &(EFI_EXT_SCSI_PASS_THRU_PROTOCOL*)ScsiPassThru,\r
+               &ScsiPassThru,\r
                This->DriverBindingHandle,\r
                ChildHandleBuffer[Index],\r
                EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
@@ -562,14 +678,14 @@ SCSIBusDriverBindingStop (
         gBS->OpenProtocol (\r
                Controller,\r
                &gEfiScsiPassThruProtocolGuid,\r
-               &(EFI_SCSI_PASS_THRU_PROTOCOL*)ScsiPassThru,\r
+               &ScsiPassThru,\r
                This->DriverBindingHandle,\r
                ChildHandleBuffer[Index],\r
                EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
                );\r
       }\r
     } else {\r
-      gBS->FreePool (ScsiIoDevice);\r
+      FreePool (ScsiIoDevice);\r
     }\r
   }\r
 \r
@@ -580,26 +696,24 @@ SCSIBusDriverBindingStop (
   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
-    Retrieves the device type information of the SCSI Controller.\r
-    \r
-  Arguments:\r
-    This                  - Protocol instance pointer.\r
-    DeviceType            - A pointer to the device type information\r
-                            retrieved from the SCSI Controller. \r
-\r
-  Returns:\r
-    EFI_SUCCESS           - Retrieves the device type information successfully.\r
-    EFI_INVALID_PARAMETER - The DeviceType is NULL.\r
---*/\r
 {\r
   SCSI_IO_DEV *ScsiIoDevice;\r
 \r
@@ -612,6 +726,20 @@ ScsiGetDeviceType (
   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
@@ -619,21 +747,6 @@ ScsiGetDeviceLocation (
   IN OUT UINT8                **Target,\r
   OUT UINT64                  *Lun\r
   )\r
-/*++\r
-  Routine Description:\r
-    Retrieves the device location in the SCSI channel.\r
-    \r
-  Arguments:\r
-    This                  - Protocol instance pointer.\r
-    Target                - A pointer to the Target 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
-    EFI_SUCCESS           - Retrieves the device location successfully.\r
-    EFI_INVALID_PARAMETER - The Target or Lun is NULL.\r
---*/\r
 {\r
   SCSI_IO_DEV *ScsiIoDevice;\r
 \r
@@ -641,36 +754,32 @@ ScsiGetDeviceLocation (
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  ScsiIoDevice  = SCSI_IO_DEV_FROM_THIS (This);\r
+  ScsiIoDevice = SCSI_IO_DEV_FROM_THIS (This);\r
 \r
   CopyMem (*Target,&ScsiIoDevice->Pun, TARGET_MAX_BYTES);\r
 \r
-  *Lun          = ScsiIoDevice->Lun;\r
+  *Lun         = ScsiIoDevice->Lun;\r
 \r
   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
-    Resets the SCSI Bus that the SCSI Controller is attached to.\r
-    \r
-  Arguments:\r
-    This                  - Protocol instance pointer.\r
-\r
-  Returns:\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
@@ -683,31 +792,25 @@ ScsiResetBus (
   }\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
-    Resets the SCSI Controller that the device handle specifies.\r
-    \r
-  Arguments:\r
-    This                  - Protocol instance pointer.\r
-    \r
-\r
-  Returns:\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
+  SCSI_IO_DEV  *ScsiIoDevice;\r
   UINT8        Target[TARGET_MAX_BYTES];\r
 \r
   ScsiIoDevice = SCSI_IO_DEV_FROM_THIS (This);\r
@@ -729,66 +832,64 @@ ScsiResetDevice (
   }\r
 }\r
 \r
+\r
+/**\r
+  Sends a SCSI Request Packet to the SCSI Controller for execution.\r
+\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
+  @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
+                          supported, then non-blocking I/O is performed,\r
+                          and Event will be signaled when the SCSI Request\r
+                          Packet completes.\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
+  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
-    Sends a SCSI Request Packet to the SCSI Controller for execution.\r
-    \r
-  Arguments:\r
-    This                  - Protocol instance pointer.\r
-    Packet                - 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
-                            If Event is NULL, then blocking I/O is performed.\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
-    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_WARN_BUFFER_TOO_SMALL - 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
-  SCSI_IO_DEV                             *ScsiIoDevice;\r
-  EFI_STATUS                              Status;\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
@@ -802,7 +903,7 @@ ScsiExecuteSCSICommand (
 \r
   ScsiIoDevice  = SCSI_IO_DEV_FROM_THIS (This);\r
   CopyMem (Target,&ScsiIoDevice->Pun, TARGET_MAX_BYTES);\r
-  \r
+\r
   if (ScsiIoDevice->ExtScsiSupport) {\r
     ExtRequestPacket = (EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *) Packet;\r
     Status = ScsiIoDevice->ExtScsiPassThru->PassThru (\r
@@ -814,26 +915,22 @@ ScsiExecuteSCSICommand (
                                           );\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
+    // 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
@@ -847,24 +944,24 @@ ScsiExecuteSCSICommand (
                        &PacketEvent\r
                        );\r
       if (EFI_ERROR(Status)) {\r
-        gBS->FreePool(WorkingBuffer);\r
+        FreePool(mWorkingBuffer);\r
         return Status;\r
       }\r
-    \r
+\r
       Status = ScsiIoDevice->ScsiPassThru->PassThru (\r
                                           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
-      \r
+\r
     } else {\r
       //\r
       // If there's no event or SCSI Device doesn't support NON-BLOCKING, just convert\r
@@ -874,69 +971,111 @@ ScsiExecuteSCSICommand (
                                           ScsiIoDevice->ScsiPassThru,\r
                                           ScsiIoDevice->Pun.ScsiId.Scsi,\r
                                           ScsiIoDevice->Lun,\r
-                                          WorkingBuffer,\r
+                                          mWorkingBuffer,\r
                                           Event\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
-      gBS->FreePool(WorkingBuffer);\r
+      FreePool(mWorkingBuffer);\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
   CopyMem(&ScsiIoDevice->Pun, TargetId, TARGET_MAX_BYTES);\r
@@ -959,55 +1098,13 @@ 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
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto ErrorExit;\r
   }\r
 \r
-  //\r
-  // Set Device Path\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
+  ScsiIoDevice->DevicePath = DevicePath;\r
 \r
-  if (ScsiIoDevice->DevicePath == NULL) {\r
-    gBS->FreePool (ScsiIoDevice);\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-  \r
   Status = gBS->InstallMultipleProtocolInterfaces (\r
                   &ScsiIoDevice->Handle,\r
                   &gEfiDevicePathProtocolGuid,\r
@@ -1017,53 +1114,64 @@ 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
+  //\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
-Routine Description:\r
+  if (DevicePath != NULL) {\r
+    FreePool (DevicePath);\r
+  }\r
 \r
-  Discovery SCSI Device\r
+  if (ScsiIoDevice != NULL) {\r
+    FreePool (ScsiIoDevice);\r
+  }\r
 \r
-Arguments:\r
+  return Status;\r
+}\r
 \r
-  ScsiIoDevice    - The pointer of SCSI_IO_DEV\r
 \r
-Returns:\r
+/**\r
+  Discovery SCSI Device\r
+\r
+  @param  ScsiIoDevice    The pointer of SCSI_IO_DEV\r
 \r
-  TRUE            - Find SCSI Device and verify it.\r
-  FALSE           - Unable to find SCSI Device.  \r
+  @retval  TRUE   Find SCSI Device and verify it.\r
+  @retval  FALSE  Unable to find SCSI Device.\r
 \r
---*/\r
+**/\r
+BOOLEAN\r
+DiscoverScsiDevice (\r
+  IN OUT  SCSI_IO_DEV   *ScsiIoDevice\r
+  )\r
 {\r
   EFI_STATUS            Status;\r
   UINT32                InquiryDataLength;\r
@@ -1072,6 +1180,8 @@ Returns:
   UINT8                 TargetStatus;\r
   EFI_SCSI_SENSE_DATA   SenseData;\r
   EFI_SCSI_INQUIRY_DATA InquiryData;\r
+  UINT8                 MaxRetry;\r
+  UINT8                 Index;\r
 \r
   HostAdapterStatus = 0;\r
   TargetStatus      = 0;\r
@@ -1079,25 +1189,35 @@ Returns:
   // Using Inquiry command to scan for the device\r
   //\r
   InquiryDataLength = sizeof (EFI_SCSI_INQUIRY_DATA);\r
-  SenseDataLength   = sizeof (EFI_SCSI_SENSE_DATA);\r
-\r
-  Status = SubmitInquiryCommand (\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
+  SenseDataLength   = (UINT8) sizeof (EFI_SCSI_SENSE_DATA);\r
+  ZeroMem (&InquiryData, InquiryDataLength);\r
+\r
+  MaxRetry = 2;\r
+  for (Index = 0; Index < MaxRetry; Index++) {\r
+    Status = ScsiInquiryCommand (\r
+              &ScsiIoDevice->ScsiIo,\r
+              EFI_TIMER_PERIOD_SECONDS (1),\r
+              (VOID *) &SenseData,\r
+              &SenseDataLength,\r
+              &HostAdapterStatus,\r
+              &TargetStatus,\r
+              (VOID *) &InquiryData,\r
+              &InquiryDataLength,\r
+              FALSE\r
+              );\r
+    if (!EFI_ERROR (Status)) {\r
+      break;\r
+    } else if ((Status == EFI_BAD_BUFFER_SIZE) || \r
+               (Status == EFI_INVALID_PARAMETER) ||\r
+               (Status == EFI_UNSUPPORTED)) {\r
+      return FALSE;\r
+    }\r
+  }\r
+\r
+  if (Index == MaxRetry) {\r
     return FALSE;\r
   }\r
+  \r
   //\r
   // Retrieved inquiry data successfully\r
   //\r
@@ -1112,52 +1232,41 @@ Returns:
     }\r
   }\r
 \r
-  if (0x1e >= InquiryData.Peripheral_Type >= 0xa) {\r
+  if (0x1e >= InquiryData.Peripheral_Type && InquiryData.Peripheral_Type >= 0xa) {\r
     return FALSE;\r
   }\r
-  \r
+\r
   //\r
   // valid device type and peripheral qualifier combination.\r
   //\r
   ScsiIoDevice->ScsiDeviceType  = InquiryData.Peripheral_Type;\r
-  ScsiIoDevice->RemovableDevice = InquiryData.RMB;\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
 }\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
@@ -1165,7 +1274,7 @@ Returns:
   if (Packet->DataDirection == EFI_SCSI_IO_DATA_DIRECTION_BIDIRECTIONAL) {\r
     return EFI_UNSUPPORTED;\r
   }\r
-  \r
+\r
   ZeroMem (CommandPacket, sizeof (EFI_SCSI_PASS_THRU_SCSI_REQUEST_PACKET));\r
 \r
   CommandPacket->Timeout           = Packet->Timeout;\r
@@ -1188,30 +1297,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
@@ -1229,56 +1327,44 @@ Returns:
     Packet->OutDataBuffer = ScsiPacket->DataBuffer;\r
     Packet->OutTransferLength = ScsiPacket->TransferLength;\r
   }\r
\r
+\r
   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
   EFI_EVENT                                CallerEvent;\r
-  SCSI_EVENT_DATA                          *PassData;                                     \r
+  SCSI_EVENT_DATA                          *PassData;\r
 \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
   //\r
   PassThruToScsiioPacket(ScsiPacket, Packet);\r
-  \r
+\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
@@ -1287,3 +1373,4 @@ Returns:
   gBS->CloseEvent(Event);\r
   gBS->SignalEvent(CallerEvent);\r
 }\r
+\r