public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Wu, Hao A" <hao.a.wu@intel.com>
To: "devel@edk2.groups.io" <devel@edk2.groups.io>,
	"Zurcher, Christopher J" <christopher.j.zurcher@intel.com>
Cc: "Kinney, Michael D" <michael.d.kinney@intel.com>,
	"Yao, Jiewen" <jiewen.yao@intel.com>,
	"Wang, Jian J" <jian.j.wang@intel.com>,
	"Gao, Liming" <liming.gao@intel.com>
Subject: Re: [edk2-devel] [PATCH v5 4/4] MdeModulePkg/ScsiDiskDxe: Support Storage Security Command Protocol
Date: Tue, 27 Aug 2019 03:03:18 +0000	[thread overview]
Message-ID: <B80AF82E9BFB8E4FBD8C89DA810C6A093C91DBE5@SHSMSX104.ccr.corp.intel.com> (raw)
In-Reply-To: <20190822220215.24536-5-christopher.j.zurcher@intel.com>

> -----Original Message-----
> From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf Of
> Zurcher, Christopher J
> Sent: Friday, August 23, 2019 6:02 AM
> To: devel@edk2.groups.io
> Cc: Kinney, Michael D; Yao, Jiewen; Wang, Jian J; Gao, Liming
> Subject: [edk2-devel] [PATCH v5 4/4] MdeModulePkg/ScsiDiskDxe: Support
> Storage Security Command Protocol
> 
> 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.


For suggested interface changes for UefiScsiLib APIs:
ScsiSecurityProtocolInCommand/ScsiSecurityProtocolOutCommand

If you agree those changes for UefiScsiLib APIs, please help to update functions
ScsiDiskReceiveData() and ScsiDiskSendData() accordingly. Thanks.

Apart from this, the patch looks good to me.

Best Regards,
Hao Wu


> 
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Jiewen Yao <jiewen.yao@intel.com>
> Cc: Jian J Wang <jian.j.wang@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Signed-off-by: Christopher J Zurcher <christopher.j.zurcher@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
> 
> 
> 


  reply	other threads:[~2019-08-27  3:03 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-08-22 22:02 [PATCH v5 0/4] Add SCSI Support for Storage Security Command Protocol Zurcher, Christopher J
2019-08-22 22:02 ` [PATCH v5 1/4] MdePkg: Implement SCSI commands for Security Protocol In/Out Zurcher, Christopher J
2019-08-27  3:03   ` [edk2-devel] " Wu, Hao A
2019-08-30  0:34     ` Zurcher, Christopher J
2019-08-30  5:17       ` Wu, Hao A
2019-08-30  9:14         ` Liming Gao
2019-09-02  1:10           ` Wu, Hao A
2019-09-02  1:46             ` Liming Gao
2019-09-02  2:01               ` Wu, Hao A
2019-08-22 22:02 ` [PATCH v5 2/4] MdeModulePkg/UfsPassThruDxe: Check for RPMB W-LUN (SecurityLun) Zurcher, Christopher J
2019-08-27  3:03   ` [edk2-devel] " Wu, Hao A
2019-08-22 22:02 ` [PATCH v5 3/4] MdeModulePkg/ScsiBusDxe: Clean up Peripheral Type check Zurcher, Christopher J
2019-08-27  3:03   ` [edk2-devel] " Wu, Hao A
2019-08-22 22:02 ` [PATCH v5 4/4] MdeModulePkg/ScsiDiskDxe: Support Storage Security Command Protocol Zurcher, Christopher J
2019-08-27  3:03   ` Wu, Hao A [this message]
2019-08-23  2:54 ` [edk2-devel] [PATCH v5 0/4] Add SCSI Support for " Wu, Hao A
2019-08-27  3:02 ` Wu, Hao A

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=B80AF82E9BFB8E4FBD8C89DA810C6A093C91DBE5@SHSMSX104.ccr.corp.intel.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox