This patch implements the EFI_STORAGE_SECURITY_COMMAND_PROTOCOL in the
ScsiDiskDxe driver.

Support is currently limited to the RPMB Well-known LUN for UFS devices.

Cc: Michael D Kinney <michael.d.kin...@intel.com>
Cc: Jiewen Yao <jiewen....@intel.com>
Cc: Jian J Wang <jian.j.w...@intel.com>
Cc: Liming Gao <liming....@intel.com>
Signed-off-by: Christopher J Zurcher <christopher.j.zurc...@intel.com>
---
 MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf |   3 +-
 MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.h      | 171 +++++-
 MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c      | 614 +++++++++++++++++++-
 3 files changed, 772 insertions(+), 16 deletions(-)

diff --git a/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf 
b/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
index 5500d828e9..40818e669b 100644
--- a/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
+++ b/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
@@ -3,7 +3,7 @@
 #  It detects the SCSI disk media and installs Block I/O and Block I/O2 
Protocol on
 #  the device handle.
 #
-#  Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
 #  SPDX-License-Identifier: BSD-2-Clause-Patent
 #
 ##
@@ -52,6 +52,7 @@
   gEfiBlockIoProtocolGuid                       ## BY_START
   gEfiBlockIo2ProtocolGuid                      ## BY_START
   gEfiEraseBlockProtocolGuid                    ## BY_START
+  gEfiStorageSecurityCommandProtocolGuid        ## BY_START
   gEfiScsiIoProtocolGuid                        ## TO_START
   gEfiScsiPassThruProtocolGuid                  ## TO_START
   gEfiExtScsiPassThruProtocolGuid               ## TO_START
diff --git a/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.h 
b/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.h
index 42c0aaaa95..2d8679ec6f 100644
--- a/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.h
+++ b/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.h
@@ -1,7 +1,7 @@
 /** @file
   Header file for SCSI Disk Driver.
 
-Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 2019, Intel Corporation. All rights reserved.<BR>
 SPDX-License-Identifier: BSD-2-Clause-Patent
 
 **/
@@ -22,6 +22,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 #include <Protocol/ScsiPassThruExt.h>
 #include <Protocol/ScsiPassThru.h>
 #include <Protocol/DiskInfo.h>
+#include <Protocol/StorageSecurityCommand.h>
 
 
 #include <Library/DebugLib.h>
@@ -38,6 +39,10 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 
 #define IS_DEVICE_FIXED(a)        (a)->FixedDevice ? 1 : 0
 
+#define IS_ALIGNED(addr, size)    (((UINTN) (addr) & (size - 1)) == 0)
+
+#define UFS_WLUN_RPMB 0xC4
+
 typedef struct {
   UINT32                    MaxLbaCnt;
   UINT32                    MaxBlkDespCnt;
@@ -51,6 +56,8 @@ typedef struct {
 
   EFI_HANDLE                Handle;
 
+  EFI_STORAGE_SECURITY_COMMAND_PROTOCOL   StorageSecurity;
+
   EFI_BLOCK_IO_PROTOCOL     BlkIo;
   EFI_BLOCK_IO2_PROTOCOL    BlkIo2;
   EFI_BLOCK_IO_MEDIA        BlkIoMedia;
@@ -95,6 +102,7 @@ typedef struct {
 #define SCSI_DISK_DEV_FROM_BLKIO(a)  CR (a, SCSI_DISK_DEV, BlkIo, 
SCSI_DISK_DEV_SIGNATURE)
 #define SCSI_DISK_DEV_FROM_BLKIO2(a)  CR (a, SCSI_DISK_DEV, BlkIo2, 
SCSI_DISK_DEV_SIGNATURE)
 #define SCSI_DISK_DEV_FROM_ERASEBLK(a)  CR (a, SCSI_DISK_DEV, EraseBlock, 
SCSI_DISK_DEV_SIGNATURE)
+#define SCSI_DISK_DEV_FROM_STORSEC(a)  CR (a, SCSI_DISK_DEV, StorageSecurity, 
SCSI_DISK_DEV_SIGNATURE)
 
 #define SCSI_DISK_DEV_FROM_DISKINFO(a) CR (a, SCSI_DISK_DEV, DiskInfo, 
SCSI_DISK_DEV_SIGNATURE)
 
@@ -638,6 +646,151 @@ ScsiDiskEraseBlocks (
   );
 
 
+/**
+  Send a security protocol command to a device that receives data and/or the 
result
+  of one or more commands sent by SendData.
+
+  The ReceiveData function sends a security protocol command to the given 
MediaId.
+  The security protocol command sent is defined by SecurityProtocolId and 
contains
+  the security protocol specific data SecurityProtocolSpecificData. The 
function
+  returns the data from the security protocol command in PayloadBuffer.
+
+  For devices supporting the SCSI command set, the security protocol command 
is sent
+  using the SECURITY PROTOCOL IN command defined in SPC-4.
+
+  If PayloadBufferSize is too small to store the available data from the 
security
+  protocol command, the function shall copy PayloadBufferSize bytes into the
+  PayloadBuffer and return EFI_WARN_BUFFER_TOO_SMALL.
+
+  If PayloadBuffer or PayloadTransferSize is NULL and PayloadBufferSize is 
non-zero,
+  the function shall return EFI_INVALID_PARAMETER.
+
+  If the given MediaId does not support security protocol commands, the 
function shall
+  return EFI_UNSUPPORTED. If there is no media in the device, the function 
returns
+  EFI_NO_MEDIA. If the MediaId is not the ID for the current media in the 
device,
+  the function returns EFI_MEDIA_CHANGED.
+
+  If the security protocol fails to complete within the Timeout period, the 
function
+  shall return EFI_TIMEOUT.
+
+  If the security protocol command completes without an error, the function 
shall
+  return EFI_SUCCESS. If the security protocol command completes with an 
error, the
+  function shall return EFI_DEVICE_ERROR.
+
+  @param  This                         Indicates a pointer to the calling 
context.
+  @param  MediaId                      ID of the medium to receive data from.
+  @param  Timeout                      The timeout, in 100ns units, to use for 
the execution
+                                       of the security protocol command. A 
Timeout value of 0
+                                       means that this function will wait 
indefinitely for the
+                                       security protocol command to execute. 
If Timeout is greater
+                                       than zero, then this function will 
return EFI_TIMEOUT if the
+                                       time required to execute the receive 
data command is greater than Timeout.
+  @param  SecurityProtocolId           The value of the "Security Protocol" 
parameter of
+                                       the security protocol command to be 
sent.
+  @param  SecurityProtocolSpecificData The value of the "Security Protocol 
Specific" parameter
+                                       of the security protocol command to be 
sent.
+  @param  PayloadBufferSize            Size in bytes of the payload data 
buffer.
+  @param  PayloadBuffer                A pointer to a destination buffer to 
store the security
+                                       protocol command specific payload data 
for the security
+                                       protocol command. The caller is 
responsible for having
+                                       either implicit or explicit ownership 
of the buffer.
+  @param  PayloadTransferSize          A pointer to a buffer to store the size 
in bytes of the
+                                       data written to the payload data buffer.
+
+  @retval EFI_SUCCESS                  The security protocol command completed 
successfully.
+  @retval EFI_WARN_BUFFER_TOO_SMALL    The PayloadBufferSize was too small to 
store the available
+                                       data from the device. The PayloadBuffer 
contains the truncated data.
+  @retval EFI_UNSUPPORTED              The given MediaId does not support 
security protocol commands.
+  @retval EFI_DEVICE_ERROR             The security protocol command completed 
with an error.
+  @retval EFI_NO_MEDIA                 There is no media in the device.
+  @retval EFI_MEDIA_CHANGED            The MediaId is not for the current 
media.
+  @retval EFI_INVALID_PARAMETER        The PayloadBuffer or 
PayloadTransferSize is NULL and
+                                       PayloadBufferSize is non-zero.
+  @retval EFI_TIMEOUT                  A timeout occurred while waiting for 
the security
+                                       protocol command to execute.
+
+**/
+EFI_STATUS
+EFIAPI
+ScsiDiskReceiveData (
+  IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL    *This,
+  IN UINT32                                   MediaId   OPTIONAL,
+  IN UINT64                                   Timeout,
+  IN UINT8                                    SecurityProtocolId,
+  IN UINT16                                   SecurityProtocolSpecificData,
+  IN UINTN                                    PayloadBufferSize,
+  OUT VOID                                    *PayloadBuffer,
+  OUT UINTN                                   *PayloadTransferSize
+  );
+
+/**
+  Send a security protocol command to a device.
+
+  The SendData function sends a security protocol command containing the 
payload
+  PayloadBuffer to the given MediaId. The security protocol command sent is
+  defined by SecurityProtocolId and contains the security protocol specific 
data
+  SecurityProtocolSpecificData. If the underlying protocol command requires a
+  specific padding for the command payload, the SendData function shall add 
padding
+  bytes to the command payload to satisfy the padding requirements.
+
+  For devices supporting the SCSI command set, the security protocol command 
is sent
+  using the SECURITY PROTOCOL OUT command defined in SPC-4.
+
+  If PayloadBuffer is NULL and PayloadBufferSize is non-zero, the function 
shall
+  return EFI_INVALID_PARAMETER.
+
+  If the given MediaId does not support security protocol commands, the 
function
+  shall return EFI_UNSUPPORTED. If there is no media in the device, the 
function
+  returns EFI_NO_MEDIA. If the MediaId is not the ID for the current media in 
the
+  device, the function returns EFI_MEDIA_CHANGED.
+
+  If the security protocol fails to complete within the Timeout period, the 
function
+  shall return EFI_TIMEOUT.
+
+  If the security protocol command completes without an error, the function 
shall return
+  EFI_SUCCESS. If the security protocol command completes with an error, the 
function
+  shall return EFI_DEVICE_ERROR.
+
+  @param  This                         Indicates a pointer to the calling 
context.
+  @param  MediaId                      ID of the medium to receive data from.
+  @param  Timeout                      The timeout, in 100ns units, to use for 
the execution
+                                       of the security protocol command. A 
Timeout value of 0
+                                       means that this function will wait 
indefinitely for the
+                                       security protocol command to execute. 
If Timeout is greater
+                                       than zero, then this function will 
return EFI_TIMEOUT if the
+                                       time required to execute the receive 
data command is greater than Timeout.
+  @param  SecurityProtocolId           The value of the "Security Protocol" 
parameter of
+                                       the security protocol command to be 
sent.
+  @param  SecurityProtocolSpecificData The value of the "Security Protocol 
Specific" parameter
+                                       of the security protocol command to be 
sent.
+  @param  PayloadBufferSize            Size in bytes of the payload data 
buffer.
+  @param  PayloadBuffer                A pointer to a destination buffer to 
store the security
+                                       protocol command specific payload data 
for the security
+                                       protocol command.
+
+  @retval EFI_SUCCESS                  The security protocol command completed 
successfully.
+  @retval EFI_UNSUPPORTED              The given MediaId does not support 
security protocol commands.
+  @retval EFI_DEVICE_ERROR             The security protocol command completed 
with an error.
+  @retval EFI_NO_MEDIA                 There is no media in the device.
+  @retval EFI_MEDIA_CHANGED            The MediaId is not for the current 
media.
+  @retval EFI_INVALID_PARAMETER        The PayloadBuffer is NULL and 
PayloadBufferSize is non-zero.
+  @retval EFI_TIMEOUT                  A timeout occurred while waiting for 
the security
+                                       protocol command to execute.
+
+**/
+EFI_STATUS
+EFIAPI
+ScsiDiskSendData (
+  IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL    *This,
+  IN UINT32                                   MediaId   OPTIONAL,
+  IN UINT64                                   Timeout,
+  IN UINT8                                    SecurityProtocolId,
+  IN UINT16                                   SecurityProtocolSpecificData,
+  IN UINTN                                    PayloadBufferSize,
+  OUT VOID                                    *PayloadBuffer
+  );
+
+
 /**
   Provides inquiry information for the controller type.
 
@@ -1428,4 +1581,20 @@ DetermineInstallEraseBlock (
   IN  EFI_HANDLE             ChildHandle
   );
 
+/**
+  Determine if EFI Storage Security Command Protocol should be produced.
+
+  @param   ScsiDiskDevice    The pointer of SCSI_DISK_DEV.
+  @param   ChildHandle       Handle of device.
+
+  @retval  TRUE    Should produce EFI Storage Security Command Protocol.
+  @retval  FALSE   Should not produce EFI Storage Security Command Protocol.
+
+**/
+BOOLEAN
+DetermineInstallStorageSecurity (
+  IN  SCSI_DISK_DEV          *ScsiDiskDevice,
+  IN  EFI_HANDLE             ChildHandle
+  );
+
 #endif
diff --git a/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c 
b/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c
index fbdf927a11..fc14a66d46 100644
--- a/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c
+++ b/MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDisk.c
@@ -1,7 +1,7 @@
 /** @file
   SCSI disk driver that layers on every SCSI IO protocol in the system.
 
-Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
 SPDX-License-Identifier: BSD-2-Clause-Patent
 
 **/
@@ -151,7 +151,9 @@ ScsiDiskDriverBindingSupported (
 
   Status = ScsiIo->GetDeviceType (ScsiIo, &DeviceType);
   if (!EFI_ERROR (Status)) {
-    if ((DeviceType == EFI_SCSI_TYPE_DISK) || (DeviceType == 
EFI_SCSI_TYPE_CDROM)) {
+    if ((DeviceType == EFI_SCSI_TYPE_DISK) ||
+        (DeviceType == EFI_SCSI_TYPE_CDROM) ||
+        (DeviceType == EFI_SCSI_TYPE_WLUN)) {
       Status = EFI_SUCCESS;
     } else {
       Status = EFI_UNSUPPORTED;
@@ -238,6 +240,8 @@ ScsiDiskDriverBindingStart (
   ScsiDiskDevice->BlkIo2.ReadBlocksEx               = ScsiDiskReadBlocksEx;
   ScsiDiskDevice->BlkIo2.WriteBlocksEx              = ScsiDiskWriteBlocksEx;
   ScsiDiskDevice->BlkIo2.FlushBlocksEx              = ScsiDiskFlushBlocksEx;
+  ScsiDiskDevice->StorageSecurity.ReceiveData       = ScsiDiskReceiveData;
+  ScsiDiskDevice->StorageSecurity.SendData          = ScsiDiskSendData;
   ScsiDiskDevice->EraseBlock.Revision               = 
EFI_ERASE_BLOCK_PROTOCOL_REVISION;
   ScsiDiskDevice->EraseBlock.EraseLengthGranularity = 1;
   ScsiDiskDevice->EraseBlock.EraseBlocks            = ScsiDiskEraseBlocks;
@@ -258,6 +262,10 @@ ScsiDiskDriverBindingStart (
     ScsiDiskDevice->BlkIo.Media->ReadOnly  = TRUE;
     MustReadCapacity = FALSE;
     break;
+
+  case EFI_SCSI_TYPE_WLUN:
+    MustReadCapacity = FALSE;
+    break;
   }
   //
   // The Sense Data Array's initial size is 6
@@ -309,8 +317,8 @@ ScsiDiskDriverBindingStart (
     // Determine if Block IO & Block IO2 should be produced on this controller
     // handle
     //
-    if (DetermineInstallBlockIo(Controller)) {
-      InitializeInstallDiskInfo(ScsiDiskDevice, Controller);
+    if (DetermineInstallBlockIo (Controller)) {
+      InitializeInstallDiskInfo (ScsiDiskDevice, Controller);
       Status = gBS->InstallMultipleProtocolInterfaces (
                       &Controller,
                       &gEfiBlockIoProtocolGuid,
@@ -321,16 +329,27 @@ ScsiDiskDriverBindingStart (
                       &ScsiDiskDevice->DiskInfo,
                       NULL
                       );
-      if (!EFI_ERROR(Status)) {
-        if (DetermineInstallEraseBlock(ScsiDiskDevice, Controller)) {
+      if (!EFI_ERROR (Status)) {
+        if (DetermineInstallEraseBlock (ScsiDiskDevice, Controller)) {
           Status = gBS->InstallProtocolInterface (
                           &Controller,
                           &gEfiEraseBlockProtocolGuid,
                           EFI_NATIVE_INTERFACE,
                           &ScsiDiskDevice->EraseBlock
                           );
-          if (EFI_ERROR(Status)) {
-            DEBUG ((EFI_D_ERROR, "ScsiDisk: Failed to install the Erase Block 
Protocol! Status = %r\n", Status));
+          if (EFI_ERROR (Status)) {
+            DEBUG ((DEBUG_ERROR, "ScsiDisk: Failed to install the Erase Block 
Protocol! Status = %r\n", Status));
+          }
+        }
+        if (DetermineInstallStorageSecurity (ScsiDiskDevice, Controller)) {
+          Status = gBS->InstallProtocolInterface (
+                          &Controller,
+                          &gEfiStorageSecurityCommandProtocolGuid,
+                          EFI_NATIVE_INTERFACE,
+                          &ScsiDiskDevice->StorageSecurity
+                          );
+          if (EFI_ERROR (Status)) {
+            DEBUG ((DEBUG_ERROR, "ScsiDisk: Failed to install the Storage 
Security Command Protocol! Status = %r\n", Status));
           }
         }
         ScsiDiskDevice->ControllerNameTable = NULL;
@@ -585,7 +604,7 @@ ScsiDiskReadBlocks (
              &ScsiDiskDevice->BlkIo2,
              &ScsiDiskDevice->BlkIo2
              );
-      if (DetermineInstallEraseBlock(ScsiDiskDevice, ScsiDiskDevice->Handle)) {
+      if (DetermineInstallEraseBlock (ScsiDiskDevice, ScsiDiskDevice->Handle)) 
{
         gBS->ReinstallProtocolInterface (
                ScsiDiskDevice->Handle,
                &gEfiEraseBlockProtocolGuid,
@@ -593,6 +612,14 @@ ScsiDiskReadBlocks (
                &ScsiDiskDevice->EraseBlock
                );
       }
+      if (DetermineInstallStorageSecurity (ScsiDiskDevice, 
ScsiDiskDevice->Handle)) {
+        gBS->ReinstallProtocolInterface (
+                ScsiDiskDevice->Handle,
+                &gEfiStorageSecurityCommandProtocolGuid,
+                &ScsiDiskDevice->StorageSecurity,
+                &ScsiDiskDevice->StorageSecurity
+                );
+      }
       if (Media->MediaPresent) {
         Status = EFI_MEDIA_CHANGED;
       } else {
@@ -606,6 +633,11 @@ ScsiDiskReadBlocks (
   //
   BlockSize       = Media->BlockSize;
 
+  if (BlockSize == 0) {
+    Status = EFI_DEVICE_ERROR;
+    goto Done;
+  }
+
   NumberOfBlocks  = BufferSize / BlockSize;
 
   if (!(Media->MediaPresent)) {
@@ -721,7 +753,7 @@ ScsiDiskWriteBlocks (
              &ScsiDiskDevice->BlkIo2,
              &ScsiDiskDevice->BlkIo2
              );
-      if (DetermineInstallEraseBlock(ScsiDiskDevice, ScsiDiskDevice->Handle)) {
+      if (DetermineInstallEraseBlock (ScsiDiskDevice, ScsiDiskDevice->Handle)) 
{
         gBS->ReinstallProtocolInterface (
                ScsiDiskDevice->Handle,
                &gEfiEraseBlockProtocolGuid,
@@ -729,6 +761,14 @@ ScsiDiskWriteBlocks (
                &ScsiDiskDevice->EraseBlock
                );
       }
+      if (DetermineInstallStorageSecurity (ScsiDiskDevice, 
ScsiDiskDevice->Handle)) {
+        gBS->ReinstallProtocolInterface (
+                ScsiDiskDevice->Handle,
+                &gEfiStorageSecurityCommandProtocolGuid,
+                &ScsiDiskDevice->StorageSecurity,
+                &ScsiDiskDevice->StorageSecurity
+                );
+      }
       if (Media->MediaPresent) {
         Status = EFI_MEDIA_CHANGED;
       } else {
@@ -742,6 +782,11 @@ ScsiDiskWriteBlocks (
   //
   BlockSize       = Media->BlockSize;
 
+  if (BlockSize == 0) {
+    Status = EFI_DEVICE_ERROR;
+    goto Done;
+  }
+
   NumberOfBlocks  = BufferSize / BlockSize;
 
   if (!(Media->MediaPresent)) {
@@ -947,7 +992,7 @@ ScsiDiskReadBlocksEx (
              &ScsiDiskDevice->BlkIo2,
              &ScsiDiskDevice->BlkIo2
              );
-      if (DetermineInstallEraseBlock(ScsiDiskDevice, ScsiDiskDevice->Handle)) {
+      if (DetermineInstallEraseBlock (ScsiDiskDevice, ScsiDiskDevice->Handle)) 
{
         gBS->ReinstallProtocolInterface (
                ScsiDiskDevice->Handle,
                &gEfiEraseBlockProtocolGuid,
@@ -955,6 +1000,14 @@ ScsiDiskReadBlocksEx (
                &ScsiDiskDevice->EraseBlock
                );
       }
+      if (DetermineInstallStorageSecurity (ScsiDiskDevice, 
ScsiDiskDevice->Handle)) {
+        gBS->ReinstallProtocolInterface (
+                ScsiDiskDevice->Handle,
+                &gEfiStorageSecurityCommandProtocolGuid,
+                &ScsiDiskDevice->StorageSecurity,
+                &ScsiDiskDevice->StorageSecurity
+                );
+      }
       if (Media->MediaPresent) {
         Status = EFI_MEDIA_CHANGED;
       } else {
@@ -968,6 +1021,11 @@ ScsiDiskReadBlocksEx (
   //
   BlockSize       = Media->BlockSize;
 
+  if (BlockSize == 0) {
+    Status = EFI_DEVICE_ERROR;
+    goto Done;
+  }
+
   NumberOfBlocks  = BufferSize / BlockSize;
 
   if (!(Media->MediaPresent)) {
@@ -1110,7 +1168,7 @@ ScsiDiskWriteBlocksEx (
              &ScsiDiskDevice->BlkIo2,
              &ScsiDiskDevice->BlkIo2
              );
-      if (DetermineInstallEraseBlock(ScsiDiskDevice, ScsiDiskDevice->Handle)) {
+      if (DetermineInstallEraseBlock (ScsiDiskDevice, ScsiDiskDevice->Handle)) 
{
         gBS->ReinstallProtocolInterface (
                ScsiDiskDevice->Handle,
                &gEfiEraseBlockProtocolGuid,
@@ -1118,6 +1176,14 @@ ScsiDiskWriteBlocksEx (
                &ScsiDiskDevice->EraseBlock
                );
       }
+      if (DetermineInstallStorageSecurity (ScsiDiskDevice, 
ScsiDiskDevice->Handle)) {
+        gBS->ReinstallProtocolInterface (
+                ScsiDiskDevice->Handle,
+                &gEfiStorageSecurityCommandProtocolGuid,
+                &ScsiDiskDevice->StorageSecurity,
+                &ScsiDiskDevice->StorageSecurity
+                );
+      }
       if (Media->MediaPresent) {
         Status = EFI_MEDIA_CHANGED;
       } else {
@@ -1131,6 +1197,11 @@ ScsiDiskWriteBlocksEx (
   //
   BlockSize       = Media->BlockSize;
 
+  if (BlockSize == 0) {
+    Status = EFI_DEVICE_ERROR;
+    goto Done;
+  }
+
   NumberOfBlocks  = BufferSize / BlockSize;
 
   if (!(Media->MediaPresent)) {
@@ -1263,7 +1334,7 @@ ScsiDiskFlushBlocksEx (
              &ScsiDiskDevice->BlkIo2,
              &ScsiDiskDevice->BlkIo2
              );
-      if (DetermineInstallEraseBlock(ScsiDiskDevice, ScsiDiskDevice->Handle)) {
+      if (DetermineInstallEraseBlock (ScsiDiskDevice, ScsiDiskDevice->Handle)) 
{
         gBS->ReinstallProtocolInterface (
                ScsiDiskDevice->Handle,
                &gEfiEraseBlockProtocolGuid,
@@ -1271,6 +1342,14 @@ ScsiDiskFlushBlocksEx (
                &ScsiDiskDevice->EraseBlock
                );
       }
+      if (DetermineInstallStorageSecurity (ScsiDiskDevice, 
ScsiDiskDevice->Handle)) {
+        gBS->ReinstallProtocolInterface (
+                ScsiDiskDevice->Handle,
+                &gEfiStorageSecurityCommandProtocolGuid,
+                &ScsiDiskDevice->StorageSecurity,
+                &ScsiDiskDevice->StorageSecurity
+                );
+      }
       if (Media->MediaPresent) {
         Status = EFI_MEDIA_CHANGED;
       } else {
@@ -1644,7 +1723,7 @@ ScsiDiskEraseBlocks (
              &ScsiDiskDevice->BlkIo2,
              &ScsiDiskDevice->BlkIo2
              );
-      if (DetermineInstallEraseBlock(ScsiDiskDevice, ScsiDiskDevice->Handle)) {
+      if (DetermineInstallEraseBlock (ScsiDiskDevice, ScsiDiskDevice->Handle)) 
{
         gBS->ReinstallProtocolInterface (
                ScsiDiskDevice->Handle,
                &gEfiEraseBlockProtocolGuid,
@@ -1652,6 +1731,14 @@ ScsiDiskEraseBlocks (
                &ScsiDiskDevice->EraseBlock
                );
       }
+      if (DetermineInstallStorageSecurity (ScsiDiskDevice, 
ScsiDiskDevice->Handle)) {
+        gBS->ReinstallProtocolInterface (
+                ScsiDiskDevice->Handle,
+                &gEfiStorageSecurityCommandProtocolGuid,
+                &ScsiDiskDevice->StorageSecurity,
+                &ScsiDiskDevice->StorageSecurity
+                );
+      }
       Status = EFI_MEDIA_CHANGED;
       goto Done;
     }
@@ -1708,6 +1795,429 @@ Done:
   return Status;
 }
 
+/**
+  Send a security protocol command to a device that receives data and/or the 
result
+  of one or more commands sent by SendData.
+
+  The ReceiveData function sends a security protocol command to the given 
MediaId.
+  The security protocol command sent is defined by SecurityProtocolId and 
contains
+  the security protocol specific data SecurityProtocolSpecificData. The 
function
+  returns the data from the security protocol command in PayloadBuffer.
+
+  For devices supporting the SCSI command set, the security protocol command 
is sent
+  using the SECURITY PROTOCOL IN command defined in SPC-4.
+
+  If PayloadBufferSize is too small to store the available data from the 
security
+  protocol command, the function shall copy PayloadBufferSize bytes into the
+  PayloadBuffer and return EFI_WARN_BUFFER_TOO_SMALL.
+
+  If PayloadBuffer or PayloadTransferSize is NULL and PayloadBufferSize is 
non-zero,
+  the function shall return EFI_INVALID_PARAMETER.
+
+  If the given MediaId does not support security protocol commands, the 
function shall
+  return EFI_UNSUPPORTED. If there is no media in the device, the function 
returns
+  EFI_NO_MEDIA. If the MediaId is not the ID for the current media in the 
device,
+  the function returns EFI_MEDIA_CHANGED.
+
+  If the security protocol fails to complete within the Timeout period, the 
function
+  shall return EFI_TIMEOUT.
+
+  If the security protocol command completes without an error, the function 
shall
+  return EFI_SUCCESS. If the security protocol command completes with an 
error, the
+  function shall return EFI_DEVICE_ERROR.
+
+  @param  This                         Indicates a pointer to the calling 
context.
+  @param  MediaId                      ID of the medium to receive data from.
+  @param  Timeout                      The timeout, in 100ns units, to use for 
the execution
+                                       of the security protocol command. A 
Timeout value of 0
+                                       means that this function will wait 
indefinitely for the
+                                       security protocol command to execute. 
If Timeout is greater
+                                       than zero, then this function will 
return EFI_TIMEOUT if the
+                                       time required to execute the receive 
data command is greater than Timeout.
+  @param  SecurityProtocolId           The value of the "Security Protocol" 
parameter of
+                                       the security protocol command to be 
sent.
+  @param  SecurityProtocolSpecificData The value of the "Security Protocol 
Specific" parameter
+                                       of the security protocol command to be 
sent.
+  @param  PayloadBufferSize            Size in bytes of the payload data 
buffer.
+  @param  PayloadBuffer                A pointer to a destination buffer to 
store the security
+                                       protocol command specific payload data 
for the security
+                                       protocol command. The caller is 
responsible for having
+                                       either implicit or explicit ownership 
of the buffer.
+  @param  PayloadTransferSize          A pointer to a buffer to store the size 
in bytes of the
+                                       data written to the payload data buffer.
+
+  @retval EFI_SUCCESS                  The security protocol command completed 
successfully.
+  @retval EFI_WARN_BUFFER_TOO_SMALL    The PayloadBufferSize was too small to 
store the available
+                                       data from the device. The PayloadBuffer 
contains the truncated data.
+  @retval EFI_UNSUPPORTED              The given MediaId does not support 
security protocol commands.
+  @retval EFI_DEVICE_ERROR             The security protocol command completed 
with an error.
+  @retval EFI_NO_MEDIA                 There is no media in the device.
+  @retval EFI_MEDIA_CHANGED            The MediaId is not for the current 
media.
+  @retval EFI_INVALID_PARAMETER        The PayloadBuffer or 
PayloadTransferSize is NULL and
+                                       PayloadBufferSize is non-zero.
+  @retval EFI_TIMEOUT                  A timeout occurred while waiting for 
the security
+                                       protocol command to execute.
+
+**/
+EFI_STATUS
+EFIAPI
+ScsiDiskReceiveData (
+  IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL    *This,
+  IN UINT32                                   MediaId   OPTIONAL,
+  IN UINT64                                   Timeout,
+  IN UINT8                                    SecurityProtocolId,
+  IN UINT16                                   SecurityProtocolSpecificData,
+  IN UINTN                                    PayloadBufferSize,
+  OUT VOID                                    *PayloadBuffer,
+  OUT UINTN                                   *PayloadTransferSize
+  )
+{
+  SCSI_DISK_DEV       *ScsiDiskDevice;
+  EFI_BLOCK_IO_MEDIA  *Media;
+  EFI_STATUS          Status;
+  BOOLEAN             MediaChange;
+  EFI_TPL             OldTpl;
+  UINT8               SenseDataLength;
+  UINT8               HostAdapterStatus;
+  UINT8               TargetStatus;
+  VOID                *AlignedBuffer;
+  BOOLEAN             AlignedBufferAllocated;
+
+  AlignedBuffer           = NULL;
+  MediaChange             = FALSE;
+  AlignedBufferAllocated  = FALSE;
+  OldTpl                  = gBS->RaiseTPL (TPL_CALLBACK);
+  ScsiDiskDevice          = SCSI_DISK_DEV_FROM_STORSEC (This);
+  Media                   = ScsiDiskDevice->BlkIo.Media;
+
+  SenseDataLength = (UINT8) (ScsiDiskDevice->SenseDataNumber * sizeof 
(EFI_SCSI_SENSE_DATA));
+
+  if (!IS_DEVICE_FIXED (ScsiDiskDevice)) {
+    Status = ScsiDiskDetectMedia (ScsiDiskDevice, FALSE, &MediaChange);
+    if (EFI_ERROR (Status)) {
+      Status = EFI_DEVICE_ERROR;
+      goto Done;
+    }
+
+    if (MediaChange) {
+      gBS->ReinstallProtocolInterface (
+            ScsiDiskDevice->Handle,
+            &gEfiBlockIoProtocolGuid,
+            &ScsiDiskDevice->BlkIo,
+            &ScsiDiskDevice->BlkIo
+            );
+      gBS->ReinstallProtocolInterface (
+             ScsiDiskDevice->Handle,
+             &gEfiBlockIo2ProtocolGuid,
+             &ScsiDiskDevice->BlkIo2,
+             &ScsiDiskDevice->BlkIo2
+             );
+      if (DetermineInstallEraseBlock (ScsiDiskDevice, ScsiDiskDevice->Handle)) 
{
+        gBS->ReinstallProtocolInterface (
+               ScsiDiskDevice->Handle,
+               &gEfiEraseBlockProtocolGuid,
+               &ScsiDiskDevice->EraseBlock,
+               &ScsiDiskDevice->EraseBlock
+               );
+      }
+      if (DetermineInstallStorageSecurity (ScsiDiskDevice, 
ScsiDiskDevice->Handle)) {
+        gBS->ReinstallProtocolInterface (
+                ScsiDiskDevice->Handle,
+                &gEfiStorageSecurityCommandProtocolGuid,
+                &ScsiDiskDevice->StorageSecurity,
+                &ScsiDiskDevice->StorageSecurity
+                );
+      }
+      if (Media->MediaPresent) {
+        Status = EFI_MEDIA_CHANGED;
+      } else {
+        Status = EFI_NO_MEDIA;
+      }
+      goto Done;
+    }
+  }
+
+  //
+  // Validate Media
+  //
+  if (!(Media->MediaPresent)) {
+    Status = EFI_NO_MEDIA;
+    goto Done;
+  }
+
+  if ((MediaId != 0) && (MediaId != Media->MediaId)) {
+    Status = EFI_MEDIA_CHANGED;
+    goto Done;
+  }
+
+  if (PayloadBufferSize != 0) {
+    if ((PayloadBuffer == NULL) || (PayloadTransferSize == NULL)) {
+      Status = EFI_INVALID_PARAMETER;
+      goto Done;
+    }
+
+    if ((ScsiDiskDevice->ScsiIo->IoAlign > 1) && !IS_ALIGNED (PayloadBuffer, 
ScsiDiskDevice->ScsiIo->IoAlign)) {
+      AlignedBuffer = AllocateAlignedBuffer (ScsiDiskDevice, 
PayloadBufferSize);
+      if (AlignedBuffer == NULL) {
+        Status = EFI_OUT_OF_RESOURCES;
+        goto Done;
+      }
+      ZeroMem (AlignedBuffer, PayloadBufferSize);
+      AlignedBufferAllocated = TRUE;
+    } else {
+      AlignedBuffer = PayloadBuffer;
+    }
+  }
+
+  Status = ScsiSecurityProtocolInCommand (
+            ScsiDiskDevice->ScsiIo,
+            Timeout,
+            ScsiDiskDevice->SenseData,
+            &SenseDataLength,
+            &HostAdapterStatus,
+            &TargetStatus,
+            SecurityProtocolId,
+            SecurityProtocolSpecificData,
+            (UINT32) PayloadBufferSize,
+            AlignedBuffer,
+            (UINT32 *) PayloadTransferSize
+          );
+  if (EFI_ERROR (Status)) {
+    goto Done;
+  }
+
+  if (AlignedBufferAllocated) {
+    CopyMem (PayloadBuffer, AlignedBuffer, PayloadBufferSize);
+  }
+
+  if (PayloadBufferSize < *PayloadTransferSize) {
+    Status = EFI_WARN_BUFFER_TOO_SMALL;
+    goto Done;
+  }
+
+  Status = CheckHostAdapterStatus (HostAdapterStatus);
+  if (EFI_ERROR (Status)) {
+    goto Done;
+  }
+
+  Status = CheckTargetStatus (TargetStatus);
+  if (EFI_ERROR (Status)) {
+    goto Done;
+  }
+
+Done:
+  if (AlignedBufferAllocated) {
+    ZeroMem (AlignedBuffer, PayloadBufferSize);
+    FreeAlignedBuffer (AlignedBuffer, PayloadBufferSize);
+  }
+  gBS->RestoreTPL (OldTpl);
+  return Status;
+}
+
+/**
+  Send a security protocol command to a device.
+
+  The SendData function sends a security protocol command containing the 
payload
+  PayloadBuffer to the given MediaId. The security protocol command sent is
+  defined by SecurityProtocolId and contains the security protocol specific 
data
+  SecurityProtocolSpecificData. If the underlying protocol command requires a
+  specific padding for the command payload, the SendData function shall add 
padding
+  bytes to the command payload to satisfy the padding requirements.
+
+  For devices supporting the SCSI command set, the security protocol command 
is sent
+  using the SECURITY PROTOCOL OUT command defined in SPC-4.
+
+  If PayloadBuffer is NULL and PayloadBufferSize is non-zero, the function 
shall
+  return EFI_INVALID_PARAMETER.
+
+  If the given MediaId does not support security protocol commands, the 
function
+  shall return EFI_UNSUPPORTED. If there is no media in the device, the 
function
+  returns EFI_NO_MEDIA. If the MediaId is not the ID for the current media in 
the
+  device, the function returns EFI_MEDIA_CHANGED.
+
+  If the security protocol fails to complete within the Timeout period, the 
function
+  shall return EFI_TIMEOUT.
+
+  If the security protocol command completes without an error, the function 
shall return
+  EFI_SUCCESS. If the security protocol command completes with an error, the 
function
+  shall return EFI_DEVICE_ERROR.
+
+  @param  This                         Indicates a pointer to the calling 
context.
+  @param  MediaId                      ID of the medium to receive data from.
+  @param  Timeout                      The timeout, in 100ns units, to use for 
the execution
+                                       of the security protocol command. A 
Timeout value of 0
+                                       means that this function will wait 
indefinitely for the
+                                       security protocol command to execute. 
If Timeout is greater
+                                       than zero, then this function will 
return EFI_TIMEOUT if the
+                                       time required to execute the receive 
data command is greater than Timeout.
+  @param  SecurityProtocolId           The value of the "Security Protocol" 
parameter of
+                                       the security protocol command to be 
sent.
+  @param  SecurityProtocolSpecificData The value of the "Security Protocol 
Specific" parameter
+                                       of the security protocol command to be 
sent.
+  @param  PayloadBufferSize            Size in bytes of the payload data 
buffer.
+  @param  PayloadBuffer                A pointer to a destination buffer to 
store the security
+                                       protocol command specific payload data 
for the security
+                                       protocol command.
+
+  @retval EFI_SUCCESS                  The security protocol command completed 
successfully.
+  @retval EFI_UNSUPPORTED              The given MediaId does not support 
security protocol commands.
+  @retval EFI_DEVICE_ERROR             The security protocol command completed 
with an error.
+  @retval EFI_NO_MEDIA                 There is no media in the device.
+  @retval EFI_MEDIA_CHANGED            The MediaId is not for the current 
media.
+  @retval EFI_INVALID_PARAMETER        The PayloadBuffer is NULL and 
PayloadBufferSize is non-zero.
+  @retval EFI_TIMEOUT                  A timeout occurred while waiting for 
the security
+                                       protocol command to execute.
+
+**/
+EFI_STATUS
+EFIAPI
+ScsiDiskSendData (
+  IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL    *This,
+  IN UINT32                                   MediaId   OPTIONAL,
+  IN UINT64                                   Timeout,
+  IN UINT8                                    SecurityProtocolId,
+  IN UINT16                                   SecurityProtocolSpecificData,
+  IN UINTN                                    PayloadBufferSize,
+  OUT VOID                                    *PayloadBuffer
+  )
+{
+  SCSI_DISK_DEV       *ScsiDiskDevice;
+  EFI_BLOCK_IO_MEDIA  *Media;
+  EFI_STATUS          Status;
+  BOOLEAN             MediaChange;
+  EFI_TPL             OldTpl;
+  UINT8               SenseDataLength;
+  UINT8               HostAdapterStatus;
+  UINT8               TargetStatus;
+  VOID                *AlignedBuffer;
+  BOOLEAN             AlignedBufferAllocated;
+
+  AlignedBuffer           = NULL;
+  MediaChange             = FALSE;
+  AlignedBufferAllocated  = FALSE;
+  OldTpl                  = gBS->RaiseTPL (TPL_CALLBACK);
+  ScsiDiskDevice          = SCSI_DISK_DEV_FROM_STORSEC (This);
+  Media                   = ScsiDiskDevice->BlkIo.Media;
+
+  SenseDataLength = (UINT8) (ScsiDiskDevice->SenseDataNumber * sizeof 
(EFI_SCSI_SENSE_DATA));
+
+  if (!IS_DEVICE_FIXED (ScsiDiskDevice)) {
+    Status = ScsiDiskDetectMedia (ScsiDiskDevice, FALSE, &MediaChange);
+    if (EFI_ERROR (Status)) {
+      Status = EFI_DEVICE_ERROR;
+      goto Done;
+    }
+
+    if (MediaChange) {
+      gBS->ReinstallProtocolInterface (
+            ScsiDiskDevice->Handle,
+            &gEfiBlockIoProtocolGuid,
+            &ScsiDiskDevice->BlkIo,
+            &ScsiDiskDevice->BlkIo
+            );
+      gBS->ReinstallProtocolInterface (
+             ScsiDiskDevice->Handle,
+             &gEfiBlockIo2ProtocolGuid,
+             &ScsiDiskDevice->BlkIo2,
+             &ScsiDiskDevice->BlkIo2
+             );
+      if (DetermineInstallEraseBlock (ScsiDiskDevice, ScsiDiskDevice->Handle)) 
{
+        gBS->ReinstallProtocolInterface (
+               ScsiDiskDevice->Handle,
+               &gEfiEraseBlockProtocolGuid,
+               &ScsiDiskDevice->EraseBlock,
+               &ScsiDiskDevice->EraseBlock
+               );
+      }
+      if (DetermineInstallStorageSecurity (ScsiDiskDevice, 
ScsiDiskDevice->Handle)) {
+        gBS->ReinstallProtocolInterface (
+                ScsiDiskDevice->Handle,
+                &gEfiStorageSecurityCommandProtocolGuid,
+                &ScsiDiskDevice->StorageSecurity,
+                &ScsiDiskDevice->StorageSecurity
+                );
+      }
+      if (Media->MediaPresent) {
+        Status = EFI_MEDIA_CHANGED;
+      } else {
+        Status = EFI_NO_MEDIA;
+      }
+      goto Done;
+    }
+  }
+
+  //
+  // Validate Media
+  //
+  if (!(Media->MediaPresent)) {
+    Status = EFI_NO_MEDIA;
+    goto Done;
+  }
+
+  if ((MediaId != 0) && (MediaId != Media->MediaId)) {
+    Status = EFI_MEDIA_CHANGED;
+    goto Done;
+  }
+
+  if (Media->ReadOnly) {
+    Status = EFI_WRITE_PROTECTED;
+    goto Done;
+  }
+
+  if (PayloadBufferSize != 0) {
+    if (PayloadBuffer == NULL) {
+      Status = EFI_INVALID_PARAMETER;
+      goto Done;
+    }
+
+    if ((ScsiDiskDevice->ScsiIo->IoAlign > 1) && !IS_ALIGNED (PayloadBuffer, 
ScsiDiskDevice->ScsiIo->IoAlign)) {
+      AlignedBuffer = AllocateAlignedBuffer (ScsiDiskDevice, 
PayloadBufferSize);
+      if (AlignedBuffer == NULL) {
+        Status = EFI_OUT_OF_RESOURCES;
+        goto Done;
+      }
+      CopyMem (AlignedBuffer, PayloadBuffer, PayloadBufferSize);
+      AlignedBufferAllocated = TRUE;
+    } else {
+      AlignedBuffer = PayloadBuffer;
+    }
+  }
+
+  Status = ScsiSecurityProtocolOutCommand (
+            ScsiDiskDevice->ScsiIo,
+            Timeout,
+            ScsiDiskDevice->SenseData,
+            &SenseDataLength,
+            &HostAdapterStatus,
+            &TargetStatus,
+            SecurityProtocolId,
+            SecurityProtocolSpecificData,
+            (UINT32) PayloadBufferSize,
+            AlignedBuffer
+          );
+  if (EFI_ERROR (Status)) {
+    goto Done;
+  }
+
+  Status = CheckHostAdapterStatus (HostAdapterStatus);
+  if (EFI_ERROR (Status)) {
+    goto Done;
+  }
+
+  Status = CheckTargetStatus (TargetStatus);
+  if (EFI_ERROR (Status)) {
+    goto Done;
+  }
+
+Done:
+  if (AlignedBufferAllocated) {
+    ZeroMem (AlignedBuffer, PayloadBufferSize);
+    FreeAlignedBuffer (AlignedBuffer, PayloadBufferSize);
+  }
+  gBS->RestoreTPL (OldTpl);
+  return Status;
+}
+
 
 /**
   Detect Device and read out capacity ,if error occurs, parse the sense key.
@@ -1812,6 +2322,15 @@ ScsiDiskDetectMedia (
     NeedReadCapacity = TRUE;
   }
 
+  //
+  // READ_CAPACITY command is not supported by any of the UFS WLUNs.
+  //
+  if (ScsiDiskDevice->DeviceType == EFI_SCSI_TYPE_WLUN) {
+    NeedReadCapacity = FALSE;
+    MustReadCapacity = FALSE;
+    ScsiDiskDevice->BlkIo.Media->MediaPresent = TRUE;
+  }
+
   //
   // either NeedReadCapacity is TRUE, or MustReadCapacity is TRUE,
   // retrieve capacity via Read Capacity command
@@ -5358,6 +5877,14 @@ DetermineInstallEraseBlock (
   RetVal         = TRUE;
   CapacityData16 = NULL;
 
+  //
+  // UNMAP command is not supported by any of the UFS WLUNs.
+  //
+  if (ScsiDiskDevice->DeviceType == EFI_SCSI_TYPE_WLUN) {
+    RetVal = FALSE;
+    goto Done;
+  }
+
   Status = gBS->HandleProtocol (
                   ChildHandle,
                   &gEfiDevicePathProtocolGuid,
@@ -5460,6 +5987,65 @@ Done:
   return RetVal;
 }
 
+/**
+  Determine if EFI Storage Security Command Protocol should be produced.
+
+  @param   ScsiDiskDevice    The pointer of SCSI_DISK_DEV.
+  @param   ChildHandle       Handle of device.
+
+  @retval  TRUE    Should produce EFI Storage Security Command Protocol.
+  @retval  FALSE   Should not produce EFI Storage Security Command Protocol.
+
+**/
+BOOLEAN
+DetermineInstallStorageSecurity (
+  IN  SCSI_DISK_DEV          *ScsiDiskDevice,
+  IN  EFI_HANDLE             ChildHandle
+  )
+{
+  EFI_STATUS                      Status;
+  UFS_DEVICE_PATH                 *UfsDevice;
+  BOOLEAN                         RetVal;
+  EFI_DEVICE_PATH_PROTOCOL        *DevicePathNode;
+
+  UfsDevice      = NULL;
+  RetVal         = TRUE;
+
+  Status = gBS->HandleProtocol (
+                  ChildHandle,
+                  &gEfiDevicePathProtocolGuid,
+                  (VOID **) &DevicePathNode
+                  );
+  //
+  // Device Path protocol must be installed on the device handle.
+  //
+  ASSERT_EFI_ERROR (Status);
+
+  while (!IsDevicePathEndType (DevicePathNode)) {
+    //
+    // For now, only support Storage Security Command Protocol on UFS devices.
+    //
+    if ((DevicePathNode->Type == MESSAGING_DEVICE_PATH) &&
+        (DevicePathNode->SubType == MSG_UFS_DP)) {
+      UfsDevice = (UFS_DEVICE_PATH *) DevicePathNode;
+      break;
+    }
+
+    DevicePathNode = NextDevicePathNode (DevicePathNode);
+  }
+  if (UfsDevice == NULL) {
+    RetVal = FALSE;
+    goto Done;
+  }
+
+  if (UfsDevice->Lun != UFS_WLUN_RPMB) {
+    RetVal = FALSE;
+  }
+
+Done:
+  return RetVal;
+}
+
 /**
   Provides inquiry information for the controller type.
 
-- 
2.16.2.windows.1


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.

View/Reply Online (#46241): https://edk2.groups.io/g/devel/message/46241
Mute This Topic: https://groups.io/mt/32994945/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub  [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to