]> git.proxmox.com Git - mirror_edk2.git/blobdiff - SecurityPkg/Tcg/Opal/OpalPasswordSmm/OpalPasswordSmm.c
SecurityPkg OpalPassword: Remove old solution
[mirror_edk2.git] / SecurityPkg / Tcg / Opal / OpalPasswordSmm / OpalPasswordSmm.c
diff --git a/SecurityPkg/Tcg/Opal/OpalPasswordSmm/OpalPasswordSmm.c b/SecurityPkg/Tcg/Opal/OpalPasswordSmm/OpalPasswordSmm.c
deleted file mode 100644 (file)
index 0ea92b1..0000000
+++ /dev/null
@@ -1,1088 +0,0 @@
-/** @file\r
-  Opal password smm driver which is used to support Opal security feature at s3 path.\r
-\r
-Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution.  The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-#include "OpalPasswordSmm.h"\r
-\r
-#define SMM_SIZE_ALLOC_BYTES                      (512)\r
-#define RESPONSE_SIZE                             (200)\r
-\r
-#define PCI_CLASS_MASS_STORAGE_AHCI               (0x06)\r
-\r
-#define OPAL_PCIE_ROOTPORT_SAVESIZE               (0x40)\r
-#define STORE_INVALID_ROOTPORT_INDEX              ((UINT8) -1)\r
-#define OPAL_DEVICE_TYPE_SATA                     0x1\r
-#define OPAL_DEVICE_TYPE_NVME                     0x2\r
-#define OPAL_DEVICE_TYPE_UNKNOWN                  0xFF\r
-\r
-//\r
-// To unlock the Intel SATA controller at S3 Resume, restored the following registers.\r
-//\r
-const OPAL_HC_PCI_REGISTER_SAVE mSataHcRegisterSaveTemplate[] = {\r
-  {0x9,  S3BootScriptWidthUint8},\r
-  {0x10, S3BootScriptWidthUint32},\r
-  {0x14, S3BootScriptWidthUint32},\r
-  {0x18, S3BootScriptWidthUint32},\r
-  {0x1C, S3BootScriptWidthUint32},\r
-  {0x20, S3BootScriptWidthUint32},\r
-  {0x24, S3BootScriptWidthUint32},\r
-  {0x3c, S3BootScriptWidthUint8},\r
-  {0x3d, S3BootScriptWidthUint8},\r
-  {0x40, S3BootScriptWidthUint16},\r
-  {0x42, S3BootScriptWidthUint16},\r
-  {0x92, S3BootScriptWidthUint16},\r
-  {0x94, S3BootScriptWidthUint32},\r
-  {0x9C, S3BootScriptWidthUint32},\r
-  {0x4,  S3BootScriptWidthUint16},\r
-};\r
-\r
-\r
-UINT8                mSwSmiValue;\r
-LIST_ENTRY           *mOpalDeviceList;\r
-LIST_ENTRY           mSmmDeviceList  = INITIALIZE_LIST_HEAD_VARIABLE (mSmmDeviceList);\r
-\r
-BOOLEAN              mSendBlockSID   = FALSE;\r
-\r
-// AHCI\r
-UINT32               mAhciBar = 0;\r
-EFI_AHCI_REGISTERS   mAhciRegisters;\r
-VOID                 *mBuffer = NULL; // DMA can not read/write Data to smram, so we pre-allocates Buffer from AcpiNVS.\r
-//\r
-// NVME\r
-NVME_CONTEXT         mNvmeContext;\r
-\r
-/**\r
-  Add new bridge node or nvme device info to the device list.\r
-\r
-  @param[in]       BusNum        The bus number.\r
-  @param[in]       DevNum        The device number.\r
-  @param[in]       FuncNum       The function number.\r
-  @param[in]       Dev           The device which need to add device node info.\r
-\r
-**/\r
-VOID\r
-AddPciDeviceNode (\r
-  UINT32                  BusNum,\r
-  UINT32                  DevNum,\r
-  UINT32                  FuncNum,\r
-  OPAL_SMM_DEVICE         *Dev\r
-  )\r
-{\r
-  UINT8       *DevList;\r
-  PCI_DEVICE  *DeviceNode;\r
-\r
-  DevList = AllocateZeroPool (sizeof (PCI_DEVICE) + Dev->Length);\r
-  ASSERT (DevList != NULL);\r
-\r
-  if (Dev->Length != 0) {\r
-    CopyMem (DevList, Dev->PciBridgeNode, Dev->Length);\r
-    FreePool (Dev->PciBridgeNode);\r
-  }\r
-\r
-  DeviceNode = (PCI_DEVICE *) (DevList + Dev->Length);\r
-\r
-  DeviceNode->BusNum  = BusNum;\r
-  DeviceNode->DevNum  = DevNum;\r
-  DeviceNode->FuncNum = FuncNum;\r
-\r
-  Dev->Length += sizeof (PCI_DEVICE);\r
-  Dev->PciBridgeNode = (PCI_DEVICE *)DevList;\r
-}\r
-\r
-/**\r
-  Extract device info from the input device path.\r
-\r
-  @param[in]       DevicePath        Device path info for the device.\r
-  @param[in,out]   Dev               The device which new inputed.\r
-\r
-**/\r
-VOID\r
-ExtractDeviceInfoFromDevicePath (\r
-  IN     EFI_DEVICE_PATH_PROTOCOL    *DevicePath,\r
-  IN OUT OPAL_SMM_DEVICE             *Dev\r
-  )\r
-{\r
-  EFI_DEVICE_PATH_PROTOCOL      *TmpDevPath;\r
-  EFI_DEVICE_PATH_PROTOCOL      *TmpDevPath2;\r
-  PCI_DEVICE_PATH               *PciDevPath;\r
-  SATA_DEVICE_PATH              *SataDevPath;\r
-  NVME_NAMESPACE_DEVICE_PATH    *NvmeDevPath;\r
-  UINTN                         BusNum;\r
-\r
-  TmpDevPath = DevicePath;\r
-  Dev->DeviceType = OPAL_DEVICE_TYPE_UNKNOWN;\r
-\r
-  while (!IsDevicePathEnd(TmpDevPath)) {\r
-    if (TmpDevPath->Type == MESSAGING_DEVICE_PATH && TmpDevPath->SubType == MSG_SATA_DP) {\r
-      //\r
-      // SATA\r
-      //\r
-      SataDevPath = ( SATA_DEVICE_PATH* )TmpDevPath;\r
-      Dev->SataPort = SataDevPath->HBAPortNumber;\r
-      Dev->SataPortMultiplierPort = SataDevPath->PortMultiplierPortNumber;\r
-      Dev->DeviceType = OPAL_DEVICE_TYPE_SATA;\r
-      break;\r
-    } else if (TmpDevPath->Type == MESSAGING_DEVICE_PATH && TmpDevPath->SubType == MSG_NVME_NAMESPACE_DP) {\r
-      //\r
-      // NVMe\r
-      //\r
-      NvmeDevPath = ( NVME_NAMESPACE_DEVICE_PATH* )TmpDevPath;\r
-      Dev->NvmeNamespaceId = NvmeDevPath->NamespaceId;\r
-      Dev->DeviceType = OPAL_DEVICE_TYPE_NVME;\r
-      break;\r
-    }\r
-    TmpDevPath = NextDevicePathNode (TmpDevPath);\r
-  }\r
-\r
-  //\r
-  // Get bridge node info for the nvme device.\r
-  //\r
-  BusNum = 0;\r
-  TmpDevPath = DevicePath;\r
-  TmpDevPath2 = NextDevicePathNode (DevicePath);\r
-  while (!IsDevicePathEnd(TmpDevPath2)) {\r
-    if (TmpDevPath->Type == HARDWARE_DEVICE_PATH && TmpDevPath->SubType == HW_PCI_DP) {\r
-      PciDevPath = (PCI_DEVICE_PATH *) TmpDevPath;\r
-      if ((TmpDevPath2->Type == MESSAGING_DEVICE_PATH && TmpDevPath2->SubType == MSG_NVME_NAMESPACE_DP)||\r
-          (TmpDevPath2->Type == MESSAGING_DEVICE_PATH && TmpDevPath2->SubType == MSG_SATA_DP)) {\r
-        Dev->BusNum = (UINT32)BusNum;\r
-        Dev->DevNum = PciDevPath->Device;\r
-        Dev->FuncNum = PciDevPath->Function;\r
-      } else {\r
-        AddPciDeviceNode((UINT32)BusNum, PciDevPath->Device, PciDevPath->Function, Dev);\r
-        if (TmpDevPath2->Type == HARDWARE_DEVICE_PATH && TmpDevPath2->SubType == HW_PCI_DP) {\r
-          BusNum = PciRead8 (PCI_LIB_ADDRESS (BusNum, PciDevPath->Device, PciDevPath->Function, NVME_PCIE_SEC_BNUM));\r
-        }\r
-      }\r
-    }\r
-\r
-    TmpDevPath  = NextDevicePathNode (TmpDevPath);\r
-    TmpDevPath2 = NextDevicePathNode (TmpDevPath2);\r
-  }\r
-}\r
-\r
-/**\r
-\r
-  The function returns whether or not the device is Opal Locked.\r
-  TRUE means that the device is partially or fully locked.\r
-  This will perform a Level 0 Discovery and parse the locking feature descriptor\r
-\r
-  @param[in]      OpalDev             Opal object to determine if locked\r
-  @param[out]     BlockSidSupported   Whether device support BlockSid feature.\r
-\r
-**/\r
-BOOLEAN\r
-IsOpalDeviceLocked(\r
-  OPAL_SMM_DEVICE    *OpalDev,\r
-  BOOLEAN            *BlockSidSupported\r
-  )\r
-{\r
-  OPAL_SESSION                   Session;\r
-  OPAL_DISK_SUPPORT_ATTRIBUTE    SupportedAttributes;\r
-  TCG_LOCKING_FEATURE_DESCRIPTOR LockingFeature;\r
-  UINT16                         OpalBaseComId;\r
-  TCG_RESULT                     Ret;\r
-\r
-  Session.Sscp = &OpalDev->Sscp;\r
-  Session.MediaId = 0;\r
-\r
-  Ret = OpalGetSupportedAttributesInfo (&Session, &SupportedAttributes, &OpalBaseComId);\r
-  if (Ret != TcgResultSuccess) {\r
-    return FALSE;\r
-  }\r
-\r
-  OpalDev->OpalBaseComId = OpalBaseComId;\r
-  Session.OpalBaseComId  = OpalBaseComId;\r
-  *BlockSidSupported     = SupportedAttributes.BlockSid == 1 ? TRUE : FALSE;\r
-\r
-  Ret = OpalGetLockingInfo(&Session, &LockingFeature);\r
-  if (Ret != TcgResultSuccess) {\r
-    return FALSE;\r
-  }\r
-\r
-  return OpalDeviceLocked (&SupportedAttributes, &LockingFeature);\r
-}\r
-\r
-/**\r
-  Save/Restore RootPort configuration space.\r
-\r
-  @param[in] DeviceNode             - The device node.\r
-  @param[in] SaveAction             - TRUE: Save, FALSE: Restore\r
-  @param[in,out] PcieConfBufferList     - Configuration space data buffer for save/restore\r
-\r
-  @retval - PCIE base address of this RootPort\r
-**/\r
-UINTN\r
-SaveRestoreRootportConfSpace (\r
-  IN     OPAL_SMM_DEVICE                *DeviceNode,\r
-  IN     BOOLEAN                        SaveAction,\r
-  IN OUT UINT8                          **PcieConfBufferList\r
-  )\r
-{\r
-  UINTN      RpBase;\r
-  UINTN      Length;\r
-  PCI_DEVICE *DevNode;\r
-  UINT8      *StorePcieConfData;\r
-  UINTN      Index;\r
-\r
-  Length = 0;\r
-  Index  = 0;\r
-  RpBase = 0;\r
-\r
-  while (Length < DeviceNode->Length) {\r
-    DevNode = (PCI_DEVICE *)((UINT8*)DeviceNode->PciBridgeNode + Length);\r
-    RpBase = PCI_LIB_ADDRESS (DevNode->BusNum, DevNode->DevNum, DevNode->FuncNum, 0x0);\r
-\r
-    if (PcieConfBufferList != NULL) {\r
-      if (SaveAction) {\r
-        StorePcieConfData = (UINT8 *) AllocateZeroPool (OPAL_PCIE_ROOTPORT_SAVESIZE);\r
-        ASSERT (StorePcieConfData != NULL);\r
-        OpalPciRead (StorePcieConfData, RpBase, OPAL_PCIE_ROOTPORT_SAVESIZE);\r
-        PcieConfBufferList[Index] = StorePcieConfData;\r
-      } else {\r
-        // Skip PCIe Command & Status registers\r
-        StorePcieConfData = PcieConfBufferList[Index];\r
-        OpalPciWrite (RpBase, StorePcieConfData, 4);\r
-        OpalPciWrite (RpBase + 8, StorePcieConfData + 8, OPAL_PCIE_ROOTPORT_SAVESIZE - 8);\r
-\r
-        FreePool (StorePcieConfData);\r
-      }\r
-    }\r
-\r
-    Length += sizeof (PCI_DEVICE);\r
-    Index ++;\r
-  }\r
-\r
-  return RpBase;\r
-}\r
-\r
-/**\r
-  Configure RootPort for downstream PCIe NAND devices.\r
-\r
-  @param[in] RpBase             - PCIe configuration space address of this RootPort\r
-  @param[in] BusNumber          - Bus number\r
-  @param[in] MemoryBase         - Memory base address\r
-  @param[in] MemoryLength       - Memory size\r
-\r
-**/\r
-VOID\r
-ConfigureRootPortForPcieNand (\r
-  IN UINTN   RpBase,\r
-  IN UINTN   BusNumber,\r
-  IN UINT32  MemoryBase,\r
-  IN UINT32  MemoryLength\r
-  )\r
-{\r
-  UINT32  MemoryLimit;\r
-\r
-  DEBUG ((DEBUG_INFO, "ConfigureRootPortForPcieNand, BusNumber: %x, MemoryBase: %x, MemoryLength: %x\n",\r
-    BusNumber, MemoryBase, MemoryLength));\r
-\r
-  if (MemoryLength == 0) {\r
-    MemoryLimit = MemoryBase;\r
-  } else {\r
-    MemoryLimit = MemoryBase + MemoryLength + 0xFFFFF; // 1M\r
-  }\r
-\r
-  ///\r
-  /// Configue PCIE configuration space for RootPort\r
-  ///\r
-  PciWrite8  (RpBase + NVME_PCIE_BNUM + 1,  (UINT8) BusNumber);           // Secondary Bus Number registers\r
-  PciWrite8  (RpBase + NVME_PCIE_BNUM + 2,  (UINT8) BusNumber);           // Subordinate Bus Number registers\r
-  PciWrite8  (RpBase + NVME_PCIE_IOBL,      0xFF);                        // I/O Base registers\r
-  PciWrite8  (RpBase + NVME_PCIE_IOBL + 1,  0x00);                        // I/O Limit registers\r
-  PciWrite16 (RpBase + NVME_PCIE_MBL,       (UINT16) RShiftU64 ((UINTN)MemoryBase, 16));  // Memory Base register\r
-  PciWrite16 (RpBase + NVME_PCIE_MBL + 2,   (UINT16) RShiftU64 ((UINTN)MemoryLimit, 16)); // Memory Limit register\r
-  PciWrite16 (RpBase + NVME_PCIE_PMBL,      0xFFFF);                      // Prefetchable Memory Base registers\r
-  PciWrite16 (RpBase + NVME_PCIE_PMBL + 2,  0x0000);                      // Prefetchable Memory Limit registers\r
-  PciWrite32 (RpBase + NVME_PCIE_PMBU32,    0xFFFFFFFF);                  // Prefetchable Memory Upper Base registers\r
-  PciWrite32 (RpBase + NVME_PCIE_PMLU32,    0x00000000);                  // Prefetchable Memory Upper Limit registers\r
-}\r
-\r
-\r
-/**\r
-  Dispatch function for a Software SMI handler.\r
-\r
-  @param[in]     DispatchHandle  The unique handle assigned to this handler by SmiHandlerRegister().\r
-  @param[in]     RegisterContext Points to an optional handler context which was specified when the\r
-                                 handler was registered.\r
-  @param[in, out] CommBuffer     A pointer to a collection of Data in memory that will\r
-                                 be conveyed from a non-SMM environment into an SMM environment.\r
-  @param[in, out] CommBufferSize The Size of the CommBuffer.\r
-\r
-  @retval EFI_SUCCESS            The interrupt was handled and quiesced. No other handlers\r
-                                 should still be called.\r
-  @retval Others                 Other execution results.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-SmmUnlockOpalPassword (\r
-  IN     EFI_HANDLE              DispatchHandle,\r
-  IN     CONST VOID              *RegisterContext,\r
-  IN OUT VOID                    *CommBuffer,\r
-  IN OUT UINTN                   *CommBufferSize\r
-  )\r
-{\r
-  EFI_STATUS                     Status;\r
-  OPAL_SMM_DEVICE                *OpalDev;\r
-  LIST_ENTRY                     *Entry;\r
-  UINT8                          BaseClassCode;\r
-  UINT8                          SubClassCode;\r
-  UINT8                          ProgInt;\r
-  TCG_RESULT                     Result;\r
-  UINT8                          SataCmdSt;\r
-  UINT8                          *StorePcieConfDataList[16];\r
-  UINTN                          RpBase;\r
-  UINTN                          MemoryBase;\r
-  UINTN                          MemoryLength;\r
-  OPAL_SESSION                   Session;\r
-  BOOLEAN                        BlockSidSupport;\r
-\r
-  ZeroMem (StorePcieConfDataList, sizeof (StorePcieConfDataList));\r
-  Status = EFI_DEVICE_ERROR;\r
-\r
-  //\r
-  // try to unlock all locked hdd disks.\r
-  //\r
-  for (Entry = mSmmDeviceList.ForwardLink; Entry != &mSmmDeviceList; Entry = Entry->ForwardLink) {\r
-    OpalDev = BASE_CR(Entry, OPAL_SMM_DEVICE, Link);\r
-\r
-    RpBase    = 0;\r
-    SataCmdSt = 0;\r
-\r
-    ///\r
-    /// Configure RootPort for PCIe AHCI/NVME devices.\r
-    ///\r
-    if (OpalDev->DeviceType == OPAL_DEVICE_TYPE_NVME) {\r
-      ///\r
-      /// Save original RootPort configuration space to heap\r
-      ///\r
-      RpBase = SaveRestoreRootportConfSpace (\r
-                  OpalDev,\r
-                  TRUE,\r
-                  StorePcieConfDataList\r
-                  );\r
-      MemoryBase = mNvmeContext.Nbar;\r
-      MemoryLength = 0;\r
-      ConfigureRootPortForPcieNand (RpBase, OpalDev->BusNum, (UINT32) MemoryBase, (UINT32) MemoryLength);\r
-\r
-      ///\r
-      /// Enable PCIE decode for RootPort\r
-      ///\r
-      SataCmdSt = PciRead8 (RpBase + NVME_PCIE_PCICMD);\r
-      PciWrite8  (RpBase + NVME_PCIE_PCICMD,  0x6);\r
-    } else {\r
-      SataCmdSt = PciRead8 (PCI_LIB_ADDRESS (OpalDev->BusNum, OpalDev->DevNum, OpalDev->FuncNum, NVME_PCIE_PCICMD));\r
-      PciWrite8 (PCI_LIB_ADDRESS (OpalDev->BusNum, OpalDev->DevNum, OpalDev->FuncNum, NVME_PCIE_PCICMD), 0x6);\r
-    }\r
-\r
-    BaseClassCode = PciRead8 (PCI_LIB_ADDRESS (OpalDev->BusNum, OpalDev->DevNum, OpalDev->FuncNum, 0x0B));\r
-    SubClassCode  = PciRead8 (PCI_LIB_ADDRESS (OpalDev->BusNum, OpalDev->DevNum, OpalDev->FuncNum, 0x0A));\r
-    ProgInt       = PciRead8 (PCI_LIB_ADDRESS (OpalDev->BusNum, OpalDev->DevNum, OpalDev->FuncNum, 0x09));\r
-    if (BaseClassCode != PCI_CLASS_MASS_STORAGE) {\r
-      Status = EFI_INVALID_PARAMETER;\r
-      break;\r
-    }\r
-\r
-    Status = EFI_DEVICE_ERROR;\r
-    if (OpalDev->DeviceType == OPAL_DEVICE_TYPE_SATA) {\r
-      if ((SubClassCode == PCI_CLASS_MASS_STORAGE_AHCI) || (SubClassCode == PCI_CLASS_MASS_STORAGE_RAID)) {\r
-        Status = GetAhciBaseAddress (OpalDev->BusNum, OpalDev->DevNum, OpalDev->FuncNum);\r
-        if (EFI_ERROR (Status)) {\r
-          DEBUG ((DEBUG_ERROR, "GetAhciBaseAddress error, Status: %r\n", Status));\r
-          goto done;\r
-        }\r
-        Status = AhciModeInitialize ((UINT8)OpalDev->SataPort);\r
-        ASSERT_EFI_ERROR (Status);\r
-        if (EFI_ERROR (Status)) {\r
-          DEBUG ((DEBUG_ERROR, "AhciModeInitialize error, Status: %r\n", Status));\r
-          goto done;\r
-        }\r
-      } else {\r
-        DEBUG ((DEBUG_ERROR, "SubClassCode not support for SATA device\n"));\r
-      }\r
-    } else if (OpalDev->DeviceType == OPAL_DEVICE_TYPE_NVME) {\r
-      if (SubClassCode == PCI_CLASS_MASS_STORAGE_NVM) {\r
-        if (ProgInt != PCI_IF_NVMHCI) {\r
-          DEBUG ((DEBUG_ERROR, "PI not support, skipped\n"));\r
-          Status = EFI_NOT_FOUND;\r
-          goto done;\r
-        }\r
-\r
-        mNvmeContext.PciBase = PCI_LIB_ADDRESS (OpalDev->BusNum, OpalDev->DevNum, OpalDev->FuncNum, 0x0);\r
-        mNvmeContext.NvmeInitWaitTime = 0;\r
-        mNvmeContext.Nsid = OpalDev->NvmeNamespaceId;\r
-        Status = NvmeControllerInit (&mNvmeContext);\r
-      } else {\r
-        DEBUG ((DEBUG_ERROR, "SubClassCode not support for NVME device\n"));\r
-      }\r
-    } else {\r
-      DEBUG ((DEBUG_ERROR, "Invalid Devicetype\n"));\r
-      goto done;\r
-    }\r
-\r
-    Status = EFI_DEVICE_ERROR;\r
-    BlockSidSupport = FALSE;\r
-    if (IsOpalDeviceLocked (OpalDev, &BlockSidSupport)) {\r
-      ZeroMem(&Session, sizeof(Session));\r
-      Session.Sscp = &OpalDev->Sscp;\r
-      Session.MediaId = 0;\r
-      Session.OpalBaseComId = OpalDev->OpalBaseComId;\r
-\r
-      Result = OpalSupportUnlock (&Session, OpalDev->Password, OpalDev->PasswordLength, NULL);\r
-      if (Result == TcgResultSuccess) {\r
-        Status = EFI_SUCCESS;\r
-      }\r
-    }\r
-\r
-    if (mSendBlockSID && BlockSidSupport) {\r
-      Result = OpalBlockSid (&Session, TRUE);\r
-      if (Result != TcgResultSuccess) {\r
-        break;\r
-      }\r
-    }\r
-\r
-    if (OpalDev->DeviceType == OPAL_DEVICE_TYPE_NVME) {\r
-      if (SubClassCode == PCI_CLASS_MASS_STORAGE_NVM) {\r
-        Status = NvmeControllerExit (&mNvmeContext);\r
-      }\r
-    }\r
-\r
-done:\r
-    if (OpalDev->DeviceType == OPAL_DEVICE_TYPE_NVME) {\r
-      ASSERT (RpBase != 0);\r
-      PciWrite8  (RpBase + NVME_PCIE_PCICMD, 0);\r
-      RpBase = SaveRestoreRootportConfSpace (\r
-                  OpalDev,\r
-                  FALSE,  // restore\r
-                  StorePcieConfDataList\r
-                  );\r
-      PciWrite8  (RpBase + NVME_PCIE_PCICMD, SataCmdSt);\r
-    } else {\r
-      PciWrite8 (PCI_LIB_ADDRESS (OpalDev->BusNum, OpalDev->DevNum, OpalDev->FuncNum, NVME_PCIE_PCICMD), SataCmdSt);\r
-    }\r
-\r
-    if (EFI_ERROR (Status)) {\r
-      break;\r
-    }\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-  The function extracts device information from OpalDeviceList and creat SmmDeviceList used for S3.\r
-\r
-  @param[in]       OpalDeviceList   Opal device list created at POST which contains the information of OPAL_DISK_AND_PASSWORD_INFO\r
-  @param[in,out]   SmmDeviceList    Opal Smm device list to be created and used for unlocking devices at S3 resume.\r
-\r
-  @retval EFI_SUCCESS            Create SmmDeviceList successfully.\r
-  @retval Others                 Other execution results.\r
-**/\r
-EFI_STATUS\r
-CreateSmmDeviceList (\r
-  IN     LIST_ENTRY                 *OpalDeviceList,\r
-  IN OUT LIST_ENTRY                 *SmmDeviceList\r
-  )\r
-{\r
-  LIST_ENTRY                        *Entry;\r
-  OPAL_DISK_AND_PASSWORD_INFO       *PciDev;\r
-  OPAL_SMM_DEVICE                   *SmmDev;\r
-\r
-  for (Entry = OpalDeviceList->ForwardLink; Entry != OpalDeviceList; Entry = Entry->ForwardLink) {\r
-    PciDev = BASE_CR (Entry, OPAL_DISK_AND_PASSWORD_INFO, Link);\r
-\r
-    SmmDev = AllocateZeroPool (sizeof (OPAL_SMM_DEVICE));\r
-    if (SmmDev == NULL) {\r
-      return EFI_OUT_OF_RESOURCES;\r
-    }\r
-    SmmDev->Signature = OPAL_SMM_DEVICE_SIGNATURE;\r
-\r
-    ExtractDeviceInfoFromDevicePath(&PciDev->OpalDevicePath, SmmDev);\r
-\r
-    SmmDev->PasswordLength = PciDev->PasswordLength;\r
-    CopyMem(&(SmmDev->Password), PciDev->Password, OPAL_PASSWORD_MAX_LENGTH);\r
-\r
-    SmmDev->Sscp.ReceiveData = SecurityReceiveData;\r
-    SmmDev->Sscp.SendData = SecuritySendData;\r
-\r
-    DEBUG ((DEBUG_INFO, "Opal SMM: Insert device node to SmmDeviceList:\n"));\r
-    DEBUG ((DEBUG_INFO, "DeviceType:%x, Bus:%d, Dev:%d, Fun:%d\n", \\r
-      SmmDev->DeviceType, SmmDev->BusNum, SmmDev->DevNum, SmmDev->FuncNum));\r
-    DEBUG ((DEBUG_INFO, "SataPort:%x, MultiplierPort:%x, NvmeNamespaceId:%x\n", \\r
-      SmmDev->SataPort, SmmDev->SataPortMultiplierPort, SmmDev->NvmeNamespaceId));\r
-\r
-    InsertHeadList (SmmDeviceList, &SmmDev->Link);\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Main entry point for an SMM handler dispatch or communicate-based callback.\r
-\r
-  @param[in]     DispatchHandle  The unique handle assigned to this handler by SmiHandlerRegister().\r
-  @param[in]     Context         Points to an optional handler context which was specified when the\r
-                                 handler was registered.\r
-  @param[in,out] CommBuffer      A pointer to a collection of Data in memory that will\r
-                                 be conveyed from a non-SMM environment into an SMM environment.\r
-  @param[in,out] CommBufferSize  The Size of the CommBuffer.\r
-\r
-  @retval EFI_SUCCESS                         The interrupt was handled and quiesced. No other handlers\r
-                                              should still be called.\r
-  @retval EFI_WARN_INTERRUPT_SOURCE_QUIESCED  The interrupt has been quiesced but other handlers should\r
-                                              still be called.\r
-  @retval EFI_WARN_INTERRUPT_SOURCE_PENDING   The interrupt is still pending and other handlers should still\r
-                                              be called.\r
-  @retval EFI_INTERRUPT_PENDING               The interrupt could not be quiesced.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-S3SleepEntryCallBack (\r
-  IN           EFI_HANDLE           DispatchHandle,\r
-  IN     CONST VOID                 *Context         OPTIONAL,\r
-  IN OUT       VOID                 *CommBuffer      OPTIONAL,\r
-  IN OUT       UINTN                *CommBufferSize  OPTIONAL\r
-  )\r
-{\r
-  UINTN                             Bus;\r
-  UINTN                             Device;\r
-  UINTN                             Function;\r
-  UINTN                             Index;\r
-  EFI_STATUS                        Status;\r
-  LIST_ENTRY                        *Entry;\r
-  UINTN                             Offset;\r
-  UINT64                            Address;\r
-  S3_BOOT_SCRIPT_LIB_WIDTH          Width;\r
-  UINT32                            Data;\r
-  OPAL_HC_PCI_REGISTER_SAVE         *HcRegisterSaveListPtr;\r
-  UINTN                             Count;\r
-  OPAL_SMM_DEVICE                   *SmmDev;\r
-\r
-  Data     = 0;\r
-  Status   = EFI_SUCCESS;\r
-\r
-  mOpalDeviceList = OpalSupportGetOpalDeviceList();\r
-  if (IsListEmpty (mOpalDeviceList)) {\r
-    //\r
-    // No Opal enabled device. Do nothing.\r
-    //\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  if (IsListEmpty (&mSmmDeviceList)) {\r
-    //\r
-    // mSmmDeviceList for S3 is empty, creat it by mOpalDeviceList.\r
-    //\r
-    Status = CreateSmmDeviceList (mOpalDeviceList, &mSmmDeviceList);\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    }\r
-  }\r
-\r
-  //\r
-  // Go through SmmDeviceList to save register data for S3\r
-  //\r
-  for (Entry = mSmmDeviceList.ForwardLink; Entry != &mSmmDeviceList; Entry = Entry->ForwardLink) {\r
-    SmmDev = BASE_CR (Entry, OPAL_SMM_DEVICE, Link);\r
-\r
-    if (SmmDev->DeviceType == OPAL_DEVICE_TYPE_NVME) {\r
-      continue;\r
-    }\r
-\r
-    //\r
-    // Save register Data for S3. Sata controller only.\r
-    //\r
-    Bus        = SmmDev->BusNum;\r
-    Device     = SmmDev->DevNum;\r
-    Function   = SmmDev->FuncNum;\r
-\r
-    ASSERT (SmmDev->DeviceType == OPAL_DEVICE_TYPE_SATA);\r
-    HcRegisterSaveListPtr = (OPAL_HC_PCI_REGISTER_SAVE *) mSataHcRegisterSaveTemplate;\r
-    Count = sizeof (mSataHcRegisterSaveTemplate) / sizeof (OPAL_HC_PCI_REGISTER_SAVE);\r
-\r
-    for (Index = 0; Index < Count; Index += 1) {\r
-      Offset  = HcRegisterSaveListPtr[Index].Address;\r
-      Width   = HcRegisterSaveListPtr[Index].Width;\r
-\r
-      switch (Width) {\r
-        case S3BootScriptWidthUint8:\r
-          Data = (UINT32)PciRead8 (PCI_LIB_ADDRESS(Bus,Device,Function,Offset));\r
-          break;\r
-        case S3BootScriptWidthUint16:\r
-          Data = (UINT32)PciRead16 (PCI_LIB_ADDRESS(Bus,Device,Function,Offset));\r
-          break;\r
-        case S3BootScriptWidthUint32:\r
-          Data = PciRead32 (PCI_LIB_ADDRESS(Bus,Device,Function,Offset));\r
-          break;\r
-        default:\r
-          ASSERT (FALSE);\r
-          break;\r
-      }\r
-\r
-      Address = S3_BOOT_SCRIPT_LIB_PCI_ADDRESS (Bus, Device, Function, Offset);\r
-      Status  = S3BootScriptSavePciCfgWrite (Width, Address, 1, &Data);\r
-      if (EFI_ERROR (Status)) {\r
-        return Status;\r
-      }\r
-    }\r
-  }\r
-\r
-  Status = S3BootScriptSaveIoWrite (S3BootScriptWidthUint8, 0xB2, 1, &mSwSmiValue);\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Main entry for this driver.\r
-\r
-  @param ImageHandle     Image handle this driver.\r
-  @param SystemTable     Pointer to SystemTable.\r
-\r
-  @retval EFI_SUCESS     This function always complete successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-OpalPasswordSmmInit (\r
-  IN EFI_HANDLE                         ImageHandle,\r
-  IN EFI_SYSTEM_TABLE                   *SystemTable\r
-  )\r
-{\r
-  EFI_STATUS                            Status;\r
-  EFI_SMM_SW_DISPATCH2_PROTOCOL         *SwDispatch;\r
-  EFI_SMM_SX_DISPATCH2_PROTOCOL         *SxDispatch;\r
-  EFI_HANDLE                            SwHandle;\r
-  EFI_SMM_SW_REGISTER_CONTEXT           Context;\r
-  EFI_HANDLE                            S3SleepEntryHandle;\r
-  EFI_SMM_SX_REGISTER_CONTEXT           EntryRegisterContext;\r
-  EFI_SMM_VARIABLE_PROTOCOL             *SmmVariable;\r
-  OPAL_EXTRA_INFO_VAR                   OpalExtraInfo;\r
-  UINTN                                 DataSize;\r
-  EFI_PHYSICAL_ADDRESS                  Address;\r
-\r
-  mBuffer            = NULL;\r
-  SwHandle           = NULL;\r
-  S3SleepEntryHandle = NULL;\r
-  ZeroMem (&mNvmeContext, sizeof (NVME_CONTEXT));\r
-\r
-  Status = gSmst->SmmLocateProtocol (\r
-                    &gEfiSmmSwDispatch2ProtocolGuid,\r
-                    NULL,\r
-                    (VOID **)&SwDispatch\r
-                    );\r
-  ASSERT_EFI_ERROR (Status);\r
-  if (EFI_ERROR (Status)) {\r
-    DEBUG((DEBUG_ERROR, " SmmLocateProtocol gEfiSmmSwDispatch2ProtocolGuid fail, Status: %r\n", Status));\r
-    return Status;\r
-  }\r
-\r
-  Status = gSmst->SmmLocateProtocol (\r
-                    &gEfiSmmSxDispatch2ProtocolGuid,\r
-                    NULL,\r
-                    (VOID **)&SxDispatch\r
-                    );\r
-  ASSERT_EFI_ERROR (Status);\r
-  if (EFI_ERROR (Status)) {\r
-    DEBUG((DEBUG_ERROR, " SmmLocateProtocol gEfiSmmSxDispatch2ProtocolGuid fail, Status: %r\n", Status));\r
-    return Status;\r
-  }\r
-\r
-  //\r
-  // Preallocate a 512 bytes Buffer to perform trusted I/O.\r
-  // Assume this is big enough for unlock commands\r
-  // It's because DMA can not access smmram stack at the cmd execution.\r
-  //\r
-  Address = 0xFFFFFFFF;\r
-  Status = gBS->AllocatePages (\r
-                  AllocateMaxAddress,\r
-                  EfiACPIMemoryNVS,\r
-                  EFI_SIZE_TO_PAGES (SMM_SIZE_ALLOC_BYTES),\r
-                  &Address\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    DEBUG((DEBUG_ERROR, " AllocatePages for SATA DAM fail, Status: %r\n", Status));\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  mBuffer = (VOID *)(UINTN)Address;\r
-  ZeroMem ((VOID *)(UINTN)mBuffer, SMM_SIZE_ALLOC_BYTES);\r
-\r
-  //\r
-  // Preallocate resource for AHCI transfer descriptor.\r
-  //\r
-  Status = AhciAllocateResource ();\r
-  if (EFI_ERROR (Status)) {\r
-    DEBUG((DEBUG_ERROR, " AhciAllocateResource fail, Status: %r\n", Status));\r
-    Status = EFI_OUT_OF_RESOURCES;\r
-    goto EXIT;\r
-  }\r
-\r
-  //\r
-  // Preallocate resource for NVMe configuration space.\r
-  //\r
-  Status = NvmeAllocateResource (ImageHandle, &mNvmeContext);\r
-  if (EFI_ERROR (Status)) {\r
-    DEBUG((DEBUG_ERROR, " NvmeAllocateResource fail, Status: %r\n", Status));\r
-    Status = EFI_OUT_OF_RESOURCES;\r
-    goto EXIT;\r
-  }\r
-\r
-  //\r
-  // Register a S3 entry callback function to store ATA host controller context to boot script.\r
-  // These boot scripts would be invoked at S3 path to recovery ATA host controller h/w context\r
-  // for executing HDD unlock cmd.\r
-  //\r
-  EntryRegisterContext.Type  = SxS3;\r
-  EntryRegisterContext.Phase = SxEntry;\r
-  Status = SxDispatch->Register (\r
-                         SxDispatch,\r
-                         S3SleepEntryCallBack,\r
-                         &EntryRegisterContext,\r
-                         &S3SleepEntryHandle\r
-                         );\r
-  ASSERT_EFI_ERROR (Status);\r
-  if (EFI_ERROR (Status)) {\r
-    goto EXIT;\r
-  }\r
-\r
-  //\r
-  // Register Opal password smm unlock handler\r
-  //\r
-  Context.SwSmiInputValue = (UINTN) -1;\r
-  Status = SwDispatch->Register (\r
-               SwDispatch,\r
-               SmmUnlockOpalPassword,\r
-               &Context,\r
-               &SwHandle\r
-               );\r
-  ASSERT_EFI_ERROR (Status);\r
-  if (EFI_ERROR (Status)) {\r
-    DEBUG((DEBUG_ERROR, " SwDispatch->Register fail, Status: %r\n", Status));\r
-    goto EXIT;\r
-  }\r
-\r
-  //\r
-  // trigger smi to unlock hdd if it's locked.\r
-  //\r
-  mSwSmiValue = (UINT8) Context.SwSmiInputValue;\r
-\r
-  Status = gSmst->SmmLocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, (VOID**)&SmmVariable);\r
-  if (!EFI_ERROR (Status)) {\r
-    DataSize = sizeof (OPAL_EXTRA_INFO_VAR);\r
-    Status = SmmVariable->SmmGetVariable (\r
-                    OPAL_EXTRA_INFO_VAR_NAME,\r
-                    &gOpalExtraInfoVariableGuid,\r
-                    NULL,\r
-                    &DataSize,\r
-                    &OpalExtraInfo\r
-                    );\r
-    if (!EFI_ERROR (Status)) {\r
-      mSendBlockSID = OpalExtraInfo.EnableBlockSid;\r
-    }\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-\r
-EXIT:\r
-  if (S3SleepEntryHandle != NULL) {\r
-    SxDispatch->UnRegister (SxDispatch, S3SleepEntryHandle);\r
-  }\r
-\r
-  AhciFreeResource ();\r
-\r
-  NvmeFreeResource (&mNvmeContext);\r
-\r
-  if (mBuffer != NULL) {\r
-    gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN) mBuffer, EFI_SIZE_TO_PAGES (SMM_SIZE_ALLOC_BYTES));\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Provide Io action support.\r
-\r
-  @param[in]     SmmDev             the opal device need to perform trust io.\r
-  @param[in]     IoType             OPAL_IO_TYPE indicating whether to perform a Trusted Send or Trusted Receive.\r
-  @param[in]     SecurityProtocol   Security Protocol\r
-  @param[in]     SpSpecific         Security Protocol Specific\r
-  @param[in]     TransferLength     Transfer Length of Buffer (in bytes) - always a multiple of 512\r
-  @param[in]     Buffer             Address of Data to transfer\r
-\r
-  @retval        TcgResultSuccess   Perform the io action success.\r
-  @retval        TcgResultFailure   Perform the io action failed.\r
-\r
-**/\r
-EFI_STATUS\r
-PerformTrustedIo (\r
-  OPAL_SMM_DEVICE  *SmmDev,\r
-  OPAL_IO_TYPE     IoType,\r
-  UINT8            SecurityProtocol,\r
-  UINT16           SpSpecific,\r
-  UINTN            TransferLength,\r
-  VOID             *Buffer\r
-  )\r
-{\r
-  EFI_STATUS                   Status;\r
-  UINTN                        BufferSizeBlocks;\r
-  EFI_ATA_COMMAND_BLOCK        AtaCommandBlock;\r
-\r
-  Status = EFI_DEVICE_ERROR;\r
-  if (SmmDev->DeviceType == OPAL_DEVICE_TYPE_SATA) {\r
-    BufferSizeBlocks = TransferLength / 512;\r
-\r
-    ZeroMem( &AtaCommandBlock, sizeof( EFI_ATA_COMMAND_BLOCK ) );\r
-    AtaCommandBlock.AtaCommand = ( IoType == OpalSend ) ? ATA_COMMAND_TRUSTED_SEND : ATA_COMMAND_TRUSTED_RECEIVE;\r
-    AtaCommandBlock.AtaSectorCount = ( UINT8 )BufferSizeBlocks;\r
-    AtaCommandBlock.AtaSectorNumber = ( UINT8 )( BufferSizeBlocks >> 8 );\r
-    AtaCommandBlock.AtaFeatures = SecurityProtocol;\r
-    AtaCommandBlock.AtaCylinderLow = ( UINT8 )( SpSpecific >> 8 );\r
-    AtaCommandBlock.AtaCylinderHigh = ( UINT8 )( SpSpecific );\r
-    AtaCommandBlock.AtaDeviceHead = ATA_DEVICE_LBA;\r
-\r
-\r
-    ZeroMem( mBuffer, HDD_PAYLOAD );\r
-    ASSERT( TransferLength <= HDD_PAYLOAD );\r
-\r
-    if (IoType == OpalSend) {\r
-      CopyMem( mBuffer, Buffer, TransferLength );\r
-    }\r
-\r
-    Status = AhciPioTransfer(\r
-                &mAhciRegisters,\r
-                (UINT8) SmmDev->SataPort,\r
-                (UINT8) SmmDev->SataPortMultiplierPort,\r
-                NULL,\r
-                0,\r
-                ( IoType == OpalSend ) ? FALSE : TRUE,   // i/o direction\r
-                &AtaCommandBlock,\r
-                NULL,\r
-                mBuffer,\r
-                (UINT32)TransferLength,\r
-                ATA_TIMEOUT\r
-                );\r
-\r
-    if (IoType == OpalRecv) {\r
-      CopyMem( Buffer, mBuffer, TransferLength );\r
-    }\r
-  } else if (SmmDev->DeviceType == OPAL_DEVICE_TYPE_NVME) {\r
-    Status = NvmeSecuritySendReceive (\r
-                &mNvmeContext,\r
-                IoType == OpalSend,\r
-                SecurityProtocol,\r
-                SwapBytes16(SpSpecific),\r
-                TransferLength,\r
-                Buffer\r
-              );\r
-  } else {\r
-    DEBUG((DEBUG_ERROR, "DeviceType(%x) not support.\n", SmmDev->DeviceType));\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Send a security protocol command to a device that receives data and/or the result\r
-  of one or more commands sent by SendData.\r
-\r
-  The ReceiveData function sends a security protocol command to the given MediaId.\r
-  The security protocol command sent is defined by SecurityProtocolId and contains\r
-  the security protocol specific data SecurityProtocolSpecificData. The function\r
-  returns the data from the security protocol command in PayloadBuffer.\r
-\r
-  For devices supporting the SCSI command set, the security protocol command is sent\r
-  using the SECURITY PROTOCOL IN command defined in SPC-4.\r
-\r
-  For devices supporting the ATA command set, the security protocol command is sent\r
-  using one of the TRUSTED RECEIVE commands defined in ATA8-ACS if PayloadBufferSize\r
-  is non-zero.\r
-\r
-  If the PayloadBufferSize is zero, the security protocol command is sent using the\r
-  Trusted Non-Data command defined in ATA8-ACS.\r
-\r
-  If PayloadBufferSize is too small to store the available data from the security\r
-  protocol command, the function shall copy PayloadBufferSize bytes into the\r
-  PayloadBuffer and return EFI_WARN_BUFFER_TOO_SMALL.\r
-\r
-  If PayloadBuffer or PayloadTransferSize is NULL and PayloadBufferSize is non-zero,\r
-  the function shall return EFI_INVALID_PARAMETER.\r
-\r
-  If the given MediaId does not support security protocol commands, the function shall\r
-  return EFI_UNSUPPORTED. If there is no media in the device, the function returns\r
-  EFI_NO_MEDIA. If the MediaId is not the ID for the current media in the device,\r
-  the function returns EFI_MEDIA_CHANGED.\r
-\r
-  If the security protocol fails to complete within the Timeout period, the function\r
-  shall return EFI_TIMEOUT.\r
-\r
-  If the security protocol command completes without an error, the function shall\r
-  return EFI_SUCCESS. If the security protocol command completes with an error, the\r
-  function shall return EFI_DEVICE_ERROR.\r
-\r
-  @param  This                         Indicates a pointer to the calling context.\r
-  @param  MediaId                      ID of the medium to receive data from.\r
-  @param  Timeout                      The timeout, in 100ns units, to use for the execution\r
-                                       of the security protocol command. A Timeout value of 0\r
-                                       means that this function will wait indefinitely for the\r
-                                       security protocol command to execute. If Timeout is greater\r
-                                       than zero, then this function will return EFI_TIMEOUT\r
-                                       if the time required to execute the receive data command\r
-                                       is greater than Timeout.\r
-  @param  SecurityProtocolId           The value of the "Security Protocol" parameter of\r
-                                       the security protocol command to be sent.\r
-  @param  SecurityProtocolSpecificData The value of the "Security Protocol Specific" parameter\r
-                                       of the security protocol command to be sent.\r
-  @param  PayloadBufferSize            Size in bytes of the payload data buffer.\r
-  @param  PayloadBuffer                A pointer to a destination buffer to store the security\r
-                                       protocol command specific payload data for the security\r
-                                       protocol command. The caller is responsible for having\r
-                                       either implicit or explicit ownership of the buffer.\r
-  @param  PayloadTransferSize          A pointer to a buffer to store the size in bytes of the\r
-                                       data written to the payload data buffer.\r
-\r
-  @retval EFI_SUCCESS                  The security protocol command completed successfully.\r
-  @retval EFI_WARN_BUFFER_TOO_SMALL    The PayloadBufferSize was too small to store the available\r
-                                       data from the device. The PayloadBuffer contains the truncated data.\r
-  @retval EFI_UNSUPPORTED              The given MediaId does not support security protocol commands.\r
-  @retval EFI_DEVICE_ERROR             The security protocol command completed with an error.\r
-  @retval EFI_NO_MEDIA                 There is no media in the device.\r
-  @retval EFI_MEDIA_CHANGED            The MediaId is not for the current media.\r
-  @retval EFI_INVALID_PARAMETER        The PayloadBuffer or PayloadTransferSize is NULL and\r
-                                       PayloadBufferSize is non-zero.\r
-  @retval EFI_TIMEOUT                  A timeout occurred while waiting for the security\r
-                                       protocol command to execute.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-SecurityReceiveData (\r
-  IN  EFI_STORAGE_SECURITY_COMMAND_PROTOCOL    *This,\r
-  IN  UINT32                                   MediaId,\r
-  IN  UINT64                                   Timeout,\r
-  IN  UINT8                                    SecurityProtocolId,\r
-  IN  UINT16                                   SecurityProtocolSpecificData,\r
-  IN  UINTN                                    PayloadBufferSize,\r
-  OUT VOID                                     *PayloadBuffer,\r
-  OUT UINTN                                    *PayloadTransferSize\r
-  )\r
-{\r
-  OPAL_SMM_DEVICE              *SmmDev;\r
-\r
-  SmmDev = OPAL_SMM_DEVICE_FROM_THIS (This);\r
-  if (SmmDev == NULL) {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  return PerformTrustedIo (\r
-                        SmmDev,\r
-                        OpalRecv,\r
-                        SecurityProtocolId,\r
-                        SecurityProtocolSpecificData,\r
-                        PayloadBufferSize,\r
-                        PayloadBuffer\r
-                        );\r
-}\r
-\r
-/**\r
-  Send a security protocol command to a device.\r
-\r
-  The SendData function sends a security protocol command containing the payload\r
-  PayloadBuffer to the given MediaId. The security protocol command sent is\r
-  defined by SecurityProtocolId and contains the security protocol specific data\r
-  SecurityProtocolSpecificData. If the underlying protocol command requires a\r
-  specific padding for the command payload, the SendData function shall add padding\r
-  bytes to the command payload to satisfy the padding requirements.\r
-\r
-  For devices supporting the SCSI command set, the security protocol command is sent\r
-  using the SECURITY PROTOCOL OUT command defined in SPC-4.\r
-\r
-  For devices supporting the ATA command set, the security protocol command is sent\r
-  using one of the TRUSTED SEND commands defined in ATA8-ACS if PayloadBufferSize\r
-  is non-zero. If the PayloadBufferSize is zero, the security protocol command is\r
-  sent using the Trusted Non-Data command defined in ATA8-ACS.\r
-\r
-  If PayloadBuffer is NULL and PayloadBufferSize is non-zero, the function shall\r
-  return EFI_INVALID_PARAMETER.\r
-\r
-  If the given MediaId does not support security protocol commands, the function\r
-  shall return EFI_UNSUPPORTED. If there is no media in the device, the function\r
-  returns EFI_NO_MEDIA. If the MediaId is not the ID for the current media in the\r
-  device, the function returns EFI_MEDIA_CHANGED.\r
-\r
-  If the security protocol fails to complete within the Timeout period, the function\r
-  shall return EFI_TIMEOUT.\r
-\r
-  If the security protocol command completes without an error, the function shall return\r
-  EFI_SUCCESS. If the security protocol command completes with an error, the function\r
-  shall return EFI_DEVICE_ERROR.\r
-\r
-  @param  This                         Indicates a pointer to the calling context.\r
-  @param  MediaId                      ID of the medium to receive data from.\r
-  @param  Timeout                      The timeout, in 100ns units, to use for the execution\r
-                                       of the security protocol command. A Timeout value of 0\r
-                                       means that this function will wait indefinitely for the\r
-                                       security protocol command to execute. If Timeout is greater\r
-                                       than zero, then this function will return EFI_TIMEOUT\r
-                                       if the time required to execute the send data command\r
-                                       is greater than Timeout.\r
-  @param  SecurityProtocolId           The value of the "Security Protocol" parameter of\r
-                                       the security protocol command to be sent.\r
-  @param  SecurityProtocolSpecificData The value of the "Security Protocol Specific" parameter\r
-                                       of the security protocol command to be sent.\r
-  @param  PayloadBufferSize            Size in bytes of the payload data buffer.\r
-  @param  PayloadBuffer                A pointer to a destination buffer to store the security\r
-                                       protocol command specific payload data for the security\r
-                                       protocol command.\r
-\r
-  @retval EFI_SUCCESS                  The security protocol command completed successfully.\r
-  @retval EFI_UNSUPPORTED              The given MediaId does not support security protocol commands.\r
-  @retval EFI_DEVICE_ERROR             The security protocol command completed with an error.\r
-  @retval EFI_NO_MEDIA                 There is no media in the device.\r
-  @retval EFI_MEDIA_CHANGED            The MediaId is not for the current media.\r
-  @retval EFI_INVALID_PARAMETER        The PayloadBuffer is NULL and PayloadBufferSize is non-zero.\r
-  @retval EFI_TIMEOUT                  A timeout occurred while waiting for the security\r
-                                       protocol command to execute.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-SecuritySendData (\r
-  IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL    *This,\r
-  IN UINT32                                   MediaId,\r
-  IN UINT64                                   Timeout,\r
-  IN UINT8                                    SecurityProtocolId,\r
-  IN UINT16                                   SecurityProtocolSpecificData,\r
-  IN UINTN                                    PayloadBufferSize,\r
-  IN VOID                                     *PayloadBuffer\r
-  )\r
-{\r
-  OPAL_SMM_DEVICE              *SmmDev;\r
-\r
-  SmmDev = OPAL_SMM_DEVICE_FROM_THIS (This);\r
-  if (SmmDev == NULL) {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  return PerformTrustedIo (\r
-                          SmmDev,\r
-                          OpalSend,\r
-                          SecurityProtocolId,\r
-                          SecurityProtocolSpecificData,\r
-                          PayloadBufferSize,\r
-                          PayloadBuffer\r
-                          );\r
-\r
-}\r
-\r