From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=134.134.136.126; helo=mga18.intel.com; envelope-from=eric.dong@intel.com; receiver=edk2-devel@lists.01.org Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id AD537202E53AC for ; Sun, 17 Feb 2019 22:29:16 -0800 (PST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by orsmga106.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 17 Feb 2019 22:29:15 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.58,383,1544515200"; d="scan'208";a="321218926" Received: from fmsmsx108.amr.corp.intel.com ([10.18.124.206]) by fmsmga005.fm.intel.com with ESMTP; 17 Feb 2019 22:29:15 -0800 Received: from fmsmsx124.amr.corp.intel.com (10.18.125.39) by FMSMSX108.amr.corp.intel.com (10.18.124.206) with Microsoft SMTP Server (TLS) id 14.3.408.0; Sun, 17 Feb 2019 22:29:15 -0800 Received: from shsmsx106.ccr.corp.intel.com (10.239.4.159) by fmsmsx124.amr.corp.intel.com (10.18.125.39) with Microsoft SMTP Server (TLS) id 14.3.408.0; Sun, 17 Feb 2019 22:29:14 -0800 Received: from shsmsx102.ccr.corp.intel.com ([169.254.2.207]) by SHSMSX106.ccr.corp.intel.com ([169.254.10.174]) with mapi id 14.03.0415.000; Mon, 18 Feb 2019 14:29:12 +0800 From: "Dong, Eric" To: "Wu, Hao A" , "edk2-devel@lists.01.org" Thread-Topic: [PATCH v5 06/13] MdeModulePkg/NvmExpressPei: Add logic to produce SSC PPI Thread-Index: AQHUxPcJpIcbb115YE2g1yWZnc2Ku6Xk2rGg//+1lACAAIvewA== Date: Mon, 18 Feb 2019 06:29:11 +0000 Message-ID: References: <20190215062338.19412-1-hao.a.wu@intel.com> <20190215062338.19412-7-hao.a.wu@intel.com> In-Reply-To: Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.239.127.40] MIME-Version: 1.0 Subject: Re: [PATCH v5 06/13] MdeModulePkg/NvmExpressPei: Add logic to produce SSC PPI X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 18 Feb 2019 06:29:16 -0000 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Hi Hao, Got it. In this case, Reviewed-by: Eric Dong for 6,= 7,8 patches. Thanks, Eric > -----Original Message----- > From: Wu, Hao A > Sent: Monday, February 18, 2019 2:07 PM > To: Dong, Eric ; edk2-devel@lists.01.org > Cc: Wang, Jian J ; Ni, Ray > Subject: RE: [PATCH v5 06/13] MdeModulePkg/NvmExpressPei: Add logic to > produce SSC PPI >=20 > > -----Original Message----- > > From: Dong, Eric > > Sent: Monday, February 18, 2019 10:59 AM > > To: Wu, Hao A; edk2-devel@lists.01.org > > Cc: Wang, Jian J; Ni, Ray > > Subject: RE: [PATCH v5 06/13] MdeModulePkg/NvmExpressPei: Add logic > to > > produce SSC PPI > > > > Hi Hao, > > > > > -----Original Message----- > > > From: Wu, Hao A > > > Sent: Friday, February 15, 2019 2:24 PM > > > To: edk2-devel@lists.01.org > > > Cc: Wu, Hao A ; Wang, Jian J > > ; > > > Ni, Ray ; Dong, Eric > > > Subject: [PATCH v5 06/13] MdeModulePkg/NvmExpressPei: Add logic to > > > produce SSC PPI > > > > > > REF:https://bugzilla.tianocore.org/show_bug.cgi?id=3D1409 > > > > > > For the NvmExpressPei driver, this commit will add codes to produce t= he > > > Storage Security Command PPI if the underlying NVM Express controller > > > supports the Security Send and Security Receive commands. > > > > > > Cc: Jian J Wang > > > Cc: Ray Ni > > > Cc: Eric Dong > > > Contributed-under: TianoCore Contribution Agreement 1.1 > > > Signed-off-by: Hao Wu > > > --- > > > MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.inf | = 10 > > +- > > > MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.h | = 58 > > ++- > > > MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiHci.h | > 20 > > +- > > > > > > MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiStorageSecurity.h > > > | 247 ++++++++++++ > > > MdeModulePkg/Bus/Pci/NvmExpressPei/DevicePath.c | = 231 > > > +++++++++++ > > > MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.c | = 143 > > > +++++-- > > > MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiHci.c | > 32 > > +- > > > > > MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiStorageSecurity.c > > > | 423 ++++++++++++++++++++ > > > 8 files changed, 1075 insertions(+), 89 deletions(-) > > > > > > diff --git a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.inf > > > b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.inf > > > index 9591572fec..0666e5892b 100644 > > > --- a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.inf > > > +++ b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.inf > > > @@ -2,7 +2,7 @@ > > > # The NvmExpressPei driver is used to manage non-volatile memory > > > subsystem > > > # which follows NVM Express specification at PEI phase. > > > # > > > -# Copyright (c) 2018, Intel Corporation. All rights reserved.
> > > +# Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved= .
> > > # > > > # This program and the accompanying materials > > > # are licensed and made available under the terms and conditions of= the > > > BSD License > > > @@ -30,6 +30,7 @@ > > > # > > > > > > [Sources] > > > + DevicePath.c > > > DmaMem.c > > > NvmExpressPei.c > > > NvmExpressPei.h > > > @@ -39,6 +40,8 @@ > > > NvmExpressPeiHci.h > > > NvmExpressPeiPassThru.c > > > NvmExpressPeiPassThru.h > > > + NvmExpressPeiStorageSecurity.c > > > + NvmExpressPeiStorageSecurity.h > > > > > > [Packages] > > > MdePkg/MdePkg.dec > > > @@ -54,11 +57,12 @@ > > > PeimEntryPoint > > > > > > [Ppis] > > > - gEfiPeiVirtualBlockIoPpiGuid ## PRODUCES > > > - gEfiPeiVirtualBlockIo2PpiGuid ## PRODUCES > > > gEdkiiPeiNvmExpressHostControllerPpiGuid ## CONSUMES > > > gEdkiiIoMmuPpiGuid ## CONSUMES > > > gEfiEndOfPeiSignalPpiGuid ## CONSUMES > > > + gEfiPeiVirtualBlockIoPpiGuid ## SOMETIMES_PRODUC= ES > > > + gEfiPeiVirtualBlockIo2PpiGuid ## SOMETIMES_PRODUC= ES > > > + gEdkiiPeiStorageSecurityCommandPpiGuid ## > > > SOMETIMES_PRODUCES > > > > > > [Depex] > > > gEfiPeiMemoryDiscoveredPpiGuid AND > > > diff --git a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.h > > > b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.h > > > index 0135eca6f0..92c3854c6e 100644 > > > --- a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.h > > > +++ b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.h > > > @@ -25,6 +25,7 @@ > > > #include > > > #include > > > #include > > > +#include > > > #include > > > #include > > > > > > @@ -44,6 +45,7 @@ typedef struct > > > _PEI_NVME_CONTROLLER_PRIVATE_DATA > > > PEI_NVME_CONTROLLER_PRIVATE_DA > > > #include "NvmExpressPeiHci.h" > > > #include "NvmExpressPeiPassThru.h" > > > #include "NvmExpressPeiBlockIo.h" > > > +#include "NvmExpressPeiStorageSecurity.h" > > > > > > // > > > // NVME PEI driver implementation related definitions > > > @@ -90,10 +92,15 @@ struct _PEI_NVME_NAMESPACE_INFO { > > > struct _PEI_NVME_CONTROLLER_PRIVATE_DATA { > > > UINT32 Signature; > > > UINTN MmioBase; > > > + UINTN DevicePathLength; > > > + EFI_DEVICE_PATH_PROTOCOL *DevicePath; > > > + > > > EFI_PEI_RECOVERY_BLOCK_IO_PPI BlkIoPpi; > > > EFI_PEI_RECOVERY_BLOCK_IO2_PPI BlkIo2Ppi; > > > + EDKII_PEI_STORAGE_SECURITY_CMD_PPI StorageSecurityPpi; > > > EFI_PEI_PPI_DESCRIPTOR BlkIoPpiList; > > > EFI_PEI_PPI_DESCRIPTOR BlkIo2PpiList; > > > + EFI_PEI_PPI_DESCRIPTOR StorageSecurityPpiList; > > > EFI_PEI_NOTIFY_DESCRIPTOR EndOfPeiNotifyList; > > > > > > // > > > @@ -139,11 +146,13 @@ struct > _PEI_NVME_CONTROLLER_PRIVATE_DATA > > { > > > PEI_NVME_NAMESPACE_INFO *NamespaceInfo; > > > }; > > > > > > -#define GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_BLKIO(a) > \ > > > +#define GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_BLKIO(a) > > > \ > > > CR (a, PEI_NVME_CONTROLLER_PRIVATE_DATA, BlkIoPpi, > > > NVME_PEI_CONTROLLER_PRIVATE_DATA_SIGNATURE) > > > -#define GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_BLKIO2(a) > > \ > > > +#define GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_BLKIO2(a) > > > \ > > > CR (a, PEI_NVME_CONTROLLER_PRIVATE_DATA, BlkIo2Ppi, > > > NVME_PEI_CONTROLLER_PRIVATE_DATA_SIGNATURE) > > > -#define GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_NOTIFY(a) > > \ > > > +#define > > > > > > GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_STROAGE_SECURITY(a) > > > \ > > > + CR (a, PEI_NVME_CONTROLLER_PRIVATE_DATA, StorageSecurityPpi, > > > NVME_PEI_CONTROLLER_PRIVATE_DATA_SIGNATURE) > > > +#define GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_NOTIFY(a) > > > \ > > > CR (a, PEI_NVME_CONTROLLER_PRIVATE_DATA, EndOfPeiNotifyList, > > > NVME_PEI_CONTROLLER_PRIVATE_DATA_SIGNATURE) > > > > > > > > > @@ -257,4 +266,47 @@ NvmePeimEndOfPei ( > > > IN VOID *Ppi > > > ); > > > > > > +/** > > > + Check the validity of the device path of a NVM Express host contro= ller. > > > + > > > + @param[in] DevicePath A pointer to the > > > EFI_DEVICE_PATH_PROTOCOL > > > + structure. > > > + @param[in] DevicePathLength The length of the device path. > > > + > > > + @retval EFI_SUCCESS The device path is valid. > > > + @retval EFI_INVALID_PARAMETER The device path is invalid. > > > + > > > +**/ > > > +EFI_STATUS > > > +NvmeCheckHcDevicePath ( > > > + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, > > > + IN UINTN DevicePathLength > > > + ); > > > + > > > +/** > > > + Build the device path for an Nvm Express device with given namespa= ce > > > identifier > > > + and namespace extended unique identifier. > > > + > > > + @param[in] Private A pointer to the > > > PEI_NVME_CONTROLLER_PRIVATE_DATA > > > + data structure. > > > + @param[in] NamespaceId The given namespace identifier. > > > + @param[in] NamespaceUuid The given namespace extended > unique > > > identifier. > > > + @param[out] DevicePathLength The length of the device path in > bytes > > > specified > > > + by DevicePath. > > > + @param[out] DevicePath The device path of Nvm Express de= vice. > > > + > > > + @retval EFI_SUCCESS The operation succeeds. > > > + @retval EFI_INVALID_PARAMETER The parameters are invalid. > > > + @retval EFI_OUT_OF_RESOURCES The operation fails due to lack o= f > > > resources. > > > + > > > +**/ > > > +EFI_STATUS > > > +NvmeBuildDevicePath ( > > > + IN PEI_NVME_CONTROLLER_PRIVATE_DATA *Private, > > > + IN UINT32 NamespaceId, > > > + IN UINT64 NamespaceUuid, > > > + OUT UINTN *DevicePathLength, > > > + OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath > > > + ); > > > + > > > #endif > > > diff --git a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiHci.h > > > b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiHci.h > > > index ff334e3e17..ad1d5d0d8a 100644 > > > --- a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiHci.h > > > +++ b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiHci.h > > > @@ -2,7 +2,7 @@ > > > The NvmExpressPei driver is used to manage non-volatile memory > > > subsystem > > > which follows NVM Express specification at PEI phase. > > > > > > - Copyright (c) 2018, Intel Corporation. All rights reserved.
> > > + Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.=
> > > > > > This program and the accompanying materials > > > are licensed and made available under the terms and conditions > > > @@ -107,20 +107,6 @@ NvmeBaseMemPageOffset ( > > > ); > > > > > > /** > > > - Disable the Nvm Express controller. > > > - > > > - @param[in] Private The pointer to the > > > PEI_NVME_CONTROLLER_PRIVATE_DATA data structure. > > > - > > > - @return EFI_SUCCESS Successfully disable the controller. > > > - @return others Fail to disable the controller. > > > - > > > -**/ > > > -EFI_STATUS > > > -NvmeDisableController ( > > > - IN PEI_NVME_CONTROLLER_PRIVATE_DATA *Private > > > - ); > > > - > > > -/** > > > Initialize the Nvm Express controller. > > > > > > @param[in] Private The pointer to the > > > PEI_NVME_CONTROLLER_PRIVATE_DATA data structure. > > > @@ -153,13 +139,13 @@ NvmeIdentifyNamespace ( > > > ); > > > > > > /** > > > - Free the resources allocated by an NVME controller. > > > + Free the DMA resources allocated by an NVME controller. > > > > > > @param[in] Private The pointer to the > > > PEI_NVME_CONTROLLER_PRIVATE_DATA data structure. > > > > > > **/ > > > VOID > > > -NvmeFreeControllerResource ( > > > +NvmeFreeDmaResource ( > > > IN PEI_NVME_CONTROLLER_PRIVATE_DATA *Private > > > ); > > > > > > diff --git > > > > > > a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiStorageSecurity. > > > h > > > > > > b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiStorageSecurity. > > > h > > > new file mode 100644 > > > index 0000000000..8ccfb425e7 > > > --- /dev/null > > > +++ > > > > > > b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiStorageSecurity. > > > h > > > @@ -0,0 +1,247 @@ > > > +/** @file > > > + The NvmExpressPei driver is used to manage non-volatile memory > > > subsystem > > > + which follows NVM Express specification at PEI phase. > > > + > > > + Copyright (c) 2019, Intel Corporation. All rights reserved.
> > > + > > > + This program and the accompanying materials > > > + are licensed and made available under the terms and conditions > > > + of the BSD License which accompanies this distribution. The > > > + full text of the license may be found at > > > + http://opensource.org/licenses/bsd-license.php > > > + > > > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > > > BASIS, > > > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > > > EXPRESS OR IMPLIED. > > > + > > > +**/ > > > + > > > +#ifndef _NVM_EXPRESS_PEI_STORAGE_SECURITY_H_ > > > +#define _NVM_EXPRESS_PEI_STORAGE_SECURITY_H_ > > > + > > > +/** > > > + Gets the count of storage security devices that one specific drive= r > > detects. > > > + > > > + @param[in] This The PPI instance pointer. > > > + @param[out] NumberofDevices The number of storage security > > devices > > > discovered. > > > + > > > + @retval EFI_SUCCESS The operation performed successfu= lly. > > > + @retval EFI_INVALID_PARAMETER The parameters are invalid. > > > + > > > +**/ > > > +EFI_STATUS > > > +EFIAPI > > > +NvmeStorageSecurityGetDeviceNo ( > > > + IN EDKII_PEI_STORAGE_SECURITY_CMD_PPI *This, > > > + OUT UINTN *NumberofDevices > > > + ); > > > + > > > +/** > > > + Gets the device path of a specific storage security device. > > > + > > > + @param[in] This The PPI instance pointer. > > > + @param[in] DeviceIndex Specifies the storage security de= vice to > > > which > > > + the function wants to talk. Becau= se the driver > > > + that implements Storage Security = Command PPIs > > > + will manage multiple storage devi= ces, the PPIs > > > + that want to talk to a single dev= ice must specify > > > + the device index that was assigne= d during the > > > + enumeration process. This index i= s a number from > > > + one to NumberofDevices. > > > + @param[out] DevicePathLength The length of the device path in > bytes > > > specified > > > + by DevicePath. > > > + @param[out] DevicePath The device path of storage securi= ty > device. > > > + This field re-uses EFI Device Pat= h Protocol as > > > + defined by Section 10.2 EFI Devic= e Path Protocol > > > + of UEFI 2.7 Specification. > > > + > > > + @retval EFI_SUCCESS The operation succeeds. > > > + @retval EFI_INVALID_PARAMETER DevicePathLength or DevicePath > is > > > NULL. > > > + @retval EFI_NOT_FOUND The specified storage security de= vice > not > > > found. > > > + @retval EFI_OUT_OF_RESOURCES The operation fails due to lack o= f > > > resources. > > > + > > > +**/ > > > +EFI_STATUS > > > +EFIAPI > > > +NvmeStorageSecurityGetDevicePath ( > > > + IN EDKII_PEI_STORAGE_SECURITY_CMD_PPI *This, > > > + IN UINTN DeviceIndex, > > > + OUT UINTN *DevicePathLength, > > > + OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath > > > + ); > > > + > > > +/** > > > + 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 > > > DeviceIndex. > > > + The security protocol command sent is defined by SecurityProtocolI= d > and > > > contains > > > + the security protocol specific data SecurityProtocolSpecificData. = The > > > function > > > + returns the data from the security protocol command in PayloadBuff= er. > > > + > > > + For devices supporting the SCSI command set, the security protocol > > > command is sent > > > + using the SECURITY PROTOCOL IN command defined in SPC-4. > > > + > > > + For devices supporting the ATA command set, the security protocol > > > command is sent > > > + using one of the TRUSTED RECEIVE commands defined in ATA8-ACS if > > > PayloadBufferSize > > > + is non-zero. > > > + > > > + If the PayloadBufferSize is zero, the security protocol command is= sent > > > using the > > > + Trusted Non-Data command defined in ATA8-ACS. > > > + > > > + 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 PayloadBufferS= ize > is > > > non-zero, > > > + the function shall return EFI_INVALID_PARAMETER. > > > + > > > + If the given DeviceIndex does not support security protocol comman= ds, > > > the function > > > + shall return EFI_UNSUPPORTED. > > > + > > > + If the security protocol fails to complete within the Timeout peri= od, 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 wit= h > > an > > > error, the > > > + function shall return EFI_DEVICE_ERROR. > > > + > > > + @param[in] This The PPI instance pointer. > > > + @param[in] DeviceIndex Specifies the storage security device= to > > which > > > the > > > + function wants to talk. Because the d= river that > > > + implements Storage Security Command P= PIs will manage > > > + multiple storage devices, the PPIs th= at want to talk > > > + to a single device must specify the d= evice index > > > + that was assigned during the enumerat= ion process. > > > + This index is a number from one to Nu= mberofDevices. > > > + @param[in] Timeout The timeout, in 100ns units, to use f= or the > > > execution > > > + of the security protocol command. A T= imeout value > > > + of 0 means that this function will wa= it indefinitely > > > + for the security protocol command to = execute. If > > > + Timeout is greater than zero, then th= is function > > > + will return EFI_TIMEOUT if the time r= equired to > > > + execute the receive data command is g= reater than > > > + Timeout. > > > + @param[in] SecurityProtocolId > > > + The value of the "Security Protocol" = parameter of > > > + the security protocol command to be s= ent. > > > + @param[in] SecurityProtocolSpecificData > > > + The value of the "Security Protocol S= pecific" > > > + parameter of the security protocol co= mmand to be > > > + sent. > > > + @param[in] PayloadBufferSize > > > + Size in bytes of the payload data buf= fer. > > > + @param[out] PayloadBuffer A pointer to a destination buffer to = store > > > the > > > + security protocol command specific pa= yload data > > > + for the security protocol command. Th= e caller is > > > + responsible for having either implici= t or explicit > > > + ownership of the buffer. > > > + @param[out] PayloadTransferSize > > > + A pointer to a buffer to store the si= ze in bytes > > > + of the data written to the payload da= ta 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 th= e truncated > > > + data. > > > + @retval EFI_UNSUPPORTED The given DeviceIndex does no= t > > > support > > > + security protocol commands. > > > + @retval EFI_DEVICE_ERROR The security protocol command > > > completed > > > + with an error. > > > + @retval EFI_INVALID_PARAMETER The PayloadBuffer or > > > PayloadTransferSize > > > + is NULL and PayloadBufferSize= is non-zero. > > > + @retval EFI_TIMEOUT A timeout occurred while wait= ing for > the > > > + security protocol command to = execute. > > > + > > > +**/ > > > +EFI_STATUS > > > +EFIAPI > > > +NvmeStorageSecurityReceiveData ( > > > + IN EDKII_PEI_STORAGE_SECURITY_CMD_PPI *This, > > > + IN UINTN DeviceIndex, > > > + IN UINT64 Timeout, > > > + IN UINT8 SecurityProtocolId, > > > + IN UINT16 SecurityProtocolSpecificDa= ta, > > > + 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 DeviceIndex. 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 sh= all > > > 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. > > > + > > > + For devices supporting the ATA command set, the security protocol > > > command is > > > + sent using one of the TRUSTED SEND commands defined in ATA8-ACS if > > > PayloadBufferSize > > > + is non-zero. If the PayloadBufferSize is zero, the security protoc= ol > > > command > > > + is sent using the Trusted Non-Data command defined in ATA8-ACS. > > > + > > > + If PayloadBuffer is NULL and PayloadBufferSize is non-zero, the > function > > > shall > > > + return EFI_INVALID_PARAMETER. > > > + > > > + If the given DeviceIndex does not support security protocol comman= ds, > > > the function > > > + shall return EFI_UNSUPPORTED. > > > + > > > + If the security protocol fails to complete within the Timeout peri= od, 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 wit= h > > an > > > error, > > > + the functio shall return EFI_DEVICE_ERROR. > > > + > > > + @param[in] This The PPI instance pointer. > > > + @param[in] DeviceIndex The ID of the device. > > > + @param[in] Timeout The timeout, in 100ns units, to use f= or the > > > execution > > > + of the security protocol command. A T= imeout value > > > + of 0 means that this function will wa= it indefinitely > > > + for the security protocol command to = execute. If > > > + Timeout is greater than zero, then th= is function > > > + will return EFI_TIMEOUT if the time r= equired to > > > + execute the receive data command is g= reater than > > > + Timeout. > > > + @param[in] SecurityProtocolId > > > + The value of the "Security Protocol" = parameter of > > > + the security protocol command to be s= ent. > > > + @param[in] SecurityProtocolSpecificData > > > + The value of the "Security Protocol S= pecific" > > > + parameter of the security protocol co= mmand to be > > > + sent. > > > + @param[in] PayloadBufferSize Size in bytes of the payload data buf= fer. > > > + @param[in] PayloadBuffer A pointer to a destination buffer to = store > > the > > > + security protocol command specific pa= yload data > > > + for the security protocol command. > > > + > > > + @retval EFI_SUCCESS The security protocol command com= pleted > > > successfully. > > > + @retval EFI_UNSUPPORTED The given DeviceIndex does not > > support > > > security > > > + protocol commands. > > > + @retval EFI_DEVICE_ERROR The security protocol command > > > completed with > > > + an error. > > > + @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 > > > +NvmeStorageSecuritySendData ( > > > + IN EDKII_PEI_STORAGE_SECURITY_CMD_PPI *This, > > > + IN UINTN DeviceIndex, > > > + IN UINT64 Timeout, > > > + IN UINT8 SecurityProtocolId, > > > + IN UINT16 SecurityProtocolSpecificDat= a, > > > + IN UINTN PayloadBufferSize, > > > + IN VOID *PayloadBuffer > > > + ); > > > + > > > +#endif > > > diff --git a/MdeModulePkg/Bus/Pci/NvmExpressPei/DevicePath.c > > > b/MdeModulePkg/Bus/Pci/NvmExpressPei/DevicePath.c > > > new file mode 100644 > > > index 0000000000..5dab447f09 > > > --- /dev/null > > > +++ b/MdeModulePkg/Bus/Pci/NvmExpressPei/DevicePath.c > > > @@ -0,0 +1,231 @@ > > > +/** @file > > > + The device path help function. > > > + > > > + Copyright (c) 2019, Intel Corporation. All rights reserved.
> > > + > > > + This program and the accompanying materials > > > + are licensed and made available under the terms and conditions > > > + of the BSD License which accompanies this distribution. The > > > + full text of the license may be found at > > > + http://opensource.org/licenses/bsd-license.php > > > + > > > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > > > BASIS, > > > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > > > EXPRESS OR IMPLIED. > > > + > > > +**/ > > > + > > > +#include "NvmExpressPei.h" > > > + > > > +// > > > +// Template for an Nvm Express Device Path node > > > +// > > > +NVME_NAMESPACE_DEVICE_PATH mNvmeDevicePathNodeTemplate > =3D > > { > > > + { // Header > > > + MESSAGING_DEVICE_PATH, > > > + MSG_NVME_NAMESPACE_DP, > > > + { > > > + (UINT8) (sizeof (NVME_NAMESPACE_DEVICE_PATH)), > > > + (UINT8) ((sizeof (NVME_NAMESPACE_DEVICE_PATH)) >> 8) > > > + } > > > + }, > > > + 0x0, // NamespaceId > > > + 0x0 // NamespaceUuid > > > +}; > > > + > > > +// > > > +// Template for an End of entire Device Path node > > > +// > > > +EFI_DEVICE_PATH_PROTOCOL mNvmeEndDevicePathNodeTemplate =3D > { > > > + END_DEVICE_PATH_TYPE, > > > + END_ENTIRE_DEVICE_PATH_SUBTYPE, > > > + { > > > + (UINT8) (sizeof (EFI_DEVICE_PATH_PROTOCOL)), > > > + (UINT8) ((sizeof (EFI_DEVICE_PATH_PROTOCOL)) >> 8) > > > + } > > > +}; > > > + > > > +/** > > > + Returns the 16-bit Length field of a device path node. > > > + > > > + Returns the 16-bit Length field of the device path node specified = by > > Node. > > > + Node is not required to be aligned on a 16-bit boundary, so it is > > > recommended > > > + that a function such as ReadUnaligned16() be used to extract the > > contents > > > of > > > + the Length field. > > > + > > > + If Node is NULL, then ASSERT(). > > > + > > > + @param Node A pointer to a device path node data structure. > > > + > > > + @return The 16-bit Length field of the device path node specified = by > > Node. > > > + > > > +**/ > > > +UINTN > > > +DevicePathNodeLength ( > > > + IN CONST VOID *Node > > > + ) > > > +{ > > > + ASSERT (Node !=3D NULL); > > > + return ReadUnaligned16 ((UINT16 *)&((EFI_DEVICE_PATH_PROTOCOL > > > *)(Node))->Length[0]); > > > +} > > > > 1. DevicePathLib has same API, can leverage that API. >=20 > Hi Eric, >=20 > Actually, Ray had similar comments as well. For the comments on patch > 06/13 & 07/13, the reason I choose to add driver internal implementation > of those functions are: >=20 > 1. I found that the DevicePathLib instances will consume the Boot Service= s > Table (e.g. try to get the 'Handle' of a device path), which is not avail= able > in the PEI phase. >=20 > 2. There are some differences between the driver-internal implementation > and the library implementation. Within the driver, some memory allocation > operations are optimized away according to no actual needs. >=20 > Best Regards, > Hao Wu >=20 > > > > > + > > > +/** > > > + Returns a pointer to the next node in a device path. > > > + > > > + If Node is NULL, then ASSERT(). > > > + > > > + @param Node A pointer to a device path node data structure. > > > + > > > + @return a pointer to the device path node that follows the device = path > > > node > > > + specified by Node. > > > + > > > +**/ > > > +EFI_DEVICE_PATH_PROTOCOL * > > > +NextDevicePathNode ( > > > + IN CONST VOID *Node > > > + ) > > > +{ > > > + ASSERT (Node !=3D NULL); > > > + return (EFI_DEVICE_PATH_PROTOCOL *)((UINT8 *)(Node) + > > > DevicePathNodeLength(Node)); > > > +} > > > > 2. DevicePathLib has same API, can leverage that API. > > > > > + > > > +/** > > > + Check the validity of the device path of a NVM Express host contro= ller. > > > + > > > + @param[in] DevicePath A pointer to the > > > EFI_DEVICE_PATH_PROTOCOL > > > + structure. > > > + @param[in] DevicePathLength The length of the device path. > > > + > > > + @retval EFI_SUCCESS The device path is valid. > > > + @retval EFI_INVALID_PARAMETER The device path is invalid. > > > + > > > +**/ > > > +EFI_STATUS > > > +NvmeCheckHcDevicePath ( > > > + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, > > > + IN UINTN DevicePathLength > > > + ) > > > +{ > > > + EFI_DEVICE_PATH_PROTOCOL *Start; > > > + UINTN Size; > > > + > > > + if (DevicePath =3D=3D NULL) { > > > + return EFI_INVALID_PARAMETER; > > > + } > > > + > > > + // > > > + // Validate the DevicePathLength is big enough to touch the first = node. > > > + // > > > + if (DevicePathLength < sizeof (EFI_DEVICE_PATH_PROTOCOL)) { > > > + return EFI_INVALID_PARAMETER; > > > + } > > > + > > > + Start =3D DevicePath; > > > + while (!(DevicePath->Type =3D=3D END_DEVICE_PATH_TYPE && > > > + DevicePath->SubType =3D=3D END_ENTIRE_DEVICE_PATH_SUBTYPE= )) { > > > + DevicePath =3D NextDevicePathNode (DevicePath); > > > + > > > + // > > > + // Prevent overflow and invalid zero in the 'Length' field of a = device > path > > > + // node. > > > + // > > > + if ((UINTN) DevicePath <=3D (UINTN) Start) { > > > + return EFI_INVALID_PARAMETER; > > > + } > > > + > > > + // > > > + // Prevent touching memory beyond given DevicePathLength. > > > + // > > > + if ((UINTN) DevicePath - (UINTN) Start > > > > + DevicePathLength - sizeof (EFI_DEVICE_PATH_PROTOCOL)) { > > > + return EFI_INVALID_PARAMETER; > > > + } > > > + } > > > + > > > + // > > > + // Check if the device path and its size match exactly with each o= ther. > > > + // > > > + Size =3D ((UINTN) DevicePath - (UINTN) Start) + sizeof > > > (EFI_DEVICE_PATH_PROTOCOL); > > > + if (Size !=3D DevicePathLength) { > > > + return EFI_INVALID_PARAMETER; > > > + } > > > + > > > + return EFI_SUCCESS; > > > +} > > > > 3. Seems like this function just do validation for the input device pat= h. > > UefiDevicePathLib has IsDevicePathValid API, can we leverage that > function? > > > > Thanks, > > Eric > > > + > > > +/** > > > + Build the device path for an Nvm Express device with given namespa= ce > > > identifier > > > + and namespace extended unique identifier. > > > + > > > + @param[in] Private A pointer to the > > > PEI_NVME_CONTROLLER_PRIVATE_DATA > > > + data structure. > > > + @param[in] NamespaceId The given namespace identifier. > > > + @param[in] NamespaceUuid The given namespace extended > unique > > > identifier. > > > + @param[out] DevicePathLength The length of the device path in > bytes > > > specified > > > + by DevicePath. > > > + @param[out] DevicePath The device path of Nvm Express de= vice. > > > + > > > + @retval EFI_SUCCESS The operation succeeds. > > > + @retval EFI_INVALID_PARAMETER The parameters are invalid. > > > + @retval EFI_OUT_OF_RESOURCES The operation fails due to lack o= f > > > resources. > > > + > > > +**/ > > > +EFI_STATUS > > > +NvmeBuildDevicePath ( > > > + IN PEI_NVME_CONTROLLER_PRIVATE_DATA *Private, > > > + IN UINT32 NamespaceId, > > > + IN UINT64 NamespaceUuid, > > > + OUT UINTN *DevicePathLength, > > > + OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath > > > + ) > > > +{ > > > + EFI_DEVICE_PATH_PROTOCOL *DevicePathWalker; > > > + NVME_NAMESPACE_DEVICE_PATH *NvmeDeviceNode; > > > + > > > + if (DevicePathLength =3D=3D NULL || DevicePath =3D=3D NULL) { > > > + return EFI_INVALID_PARAMETER; > > > + } > > > + > > > + *DevicePathLength =3D Private->DevicePathLength + sizeof > > > (NVME_NAMESPACE_DEVICE_PATH); > > > + *DevicePath =3D AllocatePool (*DevicePathLength); > > > + if (*DevicePath =3D=3D NULL) { > > > + *DevicePathLength =3D 0; > > > + return EFI_OUT_OF_RESOURCES; > > > + } > > > + > > > + // > > > + // Construct the host controller part device nodes > > > + // > > > + DevicePathWalker =3D *DevicePath; > > > + CopyMem ( > > > + DevicePathWalker, > > > + Private->DevicePath, > > > + Private->DevicePathLength - sizeof (EFI_DEVICE_PATH_PROTOCOL) > > > + ); > > > + > > > + // > > > + // Construct the Nvm Express device node > > > + // > > > + DevicePathWalker =3D (EFI_DEVICE_PATH_PROTOCOL *) ((UINT8 > > > *)DevicePathWalker + > > > + (Private->DevicePathLength - sizeof > > > (EFI_DEVICE_PATH_PROTOCOL))); > > > + CopyMem ( > > > + DevicePathWalker, > > > + &mNvmeDevicePathNodeTemplate, > > > + sizeof (mNvmeDevicePathNodeTemplate) > > > + ); > > > + NvmeDeviceNode =3D (NVME_NAMESPACE_DEVICE_PATH > > > *)DevicePathWalker; > > > + NvmeDeviceNode->NamespaceId =3D NamespaceId; > > > + NvmeDeviceNode->NamespaceUuid =3D NamespaceUuid; > > > + > > > + // > > > + // Construct the end device node > > > + // > > > + DevicePathWalker =3D (EFI_DEVICE_PATH_PROTOCOL *) ((UINT8 > > > *)DevicePathWalker + > > > + sizeof (NVME_NAMESPACE_DEVICE_PATH)); > > > + CopyMem ( > > > + DevicePathWalker, > > > + &mNvmeEndDevicePathNodeTemplate, > > > + sizeof (mNvmeEndDevicePathNodeTemplate) > > > + ); > > > + > > > + return EFI_SUCCESS; > > > +} > > > diff --git a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.c > > > b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.c > > > index 2fe73e942c..96622e6fd5 100644 > > > --- a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.c > > > +++ b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPei.c > > > @@ -24,11 +24,17 @@ EFI_PEI_PPI_DESCRIPTOR > > > mNvmeBlkIoPpiListTemplate =3D { > > > }; > > > > > > EFI_PEI_PPI_DESCRIPTOR mNvmeBlkIo2PpiListTemplate =3D { > > > - EFI_PEI_PPI_DESCRIPTOR_PPI | > > > EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, > > > + (EFI_PEI_PPI_DESCRIPTOR_PPI | > > > EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), > > > &gEfiPeiVirtualBlockIo2PpiGuid, > > > NULL > > > }; > > > > > > +EFI_PEI_PPI_DESCRIPTOR mNvmeStorageSecurityPpiListTemplate =3D { > > > + (EFI_PEI_PPI_DESCRIPTOR_PPI | > > > EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), > > > + &gEdkiiPeiStorageSecurityCommandPpiGuid, > > > + NULL > > > +}; > > > + > > > EFI_PEI_NOTIFY_DESCRIPTOR mNvmeEndOfPeiNotifyListTemplate =3D { > > > (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | > > > EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), > > > &gEfiEndOfPeiSignalPpiGuid, > > > @@ -185,8 +191,7 @@ NvmePeimEndOfPei ( > > > PEI_NVME_CONTROLLER_PRIVATE_DATA *Private; > > > > > > Private =3D GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_NOTIFY > > > (NotifyDescriptor); > > > - NvmeDisableController (Private); > > > - NvmeFreeControllerResource (Private); > > > + NvmeFreeDmaResource (Private); > > > > > > return EFI_SUCCESS; > > > } > > > @@ -211,9 +216,13 @@ NvmExpressPeimEntry ( > > > EDKII_NVM_EXPRESS_HOST_CONTROLLER_PPI *NvmeHcPpi; > > > UINT8 Controller; > > > UINTN MmioBase; > > > + UINTN DevicePathLength; > > > + EFI_DEVICE_PATH_PROTOCOL *DevicePath; > > > PEI_NVME_CONTROLLER_PRIVATE_DATA *Private; > > > EFI_PHYSICAL_ADDRESS DeviceAddress; > > > > > > + DEBUG ((DEBUG_INFO, "%a: Enters.\n", __FUNCTION__)); > > > + > > > // > > > // Locate the NVME host controller PPI > > > // > > > @@ -243,16 +252,41 @@ NvmExpressPeimEntry ( > > > break; > > > } > > > > > > + Status =3D NvmeHcPpi->GetNvmeHcDevicePath ( > > > + NvmeHcPpi, > > > + Controller, > > > + &DevicePathLength, > > > + &DevicePath > > > + ); > > > + if (EFI_ERROR (Status)) { > > > + DEBUG (( > > > + DEBUG_ERROR, "%a: Fail to allocate get the device path for > > > Controller %d.\n", > > > + __FUNCTION__, Controller > > > + )); > > > + return Status; > > > + } > > > + > > > + // > > > + // Check validity of the device path of the NVM Express controll= er. > > > + // > > > + Status =3D NvmeCheckHcDevicePath (DevicePath, DevicePathLength); > > > + if (EFI_ERROR (Status)) { > > > + DEBUG (( > > > + DEBUG_ERROR, "%a: The device path is invalid for Controller = %d.\n", > > > + __FUNCTION__, Controller > > > + )); > > > + Controller++; > > > + continue; > > > + } > > > + > > > // > > > // Memory allocation for controller private data > > > // > > > Private =3D AllocateZeroPool (sizeof > > > (PEI_NVME_CONTROLLER_PRIVATE_DATA)); > > > if (Private =3D=3D NULL) { > > > DEBUG (( > > > - DEBUG_ERROR, > > > - "%a: Fail to allocate private data for Controller %d.\n", > > > - __FUNCTION__, > > > - Controller > > > + DEBUG_ERROR, "%a: Fail to allocate private data for > Controller %d.\n", > > > + __FUNCTION__, Controller > > > )); > > > return EFI_OUT_OF_RESOURCES; > > > } > > > @@ -268,12 +302,9 @@ NvmExpressPeimEntry ( > > > ); > > > if (EFI_ERROR (Status)) { > > > DEBUG (( > > > - DEBUG_ERROR, > > > - "%a: Fail to allocate DMA buffers for Controller %d.\n", > > > - __FUNCTION__, > > > - Controller > > > + DEBUG_ERROR, "%a: Fail to allocate DMA buffers for > > Controller %d.\n", > > > + __FUNCTION__, Controller > > > )); > > > - NvmeFreeControllerResource (Private); > > > return Status; > > > } > > > ASSERT (DeviceAddress =3D=3D ((EFI_PHYSICAL_ADDRESS) (UINTN) > Private- > > > >Buffer)); > > > @@ -282,20 +313,10 @@ NvmExpressPeimEntry ( > > > // > > > // Initialize controller private data > > > // > > > - Private->Signature =3D > > > NVME_PEI_CONTROLLER_PRIVATE_DATA_SIGNATURE; > > > - Private->MmioBase =3D MmioBase; > > > - Private->BlkIoPpi.GetNumberOfBlockDevices =3D > > > NvmeBlockIoPeimGetDeviceNo; > > > - Private->BlkIoPpi.GetBlockDeviceMediaInfo =3D > > > NvmeBlockIoPeimGetMediaInfo; > > > - Private->BlkIoPpi.ReadBlocks =3D NvmeBlockIoPeimRe= adBlocks; > > > - Private->BlkIo2Ppi.Revision =3D > > > EFI_PEI_RECOVERY_BLOCK_IO2_PPI_REVISION; > > > - Private->BlkIo2Ppi.GetNumberOfBlockDevices =3D > > > NvmeBlockIoPeimGetDeviceNo2; > > > - Private->BlkIo2Ppi.GetBlockDeviceMediaInfo =3D > > > NvmeBlockIoPeimGetMediaInfo2; > > > - Private->BlkIo2Ppi.ReadBlocks =3D NvmeBlockIoPeimRe= adBlocks2; > > > - CopyMem (&Private->BlkIoPpiList, &mNvmeBlkIoPpiListTemplate, > > sizeof > > > (EFI_PEI_PPI_DESCRIPTOR)); > > > - CopyMem (&Private->BlkIo2PpiList, &mNvmeBlkIo2PpiListTemplate, > > > sizeof (EFI_PEI_PPI_DESCRIPTOR)); > > > - CopyMem (&Private->EndOfPeiNotifyList, > > > &mNvmeEndOfPeiNotifyListTemplate, sizeof > > > (EFI_PEI_NOTIFY_DESCRIPTOR)); > > > - Private->BlkIoPpiList.Ppi =3D &Private->BlkIoPpi; > > > - Private->BlkIo2PpiList.Ppi =3D &Private->BlkIo2Ppi; > > > + Private->Signature =3D > > > NVME_PEI_CONTROLLER_PRIVATE_DATA_SIGNATURE; > > > + Private->MmioBase =3D MmioBase; > > > + Private->DevicePathLength =3D DevicePathLength; > > > + Private->DevicePath =3D DevicePath; > > > > > > // > > > // Initialize the NVME controller > > > @@ -305,11 +326,9 @@ NvmExpressPeimEntry ( > > > DEBUG (( > > > DEBUG_ERROR, > > > "%a: Controller initialization fail for Controller %d with S= tatus - %r.\n", > > > - __FUNCTION__, > > > - Controller, > > > - Status > > > + __FUNCTION__, Controller, Status > > > )); > > > - NvmeFreeControllerResource (Private); > > > + NvmeFreeDmaResource (Private); > > > Controller++; > > > continue; > > > } > > > @@ -325,22 +344,68 @@ NvmExpressPeimEntry ( > > > DEBUG (( > > > DEBUG_ERROR, > > > "%a: Namespaces discovery fail for Controller %d with Status= - %r.\n", > > > - __FUNCTION__, > > > - Controller, > > > - Status > > > + __FUNCTION__, Controller, Status > > > )); > > > - NvmeFreeControllerResource (Private); > > > + NvmeFreeDmaResource (Private); > > > Controller++; > > > continue; > > > } > > > > > > + Private->BlkIoPpi.GetNumberOfBlockDevices =3D > > > NvmeBlockIoPeimGetDeviceNo; > > > + Private->BlkIoPpi.GetBlockDeviceMediaInfo =3D > > > NvmeBlockIoPeimGetMediaInfo; > > > + Private->BlkIoPpi.ReadBlocks =3D NvmeBlockIoPeimRe= adBlocks; > > > + CopyMem ( > > > + &Private->BlkIoPpiList, > > > + &mNvmeBlkIoPpiListTemplate, > > > + sizeof (EFI_PEI_PPI_DESCRIPTOR) > > > + ); > > > + Private->BlkIoPpiList.Ppi =3D &Private->BlkIoPp= i; > > > + > > > + Private->BlkIo2Ppi.Revision =3D > > > EFI_PEI_RECOVERY_BLOCK_IO2_PPI_REVISION; > > > + Private->BlkIo2Ppi.GetNumberOfBlockDevices =3D > > > NvmeBlockIoPeimGetDeviceNo2; > > > + Private->BlkIo2Ppi.GetBlockDeviceMediaInfo =3D > > > NvmeBlockIoPeimGetMediaInfo2; > > > + Private->BlkIo2Ppi.ReadBlocks =3D NvmeBlockIoPeimRe= adBlocks2; > > > + CopyMem ( > > > + &Private->BlkIo2PpiList, > > > + &mNvmeBlkIo2PpiListTemplate, > > > + sizeof (EFI_PEI_PPI_DESCRIPTOR) > > > + ); > > > + Private->BlkIo2PpiList.Ppi =3D &Private->BlkIo2P= pi; > > > PeiServicesInstallPpi (&Private->BlkIoPpiList); > > > - PeiServicesNotifyPpi (&Private->EndOfPeiNotifyList); > > > + > > > + // > > > + // Check if the NVME controller supports the Security Receive/Se= nd > > > commands > > > + // > > > + if ((Private->ControllerData->Oacs & > > > SECURITY_SEND_RECEIVE_SUPPORTED) !=3D 0) { > > > + DEBUG (( > > > + DEBUG_INFO, > > > + "%a: Security Security Command PPI will be produced for > > > Controller %d.\n", > > > + __FUNCTION__, Controller > > > + )); > > > + Private->StorageSecurityPpi.Revision =3D > > > EDKII_STORAGE_SECURITY_PPI_REVISION; > > > + Private->StorageSecurityPpi.GetNumberofDevices =3D > > > NvmeStorageSecurityGetDeviceNo; > > > + Private->StorageSecurityPpi.GetDevicePath =3D > > > NvmeStorageSecurityGetDevicePath; > > > + Private->StorageSecurityPpi.ReceiveData =3D > > > NvmeStorageSecurityReceiveData; > > > + Private->StorageSecurityPpi.SendData =3D > > > NvmeStorageSecuritySendData; > > > + CopyMem ( > > > + &Private->StorageSecurityPpiList, > > > + &mNvmeStorageSecurityPpiListTemplate, > > > + sizeof (EFI_PEI_PPI_DESCRIPTOR) > > > + ); > > > + Private->StorageSecurityPpiList.Ppi =3D &Private- > > >StorageSecurityPpi; > > > + PeiServicesInstallPpi (&Private->StorageSecurityPpiList); > > > + } > > > + > > > + CopyMem ( > > > + &Private->EndOfPeiNotifyList, > > > + &mNvmeEndOfPeiNotifyListTemplate, > > > + sizeof (EFI_PEI_NOTIFY_DESCRIPTOR) > > > + ); > > > + PeiServicesNotifyPpi (&Private->EndOfPeiNotifyList); > > > + > > > DEBUG (( > > > - DEBUG_INFO, > > > - "%a: BlockIO PPI has been installed on Controller %d.\n", > > > - __FUNCTION__, > > > - Controller > > > + DEBUG_INFO, "%a: Controller %d has been successfully initializ= ed.\n", > > > + __FUNCTION__, Controller > > > )); > > > Controller++; > > > } > > > diff --git a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiHci.c > > > b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiHci.c > > > index d4056a2a5b..b9fa3230f8 100644 > > > --- a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiHci.c > > > +++ b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiHci.c > > > @@ -2,7 +2,7 @@ > > > The NvmExpressPei driver is used to manage non-volatile memory > > > subsystem > > > which follows NVM Express specification at PEI phase. > > > > > > - Copyright (c) 2018, Intel Corporation. All rights reserved.
> > > + Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.=
> > > > > > This program and the accompanying materials > > > are licensed and made available under the terms and conditions > > > @@ -702,47 +702,25 @@ NvmeControllerInit ( > > > } > > > > > > /** > > > - Free the resources allocated by an NVME controller. > > > + Free the DMA resources allocated by an NVME controller. > > > > > > @param[in] Private The pointer to the > > > PEI_NVME_CONTROLLER_PRIVATE_DATA data structure. > > > > > > **/ > > > VOID > > > -NvmeFreeControllerResource ( > > > +NvmeFreeDmaResource ( > > > IN PEI_NVME_CONTROLLER_PRIVATE_DATA *Private > > > ) > > > { > > > - // > > > - // Free the controller data buffer > > > - // > > > - if (Private->ControllerData !=3D NULL) { > > > - FreePool (Private->ControllerData); > > > - Private->ControllerData =3D NULL; > > > - } > > > + ASSERT (Private !=3D NULL); > > > > > > - // > > > - // Free the DMA buffers > > > - // > > > - if (Private->Buffer !=3D NULL) { > > > + if (Private->BufferMapping !=3D NULL) { > > > IoMmuFreeBuffer ( > > > NVME_MEM_MAX_PAGES, > > > Private->Buffer, > > > Private->BufferMapping > > > ); > > > - Private->Buffer =3D NULL; > > > } > > > > > > - // > > > - // Free the namespaces information buffer > > > - // > > > - if (Private->NamespaceInfo !=3D NULL) { > > > - FreePool (Private->NamespaceInfo); > > > - Private->NamespaceInfo =3D NULL; > > > - } > > > - > > > - // > > > - // Free the controller private data structure > > > - // > > > - FreePool (Private); > > > return; > > > } > > > diff --git > > > > > > a/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiStorageSecurity. > > > c > > > > > > b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiStorageSecurity. > > > c > > > new file mode 100644 > > > index 0000000000..e5a2cef3d6 > > > --- /dev/null > > > +++ > > > > > > b/MdeModulePkg/Bus/Pci/NvmExpressPei/NvmExpressPeiStorageSecurity. > > > c > > > @@ -0,0 +1,423 @@ > > > +/** @file > > > + The NvmExpressPei driver is used to manage non-volatile memory > > > subsystem > > > + which follows NVM Express specification at PEI phase. > > > + > > > + Copyright (c) 2019, Intel Corporation. All rights reserved.
> > > + > > > + This program and the accompanying materials > > > + are licensed and made available under the terms and conditions > > > + of the BSD License which accompanies this distribution. The > > > + full text of the license may be found at > > > + http://opensource.org/licenses/bsd-license.php > > > + > > > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > > > BASIS, > > > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > > > EXPRESS OR IMPLIED. > > > + > > > +**/ > > > + > > > +#include "NvmExpressPei.h" > > > + > > > +/** > > > + Trust transfer data from/to NVM Express device. > > > + > > > + This function performs one NVMe transaction to do a trust transfer > > > from/to NVM > > > + Express device. > > > + > > > + @param[in] Private The pointer to the > > > PEI_NVME_CONTROLLER_PRIVATE_DATA > > > + data structure. > > > + @param[in,out] Buffer The pointer to the current transa= ction > > buffer. > > > + @param[in] SecurityProtocolId > > > + The value of the "Security Protoc= ol" parameter > > > + of the security protocol command = to be sent. > > > + @param[in] SecurityProtocolSpecificData > > > + The value of the "Security Protoc= ol Specific" > > > + parameter of the security protoco= l command to > > > + be sent. > > > + @param[in] TransferLength The block number or sector count = of > the > > > transfer. > > > + @param[in] IsTrustSend Indicates whether it is a trust s= end > > operation > > > + or not. > > > + @param[in] Timeout The timeout, in 100ns units, to u= se for the > > > + execution of the security protoco= l command. > > > + A Timeout value of 0 means that t= his function > > > + will wait indefinitely for the se= curity protocol > > > + command to execute. If Timeout is= greater than > > > + zero, then this function will ret= urn EFI_TIMEOUT > > > + if the time required to execute t= he receive > > > + data command is greater than Time= out. > > > + @param[out] TransferLengthOut A pointer to a buffer to store th= e > size > > in > > > bytes > > > + of the data written to the buffer= . Ignore it > > > + when IsTrustSend is TRUE. > > > + > > > + @retval EFI_SUCCESS The data transfer is complete successfully. > > > + @return others Some error occurs when transferring data. > > > + > > > +**/ > > > +EFI_STATUS > > > +TrustTransferNvmeDevice ( > > > + IN PEI_NVME_CONTROLLER_PRIVATE_DATA *Private, > > > + IN OUT VOID *Buffer, > > > + IN UINT8 SecurityProtocolId, > > > + IN UINT16 SecurityProtocolSpecifi= cData, > > > + IN UINTN TransferLength, > > > + IN BOOLEAN IsTrustSend, > > > + IN UINT64 Timeout, > > > + OUT UINTN *TransferLengthOut > > > + ) > > > +{ > > > + EDKII_PEI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET > > > CommandPacket; > > > + EDKII_PEI_NVM_EXPRESS_COMMAND Command; > > > + EDKII_PEI_NVM_EXPRESS_COMPLETION Completion; > > > + EFI_STATUS Status; > > > + UINT16 SpecificData; > > > + > > > + ZeroMem (&CommandPacket, > > > sizeof(EDKII_PEI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET)); > > > + ZeroMem (&Command, > sizeof(EDKII_PEI_NVM_EXPRESS_COMMAND)); > > > + ZeroMem (&Completion, > > > sizeof(EDKII_PEI_NVM_EXPRESS_COMPLETION)); > > > + > > > + CommandPacket.NvmeCmd =3D &Command; > > > + CommandPacket.NvmeCompletion =3D &Completion; > > > + > > > + // > > > + // Change Endianness of SecurityProtocolSpecificData > > > + // > > > + SpecificData =3D (((SecurityProtocolSpecificData << 8) & 0xFF00) | > > > (SecurityProtocolSpecificData >> 8)); > > > + > > > + if (IsTrustSend) { > > > + Command.Cdw0.Opcode =3D > NVME_ADMIN_SECURITY_SEND_CMD; > > > + CommandPacket.TransferBuffer =3D Buffer; > > > + CommandPacket.TransferLength =3D (UINT32)TransferLength; > > > + CommandPacket.NvmeCmd->Cdw10 =3D (UINT32)((SecurityProtocolId > << > > > 24) | (SpecificData << 8)); > > > + CommandPacket.NvmeCmd->Cdw11 =3D (UINT32)TransferLength; > > > + } else { > > > + Command.Cdw0.Opcode =3D > > NVME_ADMIN_SECURITY_RECEIVE_CMD; > > > + CommandPacket.TransferBuffer =3D Buffer; > > > + CommandPacket.TransferLength =3D (UINT32)TransferLength; > > > + CommandPacket.NvmeCmd->Cdw10 =3D (UINT32)((SecurityProtocolId > << > > > 24) | (SpecificData << 8)); > > > + CommandPacket.NvmeCmd->Cdw11 =3D (UINT32)TransferLength; > > > + } > > > + > > > + CommandPacket.NvmeCmd->Flags =3D CDW10_VALID | CDW11_VALID; > > > + CommandPacket.NvmeCmd->Nsid =3D NVME_CONTROLLER_NSID; > > > + CommandPacket.CommandTimeout =3D Timeout; > > > + CommandPacket.QueueType =3D NVME_ADMIN_QUEUE; > > > + > > > + Status =3D NvmePassThru ( > > > + Private, > > > + NVME_CONTROLLER_NSID, > > > + &CommandPacket > > > + ); > > > + > > > + if (!IsTrustSend) { > > > + if (EFI_ERROR (Status)) { > > > + *TransferLengthOut =3D 0; > > > + } else { > > > + *TransferLengthOut =3D (UINTN) TransferLength; > > > + } > > > + } > > > + > > > + return Status; > > > +} > > > + > > > +/** > > > + Gets the count of storage security devices that one specific drive= r > > detects. > > > + > > > + @param[in] This The PPI instance pointer. > > > + @param[out] NumberofDevices The number of storage security > > devices > > > discovered. > > > + > > > + @retval EFI_SUCCESS The operation performed successfu= lly. > > > + @retval EFI_INVALID_PARAMETER The parameters are invalid. > > > + > > > +**/ > > > +EFI_STATUS > > > +EFIAPI > > > +NvmeStorageSecurityGetDeviceNo ( > > > + IN EDKII_PEI_STORAGE_SECURITY_CMD_PPI *This, > > > + OUT UINTN *NumberofDevices > > > + ) > > > +{ > > > + PEI_NVME_CONTROLLER_PRIVATE_DATA *Private; > > > + > > > + if (This =3D=3D NULL || NumberofDevices =3D=3D NULL) { > > > + return EFI_INVALID_PARAMETER; > > > + } > > > + > > > + Private =3D > > > > GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_STROAGE_SECURITY > > > (This); > > > + *NumberofDevices =3D Private->ActiveNamespaceNum; > > > + > > > + return EFI_SUCCESS; > > > +} > > > + > > > +/** > > > + Gets the device path of a specific storage security device. > > > + > > > + @param[in] This The PPI instance pointer. > > > + @param[in] DeviceIndex Specifies the storage security de= vice to > > > which > > > + the function wants to talk. Becau= se the driver > > > + that implements Storage Security = Command PPIs > > > + will manage multiple storage devi= ces, the PPIs > > > + that want to talk to a single dev= ice must specify > > > + the device index that was assigne= d during the > > > + enumeration process. This index i= s a number from > > > + one to NumberofDevices. > > > + @param[out] DevicePathLength The length of the device path in > bytes > > > specified > > > + by DevicePath. > > > + @param[out] DevicePath The device path of storage securi= ty > device. > > > + This field re-uses EFI Device Pat= h Protocol as > > > + defined by Section 10.2 EFI Devic= e Path Protocol > > > + of UEFI 2.7 Specification. > > > + > > > + @retval EFI_SUCCESS The operation succeeds. > > > + @retval EFI_INVALID_PARAMETER DevicePathLength or DevicePath > is > > > NULL. > > > + @retval EFI_NOT_FOUND The specified storage security de= vice > not > > > found. > > > + @retval EFI_OUT_OF_RESOURCES The operation fails due to lack o= f > > > resources. > > > + > > > +**/ > > > +EFI_STATUS > > > +EFIAPI > > > +NvmeStorageSecurityGetDevicePath ( > > > + IN EDKII_PEI_STORAGE_SECURITY_CMD_PPI *This, > > > + IN UINTN DeviceIndex, > > > + OUT UINTN *DevicePathLength, > > > + OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath > > > + ) > > > +{ > > > + PEI_NVME_CONTROLLER_PRIVATE_DATA *Private; > > > + > > > + if (This =3D=3D NULL || DevicePathLength =3D=3D NULL || DevicePath= =3D=3D NULL) > { > > > + return EFI_INVALID_PARAMETER; > > > + } > > > + > > > + Private =3D > > > > GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_STROAGE_SECURITY > > > (This); > > > + if ((DeviceIndex =3D=3D 0) || (DeviceIndex > Private- > > >ActiveNamespaceNum)) > > > { > > > + return EFI_INVALID_PARAMETER; > > > + } > > > + > > > + return NvmeBuildDevicePath ( > > > + Private, > > > + Private->NamespaceInfo[DeviceIndex-1].NamespaceId, > > > + Private->NamespaceInfo[DeviceIndex-1].NamespaceUuid, > > > + DevicePathLength, > > > + DevicePath > > > + ); > > > +} > > > + > > > +/** > > > + 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 > > > DeviceIndex. > > > + The security protocol command sent is defined by SecurityProtocolI= d > and > > > contains > > > + the security protocol specific data SecurityProtocolSpecificData. = The > > > function > > > + returns the data from the security protocol command in PayloadBuff= er. > > > + > > > + For devices supporting the SCSI command set, the security protocol > > > command is sent > > > + using the SECURITY PROTOCOL IN command defined in SPC-4. > > > + > > > + For devices supporting the ATA command set, the security protocol > > > command is sent > > > + using one of the TRUSTED RECEIVE commands defined in ATA8-ACS if > > > PayloadBufferSize > > > + is non-zero. > > > + > > > + If the PayloadBufferSize is zero, the security protocol command is= sent > > > using the > > > + Trusted Non-Data command defined in ATA8-ACS. > > > + > > > + 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 PayloadBufferS= ize > is > > > non-zero, > > > + the function shall return EFI_INVALID_PARAMETER. > > > + > > > + If the given DeviceIndex does not support security protocol comman= ds, > > > the function > > > + shall return EFI_UNSUPPORTED. > > > + > > > + If the security protocol fails to complete within the Timeout peri= od, 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 wit= h > > an > > > error, the > > > + function shall return EFI_DEVICE_ERROR. > > > + > > > + @param[in] This The PPI instance pointer. > > > + @param[in] DeviceIndex Specifies the storage security device= to > > which > > > the > > > + function wants to talk. Because the d= river that > > > + implements Storage Security Command P= PIs will manage > > > + multiple storage devices, the PPIs th= at want to talk > > > + to a single device must specify the d= evice index > > > + that was assigned during the enumerat= ion process. > > > + This index is a number from one to Nu= mberofDevices. > > > + @param[in] Timeout The timeout, in 100ns units, to use f= or the > > > execution > > > + of the security protocol command. A T= imeout value > > > + of 0 means that this function will wa= it indefinitely > > > + for the security protocol command to = execute. If > > > + Timeout is greater than zero, then th= is function > > > + will return EFI_TIMEOUT if the time r= equired to > > > + execute the receive data command is g= reater than > > > + Timeout. > > > + @param[in] SecurityProtocolId > > > + The value of the "Security Protocol" = parameter of > > > + the security protocol command to be s= ent. > > > + @param[in] SecurityProtocolSpecificData > > > + The value of the "Security Protocol S= pecific" > > > + parameter of the security protocol co= mmand to be > > > + sent. > > > + @param[in] PayloadBufferSize > > > + Size in bytes of the payload data buf= fer. > > > + @param[out] PayloadBuffer A pointer to a destination buffer to = store > > > the > > > + security protocol command specific pa= yload data > > > + for the security protocol command. Th= e caller is > > > + responsible for having either implici= t or explicit > > > + ownership of the buffer. > > > + @param[out] PayloadTransferSize > > > + A pointer to a buffer to store the si= ze in bytes > > > + of the data written to the payload da= ta 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 th= e truncated > > > + data. > > > + @retval EFI_UNSUPPORTED The given DeviceIndex does no= t > > > support > > > + security protocol commands. > > > + @retval EFI_DEVICE_ERROR The security protocol command > > > completed > > > + with an error. > > > + @retval EFI_INVALID_PARAMETER The PayloadBuffer or > > > PayloadTransferSize > > > + is NULL and PayloadBufferSize= is non-zero. > > > + @retval EFI_TIMEOUT A timeout occurred while wait= ing for > the > > > + security protocol command to = execute. > > > + > > > +**/ > > > +EFI_STATUS > > > +EFIAPI > > > +NvmeStorageSecurityReceiveData ( > > > + IN EDKII_PEI_STORAGE_SECURITY_CMD_PPI *This, > > > + IN UINTN DeviceIndex, > > > + IN UINT64 Timeout, > > > + IN UINT8 SecurityProtocolId, > > > + IN UINT16 SecurityProtocolSpecificDa= ta, > > > + IN UINTN PayloadBufferSize, > > > + OUT VOID *PayloadBuffer, > > > + OUT UINTN *PayloadTransferSize > > > + ) > > > +{ > > > + PEI_NVME_CONTROLLER_PRIVATE_DATA *Private; > > > + EFI_STATUS Status; > > > + > > > + if ((PayloadBuffer =3D=3D NULL) || (PayloadTransferSize =3D=3D NUL= L) || > > > (PayloadBufferSize =3D=3D 0)) { > > > + return EFI_INVALID_PARAMETER; > > > + } > > > + > > > + Private =3D > > > > GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_STROAGE_SECURITY > > > (This); > > > + > > > + Status =3D TrustTransferNvmeDevice ( > > > + Private, > > > + PayloadBuffer, > > > + SecurityProtocolId, > > > + SecurityProtocolSpecificData, > > > + PayloadBufferSize, > > > + FALSE, > > > + Timeout, > > > + PayloadTransferSize > > > + ); > > > + > > > + 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 DeviceIndex. 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 sh= all > > > 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. > > > + > > > + For devices supporting the ATA command set, the security protocol > > > command is > > > + sent using one of the TRUSTED SEND commands defined in ATA8-ACS if > > > PayloadBufferSize > > > + is non-zero. If the PayloadBufferSize is zero, the security protoc= ol > > > command > > > + is sent using the Trusted Non-Data command defined in ATA8-ACS. > > > + > > > + If PayloadBuffer is NULL and PayloadBufferSize is non-zero, the > function > > > shall > > > + return EFI_INVALID_PARAMETER. > > > + > > > + If the given DeviceIndex does not support security protocol comman= ds, > > > the function > > > + shall return EFI_UNSUPPORTED. > > > + > > > + If the security protocol fails to complete within the Timeout peri= od, 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 wit= h > > an > > > error, > > > + the functio shall return EFI_DEVICE_ERROR. > > > + > > > + @param[in] This The PPI instance pointer. > > > + @param[in] DeviceIndex The ID of the device. > > > + @param[in] Timeout The timeout, in 100ns units, to use f= or the > > > execution > > > + of the security protocol command. A T= imeout value > > > + of 0 means that this function will wa= it indefinitely > > > + for the security protocol command to = execute. If > > > + Timeout is greater than zero, then th= is function > > > + will return EFI_TIMEOUT if the time r= equired to > > > + execute the receive data command is g= reater than > > > + Timeout. > > > + @param[in] SecurityProtocolId > > > + The value of the "Security Protocol" = parameter of > > > + the security protocol command to be s= ent. > > > + @param[in] SecurityProtocolSpecificData > > > + The value of the "Security Protocol S= pecific" > > > + parameter of the security protocol co= mmand to be > > > + sent. > > > + @param[in] PayloadBufferSize Size in bytes of the payload data buf= fer. > > > + @param[in] PayloadBuffer A pointer to a destination buffer to = store > > the > > > + security protocol command specific pa= yload data > > > + for the security protocol command. > > > + > > > + @retval EFI_SUCCESS The security protocol command com= pleted > > > successfully. > > > + @retval EFI_UNSUPPORTED The given DeviceIndex does not > > support > > > security > > > + protocol commands. > > > + @retval EFI_DEVICE_ERROR The security protocol command > > > completed with > > > + an error. > > > + @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 > > > +NvmeStorageSecuritySendData ( > > > + IN EDKII_PEI_STORAGE_SECURITY_CMD_PPI *This, > > > + IN UINTN DeviceIndex, > > > + IN UINT64 Timeout, > > > + IN UINT8 SecurityProtocolId, > > > + IN UINT16 SecurityProtocolSpecificDat= a, > > > + IN UINTN PayloadBufferSize, > > > + IN VOID *PayloadBuffer > > > + ) > > > +{ > > > + PEI_NVME_CONTROLLER_PRIVATE_DATA *Private; > > > + EFI_STATUS Status; > > > + > > > + if ((PayloadBuffer =3D=3D NULL) && (PayloadBufferSize !=3D 0)) { > > > + return EFI_INVALID_PARAMETER; > > > + } > > > + > > > + Private =3D > > > > GET_NVME_PEIM_HC_PRIVATE_DATA_FROM_THIS_STROAGE_SECURITY > > > (This); > > > + > > > + Status =3D TrustTransferNvmeDevice ( > > > + Private, > > > + PayloadBuffer, > > > + SecurityProtocolId, > > > + SecurityProtocolSpecificData, > > > + PayloadBufferSize, > > > + TRUE, > > > + Timeout, > > > + NULL > > > + ); > > > + > > > + return Status; > > > +} > > > -- > > > 2.12.0.windows.1