/** @file
  Entrypoint of Opal UEFI Driver and contains all the logic to
  register for new Opal device instances.

Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

// This UEFI driver consumes EFI_STORAGE_SECURITY_PROTOCOL instances and installs an
// HII GUI to manage Opal features if the device is Opal capable
// If the Opal device is being managed by the UEFI Driver, it shall provide a popup
// window during boot requesting a user password

#include "OpalDriver.h"
#include "OpalHii.h"

EFI_GUID  mOpalDeviceLockBoxGuid = OPAL_DEVICE_LOCKBOX_GUID;

BOOLEAN                mOpalEndOfDxe            = FALSE;
OPAL_REQUEST_VARIABLE  *mOpalRequestVariable    = NULL;
UINTN                  mOpalRequestVariableSize = 0;
CHAR16                 mPopUpString[100];

OPAL_DRIVER  mOpalDriver;

//
// Globals
//
EFI_DRIVER_BINDING_PROTOCOL  gOpalDriverBinding = {
  OpalEfiDriverBindingSupported,
  OpalEfiDriverBindingStart,
  OpalEfiDriverBindingStop,
  0x1b,
  NULL,
  NULL
};

/**

  The function determines the available actions for the OPAL_DISK provided.

  @param[in]   SupportedAttributes   The supported attributes for the device.
  @param[in]   LockingFeature        The locking status for the device.
  @param[in]   OwnerShip             The ownership for the device.
  @param[out]  AvalDiskActions       Pointer to fill-out with appropriate disk actions.

**/
TCG_RESULT
EFIAPI
OpalSupportGetAvailableActions (
  IN  OPAL_DISK_SUPPORT_ATTRIBUTE     *SupportedAttributes,
  IN  TCG_LOCKING_FEATURE_DESCRIPTOR  *LockingFeature,
  IN  UINT16                          OwnerShip,
  OUT OPAL_DISK_ACTIONS               *AvalDiskActions
  )
{
  BOOLEAN  ExistingPassword;

  NULL_CHECK (AvalDiskActions);

  AvalDiskActions->AdminPass   = 1;
  AvalDiskActions->UserPass    = 0;
  AvalDiskActions->DisableUser = 0;
  AvalDiskActions->Unlock      = 0;

  //
  // Revert is performed on locking sp, so only allow if locking sp is enabled
  //
  if (LockingFeature->LockingEnabled) {
    AvalDiskActions->Revert = 1;
  }

  //
  // Psid revert is available for any device with media encryption support or pyrite 2.0 type support.
  //
  if (SupportedAttributes->PyriteSscV2 || SupportedAttributes->MediaEncryption) {
    //
    // Only allow psid revert if media encryption is enabled or pyrite 2.0 type support..
    // Otherwise, someone who steals a disk can psid revert the disk and the user Data is still
    // intact and accessible
    //
    AvalDiskActions->PsidRevert           = 1;
    AvalDiskActions->RevertKeepDataForced = 0;

    //
    // Secure erase is performed by generating a new encryption key
    // this is only available if encryption is supported
    //
    AvalDiskActions->SecureErase = 1;
  } else {
    AvalDiskActions->PsidRevert  = 0;
    AvalDiskActions->SecureErase = 0;

    //
    // If no media encryption is supported, then a revert (using password) will not
    // erase the Data (since you can't generate a new encryption key)
    //
    AvalDiskActions->RevertKeepDataForced = 1;
  }

  if (LockingFeature->Locked) {
    AvalDiskActions->Unlock = 1;
  } else {
    AvalDiskActions->Unlock = 0;
  }

  //
  // Only allow user to set password if an admin password exists
  //
  ExistingPassword          = OpalUtilAdminPasswordExists (OwnerShip, LockingFeature);
  AvalDiskActions->UserPass = ExistingPassword;

  //
  // This will still show up even if there isn't a user, which is fine
  //
  AvalDiskActions->DisableUser = ExistingPassword;

  return TcgResultSuccess;
}

/**
  Enable Opal Feature for the input device.

  @param[in]      Session            The opal session for the opal device.
  @param[in]      Msid               Msid
  @param[in]      MsidLength         Msid Length
  @param[in]      Password           Admin password
  @param[in]      PassLength         Length of password in bytes

**/
TCG_RESULT
EFIAPI
OpalSupportEnableOpalFeature (
  IN OPAL_SESSION  *Session,
  IN VOID          *Msid,
  IN UINT32        MsidLength,
  IN VOID          *Password,
  IN UINT32        PassLength
  )
{
  TCG_RESULT  Ret;

  NULL_CHECK (Session);
  NULL_CHECK (Msid);
  NULL_CHECK (Password);

  Ret = OpalUtilSetAdminPasswordAsSid (
          Session,
          Msid,
          MsidLength,
          Password,
          PassLength
          );
  if (Ret == TcgResultSuccess) {
    //
    // Enable global locking range
    //
    Ret = OpalUtilSetOpalLockingRange (
            Session,
            Password,
            PassLength,
            OPAL_LOCKING_SP_LOCKING_GLOBALRANGE,
            0,
            0,
            TRUE,
            TRUE,
            FALSE,
            FALSE
            );
  }

  return Ret;
}

/**
  Update password for the Opal disk.

  @param[in, out] OpalDisk          The disk to update password.
  @param[in]      Password          The input password.
  @param[in]      PasswordLength    The input password length.

**/
VOID
OpalSupportUpdatePassword (
  IN OUT OPAL_DISK  *OpalDisk,
  IN VOID           *Password,
  IN UINT32         PasswordLength
  )
{
  CopyMem (OpalDisk->Password, Password, PasswordLength);
  OpalDisk->PasswordLength = (UINT8)PasswordLength;
}

/**
  Extract device info from the device path.

  @param[in]  DevicePath        Device path info for the device.
  @param[out] DevInfoLength     Device information length needed.
  @param[out] DevInfo           Device information extracted.

**/
VOID
ExtractDeviceInfoFromDevicePath (
  IN  EFI_DEVICE_PATH_PROTOCOL  *DevicePath,
  OUT UINT32                    *DevInfoLength,
  OUT OPAL_DEVICE_LOCKBOX_DATA  *DevInfo OPTIONAL
  )
{
  EFI_DEVICE_PATH_PROTOCOL  *TmpDevPath;
  EFI_DEVICE_PATH_PROTOCOL  *TmpDevPath2;
  PCI_DEVICE_PATH           *PciDevPath;
  UINT8                     DeviceType;
  UINT8                     BusNum;
  OPAL_PCI_DEVICE           *PciDevice;

  ASSERT (DevicePath != NULL);
  ASSERT (DevInfoLength != NULL);

  DeviceType     = OPAL_DEVICE_TYPE_UNKNOWN;
  *DevInfoLength = 0;

  TmpDevPath = DevicePath;

  //
  // Get device type.
  //
  while (!IsDevicePathEnd (TmpDevPath)) {
    if ((TmpDevPath->Type == MESSAGING_DEVICE_PATH) &&
        ((TmpDevPath->SubType == MSG_SATA_DP) || (TmpDevPath->SubType == MSG_NVME_NAMESPACE_DP)))
    {
      if (DevInfo != NULL) {
        DevInfo->DevicePathLength = (UINT32)GetDevicePathSize (DevicePath);
        CopyMem (DevInfo->DevicePath, DevicePath, DevInfo->DevicePathLength);
      }

      DeviceType     = (TmpDevPath->SubType == MSG_SATA_DP) ? OPAL_DEVICE_TYPE_ATA : OPAL_DEVICE_TYPE_NVME;
      *DevInfoLength = sizeof (OPAL_DEVICE_LOCKBOX_DATA) + (UINT32)GetDevicePathSize (DevicePath);
      break;
    }

    TmpDevPath = NextDevicePathNode (TmpDevPath);
  }

  //
  // Get device info.
  //
  BusNum      = 0;
  TmpDevPath  = DevicePath;
  TmpDevPath2 = NextDevicePathNode (DevicePath);
  while (!IsDevicePathEnd (TmpDevPath2)) {
    if ((TmpDevPath->Type == HARDWARE_DEVICE_PATH) && (TmpDevPath->SubType == HW_PCI_DP)) {
      PciDevPath = (PCI_DEVICE_PATH *)TmpDevPath;
      if ((TmpDevPath2->Type == MESSAGING_DEVICE_PATH) &&
          ((TmpDevPath2->SubType == MSG_SATA_DP) || (TmpDevPath2->SubType == MSG_NVME_NAMESPACE_DP)))
      {
        if (DevInfo != NULL) {
          PciDevice           = &DevInfo->Device;
          PciDevice->Segment  = 0;
          PciDevice->Bus      = BusNum;
          PciDevice->Device   = PciDevPath->Device;
          PciDevice->Function = PciDevPath->Function;
        }
      } else {
        if ((TmpDevPath2->Type == HARDWARE_DEVICE_PATH) && (TmpDevPath2->SubType == HW_PCI_DP)) {
          BusNum = PciRead8 (PCI_LIB_ADDRESS (BusNum, PciDevPath->Device, PciDevPath->Function, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET));
        }
      }
    }

    TmpDevPath  = NextDevicePathNode (TmpDevPath);
    TmpDevPath2 = NextDevicePathNode (TmpDevPath2);
  }

  ASSERT (DeviceType != OPAL_DEVICE_TYPE_UNKNOWN);
  return;
}

/**
  Build OPAL device info and save them to LockBox.

 **/
VOID
BuildOpalDeviceInfo (
  VOID
  )
{
  EFI_STATUS                Status;
  OPAL_DEVICE_LOCKBOX_DATA  *DevInfo;
  OPAL_DEVICE_LOCKBOX_DATA  *TempDevInfo;
  UINTN                     TotalDevInfoLength;
  UINT32                    DevInfoLength;
  OPAL_DRIVER_DEVICE        *TmpDev;
  UINT8                     DummyData;
  BOOLEAN                   S3InitDevicesExist;
  UINTN                     S3InitDevicesLength;
  EFI_DEVICE_PATH_PROTOCOL  *S3InitDevices;
  EFI_DEVICE_PATH_PROTOCOL  *S3InitDevicesBak;

  //
  // Build OPAL device info and save them to LockBox.
  //
  TotalDevInfoLength = 0;
  TmpDev             = mOpalDriver.DeviceList;
  while (TmpDev != NULL) {
    ExtractDeviceInfoFromDevicePath (
      TmpDev->OpalDisk.OpalDevicePath,
      &DevInfoLength,
      NULL
      );
    TotalDevInfoLength += DevInfoLength;
    TmpDev              = TmpDev->Next;
  }

  if (TotalDevInfoLength == 0) {
    return;
  }

  S3InitDevicesLength = sizeof (DummyData);
  Status              = RestoreLockBox (
                          &gS3StorageDeviceInitListGuid,
                          &DummyData,
                          &S3InitDevicesLength
                          );
  ASSERT ((Status == EFI_NOT_FOUND) || (Status == EFI_BUFFER_TOO_SMALL));
  if (Status == EFI_NOT_FOUND) {
    S3InitDevices      = NULL;
    S3InitDevicesExist = FALSE;
  } else if (Status == EFI_BUFFER_TOO_SMALL) {
    S3InitDevices = AllocatePool (S3InitDevicesLength);
    ASSERT (S3InitDevices != NULL);
    if (S3InitDevices == NULL) {
      return;
    }

    Status = RestoreLockBox (
               &gS3StorageDeviceInitListGuid,
               S3InitDevices,
               &S3InitDevicesLength
               );
    ASSERT_EFI_ERROR (Status);
    S3InitDevicesExist = TRUE;
  } else {
    return;
  }

  DevInfo = AllocateZeroPool (TotalDevInfoLength);
  ASSERT (DevInfo != NULL);
  if (DevInfo == NULL) {
    return;
  }

  TempDevInfo = DevInfo;
  TmpDev      = mOpalDriver.DeviceList;
  while (TmpDev != NULL) {
    ExtractDeviceInfoFromDevicePath (
      TmpDev->OpalDisk.OpalDevicePath,
      &DevInfoLength,
      TempDevInfo
      );
    TempDevInfo->Length        = DevInfoLength;
    TempDevInfo->OpalBaseComId = TmpDev->OpalDisk.OpalBaseComId;
    CopyMem (
      TempDevInfo->Password,
      TmpDev->OpalDisk.Password,
      TmpDev->OpalDisk.PasswordLength
      );
    TempDevInfo->PasswordLength = TmpDev->OpalDisk.PasswordLength;

    S3InitDevicesBak = S3InitDevices;
    S3InitDevices    = AppendDevicePathInstance (
                         S3InitDevicesBak,
                         TmpDev->OpalDisk.OpalDevicePath
                         );
    if (S3InitDevicesBak != NULL) {
      FreePool (S3InitDevicesBak);
    }

    ASSERT (S3InitDevices != NULL);
    if (S3InitDevices == NULL) {
      return;
    }

    TempDevInfo = (OPAL_DEVICE_LOCKBOX_DATA *)((UINTN)TempDevInfo + DevInfoLength);
    TmpDev      = TmpDev->Next;
  }

  Status = SaveLockBox (
             &mOpalDeviceLockBoxGuid,
             DevInfo,
             TotalDevInfoLength
             );
  ASSERT_EFI_ERROR (Status);

  Status = SetLockBoxAttributes (
             &mOpalDeviceLockBoxGuid,
             LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
             );
  ASSERT_EFI_ERROR (Status);

  S3InitDevicesLength = GetDevicePathSize (S3InitDevices);
  if (S3InitDevicesExist) {
    Status = UpdateLockBox (
               &gS3StorageDeviceInitListGuid,
               0,
               S3InitDevices,
               S3InitDevicesLength
               );
    ASSERT_EFI_ERROR (Status);
  } else {
    Status = SaveLockBox (
               &gS3StorageDeviceInitListGuid,
               S3InitDevices,
               S3InitDevicesLength
               );
    ASSERT_EFI_ERROR (Status);

    Status = SetLockBoxAttributes (
               &gS3StorageDeviceInitListGuid,
               LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
               );
    ASSERT_EFI_ERROR (Status);
  }

  ZeroMem (DevInfo, TotalDevInfoLength);
  FreePool (DevInfo);
  FreePool (S3InitDevices);
}

/**

  Send BlockSid command if needed.

**/
VOID
SendBlockSidCommand (
  VOID
  )
{
  OPAL_DRIVER_DEVICE  *Itr;
  TCG_RESULT          Result;
  OPAL_SESSION        Session;
  UINT32              PpStorageFlag;

  PpStorageFlag = Tcg2PhysicalPresenceLibGetManagementFlags ();
  if ((PpStorageFlag & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_ENABLE_BLOCK_SID) != 0) {
    //
    // Send BlockSID command to each Opal disk
    //
    Itr = mOpalDriver.DeviceList;
    while (Itr != NULL) {
      if (Itr->OpalDisk.SupportedAttributes.BlockSid) {
        ZeroMem (&Session, sizeof (Session));
        Session.Sscp          = Itr->OpalDisk.Sscp;
        Session.MediaId       = Itr->OpalDisk.MediaId;
        Session.OpalBaseComId = Itr->OpalDisk.OpalBaseComId;

        DEBUG ((DEBUG_INFO, "OpalPassword: EndOfDxe point, send BlockSid command to device!\n"));
        Result = OpalBlockSid (&Session, TRUE);  // HardwareReset must always be TRUE
        if (Result != TcgResultSuccess) {
          DEBUG ((DEBUG_ERROR, "OpalBlockSid fail\n"));
          break;
        }

        //
        // Record BlockSID command has been sent.
        //
        Itr->OpalDisk.SentBlockSID = TRUE;
      }

      Itr = Itr->Next;
    }
  }
}

/**
  Notification function of EFI_END_OF_DXE_EVENT_GROUP_GUID event group.

  This is a notification function registered on EFI_END_OF_DXE_EVENT_GROUP_GUID event group.

  @param  Event        Event whose notification function is being invoked.
  @param  Context      Pointer to the notification function's context.

**/
VOID
EFIAPI
OpalEndOfDxeEventNotify (
  EFI_EVENT  Event,
  VOID       *Context
  )
{
  OPAL_DRIVER_DEVICE  *TmpDev;

  DEBUG ((DEBUG_INFO, "%a() - enter\n", __func__));

  mOpalEndOfDxe = TRUE;

  if (mOpalRequestVariable != NULL) {
    //
    // Free the OPAL request variable buffer here
    // as the OPAL requests should have been processed.
    //
    FreePool (mOpalRequestVariable);
    mOpalRequestVariable     = NULL;
    mOpalRequestVariableSize = 0;
  }

  //
  // If no any device, return directly.
  //
  if (mOpalDriver.DeviceList == NULL) {
    gBS->CloseEvent (Event);
    return;
  }

  BuildOpalDeviceInfo ();

  //
  // Zero passsword.
  //
  TmpDev = mOpalDriver.DeviceList;
  while (TmpDev != NULL) {
    ZeroMem (TmpDev->OpalDisk.Password, TmpDev->OpalDisk.PasswordLength);
    TmpDev = TmpDev->Next;
  }

  //
  // Send BlockSid command if needed.
  //
  SendBlockSidCommand ();

  DEBUG ((DEBUG_INFO, "%a() - exit\n", __func__));

  gBS->CloseEvent (Event);
}

/**
  Get Psid input from the popup window.

  @param[in]  Dev           The device which need Psid to process Psid Revert
                            OPAL request.
  @param[in]  PopUpString   Pop up string.
  @param[in]  PopUpString2  Pop up string in line 2.
  @param[in]  PopUpString3  Pop up string in line 3.

  @param[out] PressEsc      Whether user escape function through Press ESC.

  @retval Psid string if success. NULL if failed.

**/
CHAR8 *
OpalDriverPopUpPsidInput (
  IN OPAL_DRIVER_DEVICE  *Dev,
  IN CHAR16              *PopUpString,
  IN CHAR16              *PopUpString2,
  IN CHAR16              *PopUpString3,
  OUT BOOLEAN            *PressEsc
  )
{
  EFI_INPUT_KEY  InputKey;
  UINTN          InputLength;
  CHAR16         Mask[PSID_CHARACTER_LENGTH + 1];
  CHAR16         Unicode[PSID_CHARACTER_LENGTH + 1];
  CHAR8          *Ascii;

  ZeroMem (Unicode, sizeof (Unicode));
  ZeroMem (Mask, sizeof (Mask));

  *PressEsc = FALSE;

  gST->ConOut->ClearScreen (gST->ConOut);

  InputLength = 0;
  while (TRUE) {
    Mask[InputLength] = L'_';
    if (PopUpString2 == NULL) {
      CreatePopUp (
        EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
        &InputKey,
        PopUpString,
        L"---------------------",
        Mask,
        NULL
        );
    } else {
      if (PopUpString3 == NULL) {
        CreatePopUp (
          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
          &InputKey,
          PopUpString,
          PopUpString2,
          L"---------------------",
          Mask,
          NULL
          );
      } else {
        CreatePopUp (
          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
          &InputKey,
          PopUpString,
          PopUpString2,
          PopUpString3,
          L"---------------------",
          Mask,
          NULL
          );
      }
    }

    //
    // Check key.
    //
    if (InputKey.ScanCode == SCAN_NULL) {
      //
      // password finished
      //
      if (InputKey.UnicodeChar == CHAR_CARRIAGE_RETURN) {
        //
        // Add the null terminator.
        //
        Unicode[InputLength] = 0;
        Mask[InputLength]    = 0;
        break;
      } else if ((InputKey.UnicodeChar == CHAR_NULL) ||
                 (InputKey.UnicodeChar == CHAR_TAB) ||
                 (InputKey.UnicodeChar == CHAR_LINEFEED)
                 )
      {
        continue;
      } else {
        //
        // delete last key entered
        //
        if (InputKey.UnicodeChar == CHAR_BACKSPACE) {
          if (InputLength > 0) {
            Unicode[InputLength] = 0;
            Mask[InputLength]    = 0;
            InputLength--;
          }
        } else {
          //
          // add Next key entry
          //
          Unicode[InputLength] = InputKey.UnicodeChar;
          Mask[InputLength]    = InputKey.UnicodeChar;
          InputLength++;
          if (InputLength == PSID_CHARACTER_LENGTH) {
            //
            // Add the null terminator.
            //
            Unicode[InputLength] = 0;
            Mask[InputLength]    = 0;
            break;
          }
        }
      }
    }

    //
    // exit on ESC
    //
    if (InputKey.ScanCode == SCAN_ESC) {
      *PressEsc = TRUE;
      break;
    }
  }

  gST->ConOut->ClearScreen (gST->ConOut);

  if ((InputLength == 0) || (InputKey.ScanCode == SCAN_ESC)) {
    ZeroMem (Unicode, sizeof (Unicode));
    ZeroMem (Mask, sizeof (Mask));
    return NULL;
  }

  Ascii = AllocateZeroPool (PSID_CHARACTER_LENGTH + 1);
  if (Ascii == NULL) {
    ZeroMem (Unicode, sizeof (Unicode));
    ZeroMem (Mask, sizeof (Mask));
    return NULL;
  }

  UnicodeStrToAsciiStrS (Unicode, Ascii, PSID_CHARACTER_LENGTH + 1);
  ZeroMem (Unicode, sizeof (Unicode));
  ZeroMem (Mask, sizeof (Mask));

  return Ascii;
}

/**
  Get password input from the popup window.

  @param[in]  Dev           The device which need password to unlock or
                            process OPAL request.
  @param[in]  PopUpString1  Pop up string 1.
  @param[in]  PopUpString2  Pop up string 2.
  @param[in]  PopUpString3  Pop up string 3.
  @param[out] PressEsc      Whether user escape function through Press ESC.

  @retval Password string if success. NULL if failed.

**/
CHAR8 *
OpalDriverPopUpPasswordInput (
  IN OPAL_DRIVER_DEVICE  *Dev,
  IN CHAR16              *PopUpString1,
  IN CHAR16              *PopUpString2,
  IN CHAR16              *PopUpString3,
  OUT BOOLEAN            *PressEsc
  )
{
  EFI_INPUT_KEY  InputKey;
  UINTN          InputLength;
  CHAR16         Mask[OPAL_MAX_PASSWORD_SIZE + 1];
  CHAR16         Unicode[OPAL_MAX_PASSWORD_SIZE + 1];
  CHAR8          *Ascii;

  ZeroMem (Unicode, sizeof (Unicode));
  ZeroMem (Mask, sizeof (Mask));

  *PressEsc = FALSE;

  gST->ConOut->ClearScreen (gST->ConOut);

  InputLength = 0;
  while (TRUE) {
    Mask[InputLength] = L'_';
    if (PopUpString2 == NULL) {
      CreatePopUp (
        EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
        &InputKey,
        PopUpString1,
        L"---------------------",
        Mask,
        NULL
        );
    } else {
      if (PopUpString3 == NULL) {
        CreatePopUp (
          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
          &InputKey,
          PopUpString1,
          PopUpString2,
          L"---------------------",
          Mask,
          NULL
          );
      } else {
        CreatePopUp (
          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
          &InputKey,
          PopUpString1,
          PopUpString2,
          PopUpString3,
          L"---------------------",
          Mask,
          NULL
          );
      }
    }

    //
    // Check key.
    //
    if (InputKey.ScanCode == SCAN_NULL) {
      //
      // password finished
      //
      if (InputKey.UnicodeChar == CHAR_CARRIAGE_RETURN) {
        //
        // Add the null terminator.
        //
        Unicode[InputLength] = 0;
        Mask[InputLength]    = 0;
        break;
      } else if ((InputKey.UnicodeChar == CHAR_NULL) ||
                 (InputKey.UnicodeChar == CHAR_TAB) ||
                 (InputKey.UnicodeChar == CHAR_LINEFEED)
                 )
      {
        continue;
      } else {
        //
        // delete last key entered
        //
        if (InputKey.UnicodeChar == CHAR_BACKSPACE) {
          if (InputLength > 0) {
            Unicode[InputLength] = 0;
            Mask[InputLength]    = 0;
            InputLength--;
          }
        } else {
          //
          // add Next key entry
          //
          Unicode[InputLength] = InputKey.UnicodeChar;
          Mask[InputLength]    = L'*';
          InputLength++;
          if (InputLength == OPAL_MAX_PASSWORD_SIZE) {
            //
            // Add the null terminator.
            //
            Unicode[InputLength] = 0;
            Mask[InputLength]    = 0;
            break;
          }
        }
      }
    }

    //
    // exit on ESC
    //
    if (InputKey.ScanCode == SCAN_ESC) {
      *PressEsc = TRUE;
      break;
    }
  }

  gST->ConOut->ClearScreen (gST->ConOut);

  if ((InputLength == 0) || (InputKey.ScanCode == SCAN_ESC)) {
    ZeroMem (Unicode, sizeof (Unicode));
    return NULL;
  }

  Ascii = AllocateZeroPool (OPAL_MAX_PASSWORD_SIZE + 1);
  if (Ascii == NULL) {
    ZeroMem (Unicode, sizeof (Unicode));
    return NULL;
  }

  UnicodeStrToAsciiStrS (Unicode, Ascii, OPAL_MAX_PASSWORD_SIZE + 1);
  ZeroMem (Unicode, sizeof (Unicode));

  return Ascii;
}

/**
  Get pop up string.

  @param[in] Dev            The OPAL device.
  @param[in] RequestString  Request string.

  @return Pop up string.

**/
CHAR16 *
OpalGetPopUpString (
  IN OPAL_DRIVER_DEVICE  *Dev,
  IN CHAR16              *RequestString
  )
{
  if (Dev->Name16 == NULL) {
    UnicodeSPrint (mPopUpString, sizeof (mPopUpString), L"%s Disk", RequestString);
  } else {
    UnicodeSPrint (mPopUpString, sizeof (mPopUpString), L"%s %s", RequestString, Dev->Name16);
  }

  return mPopUpString;
}

/**
  Check if disk is locked, show popup window and ask for password if it is.

  @param[in] Dev            The device which need to be unlocked.
  @param[in] RequestString  Request string.

**/
VOID
OpalDriverRequestPassword (
  IN OPAL_DRIVER_DEVICE  *Dev,
  IN CHAR16              *RequestString
  )
{
  UINT8          Count;
  BOOLEAN        IsEnabled;
  BOOLEAN        IsLocked;
  CHAR8          *Password;
  UINT32         PasswordLen;
  OPAL_SESSION   Session;
  BOOLEAN        PressEsc;
  EFI_INPUT_KEY  Key;
  TCG_RESULT     Ret;
  CHAR16         *PopUpString;

  if (Dev == NULL) {
    return;
  }

  DEBUG ((DEBUG_INFO, "%a()\n", __func__));

  PopUpString = OpalGetPopUpString (Dev, RequestString);

  Count = 0;

  IsEnabled = OpalFeatureEnabled (&Dev->OpalDisk.SupportedAttributes, &Dev->OpalDisk.LockingFeature);
  if (IsEnabled) {
    ZeroMem (&Session, sizeof (Session));
    Session.Sscp          = Dev->OpalDisk.Sscp;
    Session.MediaId       = Dev->OpalDisk.MediaId;
    Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;

    IsLocked = OpalDeviceLocked (&Dev->OpalDisk.SupportedAttributes, &Dev->OpalDisk.LockingFeature);

    //
    // Add PcdSkipOpalPasswordPrompt to determin whether to skip password prompt.
    // Due to board design, device may not power off during system warm boot, which result in
    // security status remain unlocked status, hence we add device security status check here.
    //
    // If device is in the locked status, device keeps locked and system continues booting.
    // If device is in the unlocked status, system is forced shutdown to support security requirement.
    //
    if (PcdGetBool (PcdSkipOpalPasswordPrompt)) {
      if (IsLocked) {
        return;
      } else {
        gRT->ResetSystem (EfiResetShutdown, EFI_SUCCESS, 0, NULL);
      }
    }

    while (Count < MAX_PASSWORD_TRY_COUNT) {
      Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, NULL, NULL, &PressEsc);
      if (PressEsc) {
        if (IsLocked) {
          //
          // Current device in the lock status and
          // User not input password and press ESC,
          // keep device in lock status and continue boot.
          //
          do {
            CreatePopUp (
              EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
              &Key,
              L"Press ENTER to skip the request and continue boot,",
              L"Press ESC to input password again",
              NULL
              );
          } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));

          if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
            gST->ConOut->ClearScreen (gST->ConOut);
            //
            // Keep lock and continue boot.
            //
            return;
          } else {
            //
            // Let user input password again.
            //
            continue;
          }
        } else {
          //
          // Current device in the unlock status and
          // User not input password and press ESC,
          // Shutdown the device.
          //
          do {
            CreatePopUp (
              EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
              &Key,
              L"Press ENTER to shutdown, Press ESC to input password again",
              NULL
              );
          } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));

          if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
            gRT->ResetSystem (EfiResetShutdown, EFI_SUCCESS, 0, NULL);
          } else {
            //
            // Let user input password again.
            //
            continue;
          }
        }
      }

      if (Password == NULL) {
        Count++;
        continue;
      }

      PasswordLen = (UINT32)AsciiStrLen (Password);

      if (IsLocked) {
        Ret = OpalUtilUpdateGlobalLockingRange (&Session, Password, PasswordLen, FALSE, FALSE);
      } else {
        Ret = OpalUtilUpdateGlobalLockingRange (&Session, Password, PasswordLen, TRUE, TRUE);
        if (Ret == TcgResultSuccess) {
          Ret = OpalUtilUpdateGlobalLockingRange (&Session, Password, PasswordLen, FALSE, FALSE);
        }
      }

      if (Ret == TcgResultSuccess) {
        OpalSupportUpdatePassword (&Dev->OpalDisk, Password, PasswordLen);
        DEBUG ((DEBUG_INFO, "%s Success\n", RequestString));
      } else {
        DEBUG ((DEBUG_INFO, "%s Failure\n", RequestString));
      }

      if (Password != NULL) {
        ZeroMem (Password, PasswordLen);
        FreePool (Password);
      }

      if (Ret == TcgResultSuccess) {
        break;
      }

      //
      // Check whether opal device's Tries value has reach the TryLimit value, if yes, force a shutdown
      // before accept new password.
      //
      if (Ret == TcgResultFailureInvalidType) {
        Count = MAX_PASSWORD_TRY_COUNT;
        break;
      }

      Count++;

      do {
        CreatePopUp (
          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
          &Key,
          L"Invalid password.",
          L"Press ENTER to retry",
          NULL
          );
      } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
    }

    if (Count >= MAX_PASSWORD_TRY_COUNT) {
      do {
        CreatePopUp (
          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
          &Key,
          L"Opal password retry count exceeds the limit. Must shutdown!",
          L"Press ENTER to shutdown",
          NULL
          );
      } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);

      gRT->ResetSystem (EfiResetShutdown, EFI_SUCCESS, 0, NULL);
    }
  }
}

/**
  Process Enable Feature OPAL request.

  @param[in] Dev            The device which has Enable Feature OPAL request.
  @param[in] RequestString  Request string.

**/
VOID
ProcessOpalRequestEnableFeature (
  IN OPAL_DRIVER_DEVICE  *Dev,
  IN CHAR16              *RequestString
  )
{
  UINT8          Count;
  CHAR8          *Password;
  UINT32         PasswordLen;
  CHAR8          *PasswordConfirm;
  UINT32         PasswordLenConfirm;
  OPAL_SESSION   Session;
  BOOLEAN        PressEsc;
  EFI_INPUT_KEY  Key;
  TCG_RESULT     Ret;
  CHAR16         *PopUpString;

  if (Dev == NULL) {
    return;
  }

  DEBUG ((DEBUG_INFO, "%a()\n", __func__));

  PopUpString = OpalGetPopUpString (Dev, RequestString);

  Count = 0;

  ZeroMem (&Session, sizeof (Session));
  Session.Sscp          = Dev->OpalDisk.Sscp;
  Session.MediaId       = Dev->OpalDisk.MediaId;
  Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;

  while (Count < MAX_PASSWORD_TRY_COUNT) {
    Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please type in your new password", NULL, &PressEsc);
    if (PressEsc) {
      do {
        CreatePopUp (
          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
          &Key,
          L"Press ENTER to skip the request and continue boot,",
          L"Press ESC to input password again",
          NULL
          );
      } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));

      if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
        gST->ConOut->ClearScreen (gST->ConOut);
        return;
      } else {
        //
        // Let user input password again.
        //
        continue;
      }
    }

    if (Password == NULL) {
      Count++;
      continue;
    }

    PasswordLen = (UINT32)AsciiStrLen (Password);

    PasswordConfirm = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please confirm your new password", NULL, &PressEsc);
    if (PasswordConfirm == NULL) {
      ZeroMem (Password, PasswordLen);
      FreePool (Password);
      Count++;
      continue;
    }

    PasswordLenConfirm = (UINT32)AsciiStrLen (PasswordConfirm);
    if ((PasswordLen != PasswordLenConfirm) ||
        (CompareMem (Password, PasswordConfirm, PasswordLen) != 0))
    {
      ZeroMem (Password, PasswordLen);
      FreePool (Password);
      ZeroMem (PasswordConfirm, PasswordLenConfirm);
      FreePool (PasswordConfirm);
      do {
        CreatePopUp (
          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
          &Key,
          L"Passwords are not the same.",
          L"Press ENTER to retry",
          NULL
          );
      } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);

      Count++;
      continue;
    }

    if (PasswordConfirm != NULL) {
      ZeroMem (PasswordConfirm, PasswordLenConfirm);
      FreePool (PasswordConfirm);
    }

    Ret = OpalSupportEnableOpalFeature (&Session, Dev->OpalDisk.Msid, Dev->OpalDisk.MsidLength, Password, PasswordLen);
    if (Ret == TcgResultSuccess) {
      OpalSupportUpdatePassword (&Dev->OpalDisk, Password, PasswordLen);
      DEBUG ((DEBUG_INFO, "%s Success\n", RequestString));
    } else {
      DEBUG ((DEBUG_INFO, "%s Failure\n", RequestString));
    }

    if (Password != NULL) {
      ZeroMem (Password, PasswordLen);
      FreePool (Password);
    }

    if (Ret == TcgResultSuccess) {
      break;
    }

    Count++;

    do {
      CreatePopUp (
        EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
        &Key,
        L"Request failed.",
        L"Press ENTER to retry",
        NULL
        );
    } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
  }

  if (Count >= MAX_PASSWORD_TRY_COUNT) {
    do {
      CreatePopUp (
        EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
        &Key,
        L"Opal password retry count exceeds the limit.",
        L"Press ENTER to skip the request and continue boot",
        NULL
        );
    } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);

    gST->ConOut->ClearScreen (gST->ConOut);
  }
}

/**
  Process Disable User OPAL request.

  @param[in] Dev            The device which has Disable User OPAL request.
  @param[in] RequestString  Request string.

**/
VOID
ProcessOpalRequestDisableUser (
  IN OPAL_DRIVER_DEVICE  *Dev,
  IN CHAR16              *RequestString
  )
{
  UINT8          Count;
  CHAR8          *Password;
  UINT32         PasswordLen;
  OPAL_SESSION   Session;
  BOOLEAN        PressEsc;
  EFI_INPUT_KEY  Key;
  TCG_RESULT     Ret;
  BOOLEAN        PasswordFailed;
  CHAR16         *PopUpString;

  if (Dev == NULL) {
    return;
  }

  DEBUG ((DEBUG_INFO, "%a()\n", __func__));

  PopUpString = OpalGetPopUpString (Dev, RequestString);

  Count = 0;

  ZeroMem (&Session, sizeof (Session));
  Session.Sscp          = Dev->OpalDisk.Sscp;
  Session.MediaId       = Dev->OpalDisk.MediaId;
  Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;

  while (Count < MAX_PASSWORD_TRY_COUNT) {
    Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, NULL, NULL, &PressEsc);
    if (PressEsc) {
      do {
        CreatePopUp (
          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
          &Key,
          L"Press ENTER to skip the request and continue boot,",
          L"Press ESC to input password again",
          NULL
          );
      } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));

      if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
        gST->ConOut->ClearScreen (gST->ConOut);
        return;
      } else {
        //
        // Let user input password again.
        //
        continue;
      }
    }

    if (Password == NULL) {
      Count++;
      continue;
    }

    PasswordLen = (UINT32)AsciiStrLen (Password);

    Ret = OpalUtilDisableUser (&Session, Password, PasswordLen, &PasswordFailed);
    if (Ret == TcgResultSuccess) {
      OpalSupportUpdatePassword (&Dev->OpalDisk, Password, PasswordLen);
      DEBUG ((DEBUG_INFO, "%s Success\n", RequestString));
    } else {
      DEBUG ((DEBUG_INFO, "%s Failure\n", RequestString));
    }

    if (Password != NULL) {
      ZeroMem (Password, PasswordLen);
      FreePool (Password);
    }

    if (Ret == TcgResultSuccess) {
      break;
    }

    Count++;

    do {
      CreatePopUp (
        EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
        &Key,
        L"Invalid password, request failed.",
        L"Press ENTER to retry",
        NULL
        );
    } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
  }

  if (Count >= MAX_PASSWORD_TRY_COUNT) {
    do {
      CreatePopUp (
        EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
        &Key,
        L"Opal password retry count exceeds the limit.",
        L"Press ENTER to skip the request and continue boot",
        NULL
        );
    } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);

    gST->ConOut->ClearScreen (gST->ConOut);
  }
}

/**
  Process Psid Revert OPAL request.

  @param[in] Dev            The device which has Psid Revert OPAL request.
  @param[in] RequestString  Request string.

**/
VOID
ProcessOpalRequestPsidRevert (
  IN OPAL_DRIVER_DEVICE  *Dev,
  IN CHAR16              *RequestString
  )
{
  UINT8          Count;
  CHAR8          *Psid;
  UINT32         PsidLen;
  OPAL_SESSION   Session;
  BOOLEAN        PressEsc;
  EFI_INPUT_KEY  Key;
  TCG_RESULT     Ret;
  CHAR16         *PopUpString;
  CHAR16         *PopUpString2;
  CHAR16         *PopUpString3;
  UINTN          BufferSize;

  if (Dev == NULL) {
    return;
  }

  DEBUG ((DEBUG_INFO, "%a()\n", __func__));

  PopUpString = OpalGetPopUpString (Dev, RequestString);

  if (Dev->OpalDisk.EstimateTimeCost > MAX_ACCEPTABLE_REVERTING_TIME) {
    BufferSize   = StrSize (L"Warning: Revert action will take about ####### seconds");
    PopUpString2 = AllocateZeroPool (BufferSize);
    ASSERT (PopUpString2 != NULL);
    UnicodeSPrint (
      PopUpString2,
      BufferSize,
      L"WARNING: Revert action will take about %d seconds",
      Dev->OpalDisk.EstimateTimeCost
      );
    PopUpString3 = L"DO NOT power off system during the revert action!";
  } else {
    PopUpString2 = NULL;
    PopUpString3 = NULL;
  }

  Count = 0;

  ZeroMem (&Session, sizeof (Session));
  Session.Sscp          = Dev->OpalDisk.Sscp;
  Session.MediaId       = Dev->OpalDisk.MediaId;
  Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;

  while (Count < MAX_PSID_TRY_COUNT) {
    Psid = OpalDriverPopUpPsidInput (Dev, PopUpString, PopUpString2, PopUpString3, &PressEsc);
    if (PressEsc) {
      do {
        CreatePopUp (
          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
          &Key,
          L"Press ENTER to skip the request and continue boot,",
          L"Press ESC to input Psid again",
          NULL
          );
      } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));

      if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
        gST->ConOut->ClearScreen (gST->ConOut);
        goto Done;
      } else {
        //
        // Let user input Psid again.
        //
        continue;
      }
    }

    if (Psid == NULL) {
      Count++;
      continue;
    }

    PsidLen = (UINT32)AsciiStrLen (Psid);

    Ret = OpalUtilPsidRevert (&Session, Psid, PsidLen);
    if (Ret == TcgResultSuccess) {
      DEBUG ((DEBUG_INFO, "%s Success\n", RequestString));
    } else {
      DEBUG ((DEBUG_INFO, "%s Failure\n", RequestString));
    }

    if (Psid != NULL) {
      ZeroMem (Psid, PsidLen);
      FreePool (Psid);
    }

    if (Ret == TcgResultSuccess) {
      break;
    }

    Count++;

    do {
      CreatePopUp (
        EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
        &Key,
        L"Invalid Psid, request failed.",
        L"Press ENTER to retry",
        NULL
        );
    } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
  }

  if (Count >= MAX_PSID_TRY_COUNT) {
    do {
      CreatePopUp (
        EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
        &Key,
        L"Opal Psid retry count exceeds the limit.",
        L"Press ENTER to skip the request and continue boot",
        NULL
        );
    } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);

    gST->ConOut->ClearScreen (gST->ConOut);
  }

Done:
  if (PopUpString2 != NULL) {
    FreePool (PopUpString2);
  }
}

/**
  Process Admin Revert OPAL request.

  @param[in] Dev            The device which has Revert OPAL request.
  @param[in] KeepUserData   Whether to keep user data or not.
  @param[in] RequestString  Request string.

**/
VOID
ProcessOpalRequestRevert (
  IN OPAL_DRIVER_DEVICE  *Dev,
  IN BOOLEAN             KeepUserData,
  IN CHAR16              *RequestString
  )
{
  UINT8          Count;
  CHAR8          *Password;
  UINT32         PasswordLen;
  OPAL_SESSION   Session;
  BOOLEAN        PressEsc;
  EFI_INPUT_KEY  Key;
  TCG_RESULT     Ret;
  BOOLEAN        PasswordFailed;
  CHAR16         *PopUpString;
  CHAR16         *PopUpString2;
  CHAR16         *PopUpString3;
  UINTN          BufferSize;

  if (Dev == NULL) {
    return;
  }

  DEBUG ((DEBUG_INFO, "%a()\n", __func__));

  PopUpString = OpalGetPopUpString (Dev, RequestString);

  if ((!KeepUserData) &&
      (Dev->OpalDisk.EstimateTimeCost > MAX_ACCEPTABLE_REVERTING_TIME))
  {
    BufferSize   = StrSize (L"Warning: Revert action will take about ####### seconds");
    PopUpString2 = AllocateZeroPool (BufferSize);
    ASSERT (PopUpString2 != NULL);
    UnicodeSPrint (
      PopUpString2,
      BufferSize,
      L"WARNING: Revert action will take about %d seconds",
      Dev->OpalDisk.EstimateTimeCost
      );
    PopUpString3 = L"DO NOT power off system during the revert action!";
  } else {
    PopUpString2 = NULL;
    PopUpString3 = NULL;
  }

  Count = 0;

  ZeroMem (&Session, sizeof (Session));
  Session.Sscp          = Dev->OpalDisk.Sscp;
  Session.MediaId       = Dev->OpalDisk.MediaId;
  Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;

  while (Count < MAX_PASSWORD_TRY_COUNT) {
    Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, PopUpString2, PopUpString3, &PressEsc);
    if (PressEsc) {
      do {
        CreatePopUp (
          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
          &Key,
          L"Press ENTER to skip the request and continue boot,",
          L"Press ESC to input password again",
          NULL
          );
      } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));

      if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
        gST->ConOut->ClearScreen (gST->ConOut);
        goto Done;
      } else {
        //
        // Let user input password again.
        //
        continue;
      }
    }

    if (Password == NULL) {
      Count++;
      continue;
    }

    PasswordLen = (UINT32)AsciiStrLen (Password);

    if ((Dev->OpalDisk.SupportedAttributes.PyriteSsc == 1) &&
        (Dev->OpalDisk.LockingFeature.MediaEncryption == 0))
    {
      //
      // For pyrite type device which does not support media encryption,
      // it does not accept "Keep User Data" parameter.
      // So here hardcode a FALSE for this case.
      //
      Ret = OpalUtilRevert (
              &Session,
              FALSE,
              Password,
              PasswordLen,
              &PasswordFailed,
              Dev->OpalDisk.Msid,
              Dev->OpalDisk.MsidLength
              );
    } else {
      Ret = OpalUtilRevert (
              &Session,
              KeepUserData,
              Password,
              PasswordLen,
              &PasswordFailed,
              Dev->OpalDisk.Msid,
              Dev->OpalDisk.MsidLength
              );
    }

    if (Ret == TcgResultSuccess) {
      OpalSupportUpdatePassword (&Dev->OpalDisk, Password, PasswordLen);
      DEBUG ((DEBUG_INFO, "%s Success\n", RequestString));
    } else {
      DEBUG ((DEBUG_INFO, "%s Failure\n", RequestString));
    }

    if (Password != NULL) {
      ZeroMem (Password, PasswordLen);
      FreePool (Password);
    }

    if (Ret == TcgResultSuccess) {
      break;
    }

    Count++;

    do {
      CreatePopUp (
        EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
        &Key,
        L"Invalid password, request failed.",
        L"Press ENTER to retry",
        NULL
        );
    } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
  }

  if (Count >= MAX_PASSWORD_TRY_COUNT) {
    do {
      CreatePopUp (
        EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
        &Key,
        L"Opal password retry count exceeds the limit.",
        L"Press ENTER to skip the request and continue boot",
        NULL
        );
    } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);

    gST->ConOut->ClearScreen (gST->ConOut);
  }

Done:
  if (PopUpString2 != NULL) {
    FreePool (PopUpString2);
  }
}

/**
  Process Secure Erase OPAL request.

  @param[in] Dev            The device which has Secure Erase OPAL request.
  @param[in] RequestString  Request string.

**/
VOID
ProcessOpalRequestSecureErase (
  IN OPAL_DRIVER_DEVICE  *Dev,
  IN CHAR16              *RequestString
  )
{
  UINT8          Count;
  CHAR8          *Password;
  UINT32         PasswordLen;
  OPAL_SESSION   Session;
  BOOLEAN        PressEsc;
  EFI_INPUT_KEY  Key;
  TCG_RESULT     Ret;
  BOOLEAN        PasswordFailed;
  CHAR16         *PopUpString;
  CHAR16         *PopUpString2;
  CHAR16         *PopUpString3;
  UINTN          BufferSize;

  if (Dev == NULL) {
    return;
  }

  DEBUG ((DEBUG_INFO, "%a()\n", __func__));

  PopUpString = OpalGetPopUpString (Dev, RequestString);

  if (Dev->OpalDisk.EstimateTimeCost > MAX_ACCEPTABLE_REVERTING_TIME) {
    BufferSize   = StrSize (L"Warning: Secure erase action will take about ####### seconds");
    PopUpString2 = AllocateZeroPool (BufferSize);
    ASSERT (PopUpString2 != NULL);
    UnicodeSPrint (
      PopUpString2,
      BufferSize,
      L"WARNING: Secure erase action will take about %d seconds",
      Dev->OpalDisk.EstimateTimeCost
      );
    PopUpString3 = L"DO NOT power off system during the action!";
  } else {
    PopUpString2 = NULL;
    PopUpString3 = NULL;
  }

  Count = 0;

  ZeroMem (&Session, sizeof (Session));
  Session.Sscp          = Dev->OpalDisk.Sscp;
  Session.MediaId       = Dev->OpalDisk.MediaId;
  Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;

  while (Count < MAX_PASSWORD_TRY_COUNT) {
    Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, PopUpString2, PopUpString3, &PressEsc);
    if (PressEsc) {
      do {
        CreatePopUp (
          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
          &Key,
          L"Press ENTER to skip the request and continue boot,",
          L"Press ESC to input password again",
          NULL
          );
      } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));

      if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
        gST->ConOut->ClearScreen (gST->ConOut);
        goto Done;
      } else {
        //
        // Let user input password again.
        //
        continue;
      }
    }

    if (Password == NULL) {
      Count++;
      continue;
    }

    PasswordLen = (UINT32)AsciiStrLen (Password);

    Ret = OpalUtilSecureErase (&Session, Password, PasswordLen, &PasswordFailed);
    if (Ret == TcgResultSuccess) {
      OpalSupportUpdatePassword (&Dev->OpalDisk, Password, PasswordLen);
      DEBUG ((DEBUG_INFO, "%s Success\n", RequestString));
    } else {
      DEBUG ((DEBUG_INFO, "%s Failure\n", RequestString));
    }

    if (Password != NULL) {
      ZeroMem (Password, PasswordLen);
      FreePool (Password);
    }

    if (Ret == TcgResultSuccess) {
      break;
    }

    Count++;

    do {
      CreatePopUp (
        EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
        &Key,
        L"Invalid password, request failed.",
        L"Press ENTER to retry",
        NULL
        );
    } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
  }

  if (Count >= MAX_PASSWORD_TRY_COUNT) {
    do {
      CreatePopUp (
        EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
        &Key,
        L"Opal password retry count exceeds the limit.",
        L"Press ENTER to skip the request and continue boot",
        NULL
        );
    } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);

    gST->ConOut->ClearScreen (gST->ConOut);
  }

Done:
  if (PopUpString2 != NULL) {
    FreePool (PopUpString2);
  }
}

/**
  Process Set Admin Pwd OPAL request.

  @param[in] Dev            The device which has Set Admin Pwd Feature OPAL request.
  @param[in] RequestString  Request string.

**/
VOID
ProcessOpalRequestSetUserPwd (
  IN OPAL_DRIVER_DEVICE  *Dev,
  IN CHAR16              *RequestString
  )
{
  UINT8          Count;
  CHAR8          *OldPassword;
  UINT32         OldPasswordLen;
  CHAR8          *Password;
  UINT32         PasswordLen;
  CHAR8          *PasswordConfirm;
  UINT32         PasswordLenConfirm;
  OPAL_SESSION   Session;
  BOOLEAN        PressEsc;
  EFI_INPUT_KEY  Key;
  TCG_RESULT     Ret;
  CHAR16         *PopUpString;

  if (Dev == NULL) {
    return;
  }

  DEBUG ((DEBUG_INFO, "%a()\n", __func__));

  PopUpString = OpalGetPopUpString (Dev, RequestString);

  Count = 0;

  while (Count < MAX_PASSWORD_TRY_COUNT) {
    OldPassword = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please type in your password", NULL, &PressEsc);
    if (PressEsc) {
      do {
        CreatePopUp (
          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
          &Key,
          L"Press ENTER to skip the request and continue boot,",
          L"Press ESC to input password again",
          NULL
          );
      } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));

      if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
        gST->ConOut->ClearScreen (gST->ConOut);
        return;
      } else {
        //
        // Let user input password again.
        //
        continue;
      }
    }

    if (OldPassword == NULL) {
      Count++;
      continue;
    }

    OldPasswordLen = (UINT32)AsciiStrLen (OldPassword);

    ZeroMem (&Session, sizeof (Session));
    Session.Sscp          = Dev->OpalDisk.Sscp;
    Session.MediaId       = Dev->OpalDisk.MediaId;
    Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;
    Ret                   = OpalUtilVerifyPassword (&Session, OldPassword, OldPasswordLen, OPAL_LOCKING_SP_USER1_AUTHORITY);
    if (Ret == TcgResultSuccess) {
      DEBUG ((DEBUG_INFO, "Verify with USER1 authority : Success\n"));
    } else {
      Ret = OpalUtilVerifyPassword (&Session, OldPassword, OldPasswordLen, OPAL_LOCKING_SP_ADMIN1_AUTHORITY);
      if (Ret == TcgResultSuccess) {
        DEBUG ((DEBUG_INFO, "Verify with ADMIN1 authority: Success\n"));
      } else {
        ZeroMem (OldPassword, OldPasswordLen);
        FreePool (OldPassword);
        DEBUG ((DEBUG_INFO, "Verify: Failure\n"));
        do {
          CreatePopUp (
            EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
            &Key,
            L"Incorrect password.",
            L"Press ENTER to retry",
            NULL
            );
        } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);

        Count++;
        continue;
      }
    }

    Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please type in your new password", NULL, &PressEsc);
    if (Password == NULL) {
      ZeroMem (OldPassword, OldPasswordLen);
      FreePool (OldPassword);
      Count++;
      continue;
    }

    PasswordLen = (UINT32)AsciiStrLen (Password);

    PasswordConfirm = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please confirm your new password", NULL, &PressEsc);
    if (PasswordConfirm == NULL) {
      ZeroMem (OldPassword, OldPasswordLen);
      FreePool (OldPassword);
      ZeroMem (Password, PasswordLen);
      FreePool (Password);
      Count++;
      continue;
    }

    PasswordLenConfirm = (UINT32)AsciiStrLen (PasswordConfirm);
    if ((PasswordLen != PasswordLenConfirm) ||
        (CompareMem (Password, PasswordConfirm, PasswordLen) != 0))
    {
      ZeroMem (OldPassword, OldPasswordLen);
      FreePool (OldPassword);
      ZeroMem (Password, PasswordLen);
      FreePool (Password);
      ZeroMem (PasswordConfirm, PasswordLenConfirm);
      FreePool (PasswordConfirm);
      do {
        CreatePopUp (
          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
          &Key,
          L"Passwords are not the same.",
          L"Press ENTER to retry",
          NULL
          );
      } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);

      Count++;
      continue;
    }

    if (PasswordConfirm != NULL) {
      ZeroMem (PasswordConfirm, PasswordLenConfirm);
      FreePool (PasswordConfirm);
    }

    ZeroMem (&Session, sizeof (Session));
    Session.Sscp          = Dev->OpalDisk.Sscp;
    Session.MediaId       = Dev->OpalDisk.MediaId;
    Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;
    Ret                   = OpalUtilSetUserPassword (
                              &Session,
                              OldPassword,
                              OldPasswordLen,
                              Password,
                              PasswordLen
                              );
    if (Ret == TcgResultSuccess) {
      OpalSupportUpdatePassword (&Dev->OpalDisk, Password, PasswordLen);
      DEBUG ((DEBUG_INFO, "%s Success\n", RequestString));
    } else {
      DEBUG ((DEBUG_INFO, "%s Failure\n", RequestString));
    }

    if (OldPassword != NULL) {
      ZeroMem (OldPassword, OldPasswordLen);
      FreePool (OldPassword);
    }

    if (Password != NULL) {
      ZeroMem (Password, PasswordLen);
      FreePool (Password);
    }

    if (Ret == TcgResultSuccess) {
      break;
    }

    Count++;

    do {
      CreatePopUp (
        EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
        &Key,
        L"Request failed.",
        L"Press ENTER to retry",
        NULL
        );
    } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
  }

  if (Count >= MAX_PASSWORD_TRY_COUNT) {
    do {
      CreatePopUp (
        EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
        &Key,
        L"Opal password retry count exceeds the limit.",
        L"Press ENTER to skip the request and continue boot",
        NULL
        );
    } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);

    gST->ConOut->ClearScreen (gST->ConOut);
  }
}

/**
  Process Set Admin Pwd OPAL request.

  @param[in] Dev            The device which has Set Admin Pwd Feature OPAL request.
  @param[in] RequestString  Request string.

**/
VOID
ProcessOpalRequestSetAdminPwd (
  IN OPAL_DRIVER_DEVICE  *Dev,
  IN CHAR16              *RequestString
  )
{
  UINT8          Count;
  CHAR8          *OldPassword;
  UINT32         OldPasswordLen;
  CHAR8          *Password;
  UINT32         PasswordLen;
  CHAR8          *PasswordConfirm;
  UINT32         PasswordLenConfirm;
  OPAL_SESSION   Session;
  BOOLEAN        PressEsc;
  EFI_INPUT_KEY  Key;
  TCG_RESULT     Ret;
  CHAR16         *PopUpString;

  if (Dev == NULL) {
    return;
  }

  DEBUG ((DEBUG_INFO, "%a()\n", __func__));

  PopUpString = OpalGetPopUpString (Dev, RequestString);

  Count = 0;

  while (Count < MAX_PASSWORD_TRY_COUNT) {
    OldPassword = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please type in your password", NULL, &PressEsc);
    if (PressEsc) {
      do {
        CreatePopUp (
          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
          &Key,
          L"Press ENTER to skip the request and continue boot,",
          L"Press ESC to input password again",
          NULL
          );
      } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));

      if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
        gST->ConOut->ClearScreen (gST->ConOut);
        return;
      } else {
        //
        // Let user input password again.
        //
        continue;
      }
    }

    if (OldPassword == NULL) {
      Count++;
      continue;
    }

    OldPasswordLen = (UINT32)AsciiStrLen (OldPassword);

    ZeroMem (&Session, sizeof (Session));
    Session.Sscp          = Dev->OpalDisk.Sscp;
    Session.MediaId       = Dev->OpalDisk.MediaId;
    Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;
    Ret                   = OpalUtilVerifyPassword (&Session, OldPassword, OldPasswordLen, OPAL_LOCKING_SP_ADMIN1_AUTHORITY);
    if (Ret == TcgResultSuccess) {
      DEBUG ((DEBUG_INFO, "Verify: Success\n"));
    } else {
      ZeroMem (OldPassword, OldPasswordLen);
      FreePool (OldPassword);
      DEBUG ((DEBUG_INFO, "Verify: Failure\n"));
      do {
        CreatePopUp (
          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
          &Key,
          L"Incorrect password.",
          L"Press ENTER to retry",
          NULL
          );
      } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);

      Count++;
      continue;
    }

    Password = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please type in your new password", NULL, &PressEsc);
    if (Password == NULL) {
      ZeroMem (OldPassword, OldPasswordLen);
      FreePool (OldPassword);
      Count++;
      continue;
    }

    PasswordLen = (UINT32)AsciiStrLen (Password);

    PasswordConfirm = OpalDriverPopUpPasswordInput (Dev, PopUpString, L"Please confirm your new password", NULL, &PressEsc);
    if (PasswordConfirm == NULL) {
      ZeroMem (OldPassword, OldPasswordLen);
      FreePool (OldPassword);
      ZeroMem (Password, PasswordLen);
      FreePool (Password);
      Count++;
      continue;
    }

    PasswordLenConfirm = (UINT32)AsciiStrLen (PasswordConfirm);
    if ((PasswordLen != PasswordLenConfirm) ||
        (CompareMem (Password, PasswordConfirm, PasswordLen) != 0))
    {
      ZeroMem (OldPassword, OldPasswordLen);
      FreePool (OldPassword);
      ZeroMem (Password, PasswordLen);
      FreePool (Password);
      ZeroMem (PasswordConfirm, PasswordLenConfirm);
      FreePool (PasswordConfirm);
      do {
        CreatePopUp (
          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
          &Key,
          L"Passwords are not the same.",
          L"Press ENTER to retry",
          NULL
          );
      } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);

      Count++;
      continue;
    }

    if (PasswordConfirm != NULL) {
      ZeroMem (PasswordConfirm, PasswordLenConfirm);
      FreePool (PasswordConfirm);
    }

    ZeroMem (&Session, sizeof (Session));
    Session.Sscp          = Dev->OpalDisk.Sscp;
    Session.MediaId       = Dev->OpalDisk.MediaId;
    Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;
    Ret                   = OpalUtilSetAdminPassword (
                              &Session,
                              OldPassword,
                              OldPasswordLen,
                              Password,
                              PasswordLen
                              );
    if (Ret == TcgResultSuccess) {
      OpalSupportUpdatePassword (&Dev->OpalDisk, Password, PasswordLen);
      DEBUG ((DEBUG_INFO, "%s Success\n", RequestString));
    } else {
      DEBUG ((DEBUG_INFO, "%s Failure\n", RequestString));
    }

    if (OldPassword != NULL) {
      ZeroMem (OldPassword, OldPasswordLen);
      FreePool (OldPassword);
    }

    if (Password != NULL) {
      ZeroMem (Password, PasswordLen);
      FreePool (Password);
    }

    if (Ret == TcgResultSuccess) {
      break;
    }

    Count++;

    do {
      CreatePopUp (
        EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
        &Key,
        L"Request failed.",
        L"Press ENTER to retry",
        NULL
        );
    } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
  }

  if (Count >= MAX_PASSWORD_TRY_COUNT) {
    do {
      CreatePopUp (
        EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
        &Key,
        L"Opal password retry count exceeds the limit.",
        L"Press ENTER to skip the request and continue boot",
        NULL
        );
    } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);

    gST->ConOut->ClearScreen (gST->ConOut);
  }
}

/**
  Process OPAL request.

  @param[in] Dev            The device which has OPAL request.

**/
VOID
ProcessOpalRequest (
  IN OPAL_DRIVER_DEVICE  *Dev
  )
{
  EFI_STATUS                Status;
  OPAL_REQUEST_VARIABLE     *TempVariable;
  OPAL_REQUEST_VARIABLE     *Variable;
  UINTN                     VariableSize;
  EFI_DEVICE_PATH_PROTOCOL  *DevicePathInVariable;
  UINTN                     DevicePathSizeInVariable;
  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
  UINTN                     DevicePathSize;
  BOOLEAN                   KeepUserData;

  DEBUG ((DEBUG_INFO, "%a() - enter\n", __func__));

  if (mOpalRequestVariable == NULL) {
    Status = GetVariable2 (
               OPAL_REQUEST_VARIABLE_NAME,
               &gHiiSetupVariableGuid,
               (VOID **)&Variable,
               &VariableSize
               );
    if (EFI_ERROR (Status) || (Variable == NULL)) {
      return;
    }

    mOpalRequestVariable     = Variable;
    mOpalRequestVariableSize = VariableSize;

    //
    // Delete the OPAL request variable.
    //
    Status = gRT->SetVariable (
                    OPAL_REQUEST_VARIABLE_NAME,
                    (EFI_GUID *)&gHiiSetupVariableGuid,
                    0,
                    0,
                    NULL
                    );
    ASSERT_EFI_ERROR (Status);
  } else {
    Variable     = mOpalRequestVariable;
    VariableSize = mOpalRequestVariableSize;
  }

  //
  // Process the OPAL requests.
  //
  TempVariable = Variable;
  while ((VariableSize > sizeof (OPAL_REQUEST_VARIABLE)) &&
         (VariableSize >= TempVariable->Length) &&
         (TempVariable->Length > sizeof (OPAL_REQUEST_VARIABLE)))
  {
    DevicePathInVariable     = (EFI_DEVICE_PATH_PROTOCOL *)((UINTN)TempVariable + sizeof (OPAL_REQUEST_VARIABLE));
    DevicePathSizeInVariable = GetDevicePathSize (DevicePathInVariable);
    DevicePath               = Dev->OpalDisk.OpalDevicePath;
    DevicePathSize           = GetDevicePathSize (DevicePath);
    if ((DevicePathSize == DevicePathSizeInVariable) &&
        (CompareMem (DevicePath, DevicePathInVariable, DevicePathSize) == 0))
    {
      //
      // Found the node for the OPAL device.
      //
      if (TempVariable->OpalRequest.SetAdminPwd != 0) {
        ProcessOpalRequestSetAdminPwd (Dev, L"Update Admin Pwd:");
      }

      if (TempVariable->OpalRequest.SetUserPwd != 0) {
        ProcessOpalRequestSetUserPwd (Dev, L"Set User Pwd:");
      }

      if (TempVariable->OpalRequest.SecureErase != 0) {
        ProcessOpalRequestSecureErase (Dev, L"Secure Erase:");
      }

      if (TempVariable->OpalRequest.Revert != 0) {
        KeepUserData = (BOOLEAN)TempVariable->OpalRequest.KeepUserData;
        ProcessOpalRequestRevert (
          Dev,
          KeepUserData,
          KeepUserData ? L"Admin Revert(keep):" : L"Admin Revert:"
          );
      }

      if (TempVariable->OpalRequest.PsidRevert != 0) {
        ProcessOpalRequestPsidRevert (Dev, L"Psid Revert:");
      }

      if (TempVariable->OpalRequest.DisableUser != 0) {
        ProcessOpalRequestDisableUser (Dev, L"Disable User:");
      }

      if (TempVariable->OpalRequest.EnableFeature != 0) {
        ProcessOpalRequestEnableFeature (Dev, L"Enable Feature:");
      }

      //
      // Update Device ownership.
      // Later BlockSID command may block the update.
      //
      OpalDiskUpdateOwnerShip (&Dev->OpalDisk);

      break;
    }

    VariableSize -= TempVariable->Length;
    TempVariable  = (OPAL_REQUEST_VARIABLE *)((UINTN)TempVariable + TempVariable->Length);
  }

  DEBUG ((DEBUG_INFO, "%a() - exit\n", __func__));
}

/**
  Add new device to the global device list.

  @param Dev             New create device.

**/
VOID
AddDeviceToTail (
  IN OPAL_DRIVER_DEVICE  *Dev
  )
{
  OPAL_DRIVER_DEVICE  *TmpDev;

  if (mOpalDriver.DeviceList == NULL) {
    mOpalDriver.DeviceList = Dev;
  } else {
    TmpDev = mOpalDriver.DeviceList;
    while (TmpDev->Next != NULL) {
      TmpDev = TmpDev->Next;
    }

    TmpDev->Next = Dev;
  }
}

/**
  Remove one device in the global device list.

  @param Dev             The device need to be removed.

**/
VOID
RemoveDevice (
  IN OPAL_DRIVER_DEVICE  *Dev
  )
{
  OPAL_DRIVER_DEVICE  *TmpDev;

  if (mOpalDriver.DeviceList == NULL) {
    return;
  }

  if (mOpalDriver.DeviceList == Dev) {
    mOpalDriver.DeviceList = NULL;
    return;
  }

  TmpDev = mOpalDriver.DeviceList;
  while (TmpDev->Next != NULL) {
    if (TmpDev->Next == Dev) {
      TmpDev->Next = Dev->Next;
      break;
    }
  }
}

/**
  Get current device count.

  @retval  return the current created device count.

**/
UINT8
GetDeviceCount (
  VOID
  )
{
  UINT8               Count;
  OPAL_DRIVER_DEVICE  *TmpDev;

  Count  = 0;
  TmpDev = mOpalDriver.DeviceList;

  while (TmpDev != NULL) {
    Count++;
    TmpDev = TmpDev->Next;
  }

  return Count;
}

/**
  Get devcie list info.

  @retval     return the device list pointer.
**/
OPAL_DRIVER_DEVICE *
OpalDriverGetDeviceList (
  VOID
  )
{
  return mOpalDriver.DeviceList;
}

/**
  Stop this Controller.

  @param  Dev               The device need to be stopped.

**/
VOID
OpalDriverStopDevice (
  OPAL_DRIVER_DEVICE  *Dev
  )
{
  //
  // free each name
  //
  FreePool (Dev->Name16);

  //
  // remove OPAL_DRIVER_DEVICE from the list
  // it updates the controllerList pointer
  //
  RemoveDevice (Dev);

  //
  // close protocols that were opened
  //
  gBS->CloseProtocol (
         Dev->Handle,
         &gEfiStorageSecurityCommandProtocolGuid,
         gOpalDriverBinding.DriverBindingHandle,
         Dev->Handle
         );

  gBS->CloseProtocol (
         Dev->Handle,
         &gEfiBlockIoProtocolGuid,
         gOpalDriverBinding.DriverBindingHandle,
         Dev->Handle
         );

  FreePool (Dev);
}

/**
  Get devcie name through the component name protocol.

  @param[in]       AllHandlesBuffer   The handle buffer for current system.
  @param[in]       NumAllHandles      The number of handles for the handle buffer.
  @param[in]       Dev                The device which need to get name.
  @param[in]       UseComp1           Whether use component name or name2 protocol.

  @retval     TRUE        Find the name for this device.
  @retval     FALSE       Not found the name for this device.
**/
BOOLEAN
OpalDriverGetDeviceNameByProtocol (
  EFI_HANDLE          *AllHandlesBuffer,
  UINTN               NumAllHandles,
  OPAL_DRIVER_DEVICE  *Dev,
  BOOLEAN             UseComp1
  )
{
  EFI_HANDLE                    *ProtocolHandlesBuffer;
  UINTN                         NumProtocolHandles;
  EFI_STATUS                    Status;
  EFI_COMPONENT_NAME2_PROTOCOL  *Cnp1_2; // efi component name and componentName2 have same layout
  EFI_GUID                      Protocol;
  UINTN                         StrLength;
  EFI_DEVICE_PATH_PROTOCOL      *TmpDevPath;
  UINTN                         Index1;
  UINTN                         Index2;
  EFI_HANDLE                    TmpHandle;
  CHAR16                        *DevName;

  if ((Dev == NULL) || (AllHandlesBuffer == NULL) || (NumAllHandles == 0)) {
    return FALSE;
  }

  Protocol = UseComp1 ? gEfiComponentNameProtocolGuid : gEfiComponentName2ProtocolGuid;

  //
  // Find all EFI_HANDLES with protocol
  //
  Status = gBS->LocateHandleBuffer (
                  ByProtocol,
                  &Protocol,
                  NULL,
                  &NumProtocolHandles,
                  &ProtocolHandlesBuffer
                  );
  if (EFI_ERROR (Status)) {
    return FALSE;
  }

  //
  // Exit early if no supported devices
  //
  if (NumProtocolHandles == 0) {
    return FALSE;
  }

  //
  // Get printable name by iterating through all protocols
  // using the handle as the child, and iterate through all handles for the controller
  // exit loop early once found, if not found, then delete device
  // storage security protocol instances already exist, add them to internal list
  //
  Status = EFI_DEVICE_ERROR;
  for (Index1 = 0; Index1 < NumProtocolHandles; Index1++) {
    DevName = NULL;

    if (Dev->Name16 != NULL) {
      return TRUE;
    }

    TmpHandle = ProtocolHandlesBuffer[Index1];

    Status = gBS->OpenProtocol (
                    TmpHandle,
                    &Protocol,
                    (VOID **)&Cnp1_2,
                    gImageHandle,
                    NULL,
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );
    if (EFI_ERROR (Status) || (Cnp1_2 == NULL)) {
      continue;
    }

    //
    // Use all handles array as controller handle
    //
    for (Index2 = 0; Index2 < NumAllHandles; Index2++) {
      Status = Cnp1_2->GetControllerName (
                         Cnp1_2,
                         AllHandlesBuffer[Index2],
                         Dev->Handle,
                         LANGUAGE_ISO_639_2_ENGLISH,
                         &DevName
                         );
      if (EFI_ERROR (Status)) {
        Status = Cnp1_2->GetControllerName (
                           Cnp1_2,
                           AllHandlesBuffer[Index2],
                           Dev->Handle,
                           LANGUAGE_RFC_3066_ENGLISH,
                           &DevName
                           );
      }

      if (!EFI_ERROR (Status) && (DevName != NULL)) {
        StrLength   = StrLen (DevName) + 1;     // Add one for NULL terminator
        Dev->Name16 = AllocateZeroPool (StrLength * sizeof (CHAR16));
        ASSERT (Dev->Name16 != NULL);
        StrCpyS (Dev->Name16, StrLength, DevName);
        Dev->NameZ = (CHAR8 *)AllocateZeroPool (StrLength);
        UnicodeStrToAsciiStrS (DevName, Dev->NameZ, StrLength);

        //
        // Retrieve bridge BDF info and port number or namespace depending on type
        //
        TmpDevPath = NULL;
        Status     = gBS->OpenProtocol (
                            Dev->Handle,
                            &gEfiDevicePathProtocolGuid,
                            (VOID **)&TmpDevPath,
                            gImageHandle,
                            NULL,
                            EFI_OPEN_PROTOCOL_GET_PROTOCOL
                            );
        if (!EFI_ERROR (Status)) {
          Dev->OpalDevicePath = DuplicateDevicePath (TmpDevPath);
          return TRUE;
        }

        if (Dev->Name16 != NULL) {
          FreePool (Dev->Name16);
          Dev->Name16 = NULL;
        }

        if (Dev->NameZ != NULL) {
          FreePool (Dev->NameZ);
          Dev->NameZ = NULL;
        }
      }
    }
  }

  return FALSE;
}

/**
  Get devcie name through the component name protocol.

  @param[in]       Dev                The device which need to get name.

  @retval     TRUE        Find the name for this device.
  @retval     FALSE       Not found the name for this device.
**/
BOOLEAN
OpalDriverGetDriverDeviceName (
  OPAL_DRIVER_DEVICE  *Dev
  )
{
  EFI_HANDLE  *AllHandlesBuffer;
  UINTN       NumAllHandles;
  EFI_STATUS  Status;

  if (Dev == NULL) {
    DEBUG ((DEBUG_ERROR | DEBUG_INIT, "OpalDriverGetDriverDeviceName Exiting, Dev=NULL\n"));
    return FALSE;
  }

  //
  // Iterate through ComponentName2 handles to get name, if fails, try ComponentName
  //
  if (Dev->Name16 == NULL) {
    DEBUG ((DEBUG_ERROR | DEBUG_INIT, "Name is null, update it\n"));
    //
    // Find all EFI_HANDLES
    //
    Status = gBS->LocateHandleBuffer (
                    AllHandles,
                    NULL,
                    NULL,
                    &NumAllHandles,
                    &AllHandlesBuffer
                    );
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_INFO, "LocateHandleBuffer for AllHandles failed %r\n", Status));
      return FALSE;
    }

    //
    // Try component Name2
    //
    if (!OpalDriverGetDeviceNameByProtocol (AllHandlesBuffer, NumAllHandles, Dev, FALSE)) {
      DEBUG ((DEBUG_ERROR | DEBUG_INIT, "ComponentName2 failed to get device name, try ComponentName\n"));
      if (!OpalDriverGetDeviceNameByProtocol (AllHandlesBuffer, NumAllHandles, Dev, TRUE)) {
        DEBUG ((DEBUG_ERROR | DEBUG_INIT, "ComponentName failed to get device name, skip device\n"));
        return FALSE;
      }
    }
  }

  return TRUE;
}

/**
  Main entry for this driver.

  @param ImageHandle     Image Handle this driver.
  @param SystemTable     Pointer to SystemTable.

  @retval EFI_SUCCESS    This function always complete successfully.
**/
EFI_STATUS
EFIAPI
EfiDriverEntryPoint (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS  Status;
  EFI_EVENT   EndOfDxeEvent;

  Status = EfiLibInstallDriverBindingComponentName2 (
             ImageHandle,
             SystemTable,
             &gOpalDriverBinding,
             ImageHandle,
             &gOpalComponentName,
             &gOpalComponentName2
             );

  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "Install protocols to Opal driver Handle failed\n"));
    return Status;
  }

  //
  // Initialize Driver object
  //
  ZeroMem (&mOpalDriver, sizeof (mOpalDriver));
  mOpalDriver.Handle = ImageHandle;

  Status = gBS->CreateEventEx (
                  EVT_NOTIFY_SIGNAL,
                  TPL_CALLBACK,
                  OpalEndOfDxeEventNotify,
                  NULL,
                  &gEfiEndOfDxeEventGroupGuid,
                  &EndOfDxeEvent
                  );
  ASSERT_EFI_ERROR (Status);

  //
  // Install Hii packages.
  //
  HiiInstall ();

  return Status;
}

/**
  Tests to see if this driver supports a given controller.

  This function checks to see if the controller contains an instance of the
  EFI_STORAGE_SECURITY_COMMAND_PROTOCOL and the EFI_BLOCK_IO_PROTOCOL
  and returns EFI_SUCCESS if it does.

  @param[in]  This                  A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
  @param[in]  ControllerHandle      The Handle of the controller to test. This Handle
                                    must support a protocol interface that supplies
                                    an I/O abstraction to the driver.
  @param[in]  RemainingDevicePath  This parameter is ignored.

  @retval EFI_SUCCESS               The device contains required protocols
  @retval EFI_ALREADY_STARTED       The device specified by ControllerHandle and
                                    RemainingDevicePath is already being managed by the driver
                                    specified by This.
  @retval EFI_ACCESS_DENIED         The device specified by ControllerHandle and
                                    RemainingDevicePath is already being managed by a different
                                    driver or an application that requires exclusive access.
                                    Currently not implemented.
  @retval EFI_UNSUPPORTED           The device does not contain requires protocols

**/
EFI_STATUS
EFIAPI
OpalEfiDriverBindingSupported (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   Controller,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
  )
{
  EFI_STATUS                             Status;
  EFI_STORAGE_SECURITY_COMMAND_PROTOCOL  *SecurityCommand;

  if (mOpalEndOfDxe) {
    return EFI_UNSUPPORTED;
  }

  //
  // Test EFI_STORAGE_SECURITY_COMMAND_PROTOCOL on controller Handle.
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiStorageSecurityCommandProtocolGuid,
                  (VOID **)&SecurityCommand,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );

  if (Status == EFI_ALREADY_STARTED) {
    return EFI_SUCCESS;
  }

  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Close protocol and reopen in Start call
  //
  gBS->CloseProtocol (
         Controller,
         &gEfiStorageSecurityCommandProtocolGuid,
         This->DriverBindingHandle,
         Controller
         );

  return EFI_SUCCESS;
}

/**
  Enables Opal Management on a supported device if available.

  The start function is designed to be called after the Opal UEFI Driver has confirmed the
  "controller", which is a child Handle, contains the EF_STORAGE_SECURITY_COMMAND protocols.
  This function will complete the other necessary checks, such as verifying the device supports
  the correct version of Opal.  Upon verification, it will add the device to the
  Opal HII list in order to expose Opal management options.

  @param[in]  This                  A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
  @param[in]  ControllerHandle      The Handle of the controller to start. This Handle
                                    must support a protocol interface that supplies
                                    an I/O abstraction to the driver.
  @param[in]  RemainingDevicePath   A pointer to the remaining portion of a device path.  This
                                    parameter is ignored by device drivers, and is optional for bus
                                    drivers. For a bus driver, if this parameter is NULL, then handles
                                    for all the children of Controller are created by this driver.
                                    If this parameter is not NULL and the first Device Path Node is
                                    not the End of Device Path Node, then only the Handle for the
                                    child device specified by the first Device Path Node of
                                    RemainingDevicePath is created by this driver.
                                    If the first Device Path Node of RemainingDevicePath is
                                    the End of Device Path Node, no child Handle is created by this
                                    driver.

  @retval EFI_SUCCESS               Opal management was enabled.
  @retval EFI_DEVICE_ERROR          The device could not be started due to a device error.Currently not implemented.
  @retval EFI_OUT_OF_RESOURCES      The request could not be completed due to a lack of resources.
  @retval Others                    The driver failed to start the device.

**/
EFI_STATUS
EFIAPI
OpalEfiDriverBindingStart (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   Controller,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
  )
{
  EFI_STATUS             Status;
  EFI_BLOCK_IO_PROTOCOL  *BlkIo;
  OPAL_DRIVER_DEVICE     *Dev;
  OPAL_DRIVER_DEVICE     *Itr;
  BOOLEAN                Result;

  Itr = mOpalDriver.DeviceList;
  while (Itr != NULL) {
    if (Controller == Itr->Handle) {
      return EFI_SUCCESS;
    }

    Itr = Itr->Next;
  }

  //
  // Create internal device for tracking.  This allows all disks to be tracked
  // by same HII form
  //
  Dev = (OPAL_DRIVER_DEVICE *)AllocateZeroPool (sizeof (OPAL_DRIVER_DEVICE));
  if (Dev == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Dev->Handle = Controller;

  //
  // Open EFI_STORAGE_SECURITY_COMMAND_PROTOCOL to perform Opal supported checks
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiStorageSecurityCommandProtocolGuid,
                  (VOID **)&Dev->Sscp,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    FreePool (Dev);
    return Status;
  }

  //
  // Open EFI_BLOCK_IO_PROTOCOL on controller Handle, required by EFI_STORAGE_SECURITY_COMMAND_PROTOCOL
  // function APIs
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiBlockIoProtocolGuid,
                  (VOID **)&BlkIo,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    //
    // Block_IO not supported on handle
    //
    if (Status == EFI_UNSUPPORTED) {
      BlkIo = NULL;
    } else {
      //
      // Close storage security that was opened
      //
      gBS->CloseProtocol (
             Controller,
             &gEfiStorageSecurityCommandProtocolGuid,
             This->DriverBindingHandle,
             Controller
             );

      FreePool (Dev);
      return Status;
    }
  }

  //
  // Save mediaId
  //
  if (BlkIo == NULL) {
    // If no Block IO present, use defined MediaId value.
    Dev->MediaId = 0x0;
  } else {
    Dev->MediaId = BlkIo->Media->MediaId;

    gBS->CloseProtocol (
           Controller,
           &gEfiBlockIoProtocolGuid,
           This->DriverBindingHandle,
           Controller
           );
  }

  //
  // Acquire Ascii printable name of child, if not found, then ignore device
  //
  Result = OpalDriverGetDriverDeviceName (Dev);
  if (!Result) {
    goto Done;
  }

  Status = OpalDiskInitialize (Dev);
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  AddDeviceToTail (Dev);

  //
  // Check if device is locked and prompt for password.
  //
  OpalDriverRequestPassword (Dev, L"Unlock:");

  //
  // Process OPAL request from last boot.
  //
  ProcessOpalRequest (Dev);

  return EFI_SUCCESS;

Done:
  //
  // free device, close protocols and exit
  //
  gBS->CloseProtocol (
         Controller,
         &gEfiStorageSecurityCommandProtocolGuid,
         This->DriverBindingHandle,
         Controller
         );

  FreePool (Dev);

  return EFI_DEVICE_ERROR;
}

/**
  Stop this driver on Controller.

  @param  This              Protocol instance pointer.
  @param  Controller        Handle of device to stop driver on
  @param  NumberOfChildren  Number of Handles in ChildHandleBuffer. If number of
                            children is zero stop the entire bus driver.
  @param  ChildHandleBuffer List of Child Handles to Stop.

  @retval EFI_SUCCESS       This driver is removed Controller.
  @retval other             This driver could not be removed from this device.

**/
EFI_STATUS
EFIAPI
OpalEfiDriverBindingStop (
  EFI_DRIVER_BINDING_PROTOCOL  *This,
  EFI_HANDLE                   Controller,
  UINTN                        NumberOfChildren,
  EFI_HANDLE                   *ChildHandleBuffer
  )
{
  OPAL_DRIVER_DEVICE  *Itr;

  Itr = mOpalDriver.DeviceList;

  //
  // does Controller match any of the devices we are managing for Opal
  //
  while (Itr != NULL) {
    if (Itr->Handle == Controller) {
      OpalDriverStopDevice (Itr);
      return EFI_SUCCESS;
    }

    Itr = Itr->Next;
  }

  return EFI_NOT_FOUND;
}

/**
  Unloads UEFI Driver.  Very useful for debugging and testing.

  @param ImageHandle            Image Handle this driver.

  @retval EFI_SUCCESS           This function always complete successfully.
  @retval EFI_INVALID_PARAMETER The input ImageHandle is not valid.
**/
EFI_STATUS
EFIAPI
OpalEfiDriverUnload (
  IN EFI_HANDLE  ImageHandle
  )
{
  EFI_STATUS          Status;
  OPAL_DRIVER_DEVICE  *Itr;

  Status = EFI_SUCCESS;

  if (ImageHandle != gImageHandle) {
    return (EFI_INVALID_PARAMETER);
  }

  //
  // Uninstall any interface added to each device by us
  //
  while (mOpalDriver.DeviceList) {
    Itr = mOpalDriver.DeviceList;
    //
    // Remove OPAL_DRIVER_DEVICE from the list
    // it updates the controllerList pointer
    //
    OpalDriverStopDevice (Itr);
  }

  //
  // Uninstall the HII capability
  //
  Status = HiiUninstall ();

  return Status;
}
