]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdeModulePkg / Bus / Scsi / ScsiDiskDxe / ScsiDisk.c
index 1cacbb9b4a226f689e3769fc20e7b2abeff1f4e0..fbc236cb465e293c4130b56aef94a7b003c33f01 100644 (file)
@@ -1,21 +1,15 @@
 /** @file\r
   SCSI disk driver that layers on every SCSI IO protocol in the system.\r
 \r
-Copyright (c) 2006 - 2015, 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
-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 - 2019, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 1985 - 2022, American Megatrends International LLC.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
-\r
 #include "ScsiDisk.h"\r
 \r
-EFI_DRIVER_BINDING_PROTOCOL gScsiDiskDriverBinding = {\r
+EFI_DRIVER_BINDING_PROTOCOL  gScsiDiskDriverBinding = {\r
   ScsiDiskDriverBindingSupported,\r
   ScsiDiskDriverBindingStart,\r
   ScsiDiskDriverBindingStop,\r
@@ -24,7 +18,7 @@ EFI_DRIVER_BINDING_PROTOCOL gScsiDiskDriverBinding = {
   NULL\r
 };\r
 \r
-EFI_DISK_INFO_PROTOCOL gScsiDiskInfoProtocolTemplate = {\r
+EFI_DISK_INFO_PROTOCOL  gScsiDiskInfoProtocolTemplate = {\r
   EFI_DISK_INFO_SCSI_INTERFACE_GUID,\r
   ScsiDiskInfoInquiry,\r
   ScsiDiskInfoIdentify,\r
@@ -46,8 +40,8 @@ EFI_DISK_INFO_PROTOCOL gScsiDiskInfoProtocolTemplate = {
 **/\r
 VOID *\r
 AllocateAlignedBuffer (\r
-  IN SCSI_DISK_DEV            *ScsiDiskDevice,\r
-  IN UINTN                    BufferSize\r
+  IN SCSI_DISK_DEV  *ScsiDiskDevice,\r
+  IN UINTN          BufferSize\r
   )\r
 {\r
   return AllocateAlignedPages (EFI_SIZE_TO_PAGES (BufferSize), ScsiDiskDevice->ScsiIo->IoAlign);\r
@@ -65,8 +59,8 @@ AllocateAlignedBuffer (
 **/\r
 VOID\r
 FreeAlignedBuffer (\r
-  IN VOID                     *Buffer,\r
-  IN UINTN                    BufferSize\r
+  IN VOID   *Buffer,\r
+  IN UINTN  BufferSize\r
   )\r
 {\r
   if (Buffer != NULL) {\r
@@ -74,26 +68,53 @@ FreeAlignedBuffer (
   }\r
 }\r
 \r
+/**\r
+  Remove trailing spaces from the string.\r
+\r
+  @param String   The ASCII string to remove the trailing spaces.\r
+\r
+  @retval the new length of the string.\r
+**/\r
+UINTN\r
+RemoveTrailingSpaces (\r
+  IN OUT CHAR8  *String\r
+  )\r
+{\r
+  UINTN  Length;\r
+\r
+  Length = AsciiStrLen (String);\r
+  if (Length == 0) {\r
+    return 0;\r
+  }\r
+\r
+  while ((Length > 0) && (String[Length-1] == ' ')) {\r
+    Length--;\r
+  }\r
+\r
+  String[Length] = '\0';\r
+  return Length;\r
+}\r
+\r
 /**\r
   The user Entry Point for module ScsiDisk.\r
 \r
   The user code starts with this function.\r
 \r
-  @param  ImageHandle    The firmware allocated handle for the EFI image.  \r
+  @param  ImageHandle    The firmware allocated handle for the EFI image.\r
   @param  SystemTable    A pointer to the EFI System Table.\r
-  \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
 EFIAPI\r
-InitializeScsiDisk(\r
-  IN EFI_HANDLE           ImageHandle,\r
-  IN EFI_SYSTEM_TABLE     *SystemTable\r
+InitializeScsiDisk (\r
+  IN EFI_HANDLE        ImageHandle,\r
+  IN EFI_SYSTEM_TABLE  *SystemTable\r
   )\r
 {\r
-  EFI_STATUS              Status;\r
+  EFI_STATUS  Status;\r
 \r
   //\r
   // Install driver model protocol(s).\r
@@ -108,7 +129,6 @@ InitializeScsiDisk(
              );\r
   ASSERT_EFI_ERROR (Status);\r
 \r
-\r
   return Status;\r
 }\r
 \r
@@ -146,7 +166,7 @@ ScsiDiskDriverBindingSupported (
   Status = gBS->OpenProtocol (\r
                   Controller,\r
                   &gEfiScsiIoProtocolGuid,\r
-                  (VOID **) &ScsiIo,\r
+                  (VOID **)&ScsiIo,\r
                   This->DriverBindingHandle,\r
                   Controller,\r
                   EFI_OPEN_PROTOCOL_BY_DRIVER\r
@@ -157,7 +177,10 @@ ScsiDiskDriverBindingSupported (
 \r
   Status = ScsiIo->GetDeviceType (ScsiIo, &DeviceType);\r
   if (!EFI_ERROR (Status)) {\r
-    if ((DeviceType == EFI_SCSI_TYPE_DISK) || (DeviceType == EFI_SCSI_TYPE_CDROM)) {\r
+    if ((DeviceType == EFI_SCSI_TYPE_DISK) ||\r
+        (DeviceType == EFI_SCSI_TYPE_CDROM) ||\r
+        (DeviceType == EFI_SCSI_TYPE_WLUN))\r
+    {\r
       Status = EFI_SUCCESS;\r
     } else {\r
       Status = EFI_UNSUPPORTED;\r
@@ -173,7 +196,6 @@ ScsiDiskDriverBindingSupported (
   return Status;\r
 }\r
 \r
-\r
 /**\r
   Start this driver on ControllerHandle.\r
 \r
@@ -209,10 +231,13 @@ ScsiDiskDriverBindingStart (
   UINT8                 MaxRetry;\r
   BOOLEAN               NeedRetry;\r
   BOOLEAN               MustReadCapacity;\r
+  CHAR8                 VendorStr[VENDOR_IDENTIFICATION_LENGTH + 1];\r
+  CHAR8                 ProductStr[PRODUCT_IDENTIFICATION_LENGTH + 1];\r
+  CHAR16                DeviceStr[VENDOR_IDENTIFICATION_LENGTH + PRODUCT_IDENTIFICATION_LENGTH + 2];\r
 \r
   MustReadCapacity = TRUE;\r
 \r
-  ScsiDiskDevice = (SCSI_DISK_DEV *) AllocateZeroPool (sizeof (SCSI_DISK_DEV));\r
+  ScsiDiskDevice = (SCSI_DISK_DEV *)AllocateZeroPool (sizeof (SCSI_DISK_DEV));\r
   if (ScsiDiskDevice == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
@@ -220,7 +245,7 @@ ScsiDiskDriverBindingStart (
   Status = gBS->OpenProtocol (\r
                   Controller,\r
                   &gEfiScsiIoProtocolGuid,\r
-                  (VOID **) &ScsiIo,\r
+                  (VOID **)&ScsiIo,\r
                   This->DriverBindingHandle,\r
                   Controller,\r
                   EFI_OPEN_PROTOCOL_BY_DRIVER\r
@@ -230,50 +255,62 @@ ScsiDiskDriverBindingStart (
     return Status;\r
   }\r
 \r
-  ScsiDiskDevice->Signature            = SCSI_DISK_DEV_SIGNATURE;\r
-  ScsiDiskDevice->ScsiIo               = ScsiIo;\r
-  ScsiDiskDevice->BlkIo.Revision       = EFI_BLOCK_IO_PROTOCOL_REVISION3;\r
-  ScsiDiskDevice->BlkIo.Media          = &ScsiDiskDevice->BlkIoMedia;\r
-  ScsiDiskDevice->BlkIo.Media->IoAlign = ScsiIo->IoAlign;\r
-  ScsiDiskDevice->BlkIo.Reset          = ScsiDiskReset;\r
-  ScsiDiskDevice->BlkIo.ReadBlocks     = ScsiDiskReadBlocks;\r
-  ScsiDiskDevice->BlkIo.WriteBlocks    = ScsiDiskWriteBlocks;\r
-  ScsiDiskDevice->BlkIo.FlushBlocks    = ScsiDiskFlushBlocks;\r
-  ScsiDiskDevice->BlkIo2.Media         = &ScsiDiskDevice->BlkIoMedia;\r
-  ScsiDiskDevice->BlkIo2.Reset         = ScsiDiskResetEx;\r
-  ScsiDiskDevice->BlkIo2.ReadBlocksEx  = ScsiDiskReadBlocksEx;\r
-  ScsiDiskDevice->BlkIo2.WriteBlocksEx = ScsiDiskWriteBlocksEx;\r
-  ScsiDiskDevice->BlkIo2.FlushBlocksEx = ScsiDiskFlushBlocksEx;\r
-  ScsiDiskDevice->Handle               = Controller;\r
-  InitializeListHead (&ScsiDiskDevice->BlkIo2Queue);\r
+  ScsiDiskDevice->Signature                         = SCSI_DISK_DEV_SIGNATURE;\r
+  ScsiDiskDevice->ScsiIo                            = ScsiIo;\r
+  ScsiDiskDevice->BlkIo.Revision                    = EFI_BLOCK_IO_PROTOCOL_REVISION3;\r
+  ScsiDiskDevice->BlkIo.Media                       = &ScsiDiskDevice->BlkIoMedia;\r
+  ScsiDiskDevice->BlkIo.Media->IoAlign              = ScsiIo->IoAlign;\r
+  ScsiDiskDevice->BlkIo.Reset                       = ScsiDiskReset;\r
+  ScsiDiskDevice->BlkIo.ReadBlocks                  = ScsiDiskReadBlocks;\r
+  ScsiDiskDevice->BlkIo.WriteBlocks                 = ScsiDiskWriteBlocks;\r
+  ScsiDiskDevice->BlkIo.FlushBlocks                 = ScsiDiskFlushBlocks;\r
+  ScsiDiskDevice->BlkIo2.Media                      = &ScsiDiskDevice->BlkIoMedia;\r
+  ScsiDiskDevice->BlkIo2.Reset                      = ScsiDiskResetEx;\r
+  ScsiDiskDevice->BlkIo2.ReadBlocksEx               = ScsiDiskReadBlocksEx;\r
+  ScsiDiskDevice->BlkIo2.WriteBlocksEx              = ScsiDiskWriteBlocksEx;\r
+  ScsiDiskDevice->BlkIo2.FlushBlocksEx              = ScsiDiskFlushBlocksEx;\r
+  ScsiDiskDevice->StorageSecurity.ReceiveData       = ScsiDiskReceiveData;\r
+  ScsiDiskDevice->StorageSecurity.SendData          = ScsiDiskSendData;\r
+  ScsiDiskDevice->EraseBlock.Revision               = EFI_ERASE_BLOCK_PROTOCOL_REVISION;\r
+  ScsiDiskDevice->EraseBlock.EraseLengthGranularity = 1;\r
+  ScsiDiskDevice->EraseBlock.EraseBlocks            = ScsiDiskEraseBlocks;\r
+  ScsiDiskDevice->UnmapInfo.MaxBlkDespCnt           = 1;\r
+  ScsiDiskDevice->BlockLimitsVpdSupported           = FALSE;\r
+  ScsiDiskDevice->Handle                            = Controller;\r
+  InitializeListHead (&ScsiDiskDevice->AsyncTaskQueue);\r
 \r
   ScsiIo->GetDeviceType (ScsiIo, &(ScsiDiskDevice->DeviceType));\r
   switch (ScsiDiskDevice->DeviceType) {\r
-  case EFI_SCSI_TYPE_DISK:\r
-    ScsiDiskDevice->BlkIo.Media->BlockSize = 0x200;\r
-    MustReadCapacity = TRUE;\r
-    break;\r
+    case EFI_SCSI_TYPE_DISK:\r
+      ScsiDiskDevice->BlkIo.Media->BlockSize = 0x200;\r
+      MustReadCapacity                       = TRUE;\r
+      break;\r
 \r
-  case EFI_SCSI_TYPE_CDROM:\r
-    ScsiDiskDevice->BlkIo.Media->BlockSize = 0x800;\r
-    ScsiDiskDevice->BlkIo.Media->ReadOnly  = TRUE;\r
-    MustReadCapacity = FALSE;\r
-    break;\r
+    case EFI_SCSI_TYPE_CDROM:\r
+      ScsiDiskDevice->BlkIo.Media->BlockSize = 0x800;\r
+      ScsiDiskDevice->BlkIo.Media->ReadOnly  = TRUE;\r
+      MustReadCapacity                       = FALSE;\r
+      break;\r
+\r
+    case EFI_SCSI_TYPE_WLUN:\r
+      MustReadCapacity = FALSE;\r
+      break;\r
   }\r
+\r
   //\r
   // The Sense Data Array's initial size is 6\r
   //\r
   ScsiDiskDevice->SenseDataNumber = 6;\r
-  ScsiDiskDevice->SenseData = (EFI_SCSI_SENSE_DATA *) AllocateZeroPool (\r
-                                 sizeof (EFI_SCSI_SENSE_DATA) * ScsiDiskDevice->SenseDataNumber\r
-                                 );\r
+  ScsiDiskDevice->SenseData       = (EFI_SCSI_SENSE_DATA *)AllocateZeroPool (\r
+                                                             sizeof (EFI_SCSI_SENSE_DATA) * ScsiDiskDevice->SenseDataNumber\r
+                                                             );\r
   if (ScsiDiskDevice->SenseData == NULL) {\r
     gBS->CloseProtocol (\r
-          Controller,\r
-          &gEfiScsiIoProtocolGuid,\r
-          This->DriverBindingHandle,\r
-          Controller\r
-          );\r
+           Controller,\r
+           &gEfiScsiIoProtocolGuid,\r
+           This->DriverBindingHandle,\r
+           Controller\r
+           );\r
     FreePool (ScsiDiskDevice);\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
@@ -300,6 +337,7 @@ ScsiDiskDriverBindingStart (
       return EFI_DEVICE_ERROR;\r
     }\r
   }\r
+\r
   //\r
   // The second parameter "TRUE" means must\r
   // retrieve media capacity\r
@@ -310,8 +348,8 @@ ScsiDiskDriverBindingStart (
     // Determine if Block IO & Block IO2 should be produced on this controller\r
     // handle\r
     //\r
-    if (DetermineInstallBlockIo(Controller)) {\r
-      InitializeInstallDiskInfo(ScsiDiskDevice, Controller);\r
+    if (DetermineInstallBlockIo (Controller)) {\r
+      InitializeInstallDiskInfo (ScsiDiskDevice, Controller);\r
       Status = gBS->InstallMultipleProtocolInterfaces (\r
                       &Controller,\r
                       &gEfiBlockIoProtocolGuid,\r
@@ -322,25 +360,67 @@ ScsiDiskDriverBindingStart (
                       &ScsiDiskDevice->DiskInfo,\r
                       NULL\r
                       );\r
-      if (!EFI_ERROR(Status)) {\r
+      if (!EFI_ERROR (Status)) {\r
+        if (DetermineInstallEraseBlock (ScsiDiskDevice, Controller)) {\r
+          Status = gBS->InstallProtocolInterface (\r
+                          &Controller,\r
+                          &gEfiEraseBlockProtocolGuid,\r
+                          EFI_NATIVE_INTERFACE,\r
+                          &ScsiDiskDevice->EraseBlock\r
+                          );\r
+          if (EFI_ERROR (Status)) {\r
+            DEBUG ((DEBUG_ERROR, "ScsiDisk: Failed to install the Erase Block Protocol! Status = %r\n", Status));\r
+          }\r
+        }\r
+\r
+        if (DetermineInstallStorageSecurity (ScsiDiskDevice, Controller)) {\r
+          Status = gBS->InstallProtocolInterface (\r
+                          &Controller,\r
+                          &gEfiStorageSecurityCommandProtocolGuid,\r
+                          EFI_NATIVE_INTERFACE,\r
+                          &ScsiDiskDevice->StorageSecurity\r
+                          );\r
+          if (EFI_ERROR (Status)) {\r
+            DEBUG ((DEBUG_ERROR, "ScsiDisk: Failed to install the Storage Security Command Protocol! Status = %r\n", Status));\r
+          }\r
+        }\r
+\r
+        CopyMem (\r
+          VendorStr,\r
+          &ScsiDiskDevice->InquiryData.Reserved_5_95[VENDOR_IDENTIFICATION_OFFSET],\r
+          VENDOR_IDENTIFICATION_LENGTH\r
+          );\r
+        VendorStr[VENDOR_IDENTIFICATION_LENGTH] = 0;\r
+        RemoveTrailingSpaces (VendorStr);\r
+\r
+        CopyMem (\r
+          ProductStr,\r
+          &ScsiDiskDevice->InquiryData.Reserved_5_95[PRODUCT_IDENTIFICATION_OFFSET],\r
+          PRODUCT_IDENTIFICATION_LENGTH\r
+          );\r
+        ProductStr[PRODUCT_IDENTIFICATION_LENGTH] = 0;\r
+        RemoveTrailingSpaces (ProductStr);\r
+\r
+        UnicodeSPrint (DeviceStr, sizeof (DeviceStr), L"%a %a", VendorStr, ProductStr);\r
+\r
         ScsiDiskDevice->ControllerNameTable = NULL;\r
         AddUnicodeString2 (\r
           "eng",\r
           gScsiDiskComponentName.SupportedLanguages,\r
           &ScsiDiskDevice->ControllerNameTable,\r
-          L"SCSI Disk Device",\r
+          DeviceStr,\r
           TRUE\r
           );\r
         AddUnicodeString2 (\r
           "en",\r
           gScsiDiskComponentName2.SupportedLanguages,\r
           &ScsiDiskDevice->ControllerNameTable,\r
-          L"SCSI Disk Device",\r
+          DeviceStr,\r
           FALSE\r
           );\r
         return EFI_SUCCESS;\r
       }\r
-    } \r
+    }\r
   }\r
 \r
   gBS->FreePool (ScsiDiskDevice->SenseData);\r
@@ -352,10 +432,8 @@ ScsiDiskDriverBindingStart (
          Controller\r
          );\r
   return Status;\r
-  \r
 }\r
 \r
-\r
 /**\r
   Stop this driver on ControllerHandle.\r
 \r
@@ -364,7 +442,7 @@ ScsiDiskDriverBindingStart (
   restrictions for this service. DisconnectController() must follow these\r
   calling restrictions. If any other agent wishes to call Stop() it must\r
   also follow these calling restrictions.\r
-  \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
@@ -378,20 +456,21 @@ ScsiDiskDriverBindingStart (
 EFI_STATUS\r
 EFIAPI\r
 ScsiDiskDriverBindingStop (\r
-  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,\r
-  IN  EFI_HANDLE                      Controller,\r
-  IN  UINTN                           NumberOfChildren,\r
-  IN  EFI_HANDLE                      *ChildHandleBuffer   OPTIONAL\r
+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,\r
+  IN  EFI_HANDLE                   Controller,\r
+  IN  UINTN                        NumberOfChildren,\r
+  IN  EFI_HANDLE                   *ChildHandleBuffer   OPTIONAL\r
   )\r
 {\r
-  EFI_BLOCK_IO_PROTOCOL *BlkIo;\r
-  SCSI_DISK_DEV         *ScsiDiskDevice;\r
-  EFI_STATUS            Status;\r
+  EFI_BLOCK_IO_PROTOCOL     *BlkIo;\r
+  EFI_ERASE_BLOCK_PROTOCOL  *EraseBlock;\r
+  SCSI_DISK_DEV             *ScsiDiskDevice;\r
+  EFI_STATUS                Status;\r
 \r
   Status = gBS->OpenProtocol (\r
                   Controller,\r
                   &gEfiBlockIoProtocolGuid,\r
-                  (VOID **) &BlkIo,\r
+                  (VOID **)&BlkIo,\r
                   This->DriverBindingHandle,\r
                   Controller,\r
                   EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
@@ -405,7 +484,31 @@ ScsiDiskDriverBindingStop (
   //\r
   // Wait for the BlockIo2 requests queue to become empty\r
   //\r
-  while (!IsListEmpty (&ScsiDiskDevice->BlkIo2Queue));\r
+  while (!IsListEmpty (&ScsiDiskDevice->AsyncTaskQueue)) {\r
+  }\r
+\r
+  //\r
+  // If Erase Block Protocol is installed, then uninstall this protocol.\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                  Controller,\r
+                  &gEfiEraseBlockProtocolGuid,\r
+                  (VOID **)&EraseBlock,\r
+                  This->DriverBindingHandle,\r
+                  Controller,\r
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                  );\r
+\r
+  if (!EFI_ERROR (Status)) {\r
+    Status = gBS->UninstallProtocolInterface (\r
+                    Controller,\r
+                    &gEfiEraseBlockProtocolGuid,\r
+                    &ScsiDiskDevice->EraseBlock\r
+                    );\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+  }\r
 \r
   Status = gBS->UninstallMultipleProtocolInterfaces (\r
                   Controller,\r
@@ -429,6 +532,7 @@ ScsiDiskDriverBindingStop (
 \r
     return EFI_SUCCESS;\r
   }\r
+\r
   //\r
   // errors met\r
   //\r
@@ -451,23 +555,27 @@ ScsiDiskDriverBindingStop (
 EFI_STATUS\r
 EFIAPI\r
 ScsiDiskReset (\r
-  IN  EFI_BLOCK_IO_PROTOCOL   *This,\r
-  IN  BOOLEAN                 ExtendedVerification\r
+  IN  EFI_BLOCK_IO_PROTOCOL  *This,\r
+  IN  BOOLEAN                ExtendedVerification\r
   )\r
 {\r
-  EFI_TPL       OldTpl;\r
-  SCSI_DISK_DEV *ScsiDiskDevice;\r
-  EFI_STATUS    Status;\r
+  EFI_TPL        OldTpl;\r
+  SCSI_DISK_DEV  *ScsiDiskDevice;\r
+  EFI_STATUS     Status;\r
 \r
   OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
 \r
-  ScsiDiskDevice  = SCSI_DISK_DEV_FROM_BLKIO (This);\r
+  ScsiDiskDevice = SCSI_DISK_DEV_FROM_BLKIO (This);\r
 \r
-  Status          = ScsiDiskDevice->ScsiIo->ResetDevice (ScsiDiskDevice->ScsiIo);\r
+  Status = ScsiDiskDevice->ScsiIo->ResetDevice (ScsiDiskDevice->ScsiIo);\r
 \r
   if (EFI_ERROR (Status)) {\r
-    Status = EFI_DEVICE_ERROR;\r
-    goto Done;\r
+    if (Status == EFI_UNSUPPORTED) {\r
+      Status = EFI_SUCCESS;\r
+    } else {\r
+      Status = EFI_DEVICE_ERROR;\r
+      goto Done;\r
+    }\r
   }\r
 \r
   if (!ExtendedVerification) {\r
@@ -506,11 +614,11 @@ Done:
 EFI_STATUS\r
 EFIAPI\r
 ScsiDiskReadBlocks (\r
-  IN  EFI_BLOCK_IO_PROTOCOL   *This,\r
-  IN  UINT32                  MediaId,\r
-  IN  EFI_LBA                 Lba,\r
-  IN  UINTN                   BufferSize,\r
-  OUT VOID                    *Buffer\r
+  IN  EFI_BLOCK_IO_PROTOCOL  *This,\r
+  IN  UINT32                 MediaId,\r
+  IN  EFI_LBA                Lba,\r
+  IN  UINTN                  BufferSize,\r
+  OUT VOID                   *Buffer\r
   )\r
 {\r
   SCSI_DISK_DEV       *ScsiDiskDevice;\r
@@ -524,9 +632,9 @@ ScsiDiskReadBlocks (
   MediaChange    = FALSE;\r
   OldTpl         = gBS->RaiseTPL (TPL_CALLBACK);\r
   ScsiDiskDevice = SCSI_DISK_DEV_FROM_BLKIO (This);\r
+  Media          = ScsiDiskDevice->BlkIo.Media;\r
 \r
-  if (!IS_DEVICE_FIXED(ScsiDiskDevice)) {\r
-\r
+  if (!IS_DEVICE_FIXED (ScsiDiskDevice)) {\r
     Status = ScsiDiskDetectMedia (ScsiDiskDevice, FALSE, &MediaChange);\r
     if (EFI_ERROR (Status)) {\r
       Status = EFI_DEVICE_ERROR;\r
@@ -535,28 +643,56 @@ ScsiDiskReadBlocks (
 \r
     if (MediaChange) {\r
       gBS->ReinstallProtocolInterface (\r
-            ScsiDiskDevice->Handle,\r
-            &gEfiBlockIoProtocolGuid,\r
-            &ScsiDiskDevice->BlkIo,\r
-            &ScsiDiskDevice->BlkIo\r
-            );\r
+             ScsiDiskDevice->Handle,\r
+             &gEfiBlockIoProtocolGuid,\r
+             &ScsiDiskDevice->BlkIo,\r
+             &ScsiDiskDevice->BlkIo\r
+             );\r
       gBS->ReinstallProtocolInterface (\r
              ScsiDiskDevice->Handle,\r
              &gEfiBlockIo2ProtocolGuid,\r
              &ScsiDiskDevice->BlkIo2,\r
              &ScsiDiskDevice->BlkIo2\r
              );\r
-      Status = EFI_MEDIA_CHANGED;\r
+      if (DetermineInstallEraseBlock (ScsiDiskDevice, ScsiDiskDevice->Handle)) {\r
+        gBS->ReinstallProtocolInterface (\r
+               ScsiDiskDevice->Handle,\r
+               &gEfiEraseBlockProtocolGuid,\r
+               &ScsiDiskDevice->EraseBlock,\r
+               &ScsiDiskDevice->EraseBlock\r
+               );\r
+      }\r
+\r
+      if (DetermineInstallStorageSecurity (ScsiDiskDevice, ScsiDiskDevice->Handle)) {\r
+        gBS->ReinstallProtocolInterface (\r
+               ScsiDiskDevice->Handle,\r
+               &gEfiStorageSecurityCommandProtocolGuid,\r
+               &ScsiDiskDevice->StorageSecurity,\r
+               &ScsiDiskDevice->StorageSecurity\r
+               );\r
+      }\r
+\r
+      if (Media->MediaPresent) {\r
+        Status = EFI_MEDIA_CHANGED;\r
+      } else {\r
+        Status = EFI_NO_MEDIA;\r
+      }\r
+\r
       goto Done;\r
     }\r
   }\r
+\r
   //\r
   // Get the intrinsic block size\r
   //\r
-  Media           = ScsiDiskDevice->BlkIo.Media;\r
-  BlockSize       = Media->BlockSize;\r
+  BlockSize = Media->BlockSize;\r
+\r
+  if (BlockSize == 0) {\r
+    Status = EFI_DEVICE_ERROR;\r
+    goto Done;\r
+  }\r
 \r
-  NumberOfBlocks  = BufferSize / BlockSize;\r
+  NumberOfBlocks = BufferSize / BlockSize;\r
 \r
   if (!(Media->MediaPresent)) {\r
     Status = EFI_NO_MEDIA;\r
@@ -593,7 +729,7 @@ ScsiDiskReadBlocks (
     goto Done;\r
   }\r
 \r
-  if ((Media->IoAlign > 1) && (((UINTN) Buffer & (Media->IoAlign - 1)) != 0)) {\r
+  if ((Media->IoAlign > 1) && (((UINTN)Buffer & (Media->IoAlign - 1)) != 0)) {\r
     Status = EFI_INVALID_PARAMETER;\r
     goto Done;\r
   }\r
@@ -622,7 +758,7 @@ Done:
   @retval EFI_WRITE_PROTECTED   The device can not be written to.\r
   @retval EFI_DEVICE_ERROR      Fail to detect media.\r
   @retval EFI_NO_MEDIA          Media is not present.\r
-  @retval EFI_MEDIA_CHNAGED     Media has changed.\r
+  @retval EFI_MEDIA_CHANGED     Media has changed.\r
   @retval EFI_BAD_BUFFER_SIZE   The Buffer was not a multiple of the block size of the device.\r
   @retval EFI_INVALID_PARAMETER Invalid parameter passed in.\r
 \r
@@ -630,11 +766,11 @@ Done:
 EFI_STATUS\r
 EFIAPI\r
 ScsiDiskWriteBlocks (\r
-  IN  EFI_BLOCK_IO_PROTOCOL   *This,\r
-  IN  UINT32                  MediaId,\r
-  IN  EFI_LBA                 Lba,\r
-  IN  UINTN                   BufferSize,\r
-  IN  VOID                    *Buffer\r
+  IN  EFI_BLOCK_IO_PROTOCOL  *This,\r
+  IN  UINT32                 MediaId,\r
+  IN  EFI_LBA                Lba,\r
+  IN  UINTN                  BufferSize,\r
+  IN  VOID                   *Buffer\r
   )\r
 {\r
   SCSI_DISK_DEV       *ScsiDiskDevice;\r
@@ -648,9 +784,9 @@ ScsiDiskWriteBlocks (
   MediaChange    = FALSE;\r
   OldTpl         = gBS->RaiseTPL (TPL_CALLBACK);\r
   ScsiDiskDevice = SCSI_DISK_DEV_FROM_BLKIO (This);\r
+  Media          = ScsiDiskDevice->BlkIo.Media;\r
 \r
-  if (!IS_DEVICE_FIXED(ScsiDiskDevice)) {\r
-\r
+  if (!IS_DEVICE_FIXED (ScsiDiskDevice)) {\r
     Status = ScsiDiskDetectMedia (ScsiDiskDevice, FALSE, &MediaChange);\r
     if (EFI_ERROR (Status)) {\r
       Status = EFI_DEVICE_ERROR;\r
@@ -659,28 +795,56 @@ ScsiDiskWriteBlocks (
 \r
     if (MediaChange) {\r
       gBS->ReinstallProtocolInterface (\r
-            ScsiDiskDevice->Handle,\r
-            &gEfiBlockIoProtocolGuid,\r
-            &ScsiDiskDevice->BlkIo,\r
-            &ScsiDiskDevice->BlkIo\r
-            );\r
+             ScsiDiskDevice->Handle,\r
+             &gEfiBlockIoProtocolGuid,\r
+             &ScsiDiskDevice->BlkIo,\r
+             &ScsiDiskDevice->BlkIo\r
+             );\r
       gBS->ReinstallProtocolInterface (\r
              ScsiDiskDevice->Handle,\r
              &gEfiBlockIo2ProtocolGuid,\r
              &ScsiDiskDevice->BlkIo2,\r
              &ScsiDiskDevice->BlkIo2\r
              );\r
-      Status = EFI_MEDIA_CHANGED;\r
+      if (DetermineInstallEraseBlock (ScsiDiskDevice, ScsiDiskDevice->Handle)) {\r
+        gBS->ReinstallProtocolInterface (\r
+               ScsiDiskDevice->Handle,\r
+               &gEfiEraseBlockProtocolGuid,\r
+               &ScsiDiskDevice->EraseBlock,\r
+               &ScsiDiskDevice->EraseBlock\r
+               );\r
+      }\r
+\r
+      if (DetermineInstallStorageSecurity (ScsiDiskDevice, ScsiDiskDevice->Handle)) {\r
+        gBS->ReinstallProtocolInterface (\r
+               ScsiDiskDevice->Handle,\r
+               &gEfiStorageSecurityCommandProtocolGuid,\r
+               &ScsiDiskDevice->StorageSecurity,\r
+               &ScsiDiskDevice->StorageSecurity\r
+               );\r
+      }\r
+\r
+      if (Media->MediaPresent) {\r
+        Status = EFI_MEDIA_CHANGED;\r
+      } else {\r
+        Status = EFI_NO_MEDIA;\r
+      }\r
+\r
       goto Done;\r
     }\r
   }\r
+\r
   //\r
   // Get the intrinsic block size\r
   //\r
-  Media           = ScsiDiskDevice->BlkIo.Media;\r
-  BlockSize       = Media->BlockSize;\r
+  BlockSize = Media->BlockSize;\r
+\r
+  if (BlockSize == 0) {\r
+    Status = EFI_DEVICE_ERROR;\r
+    goto Done;\r
+  }\r
 \r
-  NumberOfBlocks  = BufferSize / BlockSize;\r
+  NumberOfBlocks = BufferSize / BlockSize;\r
 \r
   if (!(Media->MediaPresent)) {\r
     Status = EFI_NO_MEDIA;\r
@@ -722,10 +886,11 @@ ScsiDiskWriteBlocks (
     goto Done;\r
   }\r
 \r
-  if ((Media->IoAlign > 1) && (((UINTN) Buffer & (Media->IoAlign - 1)) != 0)) {\r
+  if ((Media->IoAlign > 1) && (((UINTN)Buffer & (Media->IoAlign - 1)) != 0)) {\r
     Status = EFI_INVALID_PARAMETER;\r
     goto Done;\r
   }\r
+\r
   //\r
   // if all the parameters are valid, then perform read sectors command\r
   // to transfer data from device to host.\r
@@ -750,7 +915,7 @@ Done:
 EFI_STATUS\r
 EFIAPI\r
 ScsiDiskFlushBlocks (\r
-  IN  EFI_BLOCK_IO_PROTOCOL   *This\r
+  IN  EFI_BLOCK_IO_PROTOCOL  *This\r
   )\r
 {\r
   //\r
@@ -759,7 +924,6 @@ ScsiDiskFlushBlocks (
   return EFI_SUCCESS;\r
 }\r
 \r
-\r
 /**\r
   Reset SCSI Disk.\r
 \r
@@ -779,19 +943,23 @@ ScsiDiskResetEx (
   IN  BOOLEAN                 ExtendedVerification\r
   )\r
 {\r
-  EFI_TPL       OldTpl;\r
-  SCSI_DISK_DEV *ScsiDiskDevice;\r
-  EFI_STATUS    Status;\r
+  EFI_TPL        OldTpl;\r
+  SCSI_DISK_DEV  *ScsiDiskDevice;\r
+  EFI_STATUS     Status;\r
 \r
   OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
 \r
-  ScsiDiskDevice  = SCSI_DISK_DEV_FROM_BLKIO2 (This);\r
+  ScsiDiskDevice = SCSI_DISK_DEV_FROM_BLKIO2 (This);\r
 \r
-  Status          = ScsiDiskDevice->ScsiIo->ResetDevice (ScsiDiskDevice->ScsiIo);\r
+  Status = ScsiDiskDevice->ScsiIo->ResetDevice (ScsiDiskDevice->ScsiIo);\r
 \r
   if (EFI_ERROR (Status)) {\r
-    Status = EFI_DEVICE_ERROR;\r
-    goto Done;\r
+    if (Status == EFI_UNSUPPORTED) {\r
+      Status = EFI_SUCCESS;\r
+    } else {\r
+      Status = EFI_DEVICE_ERROR;\r
+      goto Done;\r
+    }\r
   }\r
 \r
   if (!ExtendedVerification) {\r
@@ -839,12 +1007,12 @@ Done:
 EFI_STATUS\r
 EFIAPI\r
 ScsiDiskReadBlocksEx (\r
-  IN     EFI_BLOCK_IO2_PROTOCOL   *This,\r
-  IN     UINT32                   MediaId,\r
-  IN     EFI_LBA                  Lba,\r
-  IN OUT EFI_BLOCK_IO2_TOKEN      *Token,\r
-  IN     UINTN                    BufferSize,\r
-  OUT    VOID                     *Buffer\r
+  IN     EFI_BLOCK_IO2_PROTOCOL  *This,\r
+  IN     UINT32                  MediaId,\r
+  IN     EFI_LBA                 Lba,\r
+  IN OUT EFI_BLOCK_IO2_TOKEN     *Token,\r
+  IN     UINTN                   BufferSize,\r
+  OUT    VOID                    *Buffer\r
   )\r
 {\r
   SCSI_DISK_DEV       *ScsiDiskDevice;\r
@@ -858,9 +1026,9 @@ ScsiDiskReadBlocksEx (
   MediaChange    = FALSE;\r
   OldTpl         = gBS->RaiseTPL (TPL_CALLBACK);\r
   ScsiDiskDevice = SCSI_DISK_DEV_FROM_BLKIO2 (This);\r
+  Media          = ScsiDiskDevice->BlkIo.Media;\r
 \r
-  if (!IS_DEVICE_FIXED(ScsiDiskDevice)) {\r
-\r
+  if (!IS_DEVICE_FIXED (ScsiDiskDevice)) {\r
     Status = ScsiDiskDetectMedia (ScsiDiskDevice, FALSE, &MediaChange);\r
     if (EFI_ERROR (Status)) {\r
       Status = EFI_DEVICE_ERROR;\r
@@ -869,28 +1037,56 @@ ScsiDiskReadBlocksEx (
 \r
     if (MediaChange) {\r
       gBS->ReinstallProtocolInterface (\r
-            ScsiDiskDevice->Handle,\r
-            &gEfiBlockIoProtocolGuid,\r
-            &ScsiDiskDevice->BlkIo,\r
-            &ScsiDiskDevice->BlkIo\r
-            );\r
+             ScsiDiskDevice->Handle,\r
+             &gEfiBlockIoProtocolGuid,\r
+             &ScsiDiskDevice->BlkIo,\r
+             &ScsiDiskDevice->BlkIo\r
+             );\r
       gBS->ReinstallProtocolInterface (\r
              ScsiDiskDevice->Handle,\r
              &gEfiBlockIo2ProtocolGuid,\r
              &ScsiDiskDevice->BlkIo2,\r
              &ScsiDiskDevice->BlkIo2\r
              );\r
-      Status = EFI_MEDIA_CHANGED;\r
+      if (DetermineInstallEraseBlock (ScsiDiskDevice, ScsiDiskDevice->Handle)) {\r
+        gBS->ReinstallProtocolInterface (\r
+               ScsiDiskDevice->Handle,\r
+               &gEfiEraseBlockProtocolGuid,\r
+               &ScsiDiskDevice->EraseBlock,\r
+               &ScsiDiskDevice->EraseBlock\r
+               );\r
+      }\r
+\r
+      if (DetermineInstallStorageSecurity (ScsiDiskDevice, ScsiDiskDevice->Handle)) {\r
+        gBS->ReinstallProtocolInterface (\r
+               ScsiDiskDevice->Handle,\r
+               &gEfiStorageSecurityCommandProtocolGuid,\r
+               &ScsiDiskDevice->StorageSecurity,\r
+               &ScsiDiskDevice->StorageSecurity\r
+               );\r
+      }\r
+\r
+      if (Media->MediaPresent) {\r
+        Status = EFI_MEDIA_CHANGED;\r
+      } else {\r
+        Status = EFI_NO_MEDIA;\r
+      }\r
+\r
       goto Done;\r
     }\r
   }\r
+\r
   //\r
   // Get the intrinsic block size\r
   //\r
-  Media           = ScsiDiskDevice->BlkIo2.Media;\r
-  BlockSize       = Media->BlockSize;\r
+  BlockSize = Media->BlockSize;\r
+\r
+  if (BlockSize == 0) {\r
+    Status = EFI_DEVICE_ERROR;\r
+    goto Done;\r
+  }\r
 \r
-  NumberOfBlocks  = BufferSize / BlockSize;\r
+  NumberOfBlocks = BufferSize / BlockSize;\r
 \r
   if (!(Media->MediaPresent)) {\r
     Status = EFI_NO_MEDIA;\r
@@ -932,7 +1128,7 @@ ScsiDiskReadBlocksEx (
     goto Done;\r
   }\r
 \r
-  if ((Media->IoAlign > 1) && (((UINTN) Buffer & (Media->IoAlign - 1)) != 0)) {\r
+  if ((Media->IoAlign > 1) && (((UINTN)Buffer & (Media->IoAlign - 1)) != 0)) {\r
     Status = EFI_INVALID_PARAMETER;\r
     goto Done;\r
   }\r
@@ -943,13 +1139,13 @@ ScsiDiskReadBlocksEx (
   //\r
   if ((Token != NULL) && (Token->Event != NULL)) {\r
     Token->TransactionStatus = EFI_SUCCESS;\r
-    Status = ScsiDiskAsyncReadSectors (\r
-               ScsiDiskDevice,\r
-               Buffer,\r
-               Lba,\r
-               NumberOfBlocks,\r
-               Token\r
-               );\r
+    Status                   = ScsiDiskAsyncReadSectors (\r
+                                 ScsiDiskDevice,\r
+                                 Buffer,\r
+                                 Lba,\r
+                                 NumberOfBlocks,\r
+                                 Token\r
+                                 );\r
   } else {\r
     Status = ScsiDiskReadSectors (\r
                ScsiDiskDevice,\r
@@ -990,12 +1186,12 @@ Done:
 EFI_STATUS\r
 EFIAPI\r
 ScsiDiskWriteBlocksEx (\r
-  IN     EFI_BLOCK_IO2_PROTOCOL *This,\r
-  IN     UINT32                 MediaId,\r
-  IN     EFI_LBA                Lba,\r
-  IN OUT EFI_BLOCK_IO2_TOKEN    *Token,\r
-  IN     UINTN                  BufferSize,\r
-  IN     VOID                   *Buffer\r
+  IN     EFI_BLOCK_IO2_PROTOCOL  *This,\r
+  IN     UINT32                  MediaId,\r
+  IN     EFI_LBA                 Lba,\r
+  IN OUT EFI_BLOCK_IO2_TOKEN     *Token,\r
+  IN     UINTN                   BufferSize,\r
+  IN     VOID                    *Buffer\r
   )\r
 {\r
   SCSI_DISK_DEV       *ScsiDiskDevice;\r
@@ -1009,9 +1205,9 @@ ScsiDiskWriteBlocksEx (
   MediaChange    = FALSE;\r
   OldTpl         = gBS->RaiseTPL (TPL_CALLBACK);\r
   ScsiDiskDevice = SCSI_DISK_DEV_FROM_BLKIO2 (This);\r
+  Media          = ScsiDiskDevice->BlkIo.Media;\r
 \r
-  if (!IS_DEVICE_FIXED(ScsiDiskDevice)) {\r
-\r
+  if (!IS_DEVICE_FIXED (ScsiDiskDevice)) {\r
     Status = ScsiDiskDetectMedia (ScsiDiskDevice, FALSE, &MediaChange);\r
     if (EFI_ERROR (Status)) {\r
       Status = EFI_DEVICE_ERROR;\r
@@ -1020,28 +1216,56 @@ ScsiDiskWriteBlocksEx (
 \r
     if (MediaChange) {\r
       gBS->ReinstallProtocolInterface (\r
-            ScsiDiskDevice->Handle,\r
-            &gEfiBlockIoProtocolGuid,\r
-            &ScsiDiskDevice->BlkIo,\r
-            &ScsiDiskDevice->BlkIo\r
-            );\r
+             ScsiDiskDevice->Handle,\r
+             &gEfiBlockIoProtocolGuid,\r
+             &ScsiDiskDevice->BlkIo,\r
+             &ScsiDiskDevice->BlkIo\r
+             );\r
       gBS->ReinstallProtocolInterface (\r
              ScsiDiskDevice->Handle,\r
              &gEfiBlockIo2ProtocolGuid,\r
              &ScsiDiskDevice->BlkIo2,\r
              &ScsiDiskDevice->BlkIo2\r
              );\r
-      Status = EFI_MEDIA_CHANGED;\r
+      if (DetermineInstallEraseBlock (ScsiDiskDevice, ScsiDiskDevice->Handle)) {\r
+        gBS->ReinstallProtocolInterface (\r
+               ScsiDiskDevice->Handle,\r
+               &gEfiEraseBlockProtocolGuid,\r
+               &ScsiDiskDevice->EraseBlock,\r
+               &ScsiDiskDevice->EraseBlock\r
+               );\r
+      }\r
+\r
+      if (DetermineInstallStorageSecurity (ScsiDiskDevice, ScsiDiskDevice->Handle)) {\r
+        gBS->ReinstallProtocolInterface (\r
+               ScsiDiskDevice->Handle,\r
+               &gEfiStorageSecurityCommandProtocolGuid,\r
+               &ScsiDiskDevice->StorageSecurity,\r
+               &ScsiDiskDevice->StorageSecurity\r
+               );\r
+      }\r
+\r
+      if (Media->MediaPresent) {\r
+        Status = EFI_MEDIA_CHANGED;\r
+      } else {\r
+        Status = EFI_NO_MEDIA;\r
+      }\r
+\r
       goto Done;\r
     }\r
   }\r
+\r
   //\r
   // Get the intrinsic block size\r
   //\r
-  Media           = ScsiDiskDevice->BlkIo2.Media;\r
-  BlockSize       = Media->BlockSize;\r
+  BlockSize = Media->BlockSize;\r
+\r
+  if (BlockSize == 0) {\r
+    Status = EFI_DEVICE_ERROR;\r
+    goto Done;\r
+  }\r
 \r
-  NumberOfBlocks  = BufferSize / BlockSize;\r
+  NumberOfBlocks = BufferSize / BlockSize;\r
 \r
   if (!(Media->MediaPresent)) {\r
     Status = EFI_NO_MEDIA;\r
@@ -1088,7 +1312,7 @@ ScsiDiskWriteBlocksEx (
     goto Done;\r
   }\r
 \r
-  if ((Media->IoAlign > 1) && (((UINTN) Buffer & (Media->IoAlign - 1)) != 0)) {\r
+  if ((Media->IoAlign > 1) && (((UINTN)Buffer & (Media->IoAlign - 1)) != 0)) {\r
     Status = EFI_INVALID_PARAMETER;\r
     goto Done;\r
   }\r
@@ -1099,13 +1323,13 @@ ScsiDiskWriteBlocksEx (
   //\r
   if ((Token != NULL) && (Token->Event != NULL)) {\r
     Token->TransactionStatus = EFI_SUCCESS;\r
-    Status = ScsiDiskAsyncWriteSectors (\r
-               ScsiDiskDevice,\r
-               Buffer,\r
-               Lba,\r
-               NumberOfBlocks,\r
-               Token\r
-               );\r
+    Status                   = ScsiDiskAsyncWriteSectors (\r
+                                 ScsiDiskDevice,\r
+                                 Buffer,\r
+                                 Lba,\r
+                                 NumberOfBlocks,\r
+                                 Token\r
+                                 );\r
   } else {\r
     Status = ScsiDiskWriteSectors (\r
                ScsiDiskDevice,\r
@@ -1121,24 +1345,816 @@ Done:
 }\r
 \r
 /**\r
-  Flush the Block Device.\r
-\r
-  @param  This       Indicates a pointer to the calling context.\r
-  @param  Token      A pointer to the token associated with the transaction.\r
-\r
-  @retval EFI_SUCCESS         All outstanding data was written to the device.\r
-  @retval EFI_DEVICE_ERROR    The device reported an error while attempting to\r
-                              write data.\r
-  @retval EFI_WRITE_PROTECTED The device cannot be written to.\r
-  @retval EFI_NO_MEDIA        There is no media in the device.\r
-  @retval EFI_MEDIA_CHANGED   The MediaId is not for the current media.\r
+  Flush the Block Device.\r
+\r
+  @param  This       Indicates a pointer to the calling context.\r
+  @param  Token      A pointer to the token associated with the transaction.\r
+\r
+  @retval EFI_SUCCESS         All outstanding data was written to the device.\r
+  @retval EFI_DEVICE_ERROR    The device reported an error while attempting to\r
+                              write data.\r
+  @retval EFI_WRITE_PROTECTED The device cannot be written to.\r
+  @retval EFI_NO_MEDIA        There is no media in the device.\r
+  @retval EFI_MEDIA_CHANGED   The MediaId is not for the current media.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ScsiDiskFlushBlocksEx (\r
+  IN     EFI_BLOCK_IO2_PROTOCOL  *This,\r
+  IN OUT EFI_BLOCK_IO2_TOKEN     *Token\r
+  )\r
+{\r
+  SCSI_DISK_DEV       *ScsiDiskDevice;\r
+  EFI_BLOCK_IO_MEDIA  *Media;\r
+  EFI_STATUS          Status;\r
+  BOOLEAN             MediaChange;\r
+  EFI_TPL             OldTpl;\r
+\r
+  MediaChange    = FALSE;\r
+  OldTpl         = gBS->RaiseTPL (TPL_CALLBACK);\r
+  ScsiDiskDevice = SCSI_DISK_DEV_FROM_BLKIO2 (This);\r
+  Media          = ScsiDiskDevice->BlkIo.Media;\r
+\r
+  if (!IS_DEVICE_FIXED (ScsiDiskDevice)) {\r
+    Status = ScsiDiskDetectMedia (ScsiDiskDevice, FALSE, &MediaChange);\r
+    if (EFI_ERROR (Status)) {\r
+      Status = EFI_DEVICE_ERROR;\r
+      goto Done;\r
+    }\r
+\r
+    if (MediaChange) {\r
+      gBS->ReinstallProtocolInterface (\r
+             ScsiDiskDevice->Handle,\r
+             &gEfiBlockIoProtocolGuid,\r
+             &ScsiDiskDevice->BlkIo,\r
+             &ScsiDiskDevice->BlkIo\r
+             );\r
+      gBS->ReinstallProtocolInterface (\r
+             ScsiDiskDevice->Handle,\r
+             &gEfiBlockIo2ProtocolGuid,\r
+             &ScsiDiskDevice->BlkIo2,\r
+             &ScsiDiskDevice->BlkIo2\r
+             );\r
+      if (DetermineInstallEraseBlock (ScsiDiskDevice, ScsiDiskDevice->Handle)) {\r
+        gBS->ReinstallProtocolInterface (\r
+               ScsiDiskDevice->Handle,\r
+               &gEfiEraseBlockProtocolGuid,\r
+               &ScsiDiskDevice->EraseBlock,\r
+               &ScsiDiskDevice->EraseBlock\r
+               );\r
+      }\r
+\r
+      if (DetermineInstallStorageSecurity (ScsiDiskDevice, ScsiDiskDevice->Handle)) {\r
+        gBS->ReinstallProtocolInterface (\r
+               ScsiDiskDevice->Handle,\r
+               &gEfiStorageSecurityCommandProtocolGuid,\r
+               &ScsiDiskDevice->StorageSecurity,\r
+               &ScsiDiskDevice->StorageSecurity\r
+               );\r
+      }\r
+\r
+      if (Media->MediaPresent) {\r
+        Status = EFI_MEDIA_CHANGED;\r
+      } else {\r
+        Status = EFI_NO_MEDIA;\r
+      }\r
+\r
+      goto Done;\r
+    }\r
+  }\r
+\r
+  if (!(Media->MediaPresent)) {\r
+    Status = EFI_NO_MEDIA;\r
+    goto Done;\r
+  }\r
+\r
+  if (Media->ReadOnly) {\r
+    Status = EFI_WRITE_PROTECTED;\r
+    goto Done;\r
+  }\r
+\r
+  //\r
+  // Wait for the BlockIo2 requests queue to become empty\r
+  //\r
+  while (!IsListEmpty (&ScsiDiskDevice->AsyncTaskQueue)) {\r
+  }\r
+\r
+  Status = EFI_SUCCESS;\r
+\r
+  //\r
+  // Signal caller event\r
+  //\r
+  if ((Token != NULL) && (Token->Event != NULL)) {\r
+    Token->TransactionStatus = EFI_SUCCESS;\r
+    gBS->SignalEvent (Token->Event);\r
+  }\r
+\r
+Done:\r
+  gBS->RestoreTPL (OldTpl);\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Internal helper notify function which process the result of an asynchronous\r
+  SCSI UNMAP Command and signal the event passed from EraseBlocks.\r
+\r
+  @param  Event    The instance of EFI_EVENT.\r
+  @param  Context  The parameter passed in.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+ScsiDiskAsyncUnmapNotify (\r
+  IN  EFI_EVENT  Event,\r
+  IN  VOID       *Context\r
+  )\r
+{\r
+  SCSI_ERASEBLK_REQUEST            *EraseBlkReq;\r
+  EFI_SCSI_IO_SCSI_REQUEST_PACKET  *CommandPacket;\r
+  EFI_ERASE_BLOCK_TOKEN            *Token;\r
+  EFI_STATUS                       Status;\r
+\r
+  gBS->CloseEvent (Event);\r
+\r
+  EraseBlkReq              = (SCSI_ERASEBLK_REQUEST *)Context;\r
+  CommandPacket            = &EraseBlkReq->CommandPacket;\r
+  Token                    = EraseBlkReq->Token;\r
+  Token->TransactionStatus = EFI_SUCCESS;\r
+\r
+  Status = CheckHostAdapterStatus (CommandPacket->HostAdapterStatus);\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((\r
+      DEBUG_ERROR,\r
+      "ScsiDiskAsyncUnmapNotify: Host adapter indicating error status 0x%x.\n",\r
+      CommandPacket->HostAdapterStatus\r
+      ));\r
+\r
+    Token->TransactionStatus = Status;\r
+    goto Done;\r
+  }\r
+\r
+  Status = CheckTargetStatus (CommandPacket->TargetStatus);\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((\r
+      DEBUG_ERROR,\r
+      "ScsiDiskAsyncUnmapNotify: Target indicating error status 0x%x.\n",\r
+      CommandPacket->HostAdapterStatus\r
+      ));\r
+\r
+    Token->TransactionStatus = Status;\r
+    goto Done;\r
+  }\r
+\r
+Done:\r
+  RemoveEntryList (&EraseBlkReq->Link);\r
+  FreePool (CommandPacket->OutDataBuffer);\r
+  FreePool (EraseBlkReq->CommandPacket.Cdb);\r
+  FreePool (EraseBlkReq);\r
+\r
+  gBS->SignalEvent (Token->Event);\r
+}\r
+\r
+/**\r
+  Require the device server to cause one or more LBAs to be unmapped.\r
+\r
+  @param  ScsiDiskDevice         The pointer of ScsiDiskDevice.\r
+  @param  Lba                    The start block number.\r
+  @param  Blocks                 Total block number to be unmapped.\r
+  @param  Token                  The pointer to the token associated with the\r
+                                 non-blocking erase block request.\r
+\r
+  @retval EFI_SUCCESS            Target blocks have been successfully unmapped.\r
+  @retval EFI_DEVICE_ERROR       Fail to unmap the target blocks.\r
+\r
+**/\r
+EFI_STATUS\r
+ScsiDiskUnmap (\r
+  IN SCSI_DISK_DEV          *ScsiDiskDevice,\r
+  IN UINT64                 Lba,\r
+  IN UINTN                  Blocks,\r
+  IN EFI_ERASE_BLOCK_TOKEN  *Token            OPTIONAL\r
+  )\r
+{\r
+  EFI_SCSI_IO_PROTOCOL             *ScsiIo;\r
+  SCSI_ERASEBLK_REQUEST            *EraseBlkReq;\r
+  EFI_SCSI_IO_SCSI_REQUEST_PACKET  *CommandPacket;\r
+  EFI_SCSI_DISK_UNMAP_BLOCK_DESP   *BlkDespPtr;\r
+  EFI_STATUS                       Status;\r
+  EFI_STATUS                       ReturnStatus;\r
+  UINT8                            *Cdb;\r
+  UINT32                           MaxLbaCnt;\r
+  UINT32                           MaxBlkDespCnt;\r
+  UINT32                           BlkDespCnt;\r
+  UINT16                           UnmapParamListLen;\r
+  VOID                             *UnmapParamList;\r
+  EFI_EVENT                        AsyncUnmapEvent;\r
+  EFI_TPL                          OldTpl;\r
+\r
+  ScsiIo          = ScsiDiskDevice->ScsiIo;\r
+  MaxLbaCnt       = ScsiDiskDevice->UnmapInfo.MaxLbaCnt;\r
+  MaxBlkDespCnt   = ScsiDiskDevice->UnmapInfo.MaxBlkDespCnt;\r
+  EraseBlkReq     = NULL;\r
+  UnmapParamList  = NULL;\r
+  AsyncUnmapEvent = NULL;\r
+  ReturnStatus    = EFI_SUCCESS;\r
+\r
+  if (Blocks / (UINTN)MaxLbaCnt > MaxBlkDespCnt) {\r
+    ReturnStatus = EFI_DEVICE_ERROR;\r
+    goto Done;\r
+  }\r
+\r
+  EraseBlkReq = AllocateZeroPool (sizeof (SCSI_ERASEBLK_REQUEST));\r
+  if (EraseBlkReq == NULL) {\r
+    ReturnStatus = EFI_DEVICE_ERROR;\r
+    goto Done;\r
+  }\r
+\r
+  EraseBlkReq->CommandPacket.Cdb = AllocateZeroPool (0xA);\r
+  if (EraseBlkReq->CommandPacket.Cdb == NULL) {\r
+    ReturnStatus = EFI_DEVICE_ERROR;\r
+    goto Done;\r
+  }\r
+\r
+  BlkDespCnt        = (UINT32)((Blocks - 1) / MaxLbaCnt + 1);\r
+  UnmapParamListLen = (UINT16)(sizeof (EFI_SCSI_DISK_UNMAP_PARAM_LIST_HEADER)\r
+                               + BlkDespCnt * sizeof (EFI_SCSI_DISK_UNMAP_BLOCK_DESP));\r
+  UnmapParamList = AllocateZeroPool (UnmapParamListLen);\r
+  if (UnmapParamList == NULL) {\r
+    ReturnStatus = EFI_DEVICE_ERROR;\r
+    goto Done;\r
+  }\r
+\r
+  *((UINT16 *)UnmapParamList)     = SwapBytes16 (UnmapParamListLen - 2);\r
+  *((UINT16 *)UnmapParamList + 1) = SwapBytes16 (UnmapParamListLen - sizeof (EFI_SCSI_DISK_UNMAP_PARAM_LIST_HEADER));\r
+\r
+  BlkDespPtr = (EFI_SCSI_DISK_UNMAP_BLOCK_DESP *)((UINT8 *)UnmapParamList + sizeof (EFI_SCSI_DISK_UNMAP_PARAM_LIST_HEADER));\r
+  while (Blocks > 0) {\r
+    if (Blocks > MaxLbaCnt) {\r
+      *(UINT64 *)(&BlkDespPtr->Lba)      = SwapBytes64 (Lba);\r
+      *(UINT32 *)(&BlkDespPtr->BlockNum) = SwapBytes32 (MaxLbaCnt);\r
+      Blocks                            -= MaxLbaCnt;\r
+      Lba                               += MaxLbaCnt;\r
+    } else {\r
+      *(UINT64 *)(&BlkDespPtr->Lba)      = SwapBytes64 (Lba);\r
+      *(UINT32 *)(&BlkDespPtr->BlockNum) = SwapBytes32 ((UINT32)Blocks);\r
+      Blocks                             = 0;\r
+    }\r
+\r
+    BlkDespPtr++;\r
+  }\r
+\r
+  CommandPacket                    = &EraseBlkReq->CommandPacket;\r
+  CommandPacket->Timeout           = SCSI_DISK_TIMEOUT;\r
+  CommandPacket->OutDataBuffer     = UnmapParamList;\r
+  CommandPacket->OutTransferLength = UnmapParamListLen;\r
+  CommandPacket->CdbLength         = 0xA;\r
+  CommandPacket->DataDirection     = EFI_SCSI_DATA_OUT;\r
+  //\r
+  // Fill Cdb for UNMAP Command\r
+  //\r
+  Cdb    = CommandPacket->Cdb;\r
+  Cdb[0] = EFI_SCSI_OP_UNMAP;\r
+  WriteUnaligned16 ((UINT16 *)&Cdb[7], SwapBytes16 (UnmapParamListLen));\r
+\r
+  if ((Token != NULL) && (Token->Event != NULL)) {\r
+    //\r
+    // Non-blocking UNMAP request\r
+    //\r
+    Status = gBS->CreateEvent (\r
+                    EVT_NOTIFY_SIGNAL,\r
+                    TPL_NOTIFY,\r
+                    ScsiDiskAsyncUnmapNotify,\r
+                    EraseBlkReq,\r
+                    &AsyncUnmapEvent\r
+                    );\r
+    if (EFI_ERROR (Status)) {\r
+      ReturnStatus = EFI_DEVICE_ERROR;\r
+      goto Done;\r
+    }\r
+\r
+    OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
+    InsertTailList (&ScsiDiskDevice->AsyncTaskQueue, &EraseBlkReq->Link);\r
+    gBS->RestoreTPL (OldTpl);\r
+\r
+    EraseBlkReq->Token = Token;\r
+\r
+    Status = ScsiIo->ExecuteScsiCommand (\r
+                       ScsiIo,\r
+                       CommandPacket,\r
+                       AsyncUnmapEvent\r
+                       );\r
+    if (EFI_ERROR (Status)) {\r
+      ReturnStatus = EFI_DEVICE_ERROR;\r
+\r
+      OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
+      RemoveEntryList (&EraseBlkReq->Link);\r
+      gBS->RestoreTPL (OldTpl);\r
+\r
+      goto Done;\r
+    } else {\r
+      //\r
+      // Directly return if the non-blocking UNMAP request is queued.\r
+      //\r
+      return EFI_SUCCESS;\r
+    }\r
+  } else {\r
+    //\r
+    // Blocking UNMAP request\r
+    //\r
+    Status = ScsiIo->ExecuteScsiCommand (\r
+                       ScsiIo,\r
+                       CommandPacket,\r
+                       NULL\r
+                       );\r
+    if (EFI_ERROR (Status)) {\r
+      ReturnStatus = EFI_DEVICE_ERROR;\r
+      goto Done;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Only blocking UNMAP request will reach here.\r
+  //\r
+  Status = CheckHostAdapterStatus (CommandPacket->HostAdapterStatus);\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((\r
+      DEBUG_ERROR,\r
+      "ScsiDiskUnmap: Host adapter indicating error status 0x%x.\n",\r
+      CommandPacket->HostAdapterStatus\r
+      ));\r
+\r
+    ReturnStatus = EFI_DEVICE_ERROR;\r
+    goto Done;\r
+  }\r
+\r
+  Status = CheckTargetStatus (CommandPacket->TargetStatus);\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((\r
+      DEBUG_ERROR,\r
+      "ScsiDiskUnmap: Target indicating error status 0x%x.\n",\r
+      CommandPacket->HostAdapterStatus\r
+      ));\r
+\r
+    ReturnStatus = EFI_DEVICE_ERROR;\r
+    goto Done;\r
+  }\r
+\r
+Done:\r
+  if (EraseBlkReq != NULL) {\r
+    if (EraseBlkReq->CommandPacket.Cdb != NULL) {\r
+      FreePool (EraseBlkReq->CommandPacket.Cdb);\r
+    }\r
+\r
+    FreePool (EraseBlkReq);\r
+  }\r
+\r
+  if (UnmapParamList != NULL) {\r
+    FreePool (UnmapParamList);\r
+  }\r
+\r
+  if (AsyncUnmapEvent != NULL) {\r
+    gBS->CloseEvent (AsyncUnmapEvent);\r
+  }\r
+\r
+  return ReturnStatus;\r
+}\r
+\r
+/**\r
+  Erase a specified number of device blocks.\r
+\r
+  @param[in]       This           Indicates a pointer to the calling context.\r
+  @param[in]       MediaId        The media ID that the erase request is for.\r
+  @param[in]       Lba            The starting logical block address to be\r
+                                  erased. The caller is responsible for erasing\r
+                                  only legitimate locations.\r
+  @param[in, out]  Token          A pointer to the token associated with the\r
+                                  transaction.\r
+  @param[in]       Size           The size in bytes to be erased. This must be\r
+                                  a multiple of the physical block size of the\r
+                                  device.\r
+\r
+  @retval EFI_SUCCESS             The erase request was queued if Event is not\r
+                                  NULL. The data was erased correctly to the\r
+                                  device if the Event is NULL.to the device.\r
+  @retval EFI_WRITE_PROTECTED     The device cannot be erased due to write\r
+                                  protection.\r
+  @retval EFI_DEVICE_ERROR        The device reported an error while attempting\r
+                                  to perform the erase operation.\r
+  @retval EFI_INVALID_PARAMETER   The erase request contains LBAs that are not\r
+                                  valid.\r
+  @retval EFI_NO_MEDIA            There is no media in the device.\r
+  @retval EFI_MEDIA_CHANGED       The MediaId is not for the current media.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ScsiDiskEraseBlocks (\r
+  IN     EFI_ERASE_BLOCK_PROTOCOL  *This,\r
+  IN     UINT32                    MediaId,\r
+  IN     EFI_LBA                   Lba,\r
+  IN OUT EFI_ERASE_BLOCK_TOKEN     *Token,\r
+  IN     UINTN                     Size\r
+  )\r
+{\r
+  SCSI_DISK_DEV       *ScsiDiskDevice;\r
+  EFI_BLOCK_IO_MEDIA  *Media;\r
+  EFI_STATUS          Status;\r
+  UINTN               BlockSize;\r
+  UINTN               NumberOfBlocks;\r
+  BOOLEAN             MediaChange;\r
+  EFI_TPL             OldTpl;\r
+\r
+  MediaChange    = FALSE;\r
+  OldTpl         = gBS->RaiseTPL (TPL_CALLBACK);\r
+  ScsiDiskDevice = SCSI_DISK_DEV_FROM_ERASEBLK (This);\r
+\r
+  if (!IS_DEVICE_FIXED (ScsiDiskDevice)) {\r
+    Status = ScsiDiskDetectMedia (ScsiDiskDevice, FALSE, &MediaChange);\r
+    if (EFI_ERROR (Status)) {\r
+      Status = EFI_DEVICE_ERROR;\r
+      goto Done;\r
+    }\r
+\r
+    if (MediaChange) {\r
+      gBS->ReinstallProtocolInterface (\r
+             ScsiDiskDevice->Handle,\r
+             &gEfiBlockIoProtocolGuid,\r
+             &ScsiDiskDevice->BlkIo,\r
+             &ScsiDiskDevice->BlkIo\r
+             );\r
+      gBS->ReinstallProtocolInterface (\r
+             ScsiDiskDevice->Handle,\r
+             &gEfiBlockIo2ProtocolGuid,\r
+             &ScsiDiskDevice->BlkIo2,\r
+             &ScsiDiskDevice->BlkIo2\r
+             );\r
+      if (DetermineInstallEraseBlock (ScsiDiskDevice, ScsiDiskDevice->Handle)) {\r
+        gBS->ReinstallProtocolInterface (\r
+               ScsiDiskDevice->Handle,\r
+               &gEfiEraseBlockProtocolGuid,\r
+               &ScsiDiskDevice->EraseBlock,\r
+               &ScsiDiskDevice->EraseBlock\r
+               );\r
+      }\r
+\r
+      if (DetermineInstallStorageSecurity (ScsiDiskDevice, ScsiDiskDevice->Handle)) {\r
+        gBS->ReinstallProtocolInterface (\r
+               ScsiDiskDevice->Handle,\r
+               &gEfiStorageSecurityCommandProtocolGuid,\r
+               &ScsiDiskDevice->StorageSecurity,\r
+               &ScsiDiskDevice->StorageSecurity\r
+               );\r
+      }\r
+\r
+      Status = EFI_MEDIA_CHANGED;\r
+      goto Done;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Get the intrinsic block size\r
+  //\r
+  Media = ScsiDiskDevice->BlkIo.Media;\r
+\r
+  if (!(Media->MediaPresent)) {\r
+    Status = EFI_NO_MEDIA;\r
+    goto Done;\r
+  }\r
+\r
+  if (MediaId != Media->MediaId) {\r
+    Status = EFI_MEDIA_CHANGED;\r
+    goto Done;\r
+  }\r
+\r
+  if (Media->ReadOnly) {\r
+    Status = EFI_WRITE_PROTECTED;\r
+    goto Done;\r
+  }\r
+\r
+  if (Size == 0) {\r
+    if ((Token != NULL) && (Token->Event != NULL)) {\r
+      Token->TransactionStatus = EFI_SUCCESS;\r
+      gBS->SignalEvent (Token->Event);\r
+    }\r
+\r
+    Status = EFI_SUCCESS;\r
+    goto Done;\r
+  }\r
+\r
+  BlockSize = Media->BlockSize;\r
+  if ((Size % BlockSize) != 0) {\r
+    Status = EFI_INVALID_PARAMETER;\r
+    goto Done;\r
+  }\r
+\r
+  NumberOfBlocks = Size / BlockSize;\r
+  if ((Lba + NumberOfBlocks - 1) > Media->LastBlock) {\r
+    Status = EFI_INVALID_PARAMETER;\r
+    goto Done;\r
+  }\r
+\r
+  if ((Token != NULL) && (Token->Event != NULL)) {\r
+    Status = ScsiDiskUnmap (ScsiDiskDevice, Lba, NumberOfBlocks, Token);\r
+  } else {\r
+    Status = ScsiDiskUnmap (ScsiDiskDevice, Lba, NumberOfBlocks, NULL);\r
+  }\r
+\r
+Done:\r
+  gBS->RestoreTPL (OldTpl);\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Send a security protocol command to a device that receives data and/or the result\r
+  of one or more commands sent by SendData.\r
+\r
+  The ReceiveData function sends a security protocol command to the given MediaId.\r
+  The security protocol command sent is defined by SecurityProtocolId and contains\r
+  the security protocol specific data SecurityProtocolSpecificData. The function\r
+  returns the data from the security protocol command in PayloadBuffer.\r
+\r
+  For devices supporting the SCSI command set, the security protocol command is sent\r
+  using the SECURITY PROTOCOL IN command defined in SPC-4.\r
+\r
+  If PayloadBufferSize is too small to store the available data from the security\r
+  protocol command, the function shall copy PayloadBufferSize bytes into the\r
+  PayloadBuffer and return EFI_WARN_BUFFER_TOO_SMALL.\r
+\r
+  If PayloadBuffer or PayloadTransferSize is NULL and PayloadBufferSize is non-zero,\r
+  the function shall return EFI_INVALID_PARAMETER.\r
+\r
+  If the given MediaId does not support security protocol commands, the function shall\r
+  return EFI_UNSUPPORTED. If there is no media in the device, the function returns\r
+  EFI_NO_MEDIA. If the MediaId is not the ID for the current media in the device,\r
+  the function returns EFI_MEDIA_CHANGED.\r
+\r
+  If the security protocol fails to complete within the Timeout period, the function\r
+  shall return EFI_TIMEOUT.\r
+\r
+  If the security protocol command completes without an error, the function shall\r
+  return EFI_SUCCESS. If the security protocol command completes with an error, the\r
+  function shall return EFI_DEVICE_ERROR.\r
+\r
+  @param  This                         Indicates a pointer to the calling context.\r
+  @param  MediaId                      ID of the medium to receive data from.\r
+  @param  Timeout                      The timeout, in 100ns units, to use for the execution\r
+                                       of the security protocol command. A Timeout value of 0\r
+                                       means that this function will wait indefinitely for the\r
+                                       security protocol command to execute. If Timeout is greater\r
+                                       than zero, then this function will return EFI_TIMEOUT if the\r
+                                       time required to execute the receive data command is greater than Timeout.\r
+  @param  SecurityProtocolId           The value of the "Security Protocol" parameter of\r
+                                       the security protocol command to be sent.\r
+  @param  SecurityProtocolSpecificData The value of the "Security Protocol Specific" parameter\r
+                                       of the security protocol command to be sent.\r
+  @param  PayloadBufferSize            Size in bytes of the payload data buffer.\r
+  @param  PayloadBuffer                A pointer to a destination buffer to store the security\r
+                                       protocol command specific payload data for the security\r
+                                       protocol command. The caller is responsible for having\r
+                                       either implicit or explicit ownership of the buffer.\r
+  @param  PayloadTransferSize          A pointer to a buffer to store the size in bytes of the\r
+                                       data written to the payload data buffer.\r
+\r
+  @retval EFI_SUCCESS                  The security protocol command completed successfully.\r
+  @retval EFI_WARN_BUFFER_TOO_SMALL    The PayloadBufferSize was too small to store the available\r
+                                       data from the device. The PayloadBuffer contains the truncated data.\r
+  @retval EFI_UNSUPPORTED              The given MediaId does not support security protocol commands.\r
+  @retval EFI_DEVICE_ERROR             The security protocol command completed with an error.\r
+  @retval EFI_NO_MEDIA                 There is no media in the device.\r
+  @retval EFI_MEDIA_CHANGED            The MediaId is not for the current media.\r
+  @retval EFI_INVALID_PARAMETER        The PayloadBuffer or PayloadTransferSize is NULL and\r
+                                       PayloadBufferSize is non-zero.\r
+  @retval EFI_TIMEOUT                  A timeout occurred while waiting for the security\r
+                                       protocol command to execute.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ScsiDiskReceiveData (\r
+  IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL  *This,\r
+  IN UINT32                                 MediaId   OPTIONAL,\r
+  IN UINT64                                 Timeout,\r
+  IN UINT8                                  SecurityProtocolId,\r
+  IN UINT16                                 SecurityProtocolSpecificData,\r
+  IN UINTN                                  PayloadBufferSize,\r
+  OUT VOID                                  *PayloadBuffer,\r
+  OUT UINTN                                 *PayloadTransferSize\r
+  )\r
+{\r
+  SCSI_DISK_DEV       *ScsiDiskDevice;\r
+  EFI_BLOCK_IO_MEDIA  *Media;\r
+  EFI_STATUS          Status;\r
+  BOOLEAN             MediaChange;\r
+  EFI_TPL             OldTpl;\r
+  UINT8               SenseDataLength;\r
+  UINT8               HostAdapterStatus;\r
+  UINT8               TargetStatus;\r
+  VOID                *AlignedBuffer;\r
+  BOOLEAN             AlignedBufferAllocated;\r
+\r
+  AlignedBuffer          = NULL;\r
+  MediaChange            = FALSE;\r
+  AlignedBufferAllocated = FALSE;\r
+  OldTpl                 = gBS->RaiseTPL (TPL_CALLBACK);\r
+  ScsiDiskDevice         = SCSI_DISK_DEV_FROM_STORSEC (This);\r
+  Media                  = ScsiDiskDevice->BlkIo.Media;\r
+\r
+  SenseDataLength = (UINT8)(ScsiDiskDevice->SenseDataNumber * sizeof (EFI_SCSI_SENSE_DATA));\r
+\r
+  if (!IS_DEVICE_FIXED (ScsiDiskDevice)) {\r
+    Status = ScsiDiskDetectMedia (ScsiDiskDevice, FALSE, &MediaChange);\r
+    if (EFI_ERROR (Status)) {\r
+      Status = EFI_DEVICE_ERROR;\r
+      goto Done;\r
+    }\r
+\r
+    if (MediaChange) {\r
+      gBS->ReinstallProtocolInterface (\r
+             ScsiDiskDevice->Handle,\r
+             &gEfiBlockIoProtocolGuid,\r
+             &ScsiDiskDevice->BlkIo,\r
+             &ScsiDiskDevice->BlkIo\r
+             );\r
+      gBS->ReinstallProtocolInterface (\r
+             ScsiDiskDevice->Handle,\r
+             &gEfiBlockIo2ProtocolGuid,\r
+             &ScsiDiskDevice->BlkIo2,\r
+             &ScsiDiskDevice->BlkIo2\r
+             );\r
+      if (DetermineInstallEraseBlock (ScsiDiskDevice, ScsiDiskDevice->Handle)) {\r
+        gBS->ReinstallProtocolInterface (\r
+               ScsiDiskDevice->Handle,\r
+               &gEfiEraseBlockProtocolGuid,\r
+               &ScsiDiskDevice->EraseBlock,\r
+               &ScsiDiskDevice->EraseBlock\r
+               );\r
+      }\r
+\r
+      if (DetermineInstallStorageSecurity (ScsiDiskDevice, ScsiDiskDevice->Handle)) {\r
+        gBS->ReinstallProtocolInterface (\r
+               ScsiDiskDevice->Handle,\r
+               &gEfiStorageSecurityCommandProtocolGuid,\r
+               &ScsiDiskDevice->StorageSecurity,\r
+               &ScsiDiskDevice->StorageSecurity\r
+               );\r
+      }\r
+\r
+      if (Media->MediaPresent) {\r
+        Status = EFI_MEDIA_CHANGED;\r
+      } else {\r
+        Status = EFI_NO_MEDIA;\r
+      }\r
+\r
+      goto Done;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Validate Media\r
+  //\r
+  if (!(Media->MediaPresent)) {\r
+    Status = EFI_NO_MEDIA;\r
+    goto Done;\r
+  }\r
+\r
+  if ((MediaId != 0) && (MediaId != Media->MediaId)) {\r
+    Status = EFI_MEDIA_CHANGED;\r
+    goto Done;\r
+  }\r
+\r
+  if (PayloadBufferSize != 0) {\r
+    if ((PayloadBuffer == NULL) || (PayloadTransferSize == NULL)) {\r
+      Status = EFI_INVALID_PARAMETER;\r
+      goto Done;\r
+    }\r
+\r
+    if ((ScsiDiskDevice->ScsiIo->IoAlign > 1) && !IS_ALIGNED (PayloadBuffer, ScsiDiskDevice->ScsiIo->IoAlign)) {\r
+      AlignedBuffer = AllocateAlignedBuffer (ScsiDiskDevice, PayloadBufferSize);\r
+      if (AlignedBuffer == NULL) {\r
+        Status = EFI_OUT_OF_RESOURCES;\r
+        goto Done;\r
+      }\r
+\r
+      ZeroMem (AlignedBuffer, PayloadBufferSize);\r
+      AlignedBufferAllocated = TRUE;\r
+    } else {\r
+      AlignedBuffer = PayloadBuffer;\r
+    }\r
+  }\r
+\r
+  Status = ScsiSecurityProtocolInCommand (\r
+             ScsiDiskDevice->ScsiIo,\r
+             Timeout,\r
+             ScsiDiskDevice->SenseData,\r
+             &SenseDataLength,\r
+             &HostAdapterStatus,\r
+             &TargetStatus,\r
+             SecurityProtocolId,\r
+             SecurityProtocolSpecificData,\r
+             FALSE,\r
+             PayloadBufferSize,\r
+             AlignedBuffer,\r
+             PayloadTransferSize\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    goto Done;\r
+  }\r
+\r
+  if (AlignedBufferAllocated) {\r
+    CopyMem (PayloadBuffer, AlignedBuffer, PayloadBufferSize);\r
+  }\r
+\r
+  if (PayloadBufferSize < *PayloadTransferSize) {\r
+    Status = EFI_WARN_BUFFER_TOO_SMALL;\r
+    goto Done;\r
+  }\r
+\r
+  Status = CheckHostAdapterStatus (HostAdapterStatus);\r
+  if (EFI_ERROR (Status)) {\r
+    goto Done;\r
+  }\r
+\r
+  Status = CheckTargetStatus (TargetStatus);\r
+  if (EFI_ERROR (Status)) {\r
+    goto Done;\r
+  }\r
+\r
+Done:\r
+  if (AlignedBufferAllocated) {\r
+    ZeroMem (AlignedBuffer, PayloadBufferSize);\r
+    FreeAlignedBuffer (AlignedBuffer, PayloadBufferSize);\r
+  }\r
+\r
+  gBS->RestoreTPL (OldTpl);\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Send a security protocol command to a device.\r
+\r
+  The SendData function sends a security protocol command containing the payload\r
+  PayloadBuffer to the given MediaId. The security protocol command sent is\r
+  defined by SecurityProtocolId and contains the security protocol specific data\r
+  SecurityProtocolSpecificData. If the underlying protocol command requires a\r
+  specific padding for the command payload, the SendData function shall add padding\r
+  bytes to the command payload to satisfy the padding requirements.\r
+\r
+  For devices supporting the SCSI command set, the security protocol command is sent\r
+  using the SECURITY PROTOCOL OUT command defined in SPC-4.\r
+\r
+  If PayloadBuffer is NULL and PayloadBufferSize is non-zero, the function shall\r
+  return EFI_INVALID_PARAMETER.\r
+\r
+  If the given MediaId does not support security protocol commands, the function\r
+  shall return EFI_UNSUPPORTED. If there is no media in the device, the function\r
+  returns EFI_NO_MEDIA. If the MediaId is not the ID for the current media in the\r
+  device, the function returns EFI_MEDIA_CHANGED.\r
+\r
+  If the security protocol fails to complete within the Timeout period, the function\r
+  shall return EFI_TIMEOUT.\r
+\r
+  If the security protocol command completes without an error, the function shall return\r
+  EFI_SUCCESS. If the security protocol command completes with an error, the function\r
+  shall return EFI_DEVICE_ERROR.\r
+\r
+  @param  This                         Indicates a pointer to the calling context.\r
+  @param  MediaId                      ID of the medium to receive data from.\r
+  @param  Timeout                      The timeout, in 100ns units, to use for the execution\r
+                                       of the security protocol command. A Timeout value of 0\r
+                                       means that this function will wait indefinitely for the\r
+                                       security protocol command to execute. If Timeout is greater\r
+                                       than zero, then this function will return EFI_TIMEOUT if the\r
+                                       time required to execute the receive data command is greater than Timeout.\r
+  @param  SecurityProtocolId           The value of the "Security Protocol" parameter of\r
+                                       the security protocol command to be sent.\r
+  @param  SecurityProtocolSpecificData The value of the "Security Protocol Specific" parameter\r
+                                       of the security protocol command to be sent.\r
+  @param  PayloadBufferSize            Size in bytes of the payload data buffer.\r
+  @param  PayloadBuffer                A pointer to a destination buffer to store the security\r
+                                       protocol command specific payload data for the security\r
+                                       protocol command.\r
+\r
+  @retval EFI_SUCCESS                  The security protocol command completed successfully.\r
+  @retval EFI_UNSUPPORTED              The given MediaId does not support security protocol commands.\r
+  @retval EFI_DEVICE_ERROR             The security protocol command completed with an error.\r
+  @retval EFI_NO_MEDIA                 There is no media in the device.\r
+  @retval EFI_MEDIA_CHANGED            The MediaId is not for the current media.\r
+  @retval EFI_INVALID_PARAMETER        The PayloadBuffer is NULL and PayloadBufferSize is non-zero.\r
+  @retval EFI_TIMEOUT                  A timeout occurred while waiting for the security\r
+                                       protocol command to execute.\r
 \r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
-ScsiDiskFlushBlocksEx (\r
-  IN     EFI_BLOCK_IO2_PROTOCOL  *This,\r
-  IN OUT EFI_BLOCK_IO2_TOKEN     *Token\r
+ScsiDiskSendData (\r
+  IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL  *This,\r
+  IN UINT32                                 MediaId   OPTIONAL,\r
+  IN UINT64                                 Timeout,\r
+  IN UINT8                                  SecurityProtocolId,\r
+  IN UINT16                                 SecurityProtocolSpecificData,\r
+  IN UINTN                                  PayloadBufferSize,\r
+  OUT VOID                                  *PayloadBuffer\r
   )\r
 {\r
   SCSI_DISK_DEV       *ScsiDiskDevice;\r
@@ -1146,13 +2162,22 @@ ScsiDiskFlushBlocksEx (
   EFI_STATUS          Status;\r
   BOOLEAN             MediaChange;\r
   EFI_TPL             OldTpl;\r
+  UINT8               SenseDataLength;\r
+  UINT8               HostAdapterStatus;\r
+  UINT8               TargetStatus;\r
+  VOID                *AlignedBuffer;\r
+  BOOLEAN             AlignedBufferAllocated;\r
 \r
-  MediaChange    = FALSE;\r
-  OldTpl         = gBS->RaiseTPL (TPL_CALLBACK);\r
-  ScsiDiskDevice = SCSI_DISK_DEV_FROM_BLKIO2 (This);\r
+  AlignedBuffer          = NULL;\r
+  MediaChange            = FALSE;\r
+  AlignedBufferAllocated = FALSE;\r
+  OldTpl                 = gBS->RaiseTPL (TPL_CALLBACK);\r
+  ScsiDiskDevice         = SCSI_DISK_DEV_FROM_STORSEC (This);\r
+  Media                  = ScsiDiskDevice->BlkIo.Media;\r
 \r
-  if (!IS_DEVICE_FIXED(ScsiDiskDevice)) {\r
+  SenseDataLength = (UINT8)(ScsiDiskDevice->SenseDataNumber * sizeof (EFI_SCSI_SENSE_DATA));\r
 \r
+  if (!IS_DEVICE_FIXED (ScsiDiskDevice)) {\r
     Status = ScsiDiskDetectMedia (ScsiDiskDevice, FALSE, &MediaChange);\r
     if (EFI_ERROR (Status)) {\r
       Status = EFI_DEVICE_ERROR;\r
@@ -1161,61 +2186,126 @@ ScsiDiskFlushBlocksEx (
 \r
     if (MediaChange) {\r
       gBS->ReinstallProtocolInterface (\r
-            ScsiDiskDevice->Handle,\r
-            &gEfiBlockIoProtocolGuid,\r
-            &ScsiDiskDevice->BlkIo,\r
-            &ScsiDiskDevice->BlkIo\r
-            );\r
+             ScsiDiskDevice->Handle,\r
+             &gEfiBlockIoProtocolGuid,\r
+             &ScsiDiskDevice->BlkIo,\r
+             &ScsiDiskDevice->BlkIo\r
+             );\r
       gBS->ReinstallProtocolInterface (\r
              ScsiDiskDevice->Handle,\r
              &gEfiBlockIo2ProtocolGuid,\r
              &ScsiDiskDevice->BlkIo2,\r
              &ScsiDiskDevice->BlkIo2\r
              );\r
-      Status = EFI_MEDIA_CHANGED;\r
+      if (DetermineInstallEraseBlock (ScsiDiskDevice, ScsiDiskDevice->Handle)) {\r
+        gBS->ReinstallProtocolInterface (\r
+               ScsiDiskDevice->Handle,\r
+               &gEfiEraseBlockProtocolGuid,\r
+               &ScsiDiskDevice->EraseBlock,\r
+               &ScsiDiskDevice->EraseBlock\r
+               );\r
+      }\r
+\r
+      if (DetermineInstallStorageSecurity (ScsiDiskDevice, ScsiDiskDevice->Handle)) {\r
+        gBS->ReinstallProtocolInterface (\r
+               ScsiDiskDevice->Handle,\r
+               &gEfiStorageSecurityCommandProtocolGuid,\r
+               &ScsiDiskDevice->StorageSecurity,\r
+               &ScsiDiskDevice->StorageSecurity\r
+               );\r
+      }\r
+\r
+      if (Media->MediaPresent) {\r
+        Status = EFI_MEDIA_CHANGED;\r
+      } else {\r
+        Status = EFI_NO_MEDIA;\r
+      }\r
+\r
       goto Done;\r
     }\r
   }\r
 \r
-  Media = ScsiDiskDevice->BlkIo2.Media;\r
-\r
+  //\r
+  // Validate Media\r
+  //\r
   if (!(Media->MediaPresent)) {\r
     Status = EFI_NO_MEDIA;\r
     goto Done;\r
   }\r
 \r
+  if ((MediaId != 0) && (MediaId != Media->MediaId)) {\r
+    Status = EFI_MEDIA_CHANGED;\r
+    goto Done;\r
+  }\r
+\r
   if (Media->ReadOnly) {\r
     Status = EFI_WRITE_PROTECTED;\r
     goto Done;\r
   }\r
 \r
-  //\r
-  // Wait for the BlockIo2 requests queue to become empty\r
-  //\r
-  while (!IsListEmpty (&ScsiDiskDevice->BlkIo2Queue));\r
+  if (PayloadBufferSize != 0) {\r
+    if (PayloadBuffer == NULL) {\r
+      Status = EFI_INVALID_PARAMETER;\r
+      goto Done;\r
+    }\r
 \r
-  Status = EFI_SUCCESS;\r
+    if ((ScsiDiskDevice->ScsiIo->IoAlign > 1) && !IS_ALIGNED (PayloadBuffer, ScsiDiskDevice->ScsiIo->IoAlign)) {\r
+      AlignedBuffer = AllocateAlignedBuffer (ScsiDiskDevice, PayloadBufferSize);\r
+      if (AlignedBuffer == NULL) {\r
+        Status = EFI_OUT_OF_RESOURCES;\r
+        goto Done;\r
+      }\r
 \r
-  //\r
-  // Signal caller event\r
-  //\r
-  if ((Token != NULL) && (Token->Event != NULL)) {\r
-    Token->TransactionStatus = EFI_SUCCESS;\r
-    gBS->SignalEvent (Token->Event);\r
+      CopyMem (AlignedBuffer, PayloadBuffer, PayloadBufferSize);\r
+      AlignedBufferAllocated = TRUE;\r
+    } else {\r
+      AlignedBuffer = PayloadBuffer;\r
+    }\r
+  }\r
+\r
+  Status = ScsiSecurityProtocolOutCommand (\r
+             ScsiDiskDevice->ScsiIo,\r
+             Timeout,\r
+             ScsiDiskDevice->SenseData,\r
+             &SenseDataLength,\r
+             &HostAdapterStatus,\r
+             &TargetStatus,\r
+             SecurityProtocolId,\r
+             SecurityProtocolSpecificData,\r
+             FALSE,\r
+             PayloadBufferSize,\r
+             AlignedBuffer\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    goto Done;\r
+  }\r
+\r
+  Status = CheckHostAdapterStatus (HostAdapterStatus);\r
+  if (EFI_ERROR (Status)) {\r
+    goto Done;\r
+  }\r
+\r
+  Status = CheckTargetStatus (TargetStatus);\r
+  if (EFI_ERROR (Status)) {\r
+    goto Done;\r
   }\r
 \r
 Done:\r
+  if (AlignedBufferAllocated) {\r
+    ZeroMem (AlignedBuffer, PayloadBufferSize);\r
+    FreeAlignedBuffer (AlignedBuffer, PayloadBufferSize);\r
+  }\r
+\r
   gBS->RestoreTPL (OldTpl);\r
   return Status;\r
 }\r
 \r
-\r
 /**\r
   Detect Device and read out capacity ,if error occurs, parse the sense key.\r
 \r
   @param  ScsiDiskDevice    The pointer of SCSI_DISK_DEV\r
   @param  MustReadCapacity  The flag about reading device capacity\r
-  @param  MediaChange       The pointer of flag indicates if media has changed \r
+  @param  MediaChange       The pointer of flag indicates if media has changed\r
 \r
   @retval EFI_DEVICE_ERROR  Indicates that error occurs\r
   @retval EFI_SUCCESS       Successfully to detect media\r
@@ -1223,31 +2313,31 @@ Done:
 **/\r
 EFI_STATUS\r
 ScsiDiskDetectMedia (\r
-  IN   SCSI_DISK_DEV   *ScsiDiskDevice,\r
-  IN   BOOLEAN         MustReadCapacity,\r
-  OUT  BOOLEAN         *MediaChange\r
+  IN   SCSI_DISK_DEV  *ScsiDiskDevice,\r
+  IN   BOOLEAN        MustReadCapacity,\r
+  OUT  BOOLEAN        *MediaChange\r
   )\r
 {\r
-  EFI_STATUS          Status;\r
-  EFI_SCSI_SENSE_DATA *SenseData;\r
-  UINTN               NumberOfSenseKeys;\r
-  BOOLEAN             NeedRetry;\r
-  BOOLEAN             NeedReadCapacity;\r
-  UINT8               Retry;\r
-  UINT8               MaxRetry;\r
-  EFI_BLOCK_IO_MEDIA  OldMedia;\r
-  UINTN               Action;\r
-  EFI_EVENT           TimeoutEvt;\r
-\r
-  Status              = EFI_SUCCESS;\r
-  SenseData           = NULL;\r
-  NumberOfSenseKeys   = 0;\r
-  Retry               = 0;\r
-  MaxRetry            = 3;\r
-  Action              = ACTION_NO_ACTION;\r
-  NeedReadCapacity    = FALSE;\r
-  *MediaChange        = FALSE;\r
-  TimeoutEvt          = NULL;\r
+  EFI_STATUS           Status;\r
+  EFI_SCSI_SENSE_DATA  *SenseData;\r
+  UINTN                NumberOfSenseKeys;\r
+  BOOLEAN              NeedRetry;\r
+  BOOLEAN              NeedReadCapacity;\r
+  UINT8                Retry;\r
+  UINT8                MaxRetry;\r
+  EFI_BLOCK_IO_MEDIA   OldMedia;\r
+  UINTN                Action;\r
+  EFI_EVENT            TimeoutEvt;\r
+\r
+  Status            = EFI_SUCCESS;\r
+  SenseData         = NULL;\r
+  NumberOfSenseKeys = 0;\r
+  Retry             = 0;\r
+  MaxRetry          = 3;\r
+  Action            = ACTION_NO_ACTION;\r
+  NeedReadCapacity  = FALSE;\r
+  *MediaChange      = FALSE;\r
+  TimeoutEvt        = NULL;\r
 \r
   CopyMem (&OldMedia, ScsiDiskDevice->BlkIo.Media, sizeof (OldMedia));\r
 \r
@@ -1262,7 +2352,7 @@ ScsiDiskDetectMedia (
     return Status;\r
   }\r
 \r
-  Status = gBS->SetTimer (TimeoutEvt, TimerRelative, EFI_TIMER_PERIOD_SECONDS(120));\r
+  Status = gBS->SetTimer (TimeoutEvt, TimerRelative, EFI_TIMER_PERIOD_SECONDS (120));\r
   if (EFI_ERROR (Status)) {\r
     goto EXIT;\r
   }\r
@@ -1274,11 +2364,11 @@ ScsiDiskDetectMedia (
   //\r
   while (EFI_ERROR (gBS->CheckEvent (TimeoutEvt))) {\r
     Status = ScsiDiskTestUnitReady (\r
-              ScsiDiskDevice,\r
-              &NeedRetry,\r
-              &SenseData,\r
-              &NumberOfSenseKeys\r
-              );\r
+               ScsiDiskDevice,\r
+               &NeedRetry,\r
+               &SenseData,\r
+               &NumberOfSenseKeys\r
+               );\r
     if (!EFI_ERROR (Status)) {\r
       Status = DetectMediaParsingSenseKeys (\r
                  ScsiDiskDevice,\r
@@ -1313,6 +2403,15 @@ ScsiDiskDetectMedia (
     NeedReadCapacity = TRUE;\r
   }\r
 \r
+  //\r
+  // READ_CAPACITY command is not supported by any of the UFS WLUNs.\r
+  //\r
+  if (ScsiDiskDevice->DeviceType == EFI_SCSI_TYPE_WLUN) {\r
+    NeedReadCapacity                          = FALSE;\r
+    MustReadCapacity                          = FALSE;\r
+    ScsiDiskDevice->BlkIo.Media->MediaPresent = TRUE;\r
+  }\r
+\r
   //\r
   // either NeedReadCapacity is TRUE, or MustReadCapacity is TRUE,\r
   // retrieve capacity via Read Capacity command\r
@@ -1350,7 +2449,7 @@ ScsiDiskDetectMedia (
         } else {\r
           break;\r
         }\r
-      } else {   \r
+      } else {\r
         Retry++;\r
         if (!NeedRetry || (Retry >= MaxRetry)) {\r
           goto EXIT;\r
@@ -1371,17 +2470,17 @@ ScsiDiskDetectMedia (
   }\r
 \r
   if (ScsiDiskDevice->BlkIo.Media->ReadOnly != OldMedia.ReadOnly) {\r
-    *MediaChange = TRUE;\r
+    *MediaChange                          = TRUE;\r
     ScsiDiskDevice->BlkIo.Media->MediaId += 1;\r
   }\r
 \r
   if (ScsiDiskDevice->BlkIo.Media->BlockSize != OldMedia.BlockSize) {\r
-    *MediaChange = TRUE;\r
+    *MediaChange                          = TRUE;\r
     ScsiDiskDevice->BlkIo.Media->MediaId += 1;\r
   }\r
 \r
   if (ScsiDiskDevice->BlkIo.Media->LastBlock != OldMedia.LastBlock) {\r
-    *MediaChange = TRUE;\r
+    *MediaChange                          = TRUE;\r
     ScsiDiskDevice->BlkIo.Media->MediaId += 1;\r
   }\r
 \r
@@ -1405,10 +2504,10 @@ EXIT:
   if (TimeoutEvt != NULL) {\r
     gBS->CloseEvent (TimeoutEvt);\r
   }\r
+\r
   return Status;\r
 }\r
 \r
-\r
 /**\r
   Send out Inquiry command to Device.\r
 \r
@@ -1421,40 +2520,40 @@ EXIT:
 **/\r
 EFI_STATUS\r
 ScsiDiskInquiryDevice (\r
-  IN OUT  SCSI_DISK_DEV   *ScsiDiskDevice,\r
-     OUT  BOOLEAN         *NeedRetry\r
+  IN OUT  SCSI_DISK_DEV  *ScsiDiskDevice,\r
+  OUT  BOOLEAN           *NeedRetry\r
   )\r
 {\r
-  UINT32                                InquiryDataLength;\r
-  UINT8                                 SenseDataLength;\r
-  UINT8                                 HostAdapterStatus;\r
-  UINT8                                 TargetStatus;\r
-  EFI_SCSI_SENSE_DATA                   *SenseDataArray;\r
-  UINTN                                 NumberOfSenseKeys;\r
-  EFI_STATUS                            Status;\r
-  UINT8                                 MaxRetry;\r
-  UINT8                                 Index;\r
-  EFI_SCSI_SUPPORTED_VPD_PAGES_VPD_PAGE *SupportedVpdPages;\r
-  EFI_SCSI_BLOCK_LIMITS_VPD_PAGE        *BlockLimits;\r
-  UINTN                                 PageLength;\r
+  UINT32                                 InquiryDataLength;\r
+  UINT8                                  SenseDataLength;\r
+  UINT8                                  HostAdapterStatus;\r
+  UINT8                                  TargetStatus;\r
+  EFI_SCSI_SENSE_DATA                    *SenseDataArray;\r
+  UINTN                                  NumberOfSenseKeys;\r
+  EFI_STATUS                             Status;\r
+  UINT8                                  MaxRetry;\r
+  UINT8                                  Index;\r
+  EFI_SCSI_SUPPORTED_VPD_PAGES_VPD_PAGE  *SupportedVpdPages;\r
+  EFI_SCSI_BLOCK_LIMITS_VPD_PAGE         *BlockLimits;\r
+  UINTN                                  PageLength;\r
 \r
   InquiryDataLength = sizeof (EFI_SCSI_INQUIRY_DATA);\r
   SenseDataLength   = 0;\r
 \r
   Status = ScsiInquiryCommand (\r
-            ScsiDiskDevice->ScsiIo,\r
-            SCSI_DISK_TIMEOUT,\r
-            NULL,\r
-            &SenseDataLength,\r
-            &HostAdapterStatus,\r
-            &TargetStatus,\r
-            (VOID *) &(ScsiDiskDevice->InquiryData),\r
-            &InquiryDataLength,\r
-            FALSE\r
-            );\r
-    //\r
-    // no need to check HostAdapterStatus and TargetStatus\r
-    //\r
+             ScsiDiskDevice->ScsiIo,\r
+             SCSI_DISK_TIMEOUT,\r
+             NULL,\r
+             &SenseDataLength,\r
+             &HostAdapterStatus,\r
+             &TargetStatus,\r
+             (VOID *)&(ScsiDiskDevice->InquiryData),\r
+             &InquiryDataLength,\r
+             FALSE\r
+             );\r
+  //\r
+  // no need to check HostAdapterStatus and TargetStatus\r
+  //\r
   if ((Status == EFI_SUCCESS) || (Status == EFI_WARN_BUFFER_TOO_SMALL)) {\r
     ParseInquiryData (ScsiDiskDevice);\r
 \r
@@ -1467,25 +2566,74 @@ ScsiDiskInquiryDevice (
         *NeedRetry = FALSE;\r
         return EFI_DEVICE_ERROR;\r
       }\r
+\r
       ZeroMem (SupportedVpdPages, sizeof (EFI_SCSI_SUPPORTED_VPD_PAGES_VPD_PAGE));\r
       InquiryDataLength = sizeof (EFI_SCSI_SUPPORTED_VPD_PAGES_VPD_PAGE);\r
       SenseDataLength   = 0;\r
-      Status = ScsiInquiryCommandEx (\r
-                 ScsiDiskDevice->ScsiIo,\r
-                 SCSI_DISK_TIMEOUT,\r
-                 NULL,\r
-                 &SenseDataLength,\r
-                 &HostAdapterStatus,\r
-                 &TargetStatus,\r
-                 (VOID *) SupportedVpdPages,\r
-                 &InquiryDataLength,\r
-                 TRUE,\r
-                 EFI_SCSI_PAGE_CODE_SUPPORTED_VPD\r
-                 );\r
+      Status            = ScsiInquiryCommandEx (\r
+                            ScsiDiskDevice->ScsiIo,\r
+                            SCSI_DISK_TIMEOUT,\r
+                            NULL,\r
+                            &SenseDataLength,\r
+                            &HostAdapterStatus,\r
+                            &TargetStatus,\r
+                            (VOID *)SupportedVpdPages,\r
+                            &InquiryDataLength,\r
+                            TRUE,\r
+                            EFI_SCSI_PAGE_CODE_SUPPORTED_VPD\r
+                            );\r
       if (!EFI_ERROR (Status)) {\r
         PageLength = (SupportedVpdPages->PageLength2 << 8)\r
-                   |  SupportedVpdPages->PageLength1;\r
+                     |  SupportedVpdPages->PageLength1;\r
+\r
+        //\r
+        // Sanity checks for coping with broken devices\r
+        //\r
+        if (PageLength > sizeof SupportedVpdPages->SupportedVpdPageList) {\r
+          DEBUG ((\r
+            DEBUG_WARN,\r
+            "%a: invalid PageLength (%u) in Supported VPD Pages page\n",\r
+            __FUNCTION__,\r
+            (UINT32)PageLength\r
+            ));\r
+          PageLength = 0;\r
+        }\r
+\r
+        if ((PageLength > 0) &&\r
+            (SupportedVpdPages->SupportedVpdPageList[0] !=\r
+             EFI_SCSI_PAGE_CODE_SUPPORTED_VPD))\r
+        {\r
+          DEBUG ((\r
+            DEBUG_WARN,\r
+            "%a: Supported VPD Pages page doesn't start with code 0x%02x\n",\r
+            __FUNCTION__,\r
+            EFI_SCSI_PAGE_CODE_SUPPORTED_VPD\r
+            ));\r
+          PageLength = 0;\r
+        }\r
+\r
+        //\r
+        // Locate the code for the Block Limits VPD page\r
+        //\r
         for (Index = 0; Index < PageLength; Index++) {\r
+          //\r
+          // Sanity check\r
+          //\r
+          if ((Index > 0) &&\r
+              (SupportedVpdPages->SupportedVpdPageList[Index] <=\r
+               SupportedVpdPages->SupportedVpdPageList[Index - 1]))\r
+          {\r
+            DEBUG ((\r
+              DEBUG_WARN,\r
+              "%a: non-ascending code in Supported VPD Pages page @ %u\n",\r
+              __FUNCTION__,\r
+              Index\r
+              ));\r
+            Index      = 0;\r
+            PageLength = 0;\r
+            break;\r
+          }\r
+\r
           if (SupportedVpdPages->SupportedVpdPageList[Index] == EFI_SCSI_PAGE_CODE_BLOCK_LIMITS_VPD) {\r
             break;\r
           }\r
@@ -1501,25 +2649,59 @@ ScsiDiskInquiryDevice (
             *NeedRetry = FALSE;\r
             return EFI_DEVICE_ERROR;\r
           }\r
+\r
           ZeroMem (BlockLimits, sizeof (EFI_SCSI_BLOCK_LIMITS_VPD_PAGE));\r
           InquiryDataLength = sizeof (EFI_SCSI_BLOCK_LIMITS_VPD_PAGE);\r
           SenseDataLength   = 0;\r
-          Status = ScsiInquiryCommandEx (\r
-                     ScsiDiskDevice->ScsiIo,\r
-                     SCSI_DISK_TIMEOUT,\r
-                     NULL,\r
-                     &SenseDataLength,\r
-                     &HostAdapterStatus,\r
-                     &TargetStatus,\r
-                     (VOID *) BlockLimits,\r
-                     &InquiryDataLength,\r
-                     TRUE,\r
-                     EFI_SCSI_PAGE_CODE_BLOCK_LIMITS_VPD\r
-                     );\r
+          Status            = ScsiInquiryCommandEx (\r
+                                ScsiDiskDevice->ScsiIo,\r
+                                SCSI_DISK_TIMEOUT,\r
+                                NULL,\r
+                                &SenseDataLength,\r
+                                &HostAdapterStatus,\r
+                                &TargetStatus,\r
+                                (VOID *)BlockLimits,\r
+                                &InquiryDataLength,\r
+                                TRUE,\r
+                                EFI_SCSI_PAGE_CODE_BLOCK_LIMITS_VPD\r
+                                );\r
           if (!EFI_ERROR (Status)) {\r
-            ScsiDiskDevice->BlkIo.Media->OptimalTransferLengthGranularity = \r
+            ScsiDiskDevice->BlkIo.Media->OptimalTransferLengthGranularity =\r
               (BlockLimits->OptimalTransferLengthGranularity2 << 8) |\r
-               BlockLimits->OptimalTransferLengthGranularity1;\r
+              BlockLimits->OptimalTransferLengthGranularity1;\r
+\r
+            ScsiDiskDevice->UnmapInfo.MaxLbaCnt =\r
+              (BlockLimits->MaximumUnmapLbaCount4 << 24) |\r
+              (BlockLimits->MaximumUnmapLbaCount3 << 16) |\r
+              (BlockLimits->MaximumUnmapLbaCount2 << 8)  |\r
+              BlockLimits->MaximumUnmapLbaCount1;\r
+            ScsiDiskDevice->UnmapInfo.MaxBlkDespCnt =\r
+              (BlockLimits->MaximumUnmapBlockDescriptorCount4 << 24) |\r
+              (BlockLimits->MaximumUnmapBlockDescriptorCount3 << 16) |\r
+              (BlockLimits->MaximumUnmapBlockDescriptorCount2 << 8)  |\r
+              BlockLimits->MaximumUnmapBlockDescriptorCount1;\r
+            ScsiDiskDevice->EraseBlock.EraseLengthGranularity =\r
+              (BlockLimits->OptimalUnmapGranularity4 << 24) |\r
+              (BlockLimits->OptimalUnmapGranularity3 << 16) |\r
+              (BlockLimits->OptimalUnmapGranularity2 << 8)  |\r
+              BlockLimits->OptimalUnmapGranularity1;\r
+            if (BlockLimits->UnmapGranularityAlignmentValid != 0) {\r
+              ScsiDiskDevice->UnmapInfo.GranularityAlignment =\r
+                (BlockLimits->UnmapGranularityAlignment4 << 24) |\r
+                (BlockLimits->UnmapGranularityAlignment3 << 16) |\r
+                (BlockLimits->UnmapGranularityAlignment2 << 8)  |\r
+                BlockLimits->UnmapGranularityAlignment1;\r
+            }\r
+\r
+            if (ScsiDiskDevice->EraseBlock.EraseLengthGranularity == 0) {\r
+              //\r
+              // A value of 0 indicates that the optimal unmap granularity is\r
+              // not reported.\r
+              //\r
+              ScsiDiskDevice->EraseBlock.EraseLengthGranularity = 1;\r
+            }\r
+\r
+            ScsiDiskDevice->BlockLimitsVpdSupported = TRUE;\r
           }\r
 \r
           FreeAlignedBuffer (BlockLimits, sizeof (EFI_SCSI_BLOCK_LIMITS_VPD_PAGE));\r
@@ -1532,15 +2714,14 @@ ScsiDiskInquiryDevice (
 \r
   if (!EFI_ERROR (Status)) {\r
     return EFI_SUCCESS;\r
-\r
   } else if (Status == EFI_NOT_READY) {\r
     *NeedRetry = TRUE;\r
     return EFI_DEVICE_ERROR;\r
\r
   } else if ((Status == EFI_INVALID_PARAMETER) || (Status == EFI_UNSUPPORTED)) {\r
     *NeedRetry = FALSE;\r
     return EFI_DEVICE_ERROR;\r
   }\r
+\r
   //\r
   // go ahead to check HostAdapterStatus and TargetStatus\r
   // (EFI_TIMEOUT, EFI_DEVICE_ERROR)\r
@@ -1551,9 +2732,9 @@ ScsiDiskInquiryDevice (
     *NeedRetry = TRUE;\r
     return EFI_DEVICE_ERROR;\r
   } else if (Status == EFI_DEVICE_ERROR) {\r
-      //\r
-      // reset the scsi channel\r
-      //\r
+    //\r
+    // reset the scsi channel\r
+    //\r
     ScsiDiskDevice->ScsiIo->ResetBus (ScsiDiskDevice->ScsiIo);\r
     *NeedRetry = FALSE;\r
     return EFI_DEVICE_ERROR;\r
@@ -1567,12 +2748,11 @@ ScsiDiskInquiryDevice (
     ScsiDiskDevice->ScsiIo->ResetDevice (ScsiDiskDevice->ScsiIo);\r
     *NeedRetry = TRUE;\r
     return EFI_DEVICE_ERROR;\r
-\r
   } else if (Status == EFI_DEVICE_ERROR) {\r
     *NeedRetry = FALSE;\r
     return EFI_DEVICE_ERROR;\r
   }\r
-  \r
+\r
   //\r
   // if goes here, meant ScsiInquiryCommand() failed.\r
   // if ScsiDiskRequestSenseKeys() succeeds at last,\r
@@ -1581,12 +2761,12 @@ ScsiDiskInquiryDevice (
   MaxRetry = 3;\r
   for (Index = 0; Index < MaxRetry; Index++) {\r
     Status = ScsiDiskRequestSenseKeys (\r
-              ScsiDiskDevice,\r
-              NeedRetry,\r
-              &SenseDataArray,\r
-              &NumberOfSenseKeys,\r
-              TRUE\r
-              );\r
+               ScsiDiskDevice,\r
+               NeedRetry,\r
+               &SenseDataArray,\r
+               &NumberOfSenseKeys,\r
+               TRUE\r
+               );\r
     if (!EFI_ERROR (Status)) {\r
       *NeedRetry = TRUE;\r
       return EFI_DEVICE_ERROR;\r
@@ -1596,6 +2776,7 @@ ScsiDiskInquiryDevice (
       return EFI_DEVICE_ERROR;\r
     }\r
   }\r
+\r
   //\r
   // ScsiDiskRequestSenseKeys() failed after several rounds of retry.\r
   // set *NeedRetry = FALSE to avoid the outside caller try again.\r
@@ -1622,10 +2803,10 @@ ScsiDiskInquiryDevice (
 **/\r
 EFI_STATUS\r
 ScsiDiskTestUnitReady (\r
-  IN  SCSI_DISK_DEV         *ScsiDiskDevice,\r
-  OUT BOOLEAN               *NeedRetry,\r
-  OUT EFI_SCSI_SENSE_DATA   **SenseDataArray,\r
-  OUT UINTN                 *NumberOfSenseKeys\r
+  IN  SCSI_DISK_DEV        *ScsiDiskDevice,\r
+  OUT BOOLEAN              *NeedRetry,\r
+  OUT EFI_SCSI_SENSE_DATA  **SenseDataArray,\r
+  OUT UINTN                *NumberOfSenseKeys\r
   )\r
 {\r
   EFI_STATUS  Status;\r
@@ -1635,31 +2816,31 @@ ScsiDiskTestUnitReady (
   UINT8       Index;\r
   UINT8       MaxRetry;\r
 \r
-  SenseDataLength     = (UINT8) (ScsiDiskDevice->SenseDataNumber * sizeof (EFI_SCSI_SENSE_DATA));\r
-  *NumberOfSenseKeys  = 0;\r
+  SenseDataLength    = (UINT8)(ScsiDiskDevice->SenseDataNumber * sizeof (EFI_SCSI_SENSE_DATA));\r
+  *NumberOfSenseKeys = 0;\r
 \r
   //\r
   // Parameter 3 and 4: do not require sense data, retrieve it when needed.\r
   //\r
   Status = ScsiTestUnitReadyCommand (\r
-            ScsiDiskDevice->ScsiIo,\r
-            SCSI_DISK_TIMEOUT,\r
-            ScsiDiskDevice->SenseData,\r
-            &SenseDataLength,\r
-            &HostAdapterStatus,\r
-            &TargetStatus\r
-            );\r
+             ScsiDiskDevice->ScsiIo,\r
+             SCSI_DISK_TIMEOUT,\r
+             ScsiDiskDevice->SenseData,\r
+             &SenseDataLength,\r
+             &HostAdapterStatus,\r
+             &TargetStatus\r
+             );\r
   //\r
   // no need to check HostAdapterStatus and TargetStatus\r
   //\r
   if (Status == EFI_NOT_READY) {\r
     *NeedRetry = TRUE;\r
     return EFI_DEVICE_ERROR;\r
-\r
   } else if ((Status == EFI_INVALID_PARAMETER) || (Status == EFI_UNSUPPORTED)) {\r
     *NeedRetry = FALSE;\r
     return EFI_DEVICE_ERROR;\r
   }\r
+\r
   //\r
   // go ahead to check HostAdapterStatus and TargetStatus(in case of EFI_DEVICE_ERROR)\r
   //\r
@@ -1668,7 +2849,6 @@ ScsiDiskTestUnitReady (
   if ((Status == EFI_TIMEOUT) || (Status == EFI_NOT_READY)) {\r
     *NeedRetry = TRUE;\r
     return EFI_DEVICE_ERROR;\r
-\r
   } else if (Status == EFI_DEVICE_ERROR) {\r
     //\r
     // reset the scsi channel\r
@@ -1686,7 +2866,6 @@ ScsiDiskTestUnitReady (
     ScsiDiskDevice->ScsiIo->ResetDevice (ScsiDiskDevice->ScsiIo);\r
     *NeedRetry = TRUE;\r
     return EFI_DEVICE_ERROR;\r
-\r
   } else if (Status == EFI_DEVICE_ERROR) {\r
     *NeedRetry = FALSE;\r
     return EFI_DEVICE_ERROR;\r
@@ -1701,12 +2880,12 @@ ScsiDiskTestUnitReady (
   MaxRetry = 3;\r
   for (Index = 0; Index < MaxRetry; Index++) {\r
     Status = ScsiDiskRequestSenseKeys (\r
-              ScsiDiskDevice,\r
-              NeedRetry,\r
-              SenseDataArray,\r
-              NumberOfSenseKeys,\r
-              FALSE\r
-              );\r
+               ScsiDiskDevice,\r
+               NeedRetry,\r
+               SenseDataArray,\r
+               NumberOfSenseKeys,\r
+               FALSE\r
+               );\r
     if (!EFI_ERROR (Status)) {\r
       return EFI_SUCCESS;\r
     }\r
@@ -1715,6 +2894,7 @@ ScsiDiskTestUnitReady (
       return EFI_DEVICE_ERROR;\r
     }\r
   }\r
+\r
   //\r
   // ScsiDiskRequestSenseKeys() failed after several rounds of retry.\r
   // set *NeedRetry = FALSE to avoid the outside caller try again.\r
@@ -1728,7 +2908,7 @@ ScsiDiskTestUnitReady (
 \r
   @param  ScsiDiskDevice     The pointer of SCSI_DISK_DEV\r
   @param  SenseData          The pointer of EFI_SCSI_SENSE_DATA\r
-  @param  NumberOfSenseKeys  The number of sense key  \r
+  @param  NumberOfSenseKeys  The number of sense key\r
   @param  Action             The pointer of action which indicates what is need to do next\r
 \r
   @retval EFI_DEVICE_ERROR   Indicates that error occurs\r
@@ -1737,13 +2917,13 @@ ScsiDiskTestUnitReady (
 **/\r
 EFI_STATUS\r
 DetectMediaParsingSenseKeys (\r
-  OUT  SCSI_DISK_DEV           *ScsiDiskDevice,\r
-  IN   EFI_SCSI_SENSE_DATA     *SenseData,\r
-  IN   UINTN                   NumberOfSenseKeys,\r
-  OUT  UINTN                   *Action\r
+  OUT  SCSI_DISK_DEV        *ScsiDiskDevice,\r
+  IN   EFI_SCSI_SENSE_DATA  *SenseData,\r
+  IN   UINTN                NumberOfSenseKeys,\r
+  OUT  UINTN                *Action\r
   )\r
 {\r
-  BOOLEAN RetryLater;\r
+  BOOLEAN  RetryLater;\r
 \r
   //\r
   // Default is to read capacity, unless..\r
@@ -1754,6 +2934,7 @@ DetectMediaParsingSenseKeys (
     if (ScsiDiskDevice->BlkIo.Media->MediaPresent == TRUE) {\r
       *Action = ACTION_NO_ACTION;\r
     }\r
+\r
     return EFI_SUCCESS;\r
   }\r
 \r
@@ -1764,37 +2945,38 @@ DetectMediaParsingSenseKeys (
     if (ScsiDiskDevice->BlkIo.Media->MediaPresent == TRUE) {\r
       *Action = ACTION_NO_ACTION;\r
     }\r
+\r
     return EFI_SUCCESS;\r
   }\r
 \r
   if (ScsiDiskIsNoMedia (SenseData, NumberOfSenseKeys)) {\r
     ScsiDiskDevice->BlkIo.Media->MediaPresent = FALSE;\r
     ScsiDiskDevice->BlkIo.Media->LastBlock    = 0;\r
-    *Action = ACTION_NO_ACTION;\r
-    DEBUG ((EFI_D_VERBOSE, "ScsiDisk: ScsiDiskIsNoMedia\n"));\r
+    *Action                                   = ACTION_NO_ACTION;\r
+    DEBUG ((DEBUG_VERBOSE, "ScsiDisk: ScsiDiskIsNoMedia\n"));\r
     return EFI_SUCCESS;\r
   }\r
 \r
   if (ScsiDiskIsMediaChange (SenseData, NumberOfSenseKeys)) {\r
     ScsiDiskDevice->BlkIo.Media->MediaId++;\r
-    DEBUG ((EFI_D_VERBOSE, "ScsiDisk: ScsiDiskIsMediaChange!\n"));\r
+    DEBUG ((DEBUG_VERBOSE, "ScsiDisk: ScsiDiskIsMediaChange!\n"));\r
     return EFI_SUCCESS;\r
   }\r
 \r
   if (ScsiDiskIsResetBefore (SenseData, NumberOfSenseKeys)) {\r
     *Action = ACTION_RETRY_COMMAND_LATER;\r
-    DEBUG ((EFI_D_VERBOSE, "ScsiDisk: ScsiDiskIsResetBefore!\n"));\r
+    DEBUG ((DEBUG_VERBOSE, "ScsiDisk: ScsiDiskIsResetBefore!\n"));\r
     return EFI_SUCCESS;\r
   }\r
 \r
   if (ScsiDiskIsMediaError (SenseData, NumberOfSenseKeys)) {\r
-    DEBUG ((EFI_D_VERBOSE, "ScsiDisk: ScsiDiskIsMediaError\n"));\r
+    DEBUG ((DEBUG_VERBOSE, "ScsiDisk: ScsiDiskIsMediaError\n"));\r
     *Action = ACTION_RETRY_WITH_BACKOFF_ALGO;\r
     return EFI_DEVICE_ERROR;\r
   }\r
 \r
   if (ScsiDiskIsHardwareError (SenseData, NumberOfSenseKeys)) {\r
-    DEBUG ((EFI_D_VERBOSE, "ScsiDisk: ScsiDiskIsHardwareError\n"));\r
+    DEBUG ((DEBUG_VERBOSE, "ScsiDisk: ScsiDiskIsHardwareError\n"));\r
     *Action = ACTION_RETRY_WITH_BACKOFF_ALGO;\r
     return EFI_DEVICE_ERROR;\r
   }\r
@@ -1802,19 +2984,19 @@ DetectMediaParsingSenseKeys (
   if (!ScsiDiskIsDriveReady (SenseData, NumberOfSenseKeys, &RetryLater)) {\r
     if (RetryLater) {\r
       *Action = ACTION_RETRY_COMMAND_LATER;\r
-      DEBUG ((EFI_D_VERBOSE, "ScsiDisk: ScsiDiskDriveNotReady!\n"));\r
+      DEBUG ((DEBUG_VERBOSE, "ScsiDisk: ScsiDiskDriveNotReady!\n"));\r
       return EFI_SUCCESS;\r
     }\r
+\r
     *Action = ACTION_NO_ACTION;\r
     return EFI_DEVICE_ERROR;\r
   }\r
 \r
   *Action = ACTION_RETRY_WITH_BACKOFF_ALGO;\r
-  DEBUG ((EFI_D_VERBOSE, "ScsiDisk: Sense Key = 0x%x ASC = 0x%x!\n", SenseData->Sense_Key, SenseData->Addnl_Sense_Code));\r
+  DEBUG ((DEBUG_VERBOSE, "ScsiDisk: Sense Key = 0x%x ASC = 0x%x!\n", SenseData->Sense_Key, SenseData->Addnl_Sense_Code));\r
   return EFI_SUCCESS;\r
 }\r
 \r
-\r
 /**\r
   Send read capacity command to device and get the device parameter.\r
 \r
@@ -1829,29 +3011,30 @@ DetectMediaParsingSenseKeys (
 **/\r
 EFI_STATUS\r
 ScsiDiskReadCapacity (\r
-  IN  OUT  SCSI_DISK_DEV           *ScsiDiskDevice,\r
-      OUT  BOOLEAN                 *NeedRetry,\r
-      OUT  EFI_SCSI_SENSE_DATA     **SenseDataArray,\r
-      OUT  UINTN                   *NumberOfSenseKeys\r
+  IN  OUT  SCSI_DISK_DEV    *ScsiDiskDevice,\r
+  OUT  BOOLEAN              *NeedRetry,\r
+  OUT  EFI_SCSI_SENSE_DATA  **SenseDataArray,\r
+  OUT  UINTN                *NumberOfSenseKeys\r
   )\r
 {\r
-  UINT8                         HostAdapterStatus;\r
-  UINT8                         TargetStatus;\r
-  EFI_STATUS                    CommandStatus;\r
-  EFI_STATUS                    Status;\r
-  UINT8                         Index;\r
-  UINT8                         MaxRetry;\r
-  UINT8                         SenseDataLength;\r
-  UINT32                        DataLength10;\r
-  UINT32                        DataLength16;\r
-  EFI_SCSI_DISK_CAPACITY_DATA   *CapacityData10;\r
-  EFI_SCSI_DISK_CAPACITY_DATA16 *CapacityData16;\r
+  UINT8                          HostAdapterStatus;\r
+  UINT8                          TargetStatus;\r
+  EFI_STATUS                     CommandStatus;\r
+  EFI_STATUS                     Status;\r
+  UINT8                          Index;\r
+  UINT8                          MaxRetry;\r
+  UINT8                          SenseDataLength;\r
+  UINT32                         DataLength10;\r
+  UINT32                         DataLength16;\r
+  EFI_SCSI_DISK_CAPACITY_DATA    *CapacityData10;\r
+  EFI_SCSI_DISK_CAPACITY_DATA16  *CapacityData16;\r
 \r
   CapacityData10 = AllocateAlignedBuffer (ScsiDiskDevice, sizeof (EFI_SCSI_DISK_CAPACITY_DATA));\r
   if (CapacityData10 == NULL) {\r
     *NeedRetry = FALSE;\r
     return EFI_DEVICE_ERROR;\r
   }\r
+\r
   CapacityData16 = AllocateAlignedBuffer (ScsiDiskDevice, sizeof (EFI_SCSI_DISK_CAPACITY_DATA16));\r
   if (CapacityData16 == NULL) {\r
     FreeAlignedBuffer (CapacityData10, sizeof (EFI_SCSI_DISK_CAPACITY_DATA));\r
@@ -1859,17 +3042,17 @@ ScsiDiskReadCapacity (
     return EFI_DEVICE_ERROR;\r
   }\r
 \r
-  SenseDataLength       = 0;\r
-  DataLength10          = sizeof (EFI_SCSI_DISK_CAPACITY_DATA);\r
-  DataLength16          = sizeof (EFI_SCSI_DISK_CAPACITY_DATA16);\r
+  SenseDataLength = 0;\r
+  DataLength10    = sizeof (EFI_SCSI_DISK_CAPACITY_DATA);\r
+  DataLength16    = sizeof (EFI_SCSI_DISK_CAPACITY_DATA16);\r
   ZeroMem (CapacityData10, sizeof (EFI_SCSI_DISK_CAPACITY_DATA));\r
   ZeroMem (CapacityData16, sizeof (EFI_SCSI_DISK_CAPACITY_DATA16));\r
 \r
-  *NumberOfSenseKeys  = 0;\r
-  *NeedRetry          = FALSE;\r
+  *NumberOfSenseKeys = 0;\r
+  *NeedRetry         = FALSE;\r
 \r
   //\r
-  // submit Read Capacity(10) Command. If it returns capacity of FFFFFFFFh, \r
+  // submit Read Capacity(10) Command. If it returns capacity of FFFFFFFFh,\r
   // 16 byte command should be used to access large hard disk >2TB\r
   //\r
   CommandStatus = ScsiReadCapacityCommand (\r
@@ -1879,14 +3062,15 @@ ScsiDiskReadCapacity (
                     &SenseDataLength,\r
                     &HostAdapterStatus,\r
                     &TargetStatus,\r
-                    (VOID *) CapacityData10,\r
+                    (VOID *)CapacityData10,\r
                     &DataLength10,\r
                     FALSE\r
                     );\r
 \r
   ScsiDiskDevice->Cdb16Byte = FALSE;\r
   if ((!EFI_ERROR (CommandStatus)) && (CapacityData10->LastLba3 == 0xff) && (CapacityData10->LastLba2 == 0xff) &&\r
-      (CapacityData10->LastLba1 == 0xff) && (CapacityData10->LastLba0 == 0xff)) {\r
+      (CapacityData10->LastLba1 == 0xff) && (CapacityData10->LastLba0 == 0xff))\r
+  {\r
     //\r
     // use Read Capacity (16), Read (16) and Write (16) next when hard disk size > 2TB\r
     //\r
@@ -1902,44 +3086,43 @@ ScsiDiskReadCapacity (
                       &SenseDataLength,\r
                       &HostAdapterStatus,\r
                       &TargetStatus,\r
-                      (VOID *) CapacityData16,\r
+                      (VOID *)CapacityData16,\r
                       &DataLength16,\r
                       FALSE\r
                       );\r
   }\r
 \r
-    //\r
-    // no need to check HostAdapterStatus and TargetStatus\r
-    //\r
-   if (CommandStatus == EFI_SUCCESS) {\r
-     GetMediaInfo (ScsiDiskDevice, CapacityData10, CapacityData16);\r
-     FreeAlignedBuffer (CapacityData10, sizeof (EFI_SCSI_DISK_CAPACITY_DATA));\r
-     FreeAlignedBuffer (CapacityData16, sizeof (EFI_SCSI_DISK_CAPACITY_DATA16));\r
-     return EFI_SUCCESS;\r
-   }\r
-\r
-   FreeAlignedBuffer (CapacityData10, sizeof (EFI_SCSI_DISK_CAPACITY_DATA));\r
-   FreeAlignedBuffer (CapacityData16, sizeof (EFI_SCSI_DISK_CAPACITY_DATA16));\r
-\r
-   if (CommandStatus == EFI_NOT_READY) {\r
-     *NeedRetry = TRUE;\r
-     return EFI_DEVICE_ERROR;\r
-   } else if ((CommandStatus == EFI_INVALID_PARAMETER) || (CommandStatus == EFI_UNSUPPORTED)) {\r
-     *NeedRetry = FALSE;\r
-     return EFI_DEVICE_ERROR;\r
-   }\r
-\r
-   //\r
-   // go ahead to check HostAdapterStatus and TargetStatus\r
-   // (EFI_TIMEOUT, EFI_DEVICE_ERROR, EFI_WARN_BUFFER_TOO_SMALL)\r
-   //\r
\r
-   Status = CheckHostAdapterStatus (HostAdapterStatus);\r
-   if ((Status == EFI_TIMEOUT) || (Status == EFI_NOT_READY)) {\r
-     *NeedRetry = TRUE;\r
-     return EFI_DEVICE_ERROR;\r
\r
-   } else if (Status == EFI_DEVICE_ERROR) {\r
+  //\r
+  // no need to check HostAdapterStatus and TargetStatus\r
+  //\r
+  if (CommandStatus == EFI_SUCCESS) {\r
+    GetMediaInfo (ScsiDiskDevice, CapacityData10, CapacityData16);\r
+    FreeAlignedBuffer (CapacityData10, sizeof (EFI_SCSI_DISK_CAPACITY_DATA));\r
+    FreeAlignedBuffer (CapacityData16, sizeof (EFI_SCSI_DISK_CAPACITY_DATA16));\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  FreeAlignedBuffer (CapacityData10, sizeof (EFI_SCSI_DISK_CAPACITY_DATA));\r
+  FreeAlignedBuffer (CapacityData16, sizeof (EFI_SCSI_DISK_CAPACITY_DATA16));\r
+\r
+  if (CommandStatus == EFI_NOT_READY) {\r
+    *NeedRetry = TRUE;\r
+    return EFI_DEVICE_ERROR;\r
+  } else if ((CommandStatus == EFI_INVALID_PARAMETER) || (CommandStatus == EFI_UNSUPPORTED)) {\r
+    *NeedRetry = FALSE;\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  //\r
+  // go ahead to check HostAdapterStatus and TargetStatus\r
+  // (EFI_TIMEOUT, EFI_DEVICE_ERROR, EFI_WARN_BUFFER_TOO_SMALL)\r
+  //\r
+\r
+  Status = CheckHostAdapterStatus (HostAdapterStatus);\r
+  if ((Status == EFI_TIMEOUT) || (Status == EFI_NOT_READY)) {\r
+    *NeedRetry = TRUE;\r
+    return EFI_DEVICE_ERROR;\r
+  } else if (Status == EFI_DEVICE_ERROR) {\r
     //\r
     // reset the scsi channel\r
     //\r
@@ -1956,12 +3139,11 @@ ScsiDiskReadCapacity (
     ScsiDiskDevice->ScsiIo->ResetDevice (ScsiDiskDevice->ScsiIo);\r
     *NeedRetry = TRUE;\r
     return EFI_DEVICE_ERROR;\r
-\r
   } else if (Status == EFI_DEVICE_ERROR) {\r
     *NeedRetry = FALSE;\r
     return EFI_DEVICE_ERROR;\r
   }\r
-  \r
+\r
   //\r
   // if goes here, meant ScsiReadCapacityCommand() failed.\r
   // if ScsiDiskRequestSenseKeys() succeeds at last,\r
@@ -1969,14 +3151,13 @@ ScsiDiskReadCapacity (
   //\r
   MaxRetry = 3;\r
   for (Index = 0; Index < MaxRetry; Index++) {\r
-\r
     Status = ScsiDiskRequestSenseKeys (\r
-              ScsiDiskDevice,\r
-              NeedRetry,\r
-              SenseDataArray,\r
-              NumberOfSenseKeys,\r
-              TRUE\r
-              );\r
+               ScsiDiskDevice,\r
+               NeedRetry,\r
+               SenseDataArray,\r
+               NumberOfSenseKeys,\r
+               TRUE\r
+               );\r
     if (!EFI_ERROR (Status)) {\r
       return EFI_SUCCESS;\r
     }\r
@@ -1985,6 +3166,7 @@ ScsiDiskReadCapacity (
       return EFI_DEVICE_ERROR;\r
     }\r
   }\r
+\r
   //\r
   // ScsiDiskRequestSenseKeys() failed after several rounds of retry.\r
   // set *NeedRetry = FALSE to avoid the outside caller try again.\r
@@ -2006,77 +3188,75 @@ ScsiDiskReadCapacity (
 **/\r
 EFI_STATUS\r
 CheckHostAdapterStatus (\r
-  IN UINT8   HostAdapterStatus\r
+  IN UINT8  HostAdapterStatus\r
   )\r
 {\r
   switch (HostAdapterStatus) {\r
-  case EFI_EXT_SCSI_STATUS_HOST_ADAPTER_OK:\r
-    return EFI_SUCCESS;\r
+    case EFI_EXT_SCSI_STATUS_HOST_ADAPTER_OK:\r
+      return EFI_SUCCESS;\r
 \r
-  case EFI_EXT_SCSI_STATUS_HOST_ADAPTER_SELECTION_TIMEOUT:\r
-  case EFI_EXT_SCSI_STATUS_HOST_ADAPTER_TIMEOUT:\r
-  case EFI_EXT_SCSI_STATUS_HOST_ADAPTER_TIMEOUT_COMMAND:\r
-    return EFI_TIMEOUT;\r
+    case EFI_EXT_SCSI_STATUS_HOST_ADAPTER_SELECTION_TIMEOUT:\r
+    case EFI_EXT_SCSI_STATUS_HOST_ADAPTER_TIMEOUT:\r
+    case EFI_EXT_SCSI_STATUS_HOST_ADAPTER_TIMEOUT_COMMAND:\r
+      return EFI_TIMEOUT;\r
 \r
-  case EFI_EXT_SCSI_STATUS_HOST_ADAPTER_MESSAGE_REJECT:\r
-  case EFI_EXT_SCSI_STATUS_HOST_ADAPTER_PARITY_ERROR:\r
-  case EFI_EXT_SCSI_STATUS_HOST_ADAPTER_REQUEST_SENSE_FAILED:\r
-  case EFI_EXT_SCSI_STATUS_HOST_ADAPTER_DATA_OVERRUN_UNDERRUN:\r
-  case EFI_EXT_SCSI_STATUS_HOST_ADAPTER_BUS_RESET:\r
-    return EFI_NOT_READY;\r
+    case EFI_EXT_SCSI_STATUS_HOST_ADAPTER_MESSAGE_REJECT:\r
+    case EFI_EXT_SCSI_STATUS_HOST_ADAPTER_PARITY_ERROR:\r
+    case EFI_EXT_SCSI_STATUS_HOST_ADAPTER_REQUEST_SENSE_FAILED:\r
+    case EFI_EXT_SCSI_STATUS_HOST_ADAPTER_DATA_OVERRUN_UNDERRUN:\r
+    case EFI_EXT_SCSI_STATUS_HOST_ADAPTER_BUS_RESET:\r
+      return EFI_NOT_READY;\r
 \r
-  case EFI_EXT_SCSI_STATUS_HOST_ADAPTER_BUS_FREE:\r
-  case EFI_EXT_SCSI_STATUS_HOST_ADAPTER_PHASE_ERROR:\r
-    return EFI_DEVICE_ERROR;\r
+    case EFI_EXT_SCSI_STATUS_HOST_ADAPTER_BUS_FREE:\r
+    case EFI_EXT_SCSI_STATUS_HOST_ADAPTER_PHASE_ERROR:\r
+      return EFI_DEVICE_ERROR;\r
 \r
-  default:\r
-    return EFI_SUCCESS;\r
+    default:\r
+      return EFI_SUCCESS;\r
   }\r
 }\r
 \r
-\r
 /**\r
   Check the target status and re-interpret it in EFI_STATUS.\r
 \r
   @param  TargetStatus  Target status\r
 \r
   @retval EFI_NOT_READY       Device is NOT ready.\r
-  @retval EFI_DEVICE_ERROR \r
+  @retval EFI_DEVICE_ERROR\r
   @retval EFI_SUCCESS\r
 \r
 **/\r
 EFI_STATUS\r
 CheckTargetStatus (\r
-  IN  UINT8   TargetStatus\r
+  IN  UINT8  TargetStatus\r
   )\r
 {\r
   switch (TargetStatus) {\r
-  case EFI_EXT_SCSI_STATUS_TARGET_GOOD:\r
-  case EFI_EXT_SCSI_STATUS_TARGET_CHECK_CONDITION:\r
-  case EFI_EXT_SCSI_STATUS_TARGET_CONDITION_MET:\r
-    return EFI_SUCCESS;\r
+    case EFI_EXT_SCSI_STATUS_TARGET_GOOD:\r
+    case EFI_EXT_SCSI_STATUS_TARGET_CHECK_CONDITION:\r
+    case EFI_EXT_SCSI_STATUS_TARGET_CONDITION_MET:\r
+      return EFI_SUCCESS;\r
 \r
-  case EFI_EXT_SCSI_STATUS_TARGET_INTERMEDIATE:\r
-  case EFI_EXT_SCSI_STATUS_TARGET_INTERMEDIATE_CONDITION_MET:\r
-  case EFI_EXT_SCSI_STATUS_TARGET_BUSY:\r
-  case EFI_EXT_SCSI_STATUS_TARGET_TASK_SET_FULL:\r
-    return EFI_NOT_READY;\r
+    case EFI_EXT_SCSI_STATUS_TARGET_INTERMEDIATE:\r
+    case EFI_EXT_SCSI_STATUS_TARGET_INTERMEDIATE_CONDITION_MET:\r
+    case EFI_EXT_SCSI_STATUS_TARGET_BUSY:\r
+    case EFI_EXT_SCSI_STATUS_TARGET_TASK_SET_FULL:\r
+      return EFI_NOT_READY;\r
 \r
-  case EFI_EXT_SCSI_STATUS_TARGET_RESERVATION_CONFLICT:\r
-    return EFI_DEVICE_ERROR;\r
+    case EFI_EXT_SCSI_STATUS_TARGET_RESERVATION_CONFLICT:\r
+      return EFI_DEVICE_ERROR;\r
 \r
-  default:\r
-    return EFI_SUCCESS;\r
+    default:\r
+      return EFI_SUCCESS;\r
   }\r
 }\r
 \r
-\r
 /**\r
   Retrieve all sense keys from the device.\r
 \r
   When encountering error during the process, if retrieve sense keys before\r
   error encountered, it returns the sense keys with return status set to EFI_SUCCESS,\r
-  and NeedRetry set to FALSE; otherwize, return the proper return status.\r
+  and NeedRetry set to FALSE; otherwise, return the proper return status.\r
 \r
   @param  ScsiDiskDevice     The pointer of SCSI_DISK_DEV\r
   @param  NeedRetry          The pointer of flag indicates if need a retry\r
@@ -2090,33 +3270,33 @@ CheckTargetStatus (
 **/\r
 EFI_STATUS\r
 ScsiDiskRequestSenseKeys (\r
-  IN  OUT  SCSI_DISK_DEV           *ScsiDiskDevice,\r
-      OUT  BOOLEAN                 *NeedRetry,\r
-      OUT  EFI_SCSI_SENSE_DATA     **SenseDataArray,\r
-      OUT  UINTN                   *NumberOfSenseKeys,\r
-  IN       BOOLEAN                 AskResetIfError\r
+  IN  OUT  SCSI_DISK_DEV    *ScsiDiskDevice,\r
+  OUT  BOOLEAN              *NeedRetry,\r
+  OUT  EFI_SCSI_SENSE_DATA  **SenseDataArray,\r
+  OUT  UINTN                *NumberOfSenseKeys,\r
+  IN       BOOLEAN          AskResetIfError\r
   )\r
 {\r
-  EFI_SCSI_SENSE_DATA *PtrSenseData;\r
-  UINT8               SenseDataLength;\r
-  BOOLEAN             SenseReq;\r
-  EFI_STATUS          Status;\r
-  EFI_STATUS          FallStatus;\r
-  UINT8               HostAdapterStatus;\r
-  UINT8               TargetStatus;\r
+  EFI_SCSI_SENSE_DATA  *PtrSenseData;\r
+  UINT8                SenseDataLength;\r
+  BOOLEAN              SenseReq;\r
+  EFI_STATUS           Status;\r
+  EFI_STATUS           FallStatus;\r
+  UINT8                HostAdapterStatus;\r
+  UINT8                TargetStatus;\r
 \r
   FallStatus      = EFI_SUCCESS;\r
-  SenseDataLength = (UINT8) sizeof (EFI_SCSI_SENSE_DATA);\r
+  SenseDataLength = (UINT8)sizeof (EFI_SCSI_SENSE_DATA);\r
 \r
   ZeroMem (\r
     ScsiDiskDevice->SenseData,\r
     sizeof (EFI_SCSI_SENSE_DATA) * (ScsiDiskDevice->SenseDataNumber)\r
     );\r
 \r
-  *NumberOfSenseKeys  = 0;\r
-  *SenseDataArray     = ScsiDiskDevice->SenseData;\r
-  Status              = EFI_SUCCESS;\r
-  PtrSenseData        = AllocateAlignedBuffer (ScsiDiskDevice, sizeof (EFI_SCSI_SENSE_DATA));\r
+  *NumberOfSenseKeys = 0;\r
+  *SenseDataArray    = ScsiDiskDevice->SenseData;\r
+  Status             = EFI_SUCCESS;\r
+  PtrSenseData       = AllocateAlignedBuffer (ScsiDiskDevice, sizeof (EFI_SCSI_SENSE_DATA));\r
   if (PtrSenseData == NULL) {\r
     return EFI_DEVICE_ERROR;\r
   }\r
@@ -2124,36 +3304,33 @@ ScsiDiskRequestSenseKeys (
   for (SenseReq = TRUE; SenseReq;) {\r
     ZeroMem (PtrSenseData, sizeof (EFI_SCSI_SENSE_DATA));\r
     Status = ScsiRequestSenseCommand (\r
-              ScsiDiskDevice->ScsiIo,\r
-              SCSI_DISK_TIMEOUT,\r
-              PtrSenseData,\r
-              &SenseDataLength,\r
-              &HostAdapterStatus,\r
-              &TargetStatus\r
-              );\r
-     if ((Status == EFI_SUCCESS) || (Status == EFI_WARN_BUFFER_TOO_SMALL)) {\r
-        FallStatus = EFI_SUCCESS;\r
-  \r
-     } else if ((Status == EFI_TIMEOUT) || (Status == EFI_NOT_READY)) {\r
-       *NeedRetry  = TRUE;\r
-       FallStatus  = EFI_DEVICE_ERROR;\r
\r
-     } else if ((Status == EFI_INVALID_PARAMETER) || (Status == EFI_UNSUPPORTED)) {\r
-       *NeedRetry  = FALSE;\r
-       FallStatus  = EFI_DEVICE_ERROR;\r
\r
-     } else if (Status == EFI_DEVICE_ERROR) {\r
-        if (AskResetIfError) {\r
-          ScsiDiskDevice->ScsiIo->ResetDevice (ScsiDiskDevice->ScsiIo);\r
-        }\r
-  \r
-        FallStatus = EFI_DEVICE_ERROR;\r
+               ScsiDiskDevice->ScsiIo,\r
+               SCSI_DISK_TIMEOUT,\r
+               PtrSenseData,\r
+               &SenseDataLength,\r
+               &HostAdapterStatus,\r
+               &TargetStatus\r
+               );\r
+    if ((Status == EFI_SUCCESS) || (Status == EFI_WARN_BUFFER_TOO_SMALL)) {\r
+      FallStatus = EFI_SUCCESS;\r
+    } else if ((Status == EFI_TIMEOUT) || (Status == EFI_NOT_READY)) {\r
+      *NeedRetry = TRUE;\r
+      FallStatus = EFI_DEVICE_ERROR;\r
+    } else if ((Status == EFI_INVALID_PARAMETER) || (Status == EFI_UNSUPPORTED)) {\r
+      *NeedRetry = FALSE;\r
+      FallStatus = EFI_DEVICE_ERROR;\r
+    } else if (Status == EFI_DEVICE_ERROR) {\r
+      if (AskResetIfError) {\r
+        ScsiDiskDevice->ScsiIo->ResetDevice (ScsiDiskDevice->ScsiIo);\r
+      }\r
+\r
+      FallStatus = EFI_DEVICE_ERROR;\r
     }\r
 \r
     if (EFI_ERROR (FallStatus)) {\r
       if (*NumberOfSenseKeys != 0) {\r
         *NeedRetry = FALSE;\r
-        Status = EFI_SUCCESS;\r
+        Status     = EFI_SUCCESS;\r
         goto EXIT;\r
       } else {\r
         Status = EFI_DEVICE_ERROR;\r
@@ -2168,8 +3345,9 @@ ScsiDiskRequestSenseKeys (
     // no more sense key or number of sense keys exceeds predefined,\r
     // skip the loop.\r
     //\r
-    if ((PtrSenseData->Sense_Key == EFI_SCSI_SK_NO_SENSE) || \r
-        (*NumberOfSenseKeys == ScsiDiskDevice->SenseDataNumber)) {\r
+    if ((PtrSenseData->Sense_Key == EFI_SCSI_SK_NO_SENSE) ||\r
+        (*NumberOfSenseKeys == ScsiDiskDevice->SenseDataNumber))\r
+    {\r
       SenseReq = FALSE;\r
     }\r
   }\r
@@ -2179,7 +3357,6 @@ EXIT:
   return Status;\r
 }\r
 \r
-\r
 /**\r
   Get information from media read capacity command.\r
 \r
@@ -2195,22 +3372,25 @@ GetMediaInfo (
   IN     EFI_SCSI_DISK_CAPACITY_DATA16  *Capacity16\r
   )\r
 {\r
-  UINT8       *Ptr;\r
+  UINT8  *Ptr;\r
 \r
   if (!ScsiDiskDevice->Cdb16Byte) {\r
-    ScsiDiskDevice->BlkIo.Media->LastBlock =  (Capacity10->LastLba3 << 24) |\r
-                                              (Capacity10->LastLba2 << 16) |\r
-                                              (Capacity10->LastLba1 << 8)  |\r
-                                               Capacity10->LastLba0;\r
-  \r
+    ScsiDiskDevice->BlkIo.Media->LastBlock =  ((UINT32)Capacity10->LastLba3 << 24) |\r
+                                             (Capacity10->LastLba2 << 16) |\r
+                                             (Capacity10->LastLba1 << 8)  |\r
+                                             Capacity10->LastLba0;\r
+\r
     ScsiDiskDevice->BlkIo.Media->BlockSize = (Capacity10->BlockSize3 << 24) |\r
-                                             (Capacity10->BlockSize2 << 16) | \r
+                                             (Capacity10->BlockSize2 << 16) |\r
                                              (Capacity10->BlockSize1 << 8)  |\r
-                                              Capacity10->BlockSize0;\r
-    ScsiDiskDevice->BlkIo.Media->LowestAlignedLba               = 0;\r
-    ScsiDiskDevice->BlkIo.Media->LogicalBlocksPerPhysicalBlock  = 0;\r
+                                             Capacity10->BlockSize0;\r
+    ScsiDiskDevice->BlkIo.Media->LowestAlignedLba              = 0;\r
+    ScsiDiskDevice->BlkIo.Media->LogicalBlocksPerPhysicalBlock = 0;\r
+    if (!ScsiDiskDevice->BlockLimitsVpdSupported) {\r
+      ScsiDiskDevice->UnmapInfo.MaxLbaCnt = (UINT32)ScsiDiskDevice->BlkIo.Media->LastBlock;\r
+    }\r
   } else {\r
-    Ptr = (UINT8*)&ScsiDiskDevice->BlkIo.Media->LastBlock;\r
+    Ptr    = (UINT8 *)&ScsiDiskDevice->BlkIo.Media->LastBlock;\r
     *Ptr++ = Capacity16->LastLba0;\r
     *Ptr++ = Capacity16->LastLba1;\r
     *Ptr++ = Capacity16->LastLba2;\r
@@ -2221,13 +3401,20 @@ GetMediaInfo (
     *Ptr   = Capacity16->LastLba7;\r
 \r
     ScsiDiskDevice->BlkIo.Media->BlockSize = (Capacity16->BlockSize3 << 24) |\r
-                                             (Capacity16->BlockSize2 << 16) | \r
+                                             (Capacity16->BlockSize2 << 16) |\r
                                              (Capacity16->BlockSize1 << 8)  |\r
-                                              Capacity16->BlockSize0;\r
+                                             Capacity16->BlockSize0;\r
 \r
     ScsiDiskDevice->BlkIo.Media->LowestAlignedLba = (Capacity16->LowestAlignLogic2 << 8) |\r
-                                                     Capacity16->LowestAlignLogic1;\r
-    ScsiDiskDevice->BlkIo.Media->LogicalBlocksPerPhysicalBlock  = (1 << Capacity16->LogicPerPhysical);\r
+                                                    Capacity16->LowestAlignLogic1;\r
+    ScsiDiskDevice->BlkIo.Media->LogicalBlocksPerPhysicalBlock = (1 << Capacity16->LogicPerPhysical);\r
+    if (!ScsiDiskDevice->BlockLimitsVpdSupported) {\r
+      if (ScsiDiskDevice->BlkIo.Media->LastBlock > (UINT32)-1) {\r
+        ScsiDiskDevice->UnmapInfo.MaxLbaCnt = (UINT32)-1;\r
+      } else {\r
+        ScsiDiskDevice->UnmapInfo.MaxLbaCnt = (UINT32)ScsiDiskDevice->BlkIo.Media->LastBlock;\r
+      }\r
+    }\r
   }\r
 \r
   ScsiDiskDevice->BlkIo.Media->MediaPresent = TRUE;\r
@@ -2241,11 +3428,11 @@ GetMediaInfo (
 **/\r
 VOID\r
 ParseInquiryData (\r
-  IN OUT SCSI_DISK_DEV   *ScsiDiskDevice\r
+  IN OUT SCSI_DISK_DEV  *ScsiDiskDevice\r
   )\r
 {\r
-  ScsiDiskDevice->FixedDevice               = (BOOLEAN) ((ScsiDiskDevice->InquiryData.Rmb == 1) ? 0 : 1);\r
-  ScsiDiskDevice->BlkIoMedia.RemovableMedia = (BOOLEAN) (!ScsiDiskDevice->FixedDevice);\r
+  ScsiDiskDevice->FixedDevice               = (BOOLEAN)((ScsiDiskDevice->InquiryData.Rmb == 1) ? 0 : 1);\r
+  ScsiDiskDevice->BlkIoMedia.RemovableMedia = (BOOLEAN)(!ScsiDiskDevice->FixedDevice);\r
 }\r
 \r
 /**\r
@@ -2262,48 +3449,47 @@ ParseInquiryData (
 **/\r
 EFI_STATUS\r
 ScsiDiskReadSectors (\r
-  IN   SCSI_DISK_DEV     *ScsiDiskDevice,\r
-  OUT  VOID              *Buffer,\r
-  IN   EFI_LBA           Lba,\r
-  IN   UINTN             NumberOfBlocks\r
+  IN   SCSI_DISK_DEV  *ScsiDiskDevice,\r
+  OUT  VOID           *Buffer,\r
+  IN   EFI_LBA        Lba,\r
+  IN   UINTN          NumberOfBlocks\r
   )\r
 {\r
-  UINTN               BlocksRemaining;\r
-  UINT8               *PtrBuffer;\r
-  UINT32              BlockSize;\r
-  UINT32              ByteCount;\r
-  UINT32              MaxBlock;\r
-  UINT32              SectorCount;\r
-  UINT32              NextSectorCount;\r
-  UINT64              Timeout;\r
-  EFI_STATUS          Status;\r
-  UINT8               Index;\r
-  UINT8               MaxRetry;\r
-  BOOLEAN             NeedRetry;\r
+  UINTN       BlocksRemaining;\r
+  UINT8       *PtrBuffer;\r
+  UINT32      BlockSize;\r
+  UINT32      ByteCount;\r
+  UINT32      MaxBlock;\r
+  UINT32      SectorCount;\r
+  UINT32      NextSectorCount;\r
+  UINT64      Timeout;\r
+  EFI_STATUS  Status;\r
+  UINT8       Index;\r
+  UINT8       MaxRetry;\r
+  BOOLEAN     NeedRetry;\r
 \r
-  Status            = EFI_SUCCESS;\r
+  Status = EFI_SUCCESS;\r
+\r
+  BlocksRemaining = NumberOfBlocks;\r
+  BlockSize       = ScsiDiskDevice->BlkIo.Media->BlockSize;\r
 \r
-  BlocksRemaining   = NumberOfBlocks;\r
-  BlockSize         = ScsiDiskDevice->BlkIo.Media->BlockSize;\r
-  \r
   //\r
   // limit the data bytes that can be transferred by one Read(10) or Read(16) Command\r
   //\r
   if (!ScsiDiskDevice->Cdb16Byte) {\r
-    MaxBlock         = 0xFFFF;\r
+    MaxBlock = 0xFFFF;\r
   } else {\r
-    MaxBlock         = 0xFFFFFFFF;\r
+    MaxBlock = 0xFFFFFFFF;\r
   }\r
 \r
   PtrBuffer = Buffer;\r
 \r
   while (BlocksRemaining > 0) {\r
-\r
     if (BlocksRemaining <= MaxBlock) {\r
       if (!ScsiDiskDevice->Cdb16Byte) {\r
-        SectorCount = (UINT16) BlocksRemaining;\r
+        SectorCount = (UINT16)BlocksRemaining;\r
       } else {\r
-        SectorCount = (UINT32) BlocksRemaining;\r
+        SectorCount = (UINT32)BlocksRemaining;\r
       }\r
     } else {\r
       SectorCount = MaxBlock;\r
@@ -2338,35 +3524,36 @@ ScsiDiskReadSectors (
     // As ScsiDisk and ScsiBus driver are used to manage SCSI or ATAPI devices, we have to use\r
     // the lowest transfer rate to calculate the possible maximum timeout value for each operation.\r
     // From the above table, we could know 2.1Mbytes per second is lowest one.\r
-    // The timout value is rounded up to nearest integar and here an additional 30s is added\r
+    // The timeout value is rounded up to nearest integer and here an additional 30s is added\r
     // to follow ATA spec in which it mentioned that the device may take up to 30s to respond\r
     // commands in the Standby/Idle mode.\r
     //\r
-    Timeout   = EFI_TIMER_PERIOD_SECONDS (ByteCount / 2100000 + 31);\r
+    Timeout = EFI_TIMER_PERIOD_SECONDS (ByteCount / 2100000 + 31);\r
 \r
-    MaxRetry  = 2;\r
+    MaxRetry = 2;\r
     for (Index = 0; Index < MaxRetry; Index++) {\r
       if (!ScsiDiskDevice->Cdb16Byte) {\r
         Status = ScsiDiskRead10 (\r
-                  ScsiDiskDevice,\r
-                  &NeedRetry,\r
-                  Timeout,\r
-                  PtrBuffer,\r
-                  &ByteCount,\r
-                  (UINT32) Lba,\r
-                  SectorCount\r
-                  );\r
+                   ScsiDiskDevice,\r
+                   &NeedRetry,\r
+                   Timeout,\r
+                   PtrBuffer,\r
+                   &ByteCount,\r
+                   (UINT32)Lba,\r
+                   SectorCount\r
+                   );\r
       } else {\r
         Status = ScsiDiskRead16 (\r
-                  ScsiDiskDevice,\r
-                  &NeedRetry,\r
-                  Timeout,\r
-                  PtrBuffer,\r
-                  &ByteCount,\r
-                  Lba,\r
-                  SectorCount\r
-                  );\r
+                   ScsiDiskDevice,\r
+                   &NeedRetry,\r
+                   Timeout,\r
+                   PtrBuffer,\r
+                   &ByteCount,\r
+                   Lba,\r
+                   SectorCount\r
+                   );\r
       }\r
+\r
       if (!EFI_ERROR (Status)) {\r
         break;\r
       }\r
@@ -2382,7 +3569,7 @@ ScsiDiskReadSectors (
       // it is invalid to request more sectors in the CDB than the entire\r
       // transfer (ie. ByteCount) can carry.\r
       //\r
-      // In addition, ByteCount is only expected to go down, or stay unchaged.\r
+      // In addition, ByteCount is only expected to go down, or stay unchanged.\r
       // Therefore we don't need to update Timeout: the original timeout should\r
       // accommodate shorter transfers too.\r
       //\r
@@ -2405,8 +3592,8 @@ ScsiDiskReadSectors (
     //\r
     SectorCount = ByteCount / BlockSize;\r
 \r
-    Lba += SectorCount;\r
-    PtrBuffer = PtrBuffer + SectorCount * BlockSize;\r
+    Lba             += SectorCount;\r
+    PtrBuffer        = PtrBuffer + SectorCount * BlockSize;\r
     BlocksRemaining -= SectorCount;\r
   }\r
 \r
@@ -2427,48 +3614,47 @@ ScsiDiskReadSectors (
 **/\r
 EFI_STATUS\r
 ScsiDiskWriteSectors (\r
-  IN  SCSI_DISK_DEV     *ScsiDiskDevice,\r
-  IN  VOID              *Buffer,\r
-  IN  EFI_LBA           Lba,\r
-  IN  UINTN             NumberOfBlocks\r
+  IN  SCSI_DISK_DEV  *ScsiDiskDevice,\r
+  IN  VOID           *Buffer,\r
+  IN  EFI_LBA        Lba,\r
+  IN  UINTN          NumberOfBlocks\r
   )\r
 {\r
-  UINTN               BlocksRemaining;\r
-  UINT8               *PtrBuffer;\r
-  UINT32              BlockSize;\r
-  UINT32              ByteCount;\r
-  UINT32              MaxBlock;\r
-  UINT32              SectorCount;\r
-  UINT32              NextSectorCount;\r
-  UINT64              Timeout;\r
-  EFI_STATUS          Status;\r
-  UINT8               Index;\r
-  UINT8               MaxRetry;\r
-  BOOLEAN             NeedRetry;\r
+  UINTN       BlocksRemaining;\r
+  UINT8       *PtrBuffer;\r
+  UINT32      BlockSize;\r
+  UINT32      ByteCount;\r
+  UINT32      MaxBlock;\r
+  UINT32      SectorCount;\r
+  UINT32      NextSectorCount;\r
+  UINT64      Timeout;\r
+  EFI_STATUS  Status;\r
+  UINT8       Index;\r
+  UINT8       MaxRetry;\r
+  BOOLEAN     NeedRetry;\r
 \r
-  Status            = EFI_SUCCESS;\r
+  Status = EFI_SUCCESS;\r
 \r
-  BlocksRemaining   = NumberOfBlocks;\r
-  BlockSize         = ScsiDiskDevice->BlkIo.Media->BlockSize;\r
+  BlocksRemaining = NumberOfBlocks;\r
+  BlockSize       = ScsiDiskDevice->BlkIo.Media->BlockSize;\r
 \r
   //\r
   // limit the data bytes that can be transferred by one Read(10) or Read(16) Command\r
   //\r
   if (!ScsiDiskDevice->Cdb16Byte) {\r
-    MaxBlock         = 0xFFFF;\r
+    MaxBlock = 0xFFFF;\r
   } else {\r
-    MaxBlock         = 0xFFFFFFFF;\r
+    MaxBlock = 0xFFFFFFFF;\r
   }\r
 \r
   PtrBuffer = Buffer;\r
 \r
   while (BlocksRemaining > 0) {\r
-\r
     if (BlocksRemaining <= MaxBlock) {\r
       if (!ScsiDiskDevice->Cdb16Byte) {\r
-        SectorCount = (UINT16) BlocksRemaining;\r
+        SectorCount = (UINT16)BlocksRemaining;\r
       } else {\r
-        SectorCount = (UINT32) BlocksRemaining;\r
+        SectorCount = (UINT32)BlocksRemaining;\r
       }\r
     } else {\r
       SectorCount = MaxBlock;\r
@@ -2503,34 +3689,35 @@ ScsiDiskWriteSectors (
     // As ScsiDisk and ScsiBus driver are used to manage SCSI or ATAPI devices, we have to use\r
     // the lowest transfer rate to calculate the possible maximum timeout value for each operation.\r
     // From the above table, we could know 2.1Mbytes per second is lowest one.\r
-    // The timout value is rounded up to nearest integar and here an additional 30s is added\r
+    // The timeout value is rounded up to nearest integer and here an additional 30s is added\r
     // to follow ATA spec in which it mentioned that the device may take up to 30s to respond\r
     // commands in the Standby/Idle mode.\r
     //\r
-    Timeout   = EFI_TIMER_PERIOD_SECONDS (ByteCount / 2100000 + 31);\r
-    MaxRetry  = 2;\r
+    Timeout  = EFI_TIMER_PERIOD_SECONDS (ByteCount / 2100000 + 31);\r
+    MaxRetry = 2;\r
     for (Index = 0; Index < MaxRetry; Index++) {\r
       if (!ScsiDiskDevice->Cdb16Byte) {\r
         Status = ScsiDiskWrite10 (\r
-                  ScsiDiskDevice,\r
-                  &NeedRetry,\r
-                  Timeout,\r
-                  PtrBuffer,\r
-                  &ByteCount,\r
-                  (UINT32) Lba,\r
-                  SectorCount\r
-                  );\r
+                   ScsiDiskDevice,\r
+                   &NeedRetry,\r
+                   Timeout,\r
+                   PtrBuffer,\r
+                   &ByteCount,\r
+                   (UINT32)Lba,\r
+                   SectorCount\r
+                   );\r
       } else {\r
         Status = ScsiDiskWrite16 (\r
-                  ScsiDiskDevice,\r
-                  &NeedRetry,\r
-                  Timeout,\r
-                  PtrBuffer,\r
-                  &ByteCount,\r
-                  Lba,\r
-                  SectorCount\r
-                  );         \r
-        }\r
+                   ScsiDiskDevice,\r
+                   &NeedRetry,\r
+                   Timeout,\r
+                   PtrBuffer,\r
+                   &ByteCount,\r
+                   Lba,\r
+                   SectorCount\r
+                   );\r
+      }\r
+\r
       if (!EFI_ERROR (Status)) {\r
         break;\r
       }\r
@@ -2546,7 +3733,7 @@ ScsiDiskWriteSectors (
       // it is invalid to request more sectors in the CDB than the entire\r
       // transfer (ie. ByteCount) can carry.\r
       //\r
-      // In addition, ByteCount is only expected to go down, or stay unchaged.\r
+      // In addition, ByteCount is only expected to go down, or stay unchanged.\r
       // Therefore we don't need to update Timeout: the original timeout should\r
       // accommodate shorter transfers too.\r
       //\r
@@ -2563,13 +3750,14 @@ ScsiDiskWriteSectors (
     if ((Index == MaxRetry) && (Status != EFI_SUCCESS)) {\r
       return EFI_DEVICE_ERROR;\r
     }\r
+\r
     //\r
     // actual transferred sectors\r
     //\r
     SectorCount = ByteCount / BlockSize;\r
 \r
-    Lba += SectorCount;\r
-    PtrBuffer = PtrBuffer + SectorCount * BlockSize;\r
+    Lba             += SectorCount;\r
+    PtrBuffer        = PtrBuffer + SectorCount * BlockSize;\r
     BlocksRemaining -= SectorCount;\r
   }\r
 \r
@@ -2593,23 +3781,23 @@ ScsiDiskWriteSectors (
 **/\r
 EFI_STATUS\r
 ScsiDiskAsyncReadSectors (\r
-  IN   SCSI_DISK_DEV         *ScsiDiskDevice,\r
-  OUT  VOID                  *Buffer,\r
-  IN   EFI_LBA               Lba,\r
-  IN   UINTN                 NumberOfBlocks,\r
-  IN   EFI_BLOCK_IO2_TOKEN   *Token\r
+  IN   SCSI_DISK_DEV        *ScsiDiskDevice,\r
+  OUT  VOID                 *Buffer,\r
+  IN   EFI_LBA              Lba,\r
+  IN   UINTN                NumberOfBlocks,\r
+  IN   EFI_BLOCK_IO2_TOKEN  *Token\r
   )\r
 {\r
-  UINTN                 BlocksRemaining;\r
-  UINT8                 *PtrBuffer;\r
-  UINT32                BlockSize;\r
-  UINT32                ByteCount;\r
-  UINT32                MaxBlock;\r
-  UINT32                SectorCount;\r
-  UINT64                Timeout;\r
-  SCSI_BLKIO2_REQUEST   *BlkIo2Req;\r
-  EFI_STATUS            Status;\r
-  EFI_TPL               OldTpl;\r
+  UINTN                BlocksRemaining;\r
+  UINT8                *PtrBuffer;\r
+  UINT32               BlockSize;\r
+  UINT32               ByteCount;\r
+  UINT32               MaxBlock;\r
+  UINT32               SectorCount;\r
+  UINT64               Timeout;\r
+  SCSI_BLKIO2_REQUEST  *BlkIo2Req;\r
+  EFI_STATUS           Status;\r
+  EFI_TPL              OldTpl;\r
 \r
   if ((Token == NULL) || (Token->Event == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -2620,38 +3808,37 @@ ScsiDiskAsyncReadSectors (
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
-  BlkIo2Req->Token  = Token;\r
+  BlkIo2Req->Token = Token;\r
 \r
   OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
-  InsertTailList (&ScsiDiskDevice->BlkIo2Queue, &BlkIo2Req->Link);\r
+  InsertTailList (&ScsiDiskDevice->AsyncTaskQueue, &BlkIo2Req->Link);\r
   gBS->RestoreTPL (OldTpl);\r
 \r
   InitializeListHead (&BlkIo2Req->ScsiRWQueue);\r
 \r
-  Status            = EFI_SUCCESS;\r
+  Status = EFI_SUCCESS;\r
 \r
-  BlocksRemaining   = NumberOfBlocks;\r
-  BlockSize         = ScsiDiskDevice->BlkIo.Media->BlockSize;\r
+  BlocksRemaining = NumberOfBlocks;\r
+  BlockSize       = ScsiDiskDevice->BlkIo.Media->BlockSize;\r
 \r
   //\r
   // Limit the data bytes that can be transferred by one Read(10) or Read(16)\r
   // Command\r
   //\r
   if (!ScsiDiskDevice->Cdb16Byte) {\r
-    MaxBlock         = 0xFFFF;\r
+    MaxBlock = 0xFFFF;\r
   } else {\r
-    MaxBlock         = 0xFFFFFFFF;\r
+    MaxBlock = 0xFFFFFFFF;\r
   }\r
 \r
   PtrBuffer = Buffer;\r
 \r
   while (BlocksRemaining > 0) {\r
-\r
     if (BlocksRemaining <= MaxBlock) {\r
       if (!ScsiDiskDevice->Cdb16Byte) {\r
-        SectorCount = (UINT16) BlocksRemaining;\r
+        SectorCount = (UINT16)BlocksRemaining;\r
       } else {\r
-        SectorCount = (UINT32) BlocksRemaining;\r
+        SectorCount = (UINT32)BlocksRemaining;\r
       }\r
     } else {\r
       SectorCount = MaxBlock;\r
@@ -2687,11 +3874,11 @@ ScsiDiskAsyncReadSectors (
     // we have to use the lowest transfer rate to calculate the possible\r
     // maximum timeout value for each operation.\r
     // From the above table, we could know 2.1Mbytes per second is lowest one.\r
-    // The timout value is rounded up to nearest integar and here an additional\r
+    // The timeout value is rounded up to nearest integer and here an additional\r
     // 30s is added to follow ATA spec in which it mentioned that the device\r
     // may take up to 30s to respond commands in the Standby/Idle mode.\r
     //\r
-    Timeout   = EFI_TIMER_PERIOD_SECONDS (ByteCount / 2100000 + 31);\r
+    Timeout = EFI_TIMER_PERIOD_SECONDS (ByteCount / 2100000 + 31);\r
 \r
     if (!ScsiDiskDevice->Cdb16Byte) {\r
       Status = ScsiDiskAsyncRead10 (\r
@@ -2700,7 +3887,7 @@ ScsiDiskAsyncReadSectors (
                  0,\r
                  PtrBuffer,\r
                  ByteCount,\r
-                 (UINT32) Lba,\r
+                 (UINT32)Lba,\r
                  SectorCount,\r
                  BlkIo2Req,\r
                  Token\r
@@ -2718,6 +3905,7 @@ ScsiDiskAsyncReadSectors (
                  Token\r
                  );\r
     }\r
+\r
     if (EFI_ERROR (Status)) {\r
       //\r
       // Some devices will return EFI_DEVICE_ERROR or EFI_TIMEOUT when the data\r
@@ -2768,8 +3956,8 @@ ScsiDiskAsyncReadSectors (
     //\r
     SectorCount = ByteCount / BlockSize;\r
 \r
-    Lba += SectorCount;\r
-    PtrBuffer = PtrBuffer + SectorCount * BlockSize;\r
+    Lba             += SectorCount;\r
+    PtrBuffer        = PtrBuffer + SectorCount * BlockSize;\r
     BlocksRemaining -= SectorCount;\r
   }\r
 \r
@@ -2787,6 +3975,7 @@ Done:
 \r
       gBS->SignalEvent (Token->Event);\r
     }\r
+\r
     gBS->RestoreTPL (OldTpl);\r
   }\r
 \r
@@ -2810,23 +3999,23 @@ Done:
 **/\r
 EFI_STATUS\r
 ScsiDiskAsyncWriteSectors (\r
-  IN  SCSI_DISK_DEV          *ScsiDiskDevice,\r
-  IN  VOID                   *Buffer,\r
-  IN  EFI_LBA                Lba,\r
-  IN  UINTN                  NumberOfBlocks,\r
-  IN  EFI_BLOCK_IO2_TOKEN    *Token\r
+  IN  SCSI_DISK_DEV        *ScsiDiskDevice,\r
+  IN  VOID                 *Buffer,\r
+  IN  EFI_LBA              Lba,\r
+  IN  UINTN                NumberOfBlocks,\r
+  IN  EFI_BLOCK_IO2_TOKEN  *Token\r
   )\r
 {\r
-  UINTN                 BlocksRemaining;\r
-  UINT8                 *PtrBuffer;\r
-  UINT32                BlockSize;\r
-  UINT32                ByteCount;\r
-  UINT32                MaxBlock;\r
-  UINT32                SectorCount;\r
-  UINT64                Timeout;\r
-  SCSI_BLKIO2_REQUEST   *BlkIo2Req;\r
-  EFI_STATUS            Status;\r
-  EFI_TPL               OldTpl;\r
+  UINTN                BlocksRemaining;\r
+  UINT8                *PtrBuffer;\r
+  UINT32               BlockSize;\r
+  UINT32               ByteCount;\r
+  UINT32               MaxBlock;\r
+  UINT32               SectorCount;\r
+  UINT64               Timeout;\r
+  SCSI_BLKIO2_REQUEST  *BlkIo2Req;\r
+  EFI_STATUS           Status;\r
+  EFI_TPL              OldTpl;\r
 \r
   if ((Token == NULL) || (Token->Event == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -2837,38 +4026,37 @@ ScsiDiskAsyncWriteSectors (
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
-  BlkIo2Req->Token  = Token;\r
+  BlkIo2Req->Token = Token;\r
 \r
   OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
-  InsertTailList (&ScsiDiskDevice->BlkIo2Queue, &BlkIo2Req->Link);\r
+  InsertTailList (&ScsiDiskDevice->AsyncTaskQueue, &BlkIo2Req->Link);\r
   gBS->RestoreTPL (OldTpl);\r
 \r
   InitializeListHead (&BlkIo2Req->ScsiRWQueue);\r
 \r
-  Status            = EFI_SUCCESS;\r
+  Status = EFI_SUCCESS;\r
 \r
-  BlocksRemaining   = NumberOfBlocks;\r
-  BlockSize         = ScsiDiskDevice->BlkIo.Media->BlockSize;\r
+  BlocksRemaining = NumberOfBlocks;\r
+  BlockSize       = ScsiDiskDevice->BlkIo.Media->BlockSize;\r
 \r
   //\r
   // Limit the data bytes that can be transferred by one Read(10) or Read(16)\r
   // Command\r
   //\r
   if (!ScsiDiskDevice->Cdb16Byte) {\r
-    MaxBlock         = 0xFFFF;\r
+    MaxBlock = 0xFFFF;\r
   } else {\r
-    MaxBlock         = 0xFFFFFFFF;\r
+    MaxBlock = 0xFFFFFFFF;\r
   }\r
 \r
   PtrBuffer = Buffer;\r
 \r
   while (BlocksRemaining > 0) {\r
-\r
     if (BlocksRemaining <= MaxBlock) {\r
       if (!ScsiDiskDevice->Cdb16Byte) {\r
-        SectorCount = (UINT16) BlocksRemaining;\r
+        SectorCount = (UINT16)BlocksRemaining;\r
       } else {\r
-        SectorCount = (UINT32) BlocksRemaining;\r
+        SectorCount = (UINT32)BlocksRemaining;\r
       }\r
     } else {\r
       SectorCount = MaxBlock;\r
@@ -2904,11 +4092,11 @@ ScsiDiskAsyncWriteSectors (
     // we have to use the lowest transfer rate to calculate the possible\r
     // maximum timeout value for each operation.\r
     // From the above table, we could know 2.1Mbytes per second is lowest one.\r
-    // The timout value is rounded up to nearest integar and here an additional\r
+    // The timeout value is rounded up to nearest integer and here an additional\r
     // 30s is added to follow ATA spec in which it mentioned that the device\r
     // may take up to 30s to respond commands in the Standby/Idle mode.\r
     //\r
-    Timeout   = EFI_TIMER_PERIOD_SECONDS (ByteCount / 2100000 + 31);\r
+    Timeout = EFI_TIMER_PERIOD_SECONDS (ByteCount / 2100000 + 31);\r
 \r
     if (!ScsiDiskDevice->Cdb16Byte) {\r
       Status = ScsiDiskAsyncWrite10 (\r
@@ -2917,7 +4105,7 @@ ScsiDiskAsyncWriteSectors (
                  0,\r
                  PtrBuffer,\r
                  ByteCount,\r
-                 (UINT32) Lba,\r
+                 (UINT32)Lba,\r
                  SectorCount,\r
                  BlkIo2Req,\r
                  Token\r
@@ -2935,6 +4123,7 @@ ScsiDiskAsyncWriteSectors (
                  Token\r
                  );\r
     }\r
+\r
     if (EFI_ERROR (Status)) {\r
       //\r
       // Some devices will return EFI_DEVICE_ERROR or EFI_TIMEOUT when the data\r
@@ -2985,8 +4174,8 @@ ScsiDiskAsyncWriteSectors (
     //\r
     SectorCount = ByteCount / BlockSize;\r
 \r
-    Lba += SectorCount;\r
-    PtrBuffer = PtrBuffer + SectorCount * BlockSize;\r
+    Lba             += SectorCount;\r
+    PtrBuffer        = PtrBuffer + SectorCount * BlockSize;\r
     BlocksRemaining -= SectorCount;\r
   }\r
 \r
@@ -3004,13 +4193,13 @@ Done:
 \r
       gBS->SignalEvent (Token->Event);\r
     }\r
+\r
     gBS->RestoreTPL (OldTpl);\r
   }\r
 \r
   return Status;\r
 }\r
 \r
-\r
 /**\r
   Submit Read(10) command.\r
 \r
@@ -3026,13 +4215,13 @@ Done:
 **/\r
 EFI_STATUS\r
 ScsiDiskRead10 (\r
-  IN     SCSI_DISK_DEV         *ScsiDiskDevice,\r
-     OUT BOOLEAN               *NeedRetry,\r
-  IN     UINT64                Timeout,\r
-     OUT UINT8                 *DataBuffer,\r
-  IN OUT UINT32                *DataLength,\r
-  IN     UINT32                StartLba,\r
-  IN     UINT32                SectorCount\r
+  IN     SCSI_DISK_DEV  *ScsiDiskDevice,\r
+  OUT BOOLEAN           *NeedRetry,\r
+  IN     UINT64         Timeout,\r
+  OUT UINT8             *DataBuffer,\r
+  IN OUT UINT32         *DataLength,\r
+  IN     UINT32         StartLba,\r
+  IN     UINT32         SectorCount\r
   )\r
 {\r
   UINT8       SenseDataLength;\r
@@ -3043,31 +4232,31 @@ ScsiDiskRead10 (
   UINTN       Action;\r
 \r
   //\r
-  // Implement a backoff algorithem to resolve some compatibility issues that\r
+  // Implement a backoff algorithm to resolve some compatibility issues that\r
   // some SCSI targets or ATAPI devices couldn't correctly response reading/writing\r
   // big data in a single operation.\r
-  // This algorithem will at first try to execute original request. If the request fails\r
+  // This algorithm will at first try to execute original request. If the request fails\r
   // with media error sense data or else, it will reduce the transfer length to half and\r
   // try again till the operation succeeds or fails with one sector transfer length.\r
   //\r
 BackOff:\r
-  *NeedRetry          = FALSE;\r
-  Action              = ACTION_NO_ACTION;\r
-  SenseDataLength     = (UINT8) (ScsiDiskDevice->SenseDataNumber * sizeof (EFI_SCSI_SENSE_DATA));\r
-  ReturnStatus = ScsiRead10Command (\r
-                   ScsiDiskDevice->ScsiIo,\r
-                   Timeout,\r
-                   ScsiDiskDevice->SenseData,\r
-                   &SenseDataLength,\r
-                   &HostAdapterStatus,\r
-                   &TargetStatus,\r
-                   DataBuffer,\r
-                   DataLength,\r
-                   StartLba,\r
-                   SectorCount\r
-                   );\r
+  *NeedRetry      = FALSE;\r
+  Action          = ACTION_NO_ACTION;\r
+  SenseDataLength = (UINT8)(ScsiDiskDevice->SenseDataNumber * sizeof (EFI_SCSI_SENSE_DATA));\r
+  ReturnStatus    = ScsiRead10Command (\r
+                      ScsiDiskDevice->ScsiIo,\r
+                      Timeout,\r
+                      ScsiDiskDevice->SenseData,\r
+                      &SenseDataLength,\r
+                      &HostAdapterStatus,\r
+                      &TargetStatus,\r
+                      DataBuffer,\r
+                      DataLength,\r
+                      StartLba,\r
+                      SectorCount\r
+                      );\r
 \r
-  if (ReturnStatus == EFI_NOT_READY || ReturnStatus == EFI_BAD_BUFFER_SIZE) {\r
+  if ((ReturnStatus == EFI_NOT_READY) || (ReturnStatus == EFI_BAD_BUFFER_SIZE)) {\r
     *NeedRetry = TRUE;\r
     return EFI_DEVICE_ERROR;\r
   } else if ((ReturnStatus == EFI_INVALID_PARAMETER) || (ReturnStatus == EFI_UNSUPPORTED)) {\r
@@ -3106,8 +4295,8 @@ BackOff:
   }\r
 \r
   if ((TargetStatus == EFI_EXT_SCSI_STATUS_TARGET_CHECK_CONDITION) || (EFI_ERROR (ReturnStatus))) {\r
-    DEBUG ((EFI_D_ERROR, "ScsiDiskRead10: Check Condition happened!\n"));\r
-    Status = DetectMediaParsingSenseKeys (ScsiDiskDevice, ScsiDiskDevice->SenseData, SenseDataLength / sizeof (EFI_SCSI_SENSE_DATA), &Action);\r
+    DEBUG ((DEBUG_ERROR, "ScsiDiskRead10: Check Condition happened!\n"));\r
+    DetectMediaParsingSenseKeys (ScsiDiskDevice, ScsiDiskDevice->SenseData, SenseDataLength / sizeof (EFI_SCSI_SENSE_DATA), &Action);\r
     if (Action == ACTION_RETRY_COMMAND_LATER) {\r
       *NeedRetry = TRUE;\r
       return EFI_DEVICE_ERROR;\r
@@ -3119,11 +4308,12 @@ BackOff:
         *NeedRetry = FALSE;\r
         return EFI_DEVICE_ERROR;\r
       }\r
+\r
       //\r
       // Try again with half length if the sense data shows we need to retry.\r
       //\r
       SectorCount >>= 1;\r
-      *DataLength = SectorCount * ScsiDiskDevice->BlkIo.Media->BlockSize;\r
+      *DataLength   = SectorCount * ScsiDiskDevice->BlkIo.Media->BlockSize;\r
       goto BackOff;\r
     } else {\r
       *NeedRetry = FALSE;\r
@@ -3134,7 +4324,6 @@ BackOff:
   return ReturnStatus;\r
 }\r
 \r
-\r
 /**\r
   Submit Write(10) Command.\r
 \r
@@ -3151,13 +4340,13 @@ BackOff:
 **/\r
 EFI_STATUS\r
 ScsiDiskWrite10 (\r
-  IN     SCSI_DISK_DEV         *ScsiDiskDevice,\r
-     OUT BOOLEAN               *NeedRetry,\r
-  IN     UINT64                Timeout,\r
-  IN     UINT8                 *DataBuffer,\r
-  IN OUT UINT32                *DataLength,\r
-  IN     UINT32                StartLba,\r
-  IN     UINT32                SectorCount\r
+  IN     SCSI_DISK_DEV  *ScsiDiskDevice,\r
+  OUT BOOLEAN           *NeedRetry,\r
+  IN     UINT64         Timeout,\r
+  IN     UINT8          *DataBuffer,\r
+  IN OUT UINT32         *DataLength,\r
+  IN     UINT32         StartLba,\r
+  IN     UINT32         SectorCount\r
   )\r
 {\r
   EFI_STATUS  Status;\r
@@ -3168,30 +4357,30 @@ ScsiDiskWrite10 (
   UINTN       Action;\r
 \r
   //\r
-  // Implement a backoff algorithem to resolve some compatibility issues that\r
+  // Implement a backoff algorithm to resolve some compatibility issues that\r
   // some SCSI targets or ATAPI devices couldn't correctly response reading/writing\r
   // big data in a single operation.\r
-  // This algorithem will at first try to execute original request. If the request fails\r
+  // This algorithm will at first try to execute original request. If the request fails\r
   // with media error sense data or else, it will reduce the transfer length to half and\r
   // try again till the operation succeeds or fails with one sector transfer length.\r
   //\r
 BackOff:\r
-  *NeedRetry          = FALSE;\r
-  Action              = ACTION_NO_ACTION;\r
-  SenseDataLength     = (UINT8) (ScsiDiskDevice->SenseDataNumber * sizeof (EFI_SCSI_SENSE_DATA));\r
-  ReturnStatus = ScsiWrite10Command (\r
-                   ScsiDiskDevice->ScsiIo,\r
-                   Timeout,\r
-                   ScsiDiskDevice->SenseData,\r
-                   &SenseDataLength,\r
-                   &HostAdapterStatus,\r
-                   &TargetStatus,\r
-                   DataBuffer,\r
-                   DataLength,\r
-                   StartLba,\r
-                   SectorCount\r
-                   );\r
-  if (ReturnStatus == EFI_NOT_READY || ReturnStatus == EFI_BAD_BUFFER_SIZE) {\r
+  *NeedRetry      = FALSE;\r
+  Action          = ACTION_NO_ACTION;\r
+  SenseDataLength = (UINT8)(ScsiDiskDevice->SenseDataNumber * sizeof (EFI_SCSI_SENSE_DATA));\r
+  ReturnStatus    = ScsiWrite10Command (\r
+                      ScsiDiskDevice->ScsiIo,\r
+                      Timeout,\r
+                      ScsiDiskDevice->SenseData,\r
+                      &SenseDataLength,\r
+                      &HostAdapterStatus,\r
+                      &TargetStatus,\r
+                      DataBuffer,\r
+                      DataLength,\r
+                      StartLba,\r
+                      SectorCount\r
+                      );\r
+  if ((ReturnStatus == EFI_NOT_READY) || (ReturnStatus == EFI_BAD_BUFFER_SIZE)) {\r
     *NeedRetry = TRUE;\r
     return EFI_DEVICE_ERROR;\r
   } else if ((ReturnStatus == EFI_INVALID_PARAMETER) || (ReturnStatus == EFI_UNSUPPORTED)) {\r
@@ -3230,8 +4419,8 @@ BackOff:
   }\r
 \r
   if ((TargetStatus == EFI_EXT_SCSI_STATUS_TARGET_CHECK_CONDITION) || (EFI_ERROR (ReturnStatus))) {\r
-    DEBUG ((EFI_D_ERROR, "ScsiDiskWrite10: Check Condition happened!\n"));\r
-    Status = DetectMediaParsingSenseKeys (ScsiDiskDevice, ScsiDiskDevice->SenseData, SenseDataLength / sizeof (EFI_SCSI_SENSE_DATA), &Action);\r
+    DEBUG ((DEBUG_ERROR, "ScsiDiskWrite10: Check Condition happened!\n"));\r
+    DetectMediaParsingSenseKeys (ScsiDiskDevice, ScsiDiskDevice->SenseData, SenseDataLength / sizeof (EFI_SCSI_SENSE_DATA), &Action);\r
     if (Action == ACTION_RETRY_COMMAND_LATER) {\r
       *NeedRetry = TRUE;\r
       return EFI_DEVICE_ERROR;\r
@@ -3243,11 +4432,12 @@ BackOff:
         *NeedRetry = FALSE;\r
         return EFI_DEVICE_ERROR;\r
       }\r
+\r
       //\r
       // Try again with half length if the sense data shows we need to retry.\r
       //\r
       SectorCount >>= 1;\r
-      *DataLength = SectorCount * ScsiDiskDevice->BlkIo.Media->BlockSize;\r
+      *DataLength   = SectorCount * ScsiDiskDevice->BlkIo.Media->BlockSize;\r
       goto BackOff;\r
     } else {\r
       *NeedRetry = FALSE;\r
@@ -3258,7 +4448,6 @@ BackOff:
   return ReturnStatus;\r
 }\r
 \r
-\r
 /**\r
   Submit Read(16) command.\r
 \r
@@ -3274,13 +4463,13 @@ BackOff:
 **/\r
 EFI_STATUS\r
 ScsiDiskRead16 (\r
-  IN     SCSI_DISK_DEV         *ScsiDiskDevice,\r
-     OUT BOOLEAN               *NeedRetry,\r
-  IN     UINT64                Timeout,\r
-     OUT UINT8                 *DataBuffer,\r
-  IN OUT UINT32                *DataLength,\r
-  IN     UINT64                StartLba,\r
-  IN     UINT32                SectorCount\r
+  IN     SCSI_DISK_DEV  *ScsiDiskDevice,\r
+  OUT BOOLEAN           *NeedRetry,\r
+  IN     UINT64         Timeout,\r
+  OUT UINT8             *DataBuffer,\r
+  IN OUT UINT32         *DataLength,\r
+  IN     UINT64         StartLba,\r
+  IN     UINT32         SectorCount\r
   )\r
 {\r
   UINT8       SenseDataLength;\r
@@ -3291,30 +4480,30 @@ ScsiDiskRead16 (
   UINTN       Action;\r
 \r
   //\r
-  // Implement a backoff algorithem to resolve some compatibility issues that\r
+  // Implement a backoff algorithm to resolve some compatibility issues that\r
   // some SCSI targets or ATAPI devices couldn't correctly response reading/writing\r
   // big data in a single operation.\r
-  // This algorithem will at first try to execute original request. If the request fails\r
+  // This algorithm will at first try to execute original request. If the request fails\r
   // with media error sense data or else, it will reduce the transfer length to half and\r
   // try again till the operation succeeds or fails with one sector transfer length.\r
   //\r
 BackOff:\r
-  *NeedRetry          = FALSE;\r
-  Action              = ACTION_NO_ACTION;\r
-  SenseDataLength     = (UINT8) (ScsiDiskDevice->SenseDataNumber * sizeof (EFI_SCSI_SENSE_DATA));\r
-  ReturnStatus = ScsiRead16Command (\r
-                   ScsiDiskDevice->ScsiIo,\r
-                   Timeout,\r
-                   ScsiDiskDevice->SenseData,\r
-                   &SenseDataLength,\r
-                   &HostAdapterStatus,\r
-                   &TargetStatus,\r
-                   DataBuffer,\r
-                   DataLength,\r
-                   StartLba,\r
-                   SectorCount\r
-                   );\r
-  if (ReturnStatus == EFI_NOT_READY || ReturnStatus == EFI_BAD_BUFFER_SIZE) {\r
+  *NeedRetry      = FALSE;\r
+  Action          = ACTION_NO_ACTION;\r
+  SenseDataLength = (UINT8)(ScsiDiskDevice->SenseDataNumber * sizeof (EFI_SCSI_SENSE_DATA));\r
+  ReturnStatus    = ScsiRead16Command (\r
+                      ScsiDiskDevice->ScsiIo,\r
+                      Timeout,\r
+                      ScsiDiskDevice->SenseData,\r
+                      &SenseDataLength,\r
+                      &HostAdapterStatus,\r
+                      &TargetStatus,\r
+                      DataBuffer,\r
+                      DataLength,\r
+                      StartLba,\r
+                      SectorCount\r
+                      );\r
+  if ((ReturnStatus == EFI_NOT_READY) || (ReturnStatus == EFI_BAD_BUFFER_SIZE)) {\r
     *NeedRetry = TRUE;\r
     return EFI_DEVICE_ERROR;\r
   } else if ((ReturnStatus == EFI_INVALID_PARAMETER) || (ReturnStatus == EFI_UNSUPPORTED)) {\r
@@ -3353,8 +4542,8 @@ BackOff:
   }\r
 \r
   if ((TargetStatus == EFI_EXT_SCSI_STATUS_TARGET_CHECK_CONDITION) || (EFI_ERROR (ReturnStatus))) {\r
-    DEBUG ((EFI_D_ERROR, "ScsiDiskRead16: Check Condition happened!\n"));\r
-    Status = DetectMediaParsingSenseKeys (ScsiDiskDevice, ScsiDiskDevice->SenseData, SenseDataLength / sizeof (EFI_SCSI_SENSE_DATA), &Action);\r
+    DEBUG ((DEBUG_ERROR, "ScsiDiskRead16: Check Condition happened!\n"));\r
+    DetectMediaParsingSenseKeys (ScsiDiskDevice, ScsiDiskDevice->SenseData, SenseDataLength / sizeof (EFI_SCSI_SENSE_DATA), &Action);\r
     if (Action == ACTION_RETRY_COMMAND_LATER) {\r
       *NeedRetry = TRUE;\r
       return EFI_DEVICE_ERROR;\r
@@ -3366,11 +4555,12 @@ BackOff:
         *NeedRetry = FALSE;\r
         return EFI_DEVICE_ERROR;\r
       }\r
+\r
       //\r
       // Try again with half length if the sense data shows we need to retry.\r
       //\r
       SectorCount >>= 1;\r
-      *DataLength = SectorCount * ScsiDiskDevice->BlkIo.Media->BlockSize;\r
+      *DataLength   = SectorCount * ScsiDiskDevice->BlkIo.Media->BlockSize;\r
       goto BackOff;\r
     } else {\r
       *NeedRetry = FALSE;\r
@@ -3381,7 +4571,6 @@ BackOff:
   return ReturnStatus;\r
 }\r
 \r
-\r
 /**\r
   Submit Write(16) Command.\r
 \r
@@ -3398,13 +4587,13 @@ BackOff:
 **/\r
 EFI_STATUS\r
 ScsiDiskWrite16 (\r
-  IN     SCSI_DISK_DEV         *ScsiDiskDevice,\r
-     OUT BOOLEAN               *NeedRetry,\r
-  IN     UINT64                Timeout,\r
-  IN     UINT8                 *DataBuffer,\r
-  IN OUT UINT32                *DataLength,\r
-  IN     UINT64                StartLba,\r
-  IN     UINT32                SectorCount\r
+  IN     SCSI_DISK_DEV  *ScsiDiskDevice,\r
+  OUT BOOLEAN           *NeedRetry,\r
+  IN     UINT64         Timeout,\r
+  IN     UINT8          *DataBuffer,\r
+  IN OUT UINT32         *DataLength,\r
+  IN     UINT64         StartLba,\r
+  IN     UINT32         SectorCount\r
   )\r
 {\r
   EFI_STATUS  Status;\r
@@ -3415,30 +4604,30 @@ ScsiDiskWrite16 (
   UINTN       Action;\r
 \r
   //\r
-  // Implement a backoff algorithem to resolve some compatibility issues that\r
+  // Implement a backoff algorithm to resolve some compatibility issues that\r
   // some SCSI targets or ATAPI devices couldn't correctly response reading/writing\r
   // big data in a single operation.\r
-  // This algorithem will at first try to execute original request. If the request fails\r
+  // This algorithm will at first try to execute original request. If the request fails\r
   // with media error sense data or else, it will reduce the transfer length to half and\r
   // try again till the operation succeeds or fails with one sector transfer length.\r
   //\r
 BackOff:\r
-  *NeedRetry          = FALSE;\r
-  Action              = ACTION_NO_ACTION;\r
-  SenseDataLength     = (UINT8) (ScsiDiskDevice->SenseDataNumber * sizeof (EFI_SCSI_SENSE_DATA));\r
-  ReturnStatus = ScsiWrite16Command (\r
-                   ScsiDiskDevice->ScsiIo,\r
-                   Timeout,\r
-                   ScsiDiskDevice->SenseData,\r
-                   &SenseDataLength,\r
-                   &HostAdapterStatus,\r
-                   &TargetStatus,\r
-                   DataBuffer,\r
-                   DataLength,\r
-                   StartLba,\r
-                   SectorCount\r
-                   );\r
-  if (ReturnStatus == EFI_NOT_READY || ReturnStatus == EFI_BAD_BUFFER_SIZE) {\r
+  *NeedRetry      = FALSE;\r
+  Action          = ACTION_NO_ACTION;\r
+  SenseDataLength = (UINT8)(ScsiDiskDevice->SenseDataNumber * sizeof (EFI_SCSI_SENSE_DATA));\r
+  ReturnStatus    = ScsiWrite16Command (\r
+                      ScsiDiskDevice->ScsiIo,\r
+                      Timeout,\r
+                      ScsiDiskDevice->SenseData,\r
+                      &SenseDataLength,\r
+                      &HostAdapterStatus,\r
+                      &TargetStatus,\r
+                      DataBuffer,\r
+                      DataLength,\r
+                      StartLba,\r
+                      SectorCount\r
+                      );\r
+  if ((ReturnStatus == EFI_NOT_READY) || (ReturnStatus == EFI_BAD_BUFFER_SIZE)) {\r
     *NeedRetry = TRUE;\r
     return EFI_DEVICE_ERROR;\r
   } else if ((ReturnStatus == EFI_INVALID_PARAMETER) || (ReturnStatus == EFI_UNSUPPORTED)) {\r
@@ -3477,8 +4666,8 @@ BackOff:
   }\r
 \r
   if ((TargetStatus == EFI_EXT_SCSI_STATUS_TARGET_CHECK_CONDITION) || (EFI_ERROR (ReturnStatus))) {\r
-    DEBUG ((EFI_D_ERROR, "ScsiDiskWrite16: Check Condition happened!\n"));\r
-    Status = DetectMediaParsingSenseKeys (ScsiDiskDevice, ScsiDiskDevice->SenseData, SenseDataLength / sizeof (EFI_SCSI_SENSE_DATA), &Action);\r
+    DEBUG ((DEBUG_ERROR, "ScsiDiskWrite16: Check Condition happened!\n"));\r
+    DetectMediaParsingSenseKeys (ScsiDiskDevice, ScsiDiskDevice->SenseData, SenseDataLength / sizeof (EFI_SCSI_SENSE_DATA), &Action);\r
     if (Action == ACTION_RETRY_COMMAND_LATER) {\r
       *NeedRetry = TRUE;\r
       return EFI_DEVICE_ERROR;\r
@@ -3490,11 +4679,12 @@ BackOff:
         *NeedRetry = FALSE;\r
         return EFI_DEVICE_ERROR;\r
       }\r
+\r
       //\r
       // Try again with half length if the sense data shows we need to retry.\r
       //\r
       SectorCount >>= 1;\r
-      *DataLength = SectorCount * ScsiDiskDevice->BlkIo.Media->BlockSize;\r
+      *DataLength   = SectorCount * ScsiDiskDevice->BlkIo.Media->BlockSize;\r
       goto BackOff;\r
     } else {\r
       *NeedRetry = FALSE;\r
@@ -3505,7 +4695,6 @@ BackOff:
   return ReturnStatus;\r
 }\r
 \r
-\r
 /**\r
   Internal helper notify function in which determine whether retry of a SCSI\r
   Read/Write command is needed and signal the event passed from Block I/O(2) if\r
@@ -3522,23 +4711,23 @@ ScsiDiskNotify (
   IN  VOID       *Context\r
   )\r
 {\r
-  EFI_STATUS                       Status;\r
-  SCSI_ASYNC_RW_REQUEST            *Request;\r
-  SCSI_DISK_DEV                    *ScsiDiskDevice;\r
-  EFI_BLOCK_IO2_TOKEN              *Token;\r
-  UINTN                            Action;\r
-  UINT32                           OldDataLength;\r
-  UINT32                           OldSectorCount;\r
-  UINT8                            MaxRetry;\r
+  EFI_STATUS             Status;\r
+  SCSI_ASYNC_RW_REQUEST  *Request;\r
+  SCSI_DISK_DEV          *ScsiDiskDevice;\r
+  EFI_BLOCK_IO2_TOKEN    *Token;\r
+  UINTN                  Action;\r
+  UINT32                 OldDataLength;\r
+  UINT32                 OldSectorCount;\r
+  UINT8                  MaxRetry;\r
 \r
   gBS->CloseEvent (Event);\r
 \r
-  Request         = (SCSI_ASYNC_RW_REQUEST *) Context;\r
-  ScsiDiskDevice  = Request->ScsiDiskDevice;\r
-  Token           = Request->BlkIo2Req->Token;\r
-  OldDataLength   = Request->DataLength;\r
-  OldSectorCount  = Request->SectorCount;\r
-  MaxRetry        = 2;\r
+  Request        = (SCSI_ASYNC_RW_REQUEST *)Context;\r
+  ScsiDiskDevice = Request->ScsiDiskDevice;\r
+  Token          = Request->BlkIo2Req->Token;\r
+  OldDataLength  = Request->DataLength;\r
+  OldSectorCount = Request->SectorCount;\r
+  MaxRetry       = 2;\r
 \r
   //\r
   // If previous sub-tasks already fails, no need to process this sub-task.\r
@@ -3586,14 +4775,14 @@ ScsiDiskNotify (
   }\r
 \r
   if (Request->TargetStatus == EFI_EXT_SCSI_STATUS_TARGET_CHECK_CONDITION) {\r
-    DEBUG ((EFI_D_ERROR, "ScsiDiskNotify: Check Condition happened!\n"));\r
-\r
-    Status = DetectMediaParsingSenseKeys (\r
-               ScsiDiskDevice,\r
-               Request->SenseData,\r
-               Request->SenseDataLength / sizeof (EFI_SCSI_SENSE_DATA),\r
-               &Action\r
-               );\r
+    DEBUG ((DEBUG_ERROR, "ScsiDiskNotify: Check Condition happened!\n"));\r
+\r
+    DetectMediaParsingSenseKeys (\r
+      ScsiDiskDevice,\r
+      Request->SenseData,\r
+      Request->SenseDataLength / sizeof (EFI_SCSI_SENSE_DATA),\r
+      &Action\r
+      );\r
     if (Action == ACTION_RETRY_COMMAND_LATER) {\r
       if (++Request->TimesRetry > MaxRetry) {\r
         Token->TransactionStatus = EFI_DEVICE_ERROR;\r
@@ -3610,13 +4799,14 @@ ScsiDiskNotify (
         Token->TransactionStatus = EFI_DEVICE_ERROR;\r
         goto Exit;\r
       }\r
+\r
       //\r
       // Try again with two half length request if the sense data shows we need\r
       // to retry.\r
       //\r
       Request->SectorCount >>= 1;\r
-      Request->DataLength = Request->SectorCount * ScsiDiskDevice->BlkIo.Media->BlockSize;\r
-      Request->TimesRetry  = 0;\r
+      Request->DataLength    = Request->SectorCount * ScsiDiskDevice->BlkIo.Media->BlockSize;\r
+      Request->TimesRetry    = 0;\r
 \r
       goto Retry;\r
     } else {\r
@@ -3642,7 +4832,7 @@ Retry:
                  Request->TimesRetry,\r
                  Request->InBuffer,\r
                  Request->DataLength,\r
-                 (UINT32) Request->StartLba,\r
+                 (UINT32)Request->StartLba,\r
                  Request->SectorCount,\r
                  Request->BlkIo2Req,\r
                  Token\r
@@ -3676,7 +4866,7 @@ Retry:
                    0,\r
                    Request->InBuffer + Request->SectorCount * ScsiDiskDevice->BlkIo.Media->BlockSize,\r
                    OldDataLength - Request->DataLength,\r
-                   (UINT32) Request->StartLba + Request->SectorCount,\r
+                   (UINT32)Request->StartLba + Request->SectorCount,\r
                    OldSectorCount - Request->SectorCount,\r
                    Request->BlkIo2Req,\r
                    Token\r
@@ -3694,6 +4884,7 @@ Retry:
                    Token\r
                    );\r
       }\r
+\r
       if (EFI_ERROR (Status)) {\r
         Token->TransactionStatus = EFI_DEVICE_ERROR;\r
         goto Exit;\r
@@ -3710,7 +4901,7 @@ Retry:
                  Request->TimesRetry,\r
                  Request->OutBuffer,\r
                  Request->DataLength,\r
-                 (UINT32) Request->StartLba,\r
+                 (UINT32)Request->StartLba,\r
                  Request->SectorCount,\r
                  Request->BlkIo2Req,\r
                  Token\r
@@ -3744,7 +4935,7 @@ Retry:
                    0,\r
                    Request->OutBuffer + Request->SectorCount * ScsiDiskDevice->BlkIo.Media->BlockSize,\r
                    OldDataLength - Request->DataLength,\r
-                   (UINT32) Request->StartLba + Request->SectorCount,\r
+                   (UINT32)Request->StartLba + Request->SectorCount,\r
                    OldSectorCount - Request->SectorCount,\r
                    Request->BlkIo2Req,\r
                    Token\r
@@ -3762,6 +4953,7 @@ Retry:
                    Token\r
                    );\r
       }\r
+\r
       if (EFI_ERROR (Status)) {\r
         Token->TransactionStatus = EFI_DEVICE_ERROR;\r
         goto Exit;\r
@@ -3772,7 +4964,8 @@ Retry:
 Exit:\r
   RemoveEntryList (&Request->Link);\r
   if ((IsListEmpty (&Request->BlkIo2Req->ScsiRWQueue)) &&\r
-      (Request->BlkIo2Req->LastScsiRW)) {\r
+      (Request->BlkIo2Req->LastScsiRW))\r
+  {\r
     //\r
     // The last SCSI R/W command of a BlockIo2 request completes\r
     //\r
@@ -3785,7 +4978,6 @@ Exit:
   FreePool (Request);\r
 }\r
 \r
-\r
 /**\r
   Submit Async Read(10) command.\r
 \r
@@ -3808,21 +5000,21 @@ Exit:
 **/\r
 EFI_STATUS\r
 ScsiDiskAsyncRead10 (\r
-  IN     SCSI_DISK_DEV         *ScsiDiskDevice,\r
-  IN     UINT64                Timeout,\r
-  IN     UINT8                 TimesRetry,\r
-     OUT UINT8                 *DataBuffer,\r
-  IN     UINT32                DataLength,\r
-  IN     UINT32                StartLba,\r
-  IN     UINT32                SectorCount,\r
-  IN OUT SCSI_BLKIO2_REQUEST   *BlkIo2Req,\r
-  IN     EFI_BLOCK_IO2_TOKEN   *Token\r
+  IN     SCSI_DISK_DEV        *ScsiDiskDevice,\r
+  IN     UINT64               Timeout,\r
+  IN     UINT8                TimesRetry,\r
+  OUT UINT8                   *DataBuffer,\r
+  IN     UINT32               DataLength,\r
+  IN     UINT32               StartLba,\r
+  IN     UINT32               SectorCount,\r
+  IN OUT SCSI_BLKIO2_REQUEST  *BlkIo2Req,\r
+  IN     EFI_BLOCK_IO2_TOKEN  *Token\r
   )\r
 {\r
-  EFI_STATUS                   Status;\r
-  SCSI_ASYNC_RW_REQUEST        *Request;\r
-  EFI_EVENT                    AsyncIoEvent;\r
-  EFI_TPL                      OldTpl;\r
+  EFI_STATUS             Status;\r
+  SCSI_ASYNC_RW_REQUEST  *Request;\r
+  EFI_EVENT              AsyncIoEvent;\r
+  EFI_TPL                OldTpl;\r
 \r
   AsyncIoEvent = NULL;\r
 \r
@@ -3835,21 +5027,21 @@ ScsiDiskAsyncRead10 (
   InsertTailList (&BlkIo2Req->ScsiRWQueue, &Request->Link);\r
   gBS->RestoreTPL (OldTpl);\r
 \r
-  Request->SenseDataLength = (UINT8) (6 * sizeof (EFI_SCSI_SENSE_DATA));\r
+  Request->SenseDataLength = (UINT8)(6 * sizeof (EFI_SCSI_SENSE_DATA));\r
   Request->SenseData       = AllocateZeroPool (Request->SenseDataLength);\r
   if (Request->SenseData == NULL) {\r
     Status = EFI_OUT_OF_RESOURCES;\r
     goto ErrorExit;\r
   }\r
 \r
-  Request->ScsiDiskDevice  = ScsiDiskDevice;\r
-  Request->Timeout         = Timeout;\r
-  Request->TimesRetry      = TimesRetry;\r
-  Request->InBuffer        = DataBuffer;\r
-  Request->DataLength      = DataLength;\r
-  Request->StartLba        = StartLba;\r
-  Request->SectorCount     = SectorCount;\r
-  Request->BlkIo2Req       = BlkIo2Req;\r
+  Request->ScsiDiskDevice = ScsiDiskDevice;\r
+  Request->Timeout        = Timeout;\r
+  Request->TimesRetry     = TimesRetry;\r
+  Request->InBuffer       = DataBuffer;\r
+  Request->DataLength     = DataLength;\r
+  Request->StartLba       = StartLba;\r
+  Request->SectorCount    = SectorCount;\r
+  Request->BlkIo2Req      = BlkIo2Req;\r
 \r
   //\r
   // Create Event\r
@@ -3861,7 +5053,7 @@ ScsiDiskAsyncRead10 (
                   Request,\r
                   &AsyncIoEvent\r
                   );\r
-  if (EFI_ERROR(Status)) {\r
+  if (EFI_ERROR (Status)) {\r
     goto ErrorExit;\r
   }\r
 \r
@@ -3874,11 +5066,11 @@ ScsiDiskAsyncRead10 (
              &Request->TargetStatus,\r
              Request->InBuffer,\r
              &Request->DataLength,\r
-             (UINT32) Request->StartLba,\r
+             (UINT32)Request->StartLba,\r
              Request->SectorCount,\r
              AsyncIoEvent\r
              );\r
-  if (EFI_ERROR(Status)) {\r
+  if (EFI_ERROR (Status)) {\r
     goto ErrorExit;\r
   }\r
 \r
@@ -3904,7 +5096,6 @@ ErrorExit:
   return Status;\r
 }\r
 \r
-\r
 /**\r
   Submit Async Write(10) command.\r
 \r
@@ -3927,21 +5118,21 @@ ErrorExit:
 **/\r
 EFI_STATUS\r
 ScsiDiskAsyncWrite10 (\r
-  IN     SCSI_DISK_DEV         *ScsiDiskDevice,\r
-  IN     UINT64                Timeout,\r
-  IN     UINT8                 TimesRetry,\r
-  IN     UINT8                 *DataBuffer,\r
-  IN     UINT32                DataLength,\r
-  IN     UINT32                StartLba,\r
-  IN     UINT32                SectorCount,\r
-  IN OUT SCSI_BLKIO2_REQUEST   *BlkIo2Req,\r
-  IN     EFI_BLOCK_IO2_TOKEN   *Token\r
+  IN     SCSI_DISK_DEV        *ScsiDiskDevice,\r
+  IN     UINT64               Timeout,\r
+  IN     UINT8                TimesRetry,\r
+  IN     UINT8                *DataBuffer,\r
+  IN     UINT32               DataLength,\r
+  IN     UINT32               StartLba,\r
+  IN     UINT32               SectorCount,\r
+  IN OUT SCSI_BLKIO2_REQUEST  *BlkIo2Req,\r
+  IN     EFI_BLOCK_IO2_TOKEN  *Token\r
   )\r
 {\r
-  EFI_STATUS                   Status;\r
-  SCSI_ASYNC_RW_REQUEST        *Request;\r
-  EFI_EVENT                    AsyncIoEvent;\r
-  EFI_TPL                      OldTpl;\r
+  EFI_STATUS             Status;\r
+  SCSI_ASYNC_RW_REQUEST  *Request;\r
+  EFI_EVENT              AsyncIoEvent;\r
+  EFI_TPL                OldTpl;\r
 \r
   AsyncIoEvent = NULL;\r
 \r
@@ -3954,21 +5145,21 @@ ScsiDiskAsyncWrite10 (
   InsertTailList (&BlkIo2Req->ScsiRWQueue, &Request->Link);\r
   gBS->RestoreTPL (OldTpl);\r
 \r
-  Request->SenseDataLength = (UINT8) (6 * sizeof (EFI_SCSI_SENSE_DATA));\r
+  Request->SenseDataLength = (UINT8)(6 * sizeof (EFI_SCSI_SENSE_DATA));\r
   Request->SenseData       = AllocateZeroPool (Request->SenseDataLength);\r
   if (Request->SenseData == NULL) {\r
     Status = EFI_OUT_OF_RESOURCES;\r
     goto ErrorExit;\r
   }\r
 \r
-  Request->ScsiDiskDevice  = ScsiDiskDevice;\r
-  Request->Timeout         = Timeout;\r
-  Request->TimesRetry      = TimesRetry;\r
-  Request->OutBuffer       = DataBuffer;\r
-  Request->DataLength      = DataLength;\r
-  Request->StartLba        = StartLba;\r
-  Request->SectorCount     = SectorCount;\r
-  Request->BlkIo2Req       = BlkIo2Req;\r
+  Request->ScsiDiskDevice = ScsiDiskDevice;\r
+  Request->Timeout        = Timeout;\r
+  Request->TimesRetry     = TimesRetry;\r
+  Request->OutBuffer      = DataBuffer;\r
+  Request->DataLength     = DataLength;\r
+  Request->StartLba       = StartLba;\r
+  Request->SectorCount    = SectorCount;\r
+  Request->BlkIo2Req      = BlkIo2Req;\r
 \r
   //\r
   // Create Event\r
@@ -3980,7 +5171,7 @@ ScsiDiskAsyncWrite10 (
                   Request,\r
                   &AsyncIoEvent\r
                   );\r
-  if (EFI_ERROR(Status)) {\r
+  if (EFI_ERROR (Status)) {\r
     goto ErrorExit;\r
   }\r
 \r
@@ -3993,11 +5184,11 @@ ScsiDiskAsyncWrite10 (
              &Request->TargetStatus,\r
              Request->OutBuffer,\r
              &Request->DataLength,\r
-             (UINT32) Request->StartLba,\r
+             (UINT32)Request->StartLba,\r
              Request->SectorCount,\r
              AsyncIoEvent\r
              );\r
-  if (EFI_ERROR(Status)) {\r
+  if (EFI_ERROR (Status)) {\r
     goto ErrorExit;\r
   }\r
 \r
@@ -4023,7 +5214,6 @@ ErrorExit:
   return Status;\r
 }\r
 \r
-\r
 /**\r
   Submit Async Read(16) command.\r
 \r
@@ -4046,21 +5236,21 @@ ErrorExit:
 **/\r
 EFI_STATUS\r
 ScsiDiskAsyncRead16 (\r
-  IN     SCSI_DISK_DEV         *ScsiDiskDevice,\r
-  IN     UINT64                Timeout,\r
-  IN     UINT8                 TimesRetry,\r
-     OUT UINT8                 *DataBuffer,\r
-  IN     UINT32                DataLength,\r
-  IN     UINT64                StartLba,\r
-  IN     UINT32                SectorCount,\r
-  IN OUT SCSI_BLKIO2_REQUEST   *BlkIo2Req,\r
-  IN     EFI_BLOCK_IO2_TOKEN   *Token\r
+  IN     SCSI_DISK_DEV        *ScsiDiskDevice,\r
+  IN     UINT64               Timeout,\r
+  IN     UINT8                TimesRetry,\r
+  OUT UINT8                   *DataBuffer,\r
+  IN     UINT32               DataLength,\r
+  IN     UINT64               StartLba,\r
+  IN     UINT32               SectorCount,\r
+  IN OUT SCSI_BLKIO2_REQUEST  *BlkIo2Req,\r
+  IN     EFI_BLOCK_IO2_TOKEN  *Token\r
   )\r
 {\r
-  EFI_STATUS                   Status;\r
-  SCSI_ASYNC_RW_REQUEST        *Request;\r
-  EFI_EVENT                    AsyncIoEvent;\r
-  EFI_TPL                      OldTpl;\r
+  EFI_STATUS             Status;\r
+  SCSI_ASYNC_RW_REQUEST  *Request;\r
+  EFI_EVENT              AsyncIoEvent;\r
+  EFI_TPL                OldTpl;\r
 \r
   AsyncIoEvent = NULL;\r
 \r
@@ -4073,21 +5263,21 @@ ScsiDiskAsyncRead16 (
   InsertTailList (&BlkIo2Req->ScsiRWQueue, &Request->Link);\r
   gBS->RestoreTPL (OldTpl);\r
 \r
-  Request->SenseDataLength = (UINT8) (6 * sizeof (EFI_SCSI_SENSE_DATA));\r
+  Request->SenseDataLength = (UINT8)(6 * sizeof (EFI_SCSI_SENSE_DATA));\r
   Request->SenseData       = AllocateZeroPool (Request->SenseDataLength);\r
   if (Request->SenseData == NULL) {\r
     Status = EFI_OUT_OF_RESOURCES;\r
     goto ErrorExit;\r
   }\r
 \r
-  Request->ScsiDiskDevice  = ScsiDiskDevice;\r
-  Request->Timeout         = Timeout;\r
-  Request->TimesRetry      = TimesRetry;\r
-  Request->InBuffer        = DataBuffer;\r
-  Request->DataLength      = DataLength;\r
-  Request->StartLba        = StartLba;\r
-  Request->SectorCount     = SectorCount;\r
-  Request->BlkIo2Req       = BlkIo2Req;\r
+  Request->ScsiDiskDevice = ScsiDiskDevice;\r
+  Request->Timeout        = Timeout;\r
+  Request->TimesRetry     = TimesRetry;\r
+  Request->InBuffer       = DataBuffer;\r
+  Request->DataLength     = DataLength;\r
+  Request->StartLba       = StartLba;\r
+  Request->SectorCount    = SectorCount;\r
+  Request->BlkIo2Req      = BlkIo2Req;\r
 \r
   //\r
   // Create Event\r
@@ -4099,7 +5289,7 @@ ScsiDiskAsyncRead16 (
                   Request,\r
                   &AsyncIoEvent\r
                   );\r
-  if (EFI_ERROR(Status)) {\r
+  if (EFI_ERROR (Status)) {\r
     goto ErrorExit;\r
   }\r
 \r
@@ -4116,7 +5306,7 @@ ScsiDiskAsyncRead16 (
              Request->SectorCount,\r
              AsyncIoEvent\r
              );\r
-  if (EFI_ERROR(Status)) {\r
+  if (EFI_ERROR (Status)) {\r
     goto ErrorExit;\r
   }\r
 \r
@@ -4142,7 +5332,6 @@ ErrorExit:
   return Status;\r
 }\r
 \r
-\r
 /**\r
   Submit Async Write(16) command.\r
 \r
@@ -4165,21 +5354,21 @@ ErrorExit:
 **/\r
 EFI_STATUS\r
 ScsiDiskAsyncWrite16 (\r
-  IN     SCSI_DISK_DEV         *ScsiDiskDevice,\r
-  IN     UINT64                Timeout,\r
-  IN     UINT8                 TimesRetry,\r
-  IN     UINT8                 *DataBuffer,\r
-  IN     UINT32                DataLength,\r
-  IN     UINT64                StartLba,\r
-  IN     UINT32                SectorCount,\r
-  IN OUT SCSI_BLKIO2_REQUEST   *BlkIo2Req,\r
-  IN     EFI_BLOCK_IO2_TOKEN   *Token\r
+  IN     SCSI_DISK_DEV        *ScsiDiskDevice,\r
+  IN     UINT64               Timeout,\r
+  IN     UINT8                TimesRetry,\r
+  IN     UINT8                *DataBuffer,\r
+  IN     UINT32               DataLength,\r
+  IN     UINT64               StartLba,\r
+  IN     UINT32               SectorCount,\r
+  IN OUT SCSI_BLKIO2_REQUEST  *BlkIo2Req,\r
+  IN     EFI_BLOCK_IO2_TOKEN  *Token\r
   )\r
 {\r
-  EFI_STATUS                   Status;\r
-  SCSI_ASYNC_RW_REQUEST        *Request;\r
-  EFI_EVENT                    AsyncIoEvent;\r
-  EFI_TPL                      OldTpl;\r
+  EFI_STATUS             Status;\r
+  SCSI_ASYNC_RW_REQUEST  *Request;\r
+  EFI_EVENT              AsyncIoEvent;\r
+  EFI_TPL                OldTpl;\r
 \r
   AsyncIoEvent = NULL;\r
 \r
@@ -4192,21 +5381,21 @@ ScsiDiskAsyncWrite16 (
   InsertTailList (&BlkIo2Req->ScsiRWQueue, &Request->Link);\r
   gBS->RestoreTPL (OldTpl);\r
 \r
-  Request->SenseDataLength = (UINT8) (6 * sizeof (EFI_SCSI_SENSE_DATA));\r
+  Request->SenseDataLength = (UINT8)(6 * sizeof (EFI_SCSI_SENSE_DATA));\r
   Request->SenseData       = AllocateZeroPool (Request->SenseDataLength);\r
   if (Request->SenseData == NULL) {\r
     Status = EFI_OUT_OF_RESOURCES;\r
     goto ErrorExit;\r
   }\r
 \r
-  Request->ScsiDiskDevice  = ScsiDiskDevice;\r
-  Request->Timeout         = Timeout;\r
-  Request->TimesRetry      = TimesRetry;\r
-  Request->OutBuffer       = DataBuffer;\r
-  Request->DataLength      = DataLength;\r
-  Request->StartLba        = StartLba;\r
-  Request->SectorCount     = SectorCount;\r
-  Request->BlkIo2Req       = BlkIo2Req;\r
+  Request->ScsiDiskDevice = ScsiDiskDevice;\r
+  Request->Timeout        = Timeout;\r
+  Request->TimesRetry     = TimesRetry;\r
+  Request->OutBuffer      = DataBuffer;\r
+  Request->DataLength     = DataLength;\r
+  Request->StartLba       = StartLba;\r
+  Request->SectorCount    = SectorCount;\r
+  Request->BlkIo2Req      = BlkIo2Req;\r
 \r
   //\r
   // Create Event\r
@@ -4218,7 +5407,7 @@ ScsiDiskAsyncWrite16 (
                   Request,\r
                   &AsyncIoEvent\r
                   );\r
-  if (EFI_ERROR(Status)) {\r
+  if (EFI_ERROR (Status)) {\r
     goto ErrorExit;\r
   }\r
 \r
@@ -4235,7 +5424,7 @@ ScsiDiskAsyncWrite16 (
              Request->SectorCount,\r
              AsyncIoEvent\r
              );\r
-  if (EFI_ERROR(Status)) {\r
+  if (EFI_ERROR (Status)) {\r
     goto ErrorExit;\r
   }\r
 \r
@@ -4261,7 +5450,6 @@ ErrorExit:
   return Status;\r
 }\r
 \r
-\r
 /**\r
   Check sense key to find if media presents.\r
 \r
@@ -4273,13 +5461,13 @@ ErrorExit:
 **/\r
 BOOLEAN\r
 ScsiDiskIsNoMedia (\r
-  IN  EFI_SCSI_SENSE_DATA   *SenseData,\r
-  IN  UINTN                 SenseCounts\r
+  IN  EFI_SCSI_SENSE_DATA  *SenseData,\r
+  IN  UINTN                SenseCounts\r
   )\r
 {\r
-  EFI_SCSI_SENSE_DATA *SensePtr;\r
-  UINTN               Index;\r
-  BOOLEAN             IsNoMedia;\r
+  EFI_SCSI_SENSE_DATA  *SensePtr;\r
+  UINTN                Index;\r
+  BOOLEAN              IsNoMedia;\r
 \r
   IsNoMedia = FALSE;\r
   SensePtr  = SenseData;\r
@@ -4290,16 +5478,17 @@ ScsiDiskIsNoMedia (
     // Additional Sense Code is ASC_NO_MEDIA (0x3A)\r
     //\r
     if ((SensePtr->Sense_Key == EFI_SCSI_SK_NOT_READY) &&\r
-        (SensePtr->Addnl_Sense_Code == EFI_SCSI_ASC_NO_MEDIA)) {\r
+        (SensePtr->Addnl_Sense_Code == EFI_SCSI_ASC_NO_MEDIA))\r
+    {\r
       IsNoMedia = TRUE;\r
     }\r
+\r
     SensePtr++;\r
   }\r
 \r
   return IsNoMedia;\r
 }\r
 \r
-\r
 /**\r
   Parse sense key.\r
 \r
@@ -4312,70 +5501,68 @@ ScsiDiskIsNoMedia (
 **/\r
 BOOLEAN\r
 ScsiDiskIsMediaError (\r
-  IN  EFI_SCSI_SENSE_DATA   *SenseData,\r
-  IN  UINTN                 SenseCounts\r
+  IN  EFI_SCSI_SENSE_DATA  *SenseData,\r
+  IN  UINTN                SenseCounts\r
   )\r
 {\r
-  EFI_SCSI_SENSE_DATA *SensePtr;\r
-  UINTN               Index;\r
-  BOOLEAN             IsError;\r
+  EFI_SCSI_SENSE_DATA  *SensePtr;\r
+  UINTN                Index;\r
+  BOOLEAN              IsError;\r
 \r
-  IsError   = FALSE;\r
-  SensePtr  = SenseData;\r
+  IsError  = FALSE;\r
+  SensePtr = SenseData;\r
 \r
   for (Index = 0; Index < SenseCounts; Index++) {\r
-\r
     switch (SensePtr->Sense_Key) {\r
+      case EFI_SCSI_SK_MEDIUM_ERROR:\r
+        //\r
+        // Sense Key is EFI_SCSI_SK_MEDIUM_ERROR (0x3)\r
+        //\r
+        switch (SensePtr->Addnl_Sense_Code) {\r
+          //\r
+          // fall through\r
+          //\r
+          case EFI_SCSI_ASC_MEDIA_ERR1:\r
 \r
-    case EFI_SCSI_SK_MEDIUM_ERROR:\r
-      //\r
-      // Sense Key is EFI_SCSI_SK_MEDIUM_ERROR (0x3)\r
-      //\r
-      switch (SensePtr->Addnl_Sense_Code) {\r
+          //\r
+          // fall through\r
+          //\r
+          case EFI_SCSI_ASC_MEDIA_ERR2:\r
 \r
-      //\r
-      // fall through\r
-      //\r
-      case EFI_SCSI_ASC_MEDIA_ERR1:\r
+          //\r
+          // fall through\r
+          //\r
+          case EFI_SCSI_ASC_MEDIA_ERR3:\r
+          case EFI_SCSI_ASC_MEDIA_ERR4:\r
+            IsError = TRUE;\r
+            break;\r
 \r
-      //\r
-      // fall through\r
-      //\r
-      case EFI_SCSI_ASC_MEDIA_ERR2:\r
+          default:\r
+            break;\r
+        }\r
 \r
-      //\r
-      // fall through\r
-      //\r
-      case EFI_SCSI_ASC_MEDIA_ERR3:\r
-      case EFI_SCSI_ASC_MEDIA_ERR4:\r
-        IsError = TRUE;\r
         break;\r
 \r
-      default:\r
-        break;\r
-      }\r
+      case EFI_SCSI_SK_NOT_READY:\r
+        //\r
+        // Sense Key is EFI_SCSI_SK_NOT_READY (0x2)\r
+        //\r
+        switch (SensePtr->Addnl_Sense_Code) {\r
+          //\r
+          // Additional Sense Code is ASC_MEDIA_UPSIDE_DOWN (0x6)\r
+          //\r
+          case EFI_SCSI_ASC_MEDIA_UPSIDE_DOWN:\r
+            IsError = TRUE;\r
+            break;\r
 \r
-      break;\r
+          default:\r
+            break;\r
+        }\r
 \r
-    case EFI_SCSI_SK_NOT_READY:\r
-      //\r
-      // Sense Key is EFI_SCSI_SK_NOT_READY (0x2)\r
-      //\r
-      switch (SensePtr->Addnl_Sense_Code) {\r
-      //\r
-      // Additional Sense Code is ASC_MEDIA_UPSIDE_DOWN (0x6)\r
-      //\r
-      case EFI_SCSI_ASC_MEDIA_UPSIDE_DOWN:\r
-        IsError = TRUE;\r
         break;\r
 \r
       default:\r
         break;\r
-      }\r
-      break;\r
-\r
-    default:\r
-      break;\r
     }\r
 \r
     SensePtr++;\r
@@ -4384,7 +5571,6 @@ ScsiDiskIsMediaError (
   return IsError;\r
 }\r
 \r
-\r
 /**\r
   Check sense key to find if hardware error happens.\r
 \r
@@ -4397,19 +5583,18 @@ ScsiDiskIsMediaError (
 **/\r
 BOOLEAN\r
 ScsiDiskIsHardwareError (\r
-  IN  EFI_SCSI_SENSE_DATA   *SenseData,\r
-  IN  UINTN                 SenseCounts\r
+  IN  EFI_SCSI_SENSE_DATA  *SenseData,\r
+  IN  UINTN                SenseCounts\r
   )\r
 {\r
-  EFI_SCSI_SENSE_DATA *SensePtr;\r
-  UINTN               Index;\r
-  BOOLEAN             IsError;\r
+  EFI_SCSI_SENSE_DATA  *SensePtr;\r
+  UINTN                Index;\r
+  BOOLEAN              IsError;\r
 \r
-  IsError   = FALSE;\r
-  SensePtr  = SenseData;\r
+  IsError  = FALSE;\r
+  SensePtr = SenseData;\r
 \r
   for (Index = 0; Index < SenseCounts; Index++) {\r
-    \r
     //\r
     // Sense Key is EFI_SCSI_SK_HARDWARE_ERROR (0x4)\r
     //\r
@@ -4423,7 +5608,6 @@ ScsiDiskIsHardwareError (
   return IsError;\r
 }\r
 \r
-\r
 /**\r
   Check sense key to find if media has changed.\r
 \r
@@ -4435,16 +5619,16 @@ ScsiDiskIsHardwareError (
 **/\r
 BOOLEAN\r
 ScsiDiskIsMediaChange (\r
-  IN  EFI_SCSI_SENSE_DATA   *SenseData,\r
-  IN  UINTN                 SenseCounts\r
+  IN  EFI_SCSI_SENSE_DATA  *SenseData,\r
+  IN  UINTN                SenseCounts\r
   )\r
 {\r
-  EFI_SCSI_SENSE_DATA *SensePtr;\r
-  UINTN               Index;\r
-  BOOLEAN             IsMediaChanged;\r
+  EFI_SCSI_SENSE_DATA  *SensePtr;\r
+  UINTN                Index;\r
+  BOOLEAN              IsMediaChanged;\r
 \r
-  IsMediaChanged  = FALSE;\r
-  SensePtr        = SenseData;\r
+  IsMediaChanged = FALSE;\r
+  SensePtr       = SenseData;\r
 \r
   for (Index = 0; Index < SenseCounts; Index++) {\r
     //\r
@@ -4452,7 +5636,8 @@ ScsiDiskIsMediaChange (
     // Additional sense code is EFI_SCSI_ASC_MEDIA_CHANGE (0x28)\r
     //\r
     if ((SensePtr->Sense_Key == EFI_SCSI_SK_UNIT_ATTENTION) &&\r
-        (SensePtr->Addnl_Sense_Code == EFI_SCSI_ASC_MEDIA_CHANGE)) {\r
+        (SensePtr->Addnl_Sense_Code == EFI_SCSI_ASC_MEDIA_CHANGE))\r
+    {\r
       IsMediaChanged = TRUE;\r
     }\r
 \r
@@ -4474,25 +5659,25 @@ ScsiDiskIsMediaChange (
 **/\r
 BOOLEAN\r
 ScsiDiskIsResetBefore (\r
-  IN  EFI_SCSI_SENSE_DATA   *SenseData,\r
-  IN  UINTN                 SenseCounts\r
+  IN  EFI_SCSI_SENSE_DATA  *SenseData,\r
+  IN  UINTN                SenseCounts\r
   )\r
 {\r
-  EFI_SCSI_SENSE_DATA *SensePtr;\r
-  UINTN               Index;\r
-  BOOLEAN             IsResetBefore;\r
+  EFI_SCSI_SENSE_DATA  *SensePtr;\r
+  UINTN                Index;\r
+  BOOLEAN              IsResetBefore;\r
 \r
   IsResetBefore = FALSE;\r
   SensePtr      = SenseData;\r
 \r
   for (Index = 0; Index < SenseCounts; Index++) {\r
-    \r
     //\r
     // Sense Key is EFI_SCSI_SK_UNIT_ATTENTION (0x6)\r
     // Additional Sense Code is EFI_SCSI_ASC_RESET (0x29)\r
     //\r
     if ((SensePtr->Sense_Key == EFI_SCSI_SK_UNIT_ATTENTION) &&\r
-        (SensePtr->Addnl_Sense_Code == EFI_SCSI_ASC_RESET)) {\r
+        (SensePtr->Addnl_Sense_Code == EFI_SCSI_ASC_RESET))\r
+    {\r
       IsResetBefore = TRUE;\r
     }\r
 \r
@@ -4507,7 +5692,7 @@ ScsiDiskIsResetBefore (
 \r
   @param  SenseData    The pointer of EFI_SCSI_SENSE_DATA\r
   @param  SenseCounts  The number of sense key\r
-  @param  RetryLater   The flag means if need a retry \r
+  @param  RetryLater   The flag means if need a retry\r
 \r
   @retval TRUE  Drive is ready.\r
   @retval FALSE Drive is NOT ready.\r
@@ -4515,56 +5700,56 @@ ScsiDiskIsResetBefore (
 **/\r
 BOOLEAN\r
 ScsiDiskIsDriveReady (\r
-  IN  EFI_SCSI_SENSE_DATA   *SenseData,\r
-  IN  UINTN                 SenseCounts,\r
-  OUT BOOLEAN               *RetryLater\r
+  IN  EFI_SCSI_SENSE_DATA  *SenseData,\r
+  IN  UINTN                SenseCounts,\r
+  OUT BOOLEAN              *RetryLater\r
   )\r
 {\r
-  EFI_SCSI_SENSE_DATA *SensePtr;\r
-  UINTN               Index;\r
-  BOOLEAN             IsReady;\r
+  EFI_SCSI_SENSE_DATA  *SensePtr;\r
+  UINTN                Index;\r
+  BOOLEAN              IsReady;\r
 \r
   IsReady     = TRUE;\r
   *RetryLater = FALSE;\r
   SensePtr    = SenseData;\r
 \r
   for (Index = 0; Index < SenseCounts; Index++) {\r
-\r
     switch (SensePtr->Sense_Key) {\r
-\r
-    case EFI_SCSI_SK_NOT_READY:\r
-      //\r
-      // Sense Key is EFI_SCSI_SK_NOT_READY (0x2)\r
-      //\r
-      switch (SensePtr->Addnl_Sense_Code) {\r
-      case EFI_SCSI_ASC_NOT_READY:\r
+      case EFI_SCSI_SK_NOT_READY:\r
         //\r
-        // Additional Sense Code is EFI_SCSI_ASC_NOT_READY (0x4)\r
+        // Sense Key is EFI_SCSI_SK_NOT_READY (0x2)\r
         //\r
-        switch (SensePtr->Addnl_Sense_Code_Qualifier) {\r
-        case EFI_SCSI_ASCQ_IN_PROGRESS:\r
-          //\r
-          // Additional Sense Code Qualifier is\r
-          // EFI_SCSI_ASCQ_IN_PROGRESS (0x1)\r
-          //\r
-          IsReady     = FALSE;\r
-          *RetryLater = TRUE;\r
-          break;\r
+        switch (SensePtr->Addnl_Sense_Code) {\r
+          case EFI_SCSI_ASC_NOT_READY:\r
+            //\r
+            // Additional Sense Code is EFI_SCSI_ASC_NOT_READY (0x4)\r
+            //\r
+            switch (SensePtr->Addnl_Sense_Code_Qualifier) {\r
+              case EFI_SCSI_ASCQ_IN_PROGRESS:\r
+                //\r
+                // Additional Sense Code Qualifier is\r
+                // EFI_SCSI_ASCQ_IN_PROGRESS (0x1)\r
+                //\r
+                IsReady     = FALSE;\r
+                *RetryLater = TRUE;\r
+                break;\r
+\r
+              default:\r
+                IsReady     = FALSE;\r
+                *RetryLater = FALSE;\r
+                break;\r
+            }\r
 \r
-        default:\r
-          IsReady     = FALSE;\r
-          *RetryLater = FALSE;\r
-          break;\r
+            break;\r
+\r
+          default:\r
+            break;\r
         }\r
+\r
         break;\r
 \r
       default:\r
         break;\r
-      }\r
-      break;\r
-\r
-    default:\r
-      break;\r
     }\r
 \r
     SensePtr++;\r
@@ -4585,13 +5770,13 @@ ScsiDiskIsDriveReady (
 **/\r
 BOOLEAN\r
 ScsiDiskHaveSenseKey (\r
-  IN  EFI_SCSI_SENSE_DATA   *SenseData,\r
-  IN  UINTN                 SenseCounts\r
+  IN  EFI_SCSI_SENSE_DATA  *SenseData,\r
+  IN  UINTN                SenseCounts\r
   )\r
 {\r
-  EFI_SCSI_SENSE_DATA *SensePtr;\r
-  UINTN               Index;\r
-  BOOLEAN             HaveSenseKey;\r
+  EFI_SCSI_SENSE_DATA  *SensePtr;\r
+  UINTN                Index;\r
+  BOOLEAN              HaveSenseKey;\r
 \r
   if (SenseCounts == 0) {\r
     HaveSenseKey = FALSE;\r
@@ -4602,12 +5787,12 @@ ScsiDiskHaveSenseKey (
   SensePtr = SenseData;\r
 \r
   for (Index = 0; Index < SenseCounts; Index++) {\r
-    \r
     //\r
     // Sense Key is SK_NO_SENSE (0x0)\r
     //\r
     if ((SensePtr->Sense_Key == EFI_SCSI_SK_NO_SENSE) &&\r
-        (Index == 0)) {\r
+        (Index == 0))\r
+    {\r
       HaveSenseKey = FALSE;\r
     }\r
 \r
@@ -4625,11 +5810,11 @@ ScsiDiskHaveSenseKey (
 **/\r
 VOID\r
 ReleaseScsiDiskDeviceResources (\r
-  IN  SCSI_DISK_DEV   *ScsiDiskDevice\r
+  IN  SCSI_DISK_DEV  *ScsiDiskDevice\r
   )\r
 {\r
   if (ScsiDiskDevice == NULL) {\r
-    return ;\r
+    return;\r
   }\r
 \r
   if (ScsiDiskDevice->SenseData != NULL) {\r
@@ -4649,21 +5834,21 @@ ReleaseScsiDiskDeviceResources (
 \r
 /**\r
   Determine if Block Io & Block Io2 should be produced.\r
-  \r
+\r
 \r
   @param  ChildHandle  Child Handle to retrieve Parent information.\r
-  \r
+\r
   @retval  TRUE    Should produce Block Io & Block Io2.\r
   @retval  FALSE   Should not produce Block Io & Block Io2.\r
 \r
-**/  \r
+**/\r
 BOOLEAN\r
 DetermineInstallBlockIo (\r
-  IN  EFI_HANDLE      ChildHandle\r
-  )  \r
+  IN  EFI_HANDLE  ChildHandle\r
+  )\r
 {\r
-  EFI_SCSI_PASS_THRU_PROTOCOL           *ScsiPassThru;\r
-  EFI_EXT_SCSI_PASS_THRU_PROTOCOL       *ExtScsiPassThru;\r
+  EFI_SCSI_PASS_THRU_PROTOCOL      *ScsiPassThru;\r
+  EFI_EXT_SCSI_PASS_THRU_PROTOCOL  *ExtScsiPassThru;\r
 \r
   //\r
   // Firstly, check if ExtScsiPassThru Protocol parent handle exists. If existence,\r
@@ -4686,7 +5871,7 @@ DetermineInstallBlockIo (
       return TRUE;\r
     }\r
   }\r
-  \r
+\r
   return FALSE;\r
 }\r
 \r
@@ -4695,25 +5880,25 @@ DetermineInstallBlockIo (
   specified by ProtocolGuid is present on a ControllerHandle and opened by\r
   ChildHandle with an attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.\r
   If the ControllerHandle is found, then the protocol specified by ProtocolGuid\r
-  will be opened on it.  \r
-  \r
+  will be opened on it.\r
+\r
 \r
   @param  ProtocolGuid   ProtocolGuid pointer.\r
   @param  ChildHandle    Child Handle to retrieve Parent information.\r
-  \r
-**/ \r
+\r
+**/\r
 VOID *\r
 EFIAPI\r
 GetParentProtocol (\r
-  IN  EFI_GUID                          *ProtocolGuid,\r
-  IN  EFI_HANDLE                        ChildHandle\r
-  ) \r
+  IN  EFI_GUID    *ProtocolGuid,\r
+  IN  EFI_HANDLE  ChildHandle\r
+  )\r
 {\r
-  UINTN                                 Index;\r
-  UINTN                                 HandleCount;\r
-  VOID                                  *Interface;  \r
-  EFI_STATUS                            Status;\r
-  EFI_HANDLE                            *HandleBuffer;\r
+  UINTN       Index;\r
+  UINTN       HandleCount;\r
+  VOID        *Interface;\r
+  EFI_STATUS  Status;\r
+  EFI_HANDLE  *HandleBuffer;\r
 \r
   //\r
   // Retrieve the list of all handles from the handle database\r
@@ -4731,7 +5916,7 @@ GetParentProtocol (
   }\r
 \r
   //\r
-  // Iterate to find who is parent handle that is opened with ProtocolGuid by ChildHandle \r
+  // Iterate to find who is parent handle that is opened with ProtocolGuid by ChildHandle\r
   //\r
   for (Index = 0; Index < HandleCount; Index++) {\r
     Status = EfiTestChildHandle (HandleBuffer[Index], ChildHandle, ProtocolGuid);\r
@@ -4746,11 +5931,217 @@ GetParentProtocol (
 \r
   gBS->FreePool (HandleBuffer);\r
   return NULL;\r
-} \r
+}\r
+\r
+/**\r
+  Determine if EFI Erase Block Protocol should be produced.\r
+\r
+  @param   ScsiDiskDevice    The pointer of SCSI_DISK_DEV.\r
+  @param   ChildHandle       Handle of device.\r
+\r
+  @retval  TRUE    Should produce EFI Erase Block Protocol.\r
+  @retval  FALSE   Should not produce EFI Erase Block Protocol.\r
+\r
+**/\r
+BOOLEAN\r
+DetermineInstallEraseBlock (\r
+  IN  SCSI_DISK_DEV  *ScsiDiskDevice,\r
+  IN  EFI_HANDLE     ChildHandle\r
+  )\r
+{\r
+  UINT8                          HostAdapterStatus;\r
+  UINT8                          TargetStatus;\r
+  EFI_STATUS                     CommandStatus;\r
+  EFI_STATUS                     Status;\r
+  BOOLEAN                        UfsDevice;\r
+  BOOLEAN                        RetVal;\r
+  EFI_DEVICE_PATH_PROTOCOL       *DevicePathNode;\r
+  UINT8                          SenseDataLength;\r
+  UINT32                         DataLength16;\r
+  EFI_SCSI_DISK_CAPACITY_DATA16  *CapacityData16;\r
+\r
+  UfsDevice      = FALSE;\r
+  RetVal         = TRUE;\r
+  CapacityData16 = NULL;\r
+\r
+  //\r
+  // UNMAP command is not supported by any of the UFS WLUNs.\r
+  //\r
+  if (ScsiDiskDevice->DeviceType == EFI_SCSI_TYPE_WLUN) {\r
+    RetVal = FALSE;\r
+    goto Done;\r
+  }\r
+\r
+  Status = gBS->HandleProtocol (\r
+                  ChildHandle,\r
+                  &gEfiDevicePathProtocolGuid,\r
+                  (VOID **)&DevicePathNode\r
+                  );\r
+  //\r
+  // Device Path protocol must be installed on the device handle.\r
+  //\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  while (!IsDevicePathEndType (DevicePathNode)) {\r
+    //\r
+    // For now, only support Erase Block Protocol on UFS devices.\r
+    //\r
+    if ((DevicePathNode->Type == MESSAGING_DEVICE_PATH) &&\r
+        (DevicePathNode->SubType == MSG_UFS_DP))\r
+    {\r
+      UfsDevice = TRUE;\r
+      break;\r
+    }\r
+\r
+    DevicePathNode = NextDevicePathNode (DevicePathNode);\r
+  }\r
+\r
+  if (!UfsDevice) {\r
+    RetVal = FALSE;\r
+    goto Done;\r
+  }\r
+\r
+  //\r
+  // Check whether the erase functionality is enabled on the UFS device.\r
+  //\r
+  CapacityData16 = AllocateAlignedBuffer (ScsiDiskDevice, sizeof (EFI_SCSI_DISK_CAPACITY_DATA16));\r
+  if (CapacityData16 == NULL) {\r
+    RetVal = FALSE;\r
+    goto Done;\r
+  }\r
+\r
+  SenseDataLength = 0;\r
+  DataLength16    = sizeof (EFI_SCSI_DISK_CAPACITY_DATA16);\r
+  ZeroMem (CapacityData16, sizeof (EFI_SCSI_DISK_CAPACITY_DATA16));\r
+\r
+  CommandStatus = ScsiReadCapacity16Command (\r
+                    ScsiDiskDevice->ScsiIo,\r
+                    SCSI_DISK_TIMEOUT,\r
+                    NULL,\r
+                    &SenseDataLength,\r
+                    &HostAdapterStatus,\r
+                    &TargetStatus,\r
+                    (VOID *)CapacityData16,\r
+                    &DataLength16,\r
+                    FALSE\r
+                    );\r
+\r
+  if (CommandStatus == EFI_SUCCESS) {\r
+    //\r
+    // Universal Flash Storage (UFS) Version 2.0\r
+    // Section 11.3.9.2\r
+    // Bits TPE and TPRZ should both be set to enable the erase feature on UFS.\r
+    //\r
+    if (((CapacityData16->LowestAlignLogic2 & BIT7) == 0) ||\r
+        ((CapacityData16->LowestAlignLogic2 & BIT6) == 0))\r
+    {\r
+      DEBUG ((\r
+        DEBUG_VERBOSE,\r
+        "ScsiDisk EraseBlock: Either TPE or TPRZ is not set: 0x%x.\n",\r
+        CapacityData16->LowestAlignLogic2\r
+        ));\r
+\r
+      RetVal = FALSE;\r
+      goto Done;\r
+    }\r
+  } else {\r
+    DEBUG ((\r
+      DEBUG_VERBOSE,\r
+      "ScsiDisk EraseBlock: ReadCapacity16 failed with status %r.\n",\r
+      CommandStatus\r
+      ));\r
+\r
+    RetVal = FALSE;\r
+    goto Done;\r
+  }\r
+\r
+  //\r
+  // Check whether the UFS device server implements the UNMAP command.\r
+  //\r
+  if ((ScsiDiskDevice->UnmapInfo.MaxLbaCnt == 0) ||\r
+      (ScsiDiskDevice->UnmapInfo.MaxBlkDespCnt == 0))\r
+  {\r
+    DEBUG ((\r
+      DEBUG_VERBOSE,\r
+      "ScsiDisk EraseBlock: The device server does not implement the UNMAP command.\n"\r
+      ));\r
+\r
+    RetVal = FALSE;\r
+    goto Done;\r
+  }\r
+\r
+Done:\r
+  if (CapacityData16 != NULL) {\r
+    FreeAlignedBuffer (CapacityData16, sizeof (EFI_SCSI_DISK_CAPACITY_DATA16));\r
+  }\r
+\r
+  return RetVal;\r
+}\r
+\r
+/**\r
+  Determine if EFI Storage Security Command Protocol should be produced.\r
+\r
+  @param   ScsiDiskDevice    The pointer of SCSI_DISK_DEV.\r
+  @param   ChildHandle       Handle of device.\r
+\r
+  @retval  TRUE    Should produce EFI Storage Security Command Protocol.\r
+  @retval  FALSE   Should not produce EFI Storage Security Command Protocol.\r
+\r
+**/\r
+BOOLEAN\r
+DetermineInstallStorageSecurity (\r
+  IN  SCSI_DISK_DEV  *ScsiDiskDevice,\r
+  IN  EFI_HANDLE     ChildHandle\r
+  )\r
+{\r
+  EFI_STATUS                Status;\r
+  UFS_DEVICE_PATH           *UfsDevice;\r
+  BOOLEAN                   RetVal;\r
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePathNode;\r
+\r
+  UfsDevice = NULL;\r
+  RetVal    = TRUE;\r
+\r
+  Status = gBS->HandleProtocol (\r
+                  ChildHandle,\r
+                  &gEfiDevicePathProtocolGuid,\r
+                  (VOID **)&DevicePathNode\r
+                  );\r
+  //\r
+  // Device Path protocol must be installed on the device handle.\r
+  //\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  while (!IsDevicePathEndType (DevicePathNode)) {\r
+    //\r
+    // For now, only support Storage Security Command Protocol on UFS devices.\r
+    //\r
+    if ((DevicePathNode->Type == MESSAGING_DEVICE_PATH) &&\r
+        (DevicePathNode->SubType == MSG_UFS_DP))\r
+    {\r
+      UfsDevice = (UFS_DEVICE_PATH *)DevicePathNode;\r
+      break;\r
+    }\r
+\r
+    DevicePathNode = NextDevicePathNode (DevicePathNode);\r
+  }\r
+\r
+  if (UfsDevice == NULL) {\r
+    RetVal = FALSE;\r
+    goto Done;\r
+  }\r
+\r
+  if (UfsDevice->Lun != UFS_WLUN_RPMB) {\r
+    RetVal = FALSE;\r
+  }\r
+\r
+Done:\r
+  return RetVal;\r
+}\r
 \r
 /**\r
   Provides inquiry information for the controller type.\r
-  \r
+\r
   This function is used by the IDE bus driver to get inquiry data.  Data format\r
   of Identify data is defined by the Interface GUID.\r
 \r
@@ -4759,85 +6150,86 @@ GetParentProtocol (
   @param[in, out] InquiryDataSize   Pointer to the value for the inquiry data size.\r
 \r
   @retval EFI_SUCCESS            The command was accepted without any errors.\r
-  @retval EFI_NOT_FOUND          Device does not support this data class \r
-  @retval EFI_DEVICE_ERROR       Error reading InquiryData from device \r
-  @retval EFI_BUFFER_TOO_SMALL   InquiryDataSize not big enough \r
+  @retval EFI_NOT_FOUND          Device does not support this data class\r
+  @retval EFI_DEVICE_ERROR       Error reading InquiryData from device\r
+  @retval EFI_BUFFER_TOO_SMALL   InquiryDataSize not big enough\r
 \r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
 ScsiDiskInfoInquiry (\r
-  IN     EFI_DISK_INFO_PROTOCOL   *This,\r
-  IN OUT VOID                     *InquiryData,\r
-  IN OUT UINT32                   *InquiryDataSize\r
+  IN     EFI_DISK_INFO_PROTOCOL  *This,\r
+  IN OUT VOID                    *InquiryData,\r
+  IN OUT UINT32                  *InquiryDataSize\r
   )\r
 {\r
-  EFI_STATUS      Status;\r
-  SCSI_DISK_DEV   *ScsiDiskDevice;\r
+  EFI_STATUS     Status;\r
+  SCSI_DISK_DEV  *ScsiDiskDevice;\r
 \r
-  ScsiDiskDevice  = SCSI_DISK_DEV_FROM_DISKINFO (This);\r
+  ScsiDiskDevice = SCSI_DISK_DEV_FROM_DISKINFO (This);\r
 \r
   Status = EFI_BUFFER_TOO_SMALL;\r
   if (*InquiryDataSize >= sizeof (ScsiDiskDevice->InquiryData)) {\r
     Status = EFI_SUCCESS;\r
     CopyMem (InquiryData, &ScsiDiskDevice->InquiryData, sizeof (ScsiDiskDevice->InquiryData));\r
   }\r
+\r
   *InquiryDataSize = sizeof (ScsiDiskDevice->InquiryData);\r
   return Status;\r
 }\r
 \r
-\r
 /**\r
   Provides identify information for the controller type.\r
 \r
   This function is used by the IDE bus driver to get identify data.  Data format\r
   of Identify data is defined by the Interface GUID.\r
 \r
-  @param[in]      This              Pointer to the EFI_DISK_INFO_PROTOCOL \r
+  @param[in]      This              Pointer to the EFI_DISK_INFO_PROTOCOL\r
                                     instance.\r
   @param[in, out] IdentifyData      Pointer to a buffer for the identify data.\r
   @param[in, out] IdentifyDataSize  Pointer to the value for the identify data\r
                                     size.\r
 \r
   @retval EFI_SUCCESS            The command was accepted without any errors.\r
-  @retval EFI_NOT_FOUND          Device does not support this data class \r
-  @retval EFI_DEVICE_ERROR       Error reading IdentifyData from device \r
-  @retval EFI_BUFFER_TOO_SMALL   IdentifyDataSize not big enough \r
+  @retval EFI_NOT_FOUND          Device does not support this data class\r
+  @retval EFI_DEVICE_ERROR       Error reading IdentifyData from device\r
+  @retval EFI_BUFFER_TOO_SMALL   IdentifyDataSize not big enough\r
 \r
 **/\r
 EFI_STATUS\r
 EFIAPI\r
 ScsiDiskInfoIdentify (\r
-  IN     EFI_DISK_INFO_PROTOCOL   *This,\r
-  IN OUT VOID                     *IdentifyData,\r
-  IN OUT UINT32                   *IdentifyDataSize\r
+  IN     EFI_DISK_INFO_PROTOCOL  *This,\r
+  IN OUT VOID                    *IdentifyData,\r
+  IN OUT UINT32                  *IdentifyDataSize\r
   )\r
 {\r
-  EFI_STATUS      Status;\r
-  SCSI_DISK_DEV   *ScsiDiskDevice;\r
+  EFI_STATUS     Status;\r
+  SCSI_DISK_DEV  *ScsiDiskDevice;\r
 \r
   if (CompareGuid (&This->Interface, &gEfiDiskInfoScsiInterfaceGuid) || CompareGuid (&This->Interface, &gEfiDiskInfoUfsInterfaceGuid)) {\r
     //\r
-    // Physical SCSI bus does not support this data class. \r
+    // Physical SCSI bus does not support this data class.\r
     //\r
     return EFI_NOT_FOUND;\r
   }\r
 \r
-  ScsiDiskDevice  = SCSI_DISK_DEV_FROM_DISKINFO (This);\r
+  ScsiDiskDevice = SCSI_DISK_DEV_FROM_DISKINFO (This);\r
 \r
   Status = EFI_BUFFER_TOO_SMALL;\r
   if (*IdentifyDataSize >= sizeof (ScsiDiskDevice->IdentifyData)) {\r
     Status = EFI_SUCCESS;\r
     CopyMem (IdentifyData, &ScsiDiskDevice->IdentifyData, sizeof (ScsiDiskDevice->IdentifyData));\r
   }\r
+\r
   *IdentifyDataSize = sizeof (ScsiDiskDevice->IdentifyData);\r
   return Status;\r
 }\r
 \r
 /**\r
   Provides sense data information for the controller type.\r
-  \r
-  This function is used by the IDE bus driver to get sense data. \r
+\r
+  This function is used by the IDE bus driver to get sense data.\r
   Data format of Sense data is defined by the Interface GUID.\r
 \r
   @param[in]      This              Pointer to the EFI_DISK_INFO_PROTOCOL instance.\r
@@ -4854,20 +6246,19 @@ ScsiDiskInfoIdentify (
 EFI_STATUS\r
 EFIAPI\r
 ScsiDiskInfoSenseData (\r
-  IN     EFI_DISK_INFO_PROTOCOL   *This,\r
-  IN OUT VOID                     *SenseData,\r
-  IN OUT UINT32                   *SenseDataSize,\r
-  OUT    UINT8                    *SenseDataNumber\r
+  IN     EFI_DISK_INFO_PROTOCOL  *This,\r
+  IN OUT VOID                    *SenseData,\r
+  IN OUT UINT32                  *SenseDataSize,\r
+  OUT    UINT8                   *SenseDataNumber\r
   )\r
 {\r
   return EFI_NOT_FOUND;\r
 }\r
 \r
-\r
 /**\r
   This function is used by the IDE bus driver to get controller information.\r
 \r
-  @param[in]  This         Pointer to the EFI_DISK_INFO_PROTOCOL instance. \r
+  @param[in]  This         Pointer to the EFI_DISK_INFO_PROTOCOL instance.\r
   @param[out] IdeChannel   Pointer to the Ide Channel number.  Primary or secondary.\r
   @param[out] IdeDevice    Pointer to the Ide Device number.  Master or slave.\r
 \r
@@ -4878,12 +6269,12 @@ ScsiDiskInfoSenseData (
 EFI_STATUS\r
 EFIAPI\r
 ScsiDiskInfoWhichIde (\r
-  IN  EFI_DISK_INFO_PROTOCOL   *This,\r
-  OUT UINT32                   *IdeChannel,\r
-  OUT UINT32                   *IdeDevice\r
+  IN  EFI_DISK_INFO_PROTOCOL  *This,\r
+  OUT UINT32                  *IdeChannel,\r
+  OUT UINT32                  *IdeDevice\r
   )\r
 {\r
-  SCSI_DISK_DEV   *ScsiDiskDevice;\r
+  SCSI_DISK_DEV  *ScsiDiskDevice;\r
 \r
   if (CompareGuid (&This->Interface, &gEfiDiskInfoScsiInterfaceGuid) || CompareGuid (&This->Interface, &gEfiDiskInfoUfsInterfaceGuid)) {\r
     //\r
@@ -4892,14 +6283,13 @@ ScsiDiskInfoWhichIde (
     return EFI_UNSUPPORTED;\r
   }\r
 \r
-  ScsiDiskDevice  = SCSI_DISK_DEV_FROM_DISKINFO (This);\r
-  *IdeChannel     = ScsiDiskDevice->Channel;\r
-  *IdeDevice      = ScsiDiskDevice->Device;\r
+  ScsiDiskDevice = SCSI_DISK_DEV_FROM_DISKINFO (This);\r
+  *IdeChannel    = ScsiDiskDevice->Channel;\r
+  *IdeDevice     = ScsiDiskDevice->Device;\r
 \r
   return EFI_SUCCESS;\r
 }\r
 \r
-\r
 /**\r
   Issues ATA IDENTIFY DEVICE command to identify ATAPI device.\r
 \r
@@ -4908,18 +6298,18 @@ ScsiDiskInfoWhichIde (
   via SCSI Request Packet.\r
 \r
   @param  ScsiDiskDevice  The pointer of SCSI_DISK_DEV\r
-  \r
+\r
   @retval EFI_SUCCESS     The ATAPI device identify data were retrieved successfully.\r
   @retval others          Some error occurred during the identification that ATAPI device.\r
 \r
-**/  \r
+**/\r
 EFI_STATUS\r
 AtapiIdentifyDevice (\r
-  IN OUT SCSI_DISK_DEV   *ScsiDiskDevice\r
+  IN OUT SCSI_DISK_DEV  *ScsiDiskDevice\r
   )\r
 {\r
-  EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket;\r
-  UINT8                           Cdb[6];\r
+  EFI_SCSI_IO_SCSI_REQUEST_PACKET  CommandPacket;\r
+  UINT8                            Cdb[6];\r
 \r
   //\r
   // Initialize SCSI REQUEST_PACKET and 6-byte Cdb\r
@@ -4927,17 +6317,16 @@ AtapiIdentifyDevice (
   ZeroMem (&CommandPacket, sizeof (CommandPacket));\r
   ZeroMem (Cdb, sizeof (Cdb));\r
 \r
-  Cdb[0] = ATA_CMD_IDENTIFY_DEVICE;\r
-  CommandPacket.Timeout = SCSI_DISK_TIMEOUT;\r
-  CommandPacket.Cdb = Cdb;\r
-  CommandPacket.CdbLength = (UINT8) sizeof (Cdb);\r
-  CommandPacket.InDataBuffer = &ScsiDiskDevice->IdentifyData;\r
+  Cdb[0]                         = ATA_CMD_IDENTIFY_DEVICE;\r
+  CommandPacket.Timeout          = SCSI_DISK_TIMEOUT;\r
+  CommandPacket.Cdb              = Cdb;\r
+  CommandPacket.CdbLength        = (UINT8)sizeof (Cdb);\r
+  CommandPacket.InDataBuffer     = &ScsiDiskDevice->IdentifyData;\r
   CommandPacket.InTransferLength = sizeof (ScsiDiskDevice->IdentifyData);\r
 \r
   return ScsiDiskDevice->ScsiIo->ExecuteScsiCommand (ScsiDiskDevice->ScsiIo, &CommandPacket, NULL);\r
 }\r
 \r
-\r
 /**\r
   Initialize the installation of DiskInfo protocol.\r
 \r
@@ -4948,12 +6337,12 @@ AtapiIdentifyDevice (
 \r
   @param  ScsiDiskDevice  The pointer of SCSI_DISK_DEV.\r
   @param  ChildHandle     Child handle to install DiskInfo protocol.\r
-  \r
-**/  \r
+\r
+**/\r
 VOID\r
 InitializeInstallDiskInfo (\r
-  IN  SCSI_DISK_DEV   *ScsiDiskDevice,\r
-  IN  EFI_HANDLE      ChildHandle\r
+  IN  SCSI_DISK_DEV  *ScsiDiskDevice,\r
+  IN  EFI_HANDLE     ChildHandle\r
   )\r
 {\r
   EFI_STATUS                Status;\r
@@ -4963,9 +6352,9 @@ InitializeInstallDiskInfo (
   SATA_DEVICE_PATH          *SataDevicePath;\r
   UINTN                     IdentifyRetry;\r
 \r
-  Status = gBS->HandleProtocol (ChildHandle, &gEfiDevicePathProtocolGuid, (VOID **) &DevicePathNode);\r
+  Status = gBS->HandleProtocol (ChildHandle, &gEfiDevicePathProtocolGuid, (VOID **)&DevicePathNode);\r
   //\r
-  // Device Path protocol must be installed on the device handle. \r
+  // Device Path protocol must be installed on the device handle.\r
   //\r
   ASSERT_EFI_ERROR (Status);\r
   //\r
@@ -4978,9 +6367,9 @@ InitializeInstallDiskInfo (
     if ((DevicePathType (DevicePathNode) == HARDWARE_DEVICE_PATH) &&\r
         (DevicePathSubType (DevicePathNode) == HW_PCI_DP) &&\r
         (DevicePathType (ChildDevicePathNode) == MESSAGING_DEVICE_PATH) &&\r
-       ((DevicePathSubType (ChildDevicePathNode) == MSG_ATAPI_DP) ||\r
-        (DevicePathSubType (ChildDevicePathNode) == MSG_SATA_DP))) {\r
-\r
+        ((DevicePathSubType (ChildDevicePathNode) == MSG_ATAPI_DP) ||\r
+         (DevicePathSubType (ChildDevicePathNode) == MSG_SATA_DP)))\r
+    {\r
       IdentifyRetry = 3;\r
       do {\r
         //\r
@@ -4989,37 +6378,40 @@ InitializeInstallDiskInfo (
         //\r
         Status = AtapiIdentifyDevice (ScsiDiskDevice);\r
         if (!EFI_ERROR (Status)) {\r
-          if (DevicePathSubType(ChildDevicePathNode) == MSG_ATAPI_DP) {\r
+          if (DevicePathSubType (ChildDevicePathNode) == MSG_ATAPI_DP) {\r
             //\r
             // We find the valid ATAPI device path\r
             //\r
-            AtapiDevicePath = (ATAPI_DEVICE_PATH *) ChildDevicePathNode;\r
+            AtapiDevicePath         = (ATAPI_DEVICE_PATH *)ChildDevicePathNode;\r
             ScsiDiskDevice->Channel = AtapiDevicePath->PrimarySecondary;\r
-            ScsiDiskDevice->Device = AtapiDevicePath->SlaveMaster;\r
+            ScsiDiskDevice->Device  = AtapiDevicePath->SlaveMaster;\r
             //\r
-            // Update the DiskInfo.Interface to IDE interface GUID for the physical ATAPI device. \r
+            // Update the DiskInfo.Interface to IDE interface GUID for the physical ATAPI device.\r
             //\r
             CopyGuid (&ScsiDiskDevice->DiskInfo.Interface, &gEfiDiskInfoIdeInterfaceGuid);\r
           } else {\r
             //\r
             // We find the valid SATA device path\r
             //\r
-            SataDevicePath = (SATA_DEVICE_PATH *) ChildDevicePathNode;\r
+            SataDevicePath          = (SATA_DEVICE_PATH *)ChildDevicePathNode;\r
             ScsiDiskDevice->Channel = SataDevicePath->HBAPortNumber;\r
-            ScsiDiskDevice->Device = SataDevicePath->PortMultiplierPortNumber;\r
+            ScsiDiskDevice->Device  = SataDevicePath->PortMultiplierPortNumber;\r
             //\r
-            // Update the DiskInfo.Interface to AHCI interface GUID for the physical AHCI device. \r
+            // Update the DiskInfo.Interface to AHCI interface GUID for the physical AHCI device.\r
             //\r
             CopyGuid (&ScsiDiskDevice->DiskInfo.Interface, &gEfiDiskInfoAhciInterfaceGuid);\r
           }\r
+\r
           return;\r
         }\r
       } while (--IdentifyRetry > 0);\r
     } else if ((DevicePathType (ChildDevicePathNode) == MESSAGING_DEVICE_PATH) &&\r
-       (DevicePathSubType (ChildDevicePathNode) == MSG_UFS_DP)) {\r
+               (DevicePathSubType (ChildDevicePathNode) == MSG_UFS_DP))\r
+    {\r
       CopyGuid (&ScsiDiskDevice->DiskInfo.Interface, &gEfiDiskInfoUfsInterfaceGuid);\r
       break;\r
     }\r
+\r
     DevicePathNode = ChildDevicePathNode;\r
   }\r
 \r