/** @file
  Miscellaneous routines for iSCSI driver.

Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution.  The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php

THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include "IScsiImpl.h"

GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8  IScsiHexString[] = "0123456789ABCDEFabcdef";

/**
  Removes (trims) specified leading and trailing characters from a string.

  @param[in, out] Str   Pointer to the null-terminated string to be trimmed.
                        On return, Str will hold the trimmed string. 

  @param[in]      CharC Character will be trimmed from str.

**/
VOID
IScsiStrTrim (
  IN OUT CHAR16   *Str,
  IN     CHAR16   CharC
  )
{
  CHAR16  *Pointer1;
  CHAR16  *Pointer2;
  
  if (*Str == 0) {
    return ;
  }
  
  //
  // Trim off the leading and trailing characters c
  //
  for (Pointer1 = Str; (*Pointer1 != 0) && (*Pointer1 == CharC); Pointer1++) {
    ;
  }
  
  Pointer2 = Str;
  if (Pointer2 == Pointer1) {
    while (*Pointer1 != 0) {
      Pointer2++;
      Pointer1++;
    }
  } else {
    while (*Pointer1 != 0) {    
    *Pointer2 = *Pointer1;    
    Pointer1++;
    Pointer2++;
    }
    *Pointer2 = 0;
  }
  
  
  for (Pointer1 = Str + StrLen(Str) - 1; Pointer1 >= Str && *Pointer1 == CharC; Pointer1--) {
    ;
  }
  if  (Pointer1 !=  Str + StrLen(Str) - 1) { 
    *(Pointer1 + 1) = 0;
  }
}

/**
  Calculate the prefix length of the IPv4 subnet mask.

  @param[in]  SubnetMask The IPv4 subnet mask.

  @return     The prefix length of the subnet mask.
  @retval 0   Other errors as indicated.

**/
UINT8
IScsiGetSubnetMaskPrefixLength (
  IN EFI_IPv4_ADDRESS  *SubnetMask
  )
{
  UINT8   Len;
  UINT32  ReverseMask;

  //
  // The SubnetMask is in network byte order.
  //
  ReverseMask = (SubnetMask->Addr[0] << 24) | (SubnetMask->Addr[1] << 16) | (SubnetMask->Addr[2] << 8) | (SubnetMask->Addr[3]);

  //
  // Reverse it.
  //
  ReverseMask = ~ReverseMask;

  if ((ReverseMask & (ReverseMask + 1)) != 0) {
    return 0;
  }

  Len = 0;

  while (ReverseMask != 0) {
    ReverseMask = ReverseMask >> 1;
    Len++;
  }

  return (UINT8) (32 - Len);
}


/**
  Convert the hexadecimal encoded LUN string into the 64-bit LUN.

  @param[in]   Str             The hexadecimal encoded LUN string.
  @param[out]  Lun             Storage to return the 64-bit LUN.

  @retval EFI_SUCCESS            The 64-bit LUN is stored in Lun.
  @retval EFI_INVALID_PARAMETER  The string is malformatted.

**/
EFI_STATUS
IScsiAsciiStrToLun (
  IN  CHAR8  *Str,
  OUT UINT8  *Lun
  )
{
  UINTN   Index, IndexValue, IndexNum, SizeStr;
  CHAR8   TemStr[2];
  UINT8   TemValue;
  UINT16  Value[4];
  
  ZeroMem (Lun, 8);
  ZeroMem (TemStr, 2);
  ZeroMem ((UINT8 *) Value, sizeof (Value));
  SizeStr    = AsciiStrLen (Str);  
  IndexValue = 0;
  IndexNum   = 0;

  for (Index = 0; Index < SizeStr; Index ++) {
    TemStr[0] = Str[Index];
    TemValue = (UINT8) AsciiStrHexToUint64 (TemStr);
    if (TemValue == 0 && TemStr[0] != '0') {
      if ((TemStr[0] != '-') || (IndexNum == 0)) {
        //
        // Invalid Lun Char.
        //
        return EFI_INVALID_PARAMETER;
      }
    }
    
    if ((TemValue == 0) && (TemStr[0] == '-')) {
      //
      // Next Lun value.
      //
      if (++IndexValue >= 4) {
        //
        // Max 4 Lun value.
        //
        return EFI_INVALID_PARAMETER;
      }
      //
      // Restart str index for the next lun value.
      //
      IndexNum = 0;
      continue;
    }
    
    if (++IndexNum > 4) {
      //     
      // Each Lun Str can't exceed size 4, because it will be as UINT16 value.
      //
      return EFI_INVALID_PARAMETER;
    }
    
    //
    // Combine UINT16 value.
    //
    Value[IndexValue] = (UINT16) ((Value[IndexValue] << 4) + TemValue);
  }
 
  for (Index = 0; Index <= IndexValue; Index ++) {
    *((UINT16 *) &Lun[Index * 2]) =  HTONS (Value[Index]);
  }
  
  return EFI_SUCCESS;
}

/**
  Convert the 64-bit LUN into the hexadecimal encoded LUN string.

  @param[in]   Lun The 64-bit LUN.
  @param[out]  Str The storage to return the hexadecimal encoded LUN string.

**/
VOID
IScsiLunToUnicodeStr (
  IN UINT8    *Lun,
  OUT CHAR16  *Str
  )
{
  UINTN   Index;
  CHAR16  *TempStr;

  TempStr = Str;

  for (Index = 0; Index < 4; Index++) {

    if ((Lun[2 * Index] | Lun[2 * Index + 1]) == 0) {
      CopyMem (TempStr, L"0-", sizeof (L"0-"));
    } else {
      TempStr[0]  = (CHAR16) IScsiHexString[Lun[2 * Index] >> 4];
      TempStr[1]  = (CHAR16) IScsiHexString[Lun[2 * Index] & 0x0F];
      TempStr[2]  = (CHAR16) IScsiHexString[Lun[2 * Index + 1] >> 4];
      TempStr[3]  = (CHAR16) IScsiHexString[Lun[2 * Index + 1] & 0x0F];
      TempStr[4]  = L'-';
      TempStr[5]  = 0;

      IScsiStrTrim (TempStr, L'0');
    }

    TempStr += StrLen (TempStr);
  }
  //
  // Remove the last '-'
  //
  ASSERT (StrLen(Str) >= 1);
  Str[StrLen (Str) - 1] = 0;

  for (Index = StrLen (Str) - 1; Index > 1; Index = Index - 2) {
    if ((Str[Index] == L'0') && (Str[Index - 1] == L'-')) {
      Str[Index - 1] = 0;
    } else {
      break;
    }
  }
}

/**
  Convert the formatted IP address into the binary IP address.

  @param[in]   Str               The UNICODE string.
  @param[in]   IpMode            Indicates whether the IP address is v4 or v6.
  @param[out]  Ip                The storage to return the ASCII string.

  @retval EFI_SUCCESS            The binary IP address is returned in Ip.
  @retval EFI_INVALID_PARAMETER  The IP string is malformatted or IpMode is
                                 invalid.

**/
EFI_STATUS
IScsiAsciiStrToIp (
  IN  CHAR8             *Str,
  IN  UINT8             IpMode,
  OUT EFI_IP_ADDRESS    *Ip
  )
{
  EFI_STATUS            Status;

  if (IpMode == IP_MODE_IP4 || IpMode == IP_MODE_AUTOCONFIG_IP4) {
    return NetLibAsciiStrToIp4 (Str, &Ip->v4);

  } else if (IpMode == IP_MODE_IP6 || IpMode == IP_MODE_AUTOCONFIG_IP6) {
    return NetLibAsciiStrToIp6 (Str, &Ip->v6);

  } else if (IpMode == IP_MODE_AUTOCONFIG) {
    Status = NetLibAsciiStrToIp4 (Str, &Ip->v4);
    if (!EFI_ERROR (Status)) {
      return Status;
    }
    return NetLibAsciiStrToIp6 (Str, &Ip->v6);

  }

  return EFI_INVALID_PARAMETER;
}

/**
  Convert the mac address into a hexadecimal encoded "-" seperated string.

  @param[in]  Mac     The mac address.
  @param[in]  Len     Length in bytes of the mac address.
  @param[in]  VlanId  VLAN ID of the network device.
  @param[out] Str     The storage to return the mac string.

**/
VOID
IScsiMacAddrToStr (
  IN  EFI_MAC_ADDRESS  *Mac,
  IN  UINT32           Len,
  IN  UINT16           VlanId,
  OUT CHAR16           *Str
  )
{
  UINT32  Index;
  CHAR16  *String;

  for (Index = 0; Index < Len; Index++) {
    Str[3 * Index]      = (CHAR16) IScsiHexString[(Mac->Addr[Index] >> 4) & 0x0F];
    Str[3 * Index + 1]  = (CHAR16) IScsiHexString[Mac->Addr[Index] & 0x0F];
    Str[3 * Index + 2]  = L':';
  }

  String = &Str[3 * Index - 1] ;
  if (VlanId != 0) {
    String += UnicodeSPrint (String, 6 * sizeof (CHAR16), L"\\%04x", (UINTN) VlanId);
  }

  *String = L'\0';
}

/**
  Convert the binary encoded buffer into a hexadecimal encoded string.

  @param[in]       BinBuffer   The buffer containing the binary data.
  @param[in]       BinLength   Length of the binary buffer.
  @param[in, out]  HexStr      Pointer to the string.
  @param[in, out]  HexLength   The length of the string.

  @retval EFI_SUCCESS          The binary data is converted to the hexadecimal string 
                               and the length of the string is updated.
  @retval EFI_BUFFER_TOO_SMALL The string is too small.
  @retval EFI_INVALID_PARAMETER The IP string is malformatted.

**/
EFI_STATUS
IScsiBinToHex (
  IN     UINT8  *BinBuffer,
  IN     UINT32 BinLength,
  IN OUT CHAR8  *HexStr,
  IN OUT UINT32 *HexLength
  )
{
  UINTN Index;

  if ((HexStr == NULL) || (BinBuffer == NULL) || (BinLength == 0)) {
    return EFI_INVALID_PARAMETER;
  }

  if (((*HexLength) - 3) < BinLength * 2) {
    *HexLength = BinLength * 2 + 3;
    return EFI_BUFFER_TOO_SMALL;
  }

  *HexLength = BinLength * 2 + 3;
  //
  // Prefix for Hex String.
  //
  HexStr[0] = '0';
  HexStr[1] = 'x';

  for (Index = 0; Index < BinLength; Index++) {
    HexStr[Index * 2 + 2] = IScsiHexString[BinBuffer[Index] >> 4];
    HexStr[Index * 2 + 3] = IScsiHexString[BinBuffer[Index] & 0xf];
  }

  HexStr[Index * 2 + 2] = '\0';

  return EFI_SUCCESS;
}


/**
  Convert the hexadecimal string into a binary encoded buffer.

  @param[in, out]  BinBuffer   The binary buffer.
  @param[in, out]  BinLength   Length of the binary buffer.
  @param[in]       HexStr      The hexadecimal string.

  @retval EFI_SUCCESS          The hexadecimal string is converted into a binary
                               encoded buffer.
  @retval EFI_BUFFER_TOO_SMALL The binary buffer is too small to hold the converted data.

**/
EFI_STATUS
IScsiHexToBin (
  IN OUT UINT8  *BinBuffer,
  IN OUT UINT32 *BinLength,
  IN     CHAR8  *HexStr
  )
{
  UINTN   Index;
  UINTN   Length;
  UINT8   Digit;
  CHAR8   TemStr[2];
  
  ZeroMem (TemStr, sizeof (TemStr));

  //
  // Find out how many hex characters the string has.
  //
  if ((HexStr[0] == '0') && ((HexStr[1] == 'x') || (HexStr[1] == 'X'))) {
    HexStr += 2;
  }
  
  Length = AsciiStrLen (HexStr);

  for (Index = 0; Index < Length; Index ++) {
    TemStr[0] = HexStr[Index];
    Digit = (UINT8) AsciiStrHexToUint64 (TemStr);
    if (Digit == 0 && TemStr[0] != '0') {
      //
      // Invalid Lun Char.
      //
      break;
    }
    if ((Index & 1) == 0) {
      BinBuffer [Index/2] = Digit;
    } else {
      BinBuffer [Index/2] = (UINT8) ((BinBuffer [Index/2] << 4) + Digit);
    }
  }
  
  *BinLength = (UINT32) ((Index + 1)/2);

  return EFI_SUCCESS;
}


/**
  Convert the decimal-constant string or hex-constant string into a numerical value.

  @param[in] Str                    String in decimal or hex.

  @return The numerical value.

**/
UINTN
IScsiNetNtoi (
  IN     CHAR8  *Str
  )
{
  if ((Str[0] == '0') && ((Str[1] == 'x') || (Str[1] == 'X'))) {
    Str += 2;

    return AsciiStrHexToUintn (Str);
  }

  return AsciiStrDecimalToUintn (Str);
}


/**
  Generate random numbers.

  @param[in, out]  Rand       The buffer to contain random numbers.
  @param[in]       RandLength The length of the Rand buffer.

**/
VOID
IScsiGenRandom (
  IN OUT UINT8  *Rand,
  IN     UINTN  RandLength
  )
{
  UINT32  Random;

  while (RandLength > 0) {
    Random  = NET_RANDOM (NetRandomInitSeed ());
    *Rand++ = (UINT8) (Random);
    RandLength--;
  }
}


/**
  Record the NIC info in global structure.

  @param[in]  Controller         The handle of the controller.

  @retval EFI_SUCCESS            The operation is completed.
  @retval EFI_OUT_OF_RESOURCES   Do not have sufficient resources to finish this
                                 operation.

**/
EFI_STATUS
IScsiAddNic (
  IN EFI_HANDLE  Controller
  )
{
  EFI_STATUS                  Status;
  ISCSI_NIC_INFO              *NicInfo;
  LIST_ENTRY                  *Entry;
  EFI_MAC_ADDRESS             MacAddr;
  UINTN                       HwAddressSize;
  UINT16                      VlanId;

  //
  // Get MAC address of this network device.
  //
  Status = NetLibGetMacAddress (Controller, &MacAddr, &HwAddressSize);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Get VLAN ID of this network device.
  //
  VlanId = NetLibGetVlanId (Controller);

  //
  // Check whether the NIC info already exists. Return directly if so.
  //
  NET_LIST_FOR_EACH (Entry, &mPrivate->NicInfoList) {
    NicInfo = NET_LIST_USER_STRUCT (Entry, ISCSI_NIC_INFO, Link);
    if (NicInfo->HwAddressSize == HwAddressSize &&
        CompareMem (&NicInfo->PermanentAddress, MacAddr.Addr, HwAddressSize) == 0 &&
        NicInfo->VlanId == VlanId) {
      mPrivate->CurrentNic = NicInfo->NicIndex;
      return EFI_SUCCESS;
    }

    if (mPrivate->MaxNic < NicInfo->NicIndex) {
      mPrivate->MaxNic = NicInfo->NicIndex;
    }
  }

  //
  // Record the NIC info in private structure.
  //
  NicInfo = AllocateZeroPool (sizeof (ISCSI_NIC_INFO));
  if (NicInfo == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  CopyMem (&NicInfo->PermanentAddress, MacAddr.Addr, HwAddressSize);
  NicInfo->HwAddressSize  = (UINT32) HwAddressSize;
  NicInfo->VlanId         = VlanId;
  NicInfo->NicIndex       = (UINT8) (mPrivate->MaxNic + 1);
  mPrivate->MaxNic        = NicInfo->NicIndex;

  //
  // Get the PCI location.
  //
  IScsiGetNICPciLocation (
    Controller,
    &NicInfo->BusNumber,
    &NicInfo->DeviceNumber,
    &NicInfo->FunctionNumber
    );

  InsertTailList (&mPrivate->NicInfoList, &NicInfo->Link);
  mPrivate->NicCount++;

  mPrivate->CurrentNic = NicInfo->NicIndex;
  return EFI_SUCCESS;
}


/**
  Delete the recorded NIC info from global structure. Also delete corresponding
  attempts.

  @param[in]  Controller         The handle of the controller.

  @retval EFI_SUCCESS            The operation is completed.
  @retval EFI_NOT_FOUND          The NIC info to be deleted is not recorded.

**/
EFI_STATUS
IScsiRemoveNic (
  IN EFI_HANDLE  Controller
  )
{
  EFI_STATUS                  Status;
  ISCSI_NIC_INFO              *NicInfo;
  LIST_ENTRY                  *Entry;
  LIST_ENTRY                  *NextEntry;
  ISCSI_ATTEMPT_CONFIG_NVDATA *AttemptConfigData;
  ISCSI_NIC_INFO              *ThisNic;
  EFI_MAC_ADDRESS             MacAddr;
  UINTN                       HwAddressSize;
  UINT16                      VlanId;

  //
  // Get MAC address of this network device.
  //
  Status = NetLibGetMacAddress (Controller, &MacAddr, &HwAddressSize);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Get VLAN ID of this network device.
  //
  VlanId = NetLibGetVlanId (Controller);

  //
  // Check whether the NIC information exists.
  //
  ThisNic = NULL;

  NET_LIST_FOR_EACH (Entry, &mPrivate->NicInfoList) {
    NicInfo = NET_LIST_USER_STRUCT (Entry, ISCSI_NIC_INFO, Link);
    if (NicInfo->HwAddressSize == HwAddressSize &&
        CompareMem (&NicInfo->PermanentAddress, MacAddr.Addr, HwAddressSize) == 0 &&
        NicInfo->VlanId == VlanId) {

      ThisNic = NicInfo;
      break;
    }
  }

  if (ThisNic == NULL) {
    return EFI_NOT_FOUND;
  }

  mPrivate->CurrentNic = ThisNic->NicIndex;

  RemoveEntryList (&ThisNic->Link);
  FreePool (ThisNic);
  mPrivate->NicCount--;

  //
  // Remove all attempts related to this NIC.
  //
  NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &mPrivate->AttemptConfigs) {
    AttemptConfigData = NET_LIST_USER_STRUCT (Entry, ISCSI_ATTEMPT_CONFIG_NVDATA, Link);
    if (AttemptConfigData->NicIndex == mPrivate->CurrentNic) {
      RemoveEntryList (&AttemptConfigData->Link);
      mPrivate->AttemptCount--;

      if (AttemptConfigData->SessionConfigData.Enabled == ISCSI_ENABLED_FOR_MPIO && mPrivate->MpioCount > 0) {
        if (--mPrivate->MpioCount == 0) {
          mPrivate->EnableMpio = FALSE;
        }

        if (AttemptConfigData->AuthenticationType == ISCSI_AUTH_TYPE_KRB && mPrivate->Krb5MpioCount > 0) {
          mPrivate->Krb5MpioCount--;
        }

      } else if (AttemptConfigData->SessionConfigData.Enabled == ISCSI_ENABLED && mPrivate->SinglePathCount > 0) {
        mPrivate->SinglePathCount--;

        if (mPrivate->ValidSinglePathCount > 0) {
          mPrivate->ValidSinglePathCount--;
        }
      }

      FreePool (AttemptConfigData);
    }
  }

  //
  // Free attempt is created but not saved to system.
  //
  if (mPrivate->NewAttempt != NULL) {
    FreePool (mPrivate->NewAttempt);
    mPrivate->NewAttempt = NULL;
  }

  return EFI_SUCCESS;
}


/**
  Get the recorded NIC info from global structure by the Index.

  @param[in]  NicIndex          The index indicates the position of NIC info.

  @return Pointer to the NIC info, or NULL if not found.

**/
ISCSI_NIC_INFO *
IScsiGetNicInfoByIndex (
  IN UINT8      NicIndex
  )
{
  LIST_ENTRY        *Entry;
  ISCSI_NIC_INFO    *NicInfo;

  NET_LIST_FOR_EACH (Entry, &mPrivate->NicInfoList) {
    NicInfo = NET_LIST_USER_STRUCT (Entry, ISCSI_NIC_INFO, Link);
    if (NicInfo->NicIndex == NicIndex) {
      return NicInfo;
    }
  }

  return NULL;
}


/**
  Get the NIC's PCI location and return it accroding to the composited
  format defined in iSCSI Boot Firmware Table.

  @param[in]   Controller        The handle of the controller.
  @param[out]  Bus               The bus number.
  @param[out]  Device            The device number.
  @param[out]  Function          The function number.

  @return      The composited representation of the NIC PCI location.

**/
UINT16
IScsiGetNICPciLocation (
  IN EFI_HANDLE  Controller,
  OUT UINTN      *Bus,
  OUT UINTN      *Device,
  OUT UINTN      *Function
  )
{
  EFI_STATUS                Status;
  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
  EFI_HANDLE                PciIoHandle;
  EFI_PCI_IO_PROTOCOL       *PciIo;
  UINTN                     Segment;

  Status = gBS->HandleProtocol (
                  Controller,
                  &gEfiDevicePathProtocolGuid,
                  (VOID **) &DevicePath
                  );
  if (EFI_ERROR (Status)) {
    return 0;
  }

  Status = gBS->LocateDevicePath (
                  &gEfiPciIoProtocolGuid,
                  &DevicePath,
                  &PciIoHandle
                  );
  if (EFI_ERROR (Status)) {
    return 0;
  }

  Status = gBS->HandleProtocol (PciIoHandle, &gEfiPciIoProtocolGuid, (VOID **) &PciIo);
  if (EFI_ERROR (Status)) {
    return 0;
  }

  Status = PciIo->GetLocation (PciIo, &Segment, Bus, Device, Function);
  if (EFI_ERROR (Status)) {
    return 0;
  }

  return (UINT16) ((*Bus << 8) | (*Device << 3) | *Function);
}


/**
  Read the EFI variable (VendorGuid/Name) and return a dynamically allocated
  buffer, and the size of the buffer. If failure, return NULL.

  @param[in]   Name                   String part of EFI variable name.
  @param[in]   VendorGuid             GUID part of EFI variable name.
  @param[out]  VariableSize           Returns the size of the EFI variable that was read.

  @return Dynamically allocated memory that contains a copy of the EFI variable.
  @return Caller is responsible freeing the buffer.
  @retval NULL                   Variable was not read.

**/
VOID *
IScsiGetVariableAndSize (
  IN  CHAR16              *Name,
  IN  EFI_GUID            *VendorGuid,
  OUT UINTN               *VariableSize
  )
{
  EFI_STATUS  Status;
  UINTN       BufferSize;
  VOID        *Buffer;

  Buffer = NULL;

  //
  // Pass in a zero size buffer to find the required buffer size.
  //
  BufferSize  = 0;
  Status      = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer);
  if (Status == EFI_BUFFER_TOO_SMALL) {
    //
    // Allocate the buffer to return
    //
    Buffer = AllocateZeroPool (BufferSize);
    if (Buffer == NULL) {
      return NULL;
    }
    //
    // Read variable into the allocated buffer.
    //
    Status = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer);
    if (EFI_ERROR (Status)) {
      BufferSize = 0;
    }
  }

  *VariableSize = BufferSize;
  return Buffer;
}


/**
  Create the iSCSI driver data.

  @param[in] Image      The handle of the driver image.
  @param[in] Controller The handle of the controller.

  @return The iSCSI driver data created.
  @retval NULL Other errors as indicated.

**/
ISCSI_DRIVER_DATA *
IScsiCreateDriverData (
  IN EFI_HANDLE  Image,
  IN EFI_HANDLE  Controller
  )
{
  ISCSI_DRIVER_DATA *Private;
  EFI_STATUS        Status;

  Private = AllocateZeroPool (sizeof (ISCSI_DRIVER_DATA));
  if (Private == NULL) {
    return NULL;
  }

  Private->Signature  = ISCSI_DRIVER_DATA_SIGNATURE;
  Private->Image      = Image;
  Private->Controller = Controller;
  Private->Session    = NULL;

  //
  // Create an event to be signaled when the BS to RT transition is triggerd so
  // as to abort the iSCSI session.
  //
  Status = gBS->CreateEventEx (
                  EVT_NOTIFY_SIGNAL,
                  TPL_CALLBACK,
                  IScsiOnExitBootService,
                  Private,
                  &gEfiEventExitBootServicesGuid,
                  &Private->ExitBootServiceEvent
                  );
  if (EFI_ERROR (Status)) {
    FreePool (Private);
    return NULL;
  }

  Private->ExtScsiPassThruHandle = NULL;
  CopyMem(&Private->IScsiExtScsiPassThru, &gIScsiExtScsiPassThruProtocolTemplate, sizeof(EFI_EXT_SCSI_PASS_THRU_PROTOCOL));

  //
  // 0 is designated to the TargetId, so use another value for the AdapterId.
  //
  Private->ExtScsiPassThruMode.AdapterId  = 2;
  Private->ExtScsiPassThruMode.Attributes = EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL | EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_LOGICAL;
  Private->ExtScsiPassThruMode.IoAlign    = 4;
  Private->IScsiExtScsiPassThru.Mode      = &Private->ExtScsiPassThruMode;

  return Private;
}


/**
  Clean the iSCSI driver data.

  @param[in]  Private The iSCSI driver data.

**/
VOID
IScsiCleanDriverData (
  IN ISCSI_DRIVER_DATA  *Private
  )
{
  EFI_STATUS            Status;

  if (Private->DevicePath != NULL) {
    gBS->UninstallProtocolInterface (
           Private->ExtScsiPassThruHandle,
           &gEfiDevicePathProtocolGuid,
           Private->DevicePath
           );

    FreePool (Private->DevicePath);
  }

  if (Private->ExtScsiPassThruHandle != NULL) {
    Status = gBS->UninstallProtocolInterface (
                    Private->ExtScsiPassThruHandle,
                    &gEfiExtScsiPassThruProtocolGuid,
                    &Private->IScsiExtScsiPassThru
                    );
    if (!EFI_ERROR (Status)) {
      mPrivate->OneSessionEstablished = FALSE;
    }
  }

  gBS->CloseEvent (Private->ExitBootServiceEvent);

  FreePool (Private);
}

/**
  Check wheather the Controller handle is configured to use DHCP protocol.

  @param[in]  Controller           The handle of the controller.
  @param[in]  IpVersion            IP_VERSION_4 or IP_VERSION_6.
  
  @retval TRUE                     The handle of the controller need the Dhcp protocol.
  @retval FALSE                    The handle of the controller does not need the Dhcp protocol.
  
**/
BOOLEAN
IScsiDhcpIsConfigured (
  IN EFI_HANDLE  Controller,
  IN UINT8       IpVersion
  )
{
  ISCSI_ATTEMPT_CONFIG_NVDATA *AttemptTmp;
  UINT8                       *AttemptConfigOrder;
  UINTN                       AttemptConfigOrderSize;
  UINTN                       Index;
  EFI_STATUS                  Status;
  EFI_MAC_ADDRESS             MacAddr;
  UINTN                       HwAddressSize;
  UINT16                      VlanId;
  CHAR16                      MacString[ISCSI_MAX_MAC_STRING_LEN];
  CHAR16                      AttemptName[ISCSI_NAME_IFR_MAX_SIZE];
  
  AttemptConfigOrder = IScsiGetVariableAndSize (
                         L"AttemptOrder",
                         &gIScsiConfigGuid,
                         &AttemptConfigOrderSize
                         );
  if (AttemptConfigOrder == NULL || AttemptConfigOrderSize == 0) {
    return FALSE;
  }
  
  //
  // Get MAC address of this network device.
  //
  Status = NetLibGetMacAddress (Controller, &MacAddr, &HwAddressSize);
  if(EFI_ERROR (Status)) {
    return FALSE;
  }
  //
  // Get VLAN ID of this network device.
  //
  VlanId = NetLibGetVlanId (Controller);
  IScsiMacAddrToStr (&MacAddr, (UINT32) HwAddressSize, VlanId, MacString);
  
  for (Index = 0; Index < AttemptConfigOrderSize / sizeof (UINT8); Index++) {
    UnicodeSPrint (
      AttemptName,
      (UINTN) 128,
      L"%s%d",
      MacString,
      (UINTN) AttemptConfigOrder[Index]
      );
    Status = GetVariable2 (
               AttemptName,
               &gEfiIScsiInitiatorNameProtocolGuid,
               (VOID**)&AttemptTmp,
               NULL
               );
    if(AttemptTmp == NULL || EFI_ERROR (Status)) {
      continue;
    }
    
    ASSERT (AttemptConfigOrder[Index] == AttemptTmp->AttemptConfigIndex);

    if (AttemptTmp->SessionConfigData.Enabled == ISCSI_DISABLED) {
      FreePool (AttemptTmp);
      continue;
    }

    if (AttemptTmp->SessionConfigData.IpMode != IP_MODE_AUTOCONFIG && 
        AttemptTmp->SessionConfigData.IpMode != ((IpVersion == IP_VERSION_4) ? IP_MODE_IP4 : IP_MODE_IP6)) {
      FreePool (AttemptTmp);
      continue;
    }
    
    if(AttemptTmp->SessionConfigData.IpMode == IP_MODE_AUTOCONFIG ||
       AttemptTmp->SessionConfigData.InitiatorInfoFromDhcp == TRUE ||
       AttemptTmp->SessionConfigData.TargetInfoFromDhcp == TRUE) { 
      FreePool (AttemptTmp);
      FreePool (AttemptConfigOrder);
      return TRUE;
    }

    FreePool (AttemptTmp);
  }
  
  FreePool (AttemptConfigOrder);
  return FALSE;
}

/**
  Get the various configuration data.

  @param[in]  Private   The iSCSI driver data.

  @retval EFI_SUCCESS            The configuration data is retrieved.
  @retval EFI_NOT_FOUND          This iSCSI driver is not configured yet.

**/
EFI_STATUS
IScsiGetConfigData (
  IN ISCSI_DRIVER_DATA  *Private
  )
{
  EFI_STATUS                  Status;
  CHAR16                      MacString[ISCSI_MAX_MAC_STRING_LEN];
  UINTN                       Index;
  ISCSI_NIC_INFO              *NicInfo;
  ISCSI_ATTEMPT_CONFIG_NVDATA *AttemptConfigData;
  ISCSI_ATTEMPT_CONFIG_NVDATA *AttemptTmp;
  UINT8                       *AttemptConfigOrder;
  UINTN                       AttemptConfigOrderSize;
  CHAR16                      IScsiMode[64];
  CHAR16                      IpMode[64];

  //
  // There should be at least one attempt configured.
  //
  AttemptConfigOrder = IScsiGetVariableAndSize (
                         L"AttemptOrder",
                         &gIScsiConfigGuid,
                         &AttemptConfigOrderSize
                         );
  if (AttemptConfigOrder == NULL || AttemptConfigOrderSize == 0) {
    return EFI_NOT_FOUND;
  }

  //
  // Get the iSCSI Initiator Name.
  //
  mPrivate->InitiatorNameLength  = ISCSI_NAME_MAX_SIZE;
  Status = gIScsiInitiatorName.Get (
                                 &gIScsiInitiatorName,
                                 &mPrivate->InitiatorNameLength,
                                 mPrivate->InitiatorName
                                 );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Get the normal configuration.
  //
  for (Index = 0; Index < AttemptConfigOrderSize / sizeof (UINT8); Index++) {

    //
    // Check whether the attempt exists in AttemptConfig.
    //
    AttemptTmp = IScsiConfigGetAttemptByConfigIndex (AttemptConfigOrder[Index]);    
    if (AttemptTmp != NULL && AttemptTmp->SessionConfigData.Enabled == ISCSI_DISABLED) {
      continue;
    } else if (AttemptTmp != NULL && AttemptTmp->SessionConfigData.Enabled != ISCSI_DISABLED) {
      //
      // Check the autoconfig path to see whether it should be retried.
      //
      if (AttemptTmp->SessionConfigData.IpMode == IP_MODE_AUTOCONFIG &&
          AttemptTmp->AutoConfigureMode != IP_MODE_AUTOCONFIG_SUCCESS) {
        if (mPrivate->Ipv6Flag &&
            AttemptTmp->AutoConfigureMode == IP_MODE_AUTOCONFIG_IP6) {
          //
          // Autoconfigure for IP6 already attempted but failed. Do not try again.
          //
          continue;
        } else if (!mPrivate->Ipv6Flag &&
                   AttemptTmp->AutoConfigureMode == IP_MODE_AUTOCONFIG_IP4) {
          //
          // Autoconfigure for IP4  already attempted but failed. Do not try again.
          //
          continue;
        } else {
          //
          // Try another approach for this autoconfigure path.
          //
          AttemptTmp->AutoConfigureMode =
            (UINT8) (mPrivate->Ipv6Flag ? IP_MODE_AUTOCONFIG_IP6 : IP_MODE_AUTOCONFIG_IP4);
          AttemptTmp->SessionConfigData.InitiatorInfoFromDhcp = TRUE;
          AttemptTmp->SessionConfigData.TargetInfoFromDhcp    = TRUE;
          AttemptTmp->DhcpSuccess                             = FALSE;

          //
          // Get some information from the dhcp server.
          //
          if (!mPrivate->Ipv6Flag) {
            Status = IScsiDoDhcp (Private->Image, Private->Controller, AttemptTmp);
            if (!EFI_ERROR (Status)) {
              AttemptTmp->DhcpSuccess = TRUE;
            }
          } else {
            Status = IScsiDoDhcp6 (Private->Image, Private->Controller, AttemptTmp);
            if (!EFI_ERROR (Status)) {
              AttemptTmp->DhcpSuccess = TRUE;
            }
          }

          //
          // Refresh the state of this attempt to NVR.
          //
          AsciiStrToUnicodeStr (AttemptTmp->MacString, MacString);
          UnicodeSPrint (
            mPrivate->PortString,
            (UINTN) ISCSI_NAME_IFR_MAX_SIZE,
            L"%s%d",
            MacString,
            (UINTN) AttemptTmp->AttemptConfigIndex
            );

          gRT->SetVariable (
                 mPrivate->PortString,
                 &gEfiIScsiInitiatorNameProtocolGuid,
                 ISCSI_CONFIG_VAR_ATTR,
                 sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA),
                 AttemptTmp
                 );

          continue;
        }
      } else if (AttemptTmp->SessionConfigData.InitiatorInfoFromDhcp && !AttemptTmp->ValidPath) {
        //
        // Get DHCP information for already added, but failed, attempt.
        //
        AttemptTmp->DhcpSuccess = FALSE;
        if (!mPrivate->Ipv6Flag && (AttemptTmp->SessionConfigData.IpMode == IP_MODE_IP4)) {
          Status = IScsiDoDhcp (Private->Image, Private->Controller, AttemptTmp);
          if (!EFI_ERROR (Status)) {
            AttemptTmp->DhcpSuccess = TRUE;
          }
        } else if (mPrivate->Ipv6Flag && (AttemptTmp->SessionConfigData.IpMode == IP_MODE_IP6)) {
          Status = IScsiDoDhcp6 (Private->Image, Private->Controller, AttemptTmp);
          if (!EFI_ERROR (Status)) {
            AttemptTmp->DhcpSuccess = TRUE;
          }
        }

        //
        // Refresh the state of this attempt to NVR.
        //
        AsciiStrToUnicodeStr (AttemptTmp->MacString, MacString);
        UnicodeSPrint (
          mPrivate->PortString,
          (UINTN) ISCSI_NAME_IFR_MAX_SIZE,
          L"%s%d",
          MacString,
          (UINTN) AttemptTmp->AttemptConfigIndex
          );

        gRT->SetVariable (
               mPrivate->PortString,
               &gEfiIScsiInitiatorNameProtocolGuid,
               ISCSI_CONFIG_VAR_ATTR,
               sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA),
               AttemptTmp
               );

        continue;

      } else {
        continue;
      }
    }

    //
    // This attempt does not exist in AttemptConfig. Try to add a new one.
    //

    NicInfo = IScsiGetNicInfoByIndex (mPrivate->CurrentNic);
    ASSERT (NicInfo != NULL);
    IScsiMacAddrToStr (&NicInfo->PermanentAddress, NicInfo->HwAddressSize, NicInfo->VlanId, MacString);
    UnicodeSPrint (
      mPrivate->PortString,
      (UINTN) 128,
      L"%s%d",
      MacString,
      (UINTN) AttemptConfigOrder[Index]
      );

    GetVariable2 (
                 mPrivate->PortString,
                 &gEfiIScsiInitiatorNameProtocolGuid,
                 (VOID**)&AttemptConfigData,
                 NULL
                 );

    if (AttemptConfigData == NULL) {
      continue;
    }

    ASSERT (AttemptConfigOrder[Index] == AttemptConfigData->AttemptConfigIndex);

    AttemptConfigData->NicIndex      = NicInfo->NicIndex;
    AttemptConfigData->DhcpSuccess   = FALSE;
    AttemptConfigData->ValidiBFTPath = (BOOLEAN) (mPrivate->EnableMpio ? TRUE : FALSE);
    AttemptConfigData->ValidPath     = FALSE;

    if (AttemptConfigData->SessionConfigData.IpMode == IP_MODE_AUTOCONFIG) {
      AttemptConfigData->SessionConfigData.InitiatorInfoFromDhcp = TRUE;
      AttemptConfigData->SessionConfigData.TargetInfoFromDhcp    = TRUE;

      AttemptConfigData->AutoConfigureMode =
        (UINT8) (mPrivate->Ipv6Flag ? IP_MODE_AUTOCONFIG_IP6 : IP_MODE_AUTOCONFIG_IP4);
    }
    
    //
    // Get some information from dhcp server.
    //
    if (AttemptConfigData->SessionConfigData.Enabled != ISCSI_DISABLED &&
        AttemptConfigData->SessionConfigData.InitiatorInfoFromDhcp) {

      if (!mPrivate->Ipv6Flag &&
          (AttemptConfigData->SessionConfigData.IpMode == IP_MODE_IP4 ||
           AttemptConfigData->AutoConfigureMode == IP_MODE_AUTOCONFIG_IP4)) {
        Status = IScsiDoDhcp (Private->Image, Private->Controller, AttemptConfigData);
        if (!EFI_ERROR (Status)) {
          AttemptConfigData->DhcpSuccess = TRUE;
        }
      } else if (mPrivate->Ipv6Flag &&
                (AttemptConfigData->SessionConfigData.IpMode == IP_MODE_IP6 ||
                 AttemptConfigData->AutoConfigureMode == IP_MODE_AUTOCONFIG_IP6)) {
        Status = IScsiDoDhcp6 (Private->Image, Private->Controller, AttemptConfigData);
        if (!EFI_ERROR (Status)) {
          AttemptConfigData->DhcpSuccess = TRUE;
        }
      }

      //
      // Refresh the state of this attempt to NVR.
      //
      AsciiStrToUnicodeStr (AttemptConfigData->MacString, MacString);
      UnicodeSPrint (
        mPrivate->PortString,
        (UINTN) ISCSI_NAME_IFR_MAX_SIZE,
        L"%s%d",
        MacString,
        (UINTN) AttemptConfigData->AttemptConfigIndex
        );

      gRT->SetVariable (
             mPrivate->PortString,
             &gEfiIScsiInitiatorNameProtocolGuid,
             ISCSI_CONFIG_VAR_ATTR,
             sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA),
             AttemptConfigData
             );
    }

    //
    // Update Attempt Help Info.
    //

    if (AttemptConfigData->SessionConfigData.Enabled == ISCSI_DISABLED) {
      UnicodeSPrint (IScsiMode, 64, L"Disabled");
    } else if (AttemptConfigData->SessionConfigData.Enabled == ISCSI_ENABLED) {
      UnicodeSPrint (IScsiMode, 64, L"Enabled");
    } else if (AttemptConfigData->SessionConfigData.Enabled == ISCSI_ENABLED_FOR_MPIO) {
      UnicodeSPrint (IScsiMode, 64, L"Enabled for MPIO");
    }

    if (AttemptConfigData->SessionConfigData.IpMode == IP_MODE_IP4) {
      UnicodeSPrint (IpMode, 64, L"IP4");
    } else if (AttemptConfigData->SessionConfigData.IpMode == IP_MODE_IP6) {
      UnicodeSPrint (IpMode, 64, L"IP6");
    } else if (AttemptConfigData->SessionConfigData.IpMode == IP_MODE_AUTOCONFIG) {
      UnicodeSPrint (IpMode, 64, L"Autoconfigure");
    }

    UnicodeSPrint (
      mPrivate->PortString,
      (UINTN) ISCSI_NAME_IFR_MAX_SIZE,
      L"MAC: %s, PFA: Bus %d | Dev %d | Func %d, iSCSI mode: %s, IP version: %s",
      MacString,
      NicInfo->BusNumber,
      NicInfo->DeviceNumber,
      NicInfo->FunctionNumber,
      IScsiMode,
      IpMode
      );

    AttemptConfigData->AttemptTitleHelpToken = HiiSetString (
                                                 mCallbackInfo->RegisteredHandle,
                                                 0,
                                                 mPrivate->PortString,
                                                 NULL
                                                 );
    ASSERT (AttemptConfigData->AttemptTitleHelpToken != 0);

    //
    // Record the attempt in global link list.
    //
    InsertTailList (&mPrivate->AttemptConfigs, &AttemptConfigData->Link);
    mPrivate->AttemptCount++;

    if (AttemptConfigData->SessionConfigData.Enabled == ISCSI_ENABLED_FOR_MPIO) {
      mPrivate->MpioCount++;
      mPrivate->EnableMpio = TRUE;

      if (AttemptConfigData->AuthenticationType == ISCSI_AUTH_TYPE_KRB) {
        mPrivate->Krb5MpioCount++;
      }
    } else if (AttemptConfigData->SessionConfigData.Enabled == ISCSI_ENABLED) {
      mPrivate->SinglePathCount++;
    }
  }

  //
  // Reorder the AttemptConfig by the configured order.
  //
  for (Index = 0; Index < AttemptConfigOrderSize / sizeof (UINT8); Index++) {
    AttemptConfigData = IScsiConfigGetAttemptByConfigIndex (AttemptConfigOrder[Index]);
    if (AttemptConfigData == NULL) {
      continue;
    }

    RemoveEntryList (&AttemptConfigData->Link);
    InsertTailList (&mPrivate->AttemptConfigs, &AttemptConfigData->Link);
  }

  //
  // Update the Main Form.
  //
  IScsiConfigUpdateAttempt ();

  FreePool (AttemptConfigOrder);

  //
  //  There should be at least one attempt configuration.
  //
  if (!mPrivate->EnableMpio) {
    if (mPrivate->SinglePathCount == 0) {
      return EFI_NOT_FOUND;
    }
    mPrivate->ValidSinglePathCount = mPrivate->SinglePathCount;
  }

  return EFI_SUCCESS;
}


/**
  Get the device path of the iSCSI tcp connection and update it.

  @param  Session                The iSCSI session.

  @return The updated device path.
  @retval NULL Other errors as indicated.

**/
EFI_DEVICE_PATH_PROTOCOL *
IScsiGetTcpConnDevicePath (
  IN ISCSI_SESSION      *Session
  )
{
  ISCSI_CONNECTION          *Conn;
  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
  EFI_STATUS                Status;
  EFI_DEV_PATH              *DPathNode;

  if (Session->State != SESSION_STATE_LOGGED_IN) {
    return NULL;
  }

  Conn = NET_LIST_USER_STRUCT_S (
           Session->Conns.ForwardLink,
           ISCSI_CONNECTION,
           Link,
           ISCSI_CONNECTION_SIGNATURE
           );

  Status = gBS->HandleProtocol (
                  Conn->TcpIo.Handle,
                  &gEfiDevicePathProtocolGuid,
                  (VOID **) &DevicePath
                  );  
  if (EFI_ERROR (Status)) {
    return NULL;
  }
  //
  // Duplicate it.
  //
  DevicePath  = DuplicateDevicePath (DevicePath);
  if (DevicePath == NULL) {
    return NULL;
  }

  DPathNode   = (EFI_DEV_PATH *) DevicePath;

  while (!IsDevicePathEnd (&DPathNode->DevPath)) {
    if (DevicePathType (&DPathNode->DevPath) == MESSAGING_DEVICE_PATH) {
      if (!Conn->Ipv6Flag && DevicePathSubType (&DPathNode->DevPath) == MSG_IPv4_DP) {
        DPathNode->Ipv4.LocalPort       = 0;

        DPathNode->Ipv4.StaticIpAddress = 
          (BOOLEAN) (!Session->ConfigData->SessionConfigData.InitiatorInfoFromDhcp);

        IP4_COPY_ADDRESS (
          &DPathNode->Ipv4.GatewayIpAddress,
          &Session->ConfigData->SessionConfigData.Gateway
          );

        IP4_COPY_ADDRESS (
          &DPathNode->Ipv4.SubnetMask,
          &Session->ConfigData->SessionConfigData.SubnetMask
          );
        break;
      } else if (Conn->Ipv6Flag && DevicePathSubType (&DPathNode->DevPath) == MSG_IPv6_DP) {
        DPathNode->Ipv6.LocalPort       = 0;
        DPathNode->Ipv6.IpAddressOrigin = 0;
        DPathNode->Ipv6.PrefixLength    = IP6_PREFIX_LENGTH;
        ZeroMem (&DPathNode->Ipv6.GatewayIpAddress, sizeof (EFI_IPv6_ADDRESS));
        break;
      }
    }

    DPathNode = (EFI_DEV_PATH *) NextDevicePathNode (&DPathNode->DevPath);
  }

  return DevicePath;
}


/**
  Abort the session when the transition from BS to RT is initiated.

  @param[in]   Event  The event signaled.
  @param[in]  Context The iSCSI driver data.

**/
VOID
EFIAPI
IScsiOnExitBootService (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  )
{
  ISCSI_DRIVER_DATA *Private;

  Private = (ISCSI_DRIVER_DATA *) Context;
  gBS->CloseEvent (Private->ExitBootServiceEvent);

  if (Private->Session != NULL) {
    IScsiSessionAbort (Private->Session);
  }
}

/**
  Tests whether a controller handle is being managed by IScsi driver.

  This function tests whether the driver specified by DriverBindingHandle is
  currently managing the controller specified by ControllerHandle.  This test
  is performed by evaluating if the the protocol specified by ProtocolGuid is
  present on ControllerHandle and is was opened by DriverBindingHandle and Nic
  Device handle with an attribute of EFI_OPEN_PROTOCOL_BY_DRIVER. 
  If ProtocolGuid is NULL, then ASSERT().

  @param  ControllerHandle     A handle for a controller to test.
  @param  DriverBindingHandle  Specifies the driver binding handle for the
                               driver.
  @param  ProtocolGuid         Specifies the protocol that the driver specified
                               by DriverBindingHandle opens in its Start()
                               function.

  @retval EFI_SUCCESS          ControllerHandle is managed by the driver
                               specified by DriverBindingHandle.
  @retval EFI_UNSUPPORTED      ControllerHandle is not managed by the driver
                               specified by DriverBindingHandle.

**/
EFI_STATUS
EFIAPI
IScsiTestManagedDevice (
  IN  EFI_HANDLE       ControllerHandle,
  IN  EFI_HANDLE       DriverBindingHandle,
  IN  EFI_GUID         *ProtocolGuid
  )
{
  EFI_STATUS     Status;
  VOID           *ManagedInterface;
  EFI_HANDLE     NicControllerHandle;

  ASSERT (ProtocolGuid != NULL);

  NicControllerHandle = NetLibGetNicHandle (ControllerHandle, ProtocolGuid);
  if (NicControllerHandle == NULL) {
    return EFI_UNSUPPORTED;
  }

  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  (EFI_GUID *) ProtocolGuid,
                  &ManagedInterface,
                  DriverBindingHandle,
                  NicControllerHandle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (!EFI_ERROR (Status)) {
    gBS->CloseProtocol (
           ControllerHandle,
           (EFI_GUID *) ProtocolGuid,
           DriverBindingHandle,
           NicControllerHandle
           );
    return EFI_UNSUPPORTED;
  }

  if (Status != EFI_ALREADY_STARTED) {
    return EFI_UNSUPPORTED;
  }

  return EFI_SUCCESS;
}
