/** @file
  The entry point of IScsi driver.

Copyright (c) 2019, NVIDIA Corporation. All rights reserved.
Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
(C) Copyright 2017 Hewlett Packard Enterprise Development LP<BR>

SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "IScsiImpl.h"

EFI_DRIVER_BINDING_PROTOCOL  gIScsiIp4DriverBinding = {
  IScsiIp4DriverBindingSupported,
  IScsiIp4DriverBindingStart,
  IScsiIp4DriverBindingStop,
  0xa,
  NULL,
  NULL
};

EFI_DRIVER_BINDING_PROTOCOL  gIScsiIp6DriverBinding = {
  IScsiIp6DriverBindingSupported,
  IScsiIp6DriverBindingStart,
  IScsiIp6DriverBindingStop,
  0xa,
  NULL,
  NULL
};

EFI_GUID            gIScsiV4PrivateGuid = ISCSI_V4_PRIVATE_GUID;
EFI_GUID            gIScsiV6PrivateGuid = ISCSI_V6_PRIVATE_GUID;
ISCSI_PRIVATE_DATA  *mPrivate           = NULL;

/**
  Tests to see if this driver supports the RemainingDevicePath.

  @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 bus drivers, if this parameter is not NULL, then
                                   the bus driver must determine if the bus controller specified
                                   by ControllerHandle and the child controller specified
                                   by RemainingDevicePath are both supported by this
                                   bus driver.

  @retval EFI_SUCCESS              The RemainingDevicePath is supported or NULL.
  @retval EFI_UNSUPPORTED          The device specified by ControllerHandle and
                                   RemainingDevicePath is not supported by the driver specified by This.
**/
EFI_STATUS
IScsiIsDevicePathSupported (
  IN EFI_DEVICE_PATH_PROTOCOL  *RemainingDevicePath OPTIONAL
  )
{
  EFI_DEVICE_PATH_PROTOCOL  *CurrentDevicePath;

  CurrentDevicePath = RemainingDevicePath;
  if (CurrentDevicePath != NULL) {
    while (!IsDevicePathEnd (CurrentDevicePath)) {
      if ((CurrentDevicePath->Type == MESSAGING_DEVICE_PATH) && (CurrentDevicePath->SubType == MSG_ISCSI_DP)) {
        return EFI_SUCCESS;
      }

      CurrentDevicePath = NextDevicePathNode (CurrentDevicePath);
    }

    return EFI_UNSUPPORTED;
  }

  return EFI_SUCCESS;
}

/**
  Check whether an iSCSI HBA adapter already installs an AIP instance with
  network boot policy matching the value specified in PcdIScsiAIPNetworkBootPolicy.
  If yes, return EFI_SUCCESS.

  @retval EFI_SUCCESS              Found an AIP with matching network boot policy.
  @retval EFI_NOT_FOUND            AIP is unavailable or the network boot policy
                                   not matched.
**/
EFI_STATUS
IScsiCheckAip (
  VOID
  )
{
  UINTN                             AipHandleCount;
  EFI_HANDLE                        *AipHandleBuffer;
  UINTN                             AipIndex;
  EFI_ADAPTER_INFORMATION_PROTOCOL  *Aip;
  EFI_EXT_SCSI_PASS_THRU_PROTOCOL   *ExtScsiPassThru;
  EFI_GUID                          *InfoTypesBuffer;
  UINTN                             InfoTypeBufferCount;
  UINTN                             TypeIndex;
  VOID                              *InfoBlock;
  UINTN                             InfoBlockSize;
  BOOLEAN                           Supported;
  EFI_ADAPTER_INFO_NETWORK_BOOT     *NetworkBoot;
  EFI_STATUS                        Status;
  UINT8                             NetworkBootPolicy;

  //
  // Check any AIP instances exist in system.
  //
  AipHandleCount  = 0;
  AipHandleBuffer = NULL;
  Status          = gBS->LocateHandleBuffer (
                           ByProtocol,
                           &gEfiAdapterInformationProtocolGuid,
                           NULL,
                           &AipHandleCount,
                           &AipHandleBuffer
                           );
  if (EFI_ERROR (Status) || (AipHandleCount == 0)) {
    return EFI_NOT_FOUND;
  }

  ASSERT (AipHandleBuffer != NULL);

  InfoBlock = NULL;

  for (AipIndex = 0; AipIndex < AipHandleCount; AipIndex++) {
    Status = gBS->HandleProtocol (
                    AipHandleBuffer[AipIndex],
                    &gEfiAdapterInformationProtocolGuid,
                    (VOID *)&Aip
                    );
    ASSERT_EFI_ERROR (Status);
    ASSERT (Aip != NULL);

    Status = gBS->HandleProtocol (
                    AipHandleBuffer[AipIndex],
                    &gEfiExtScsiPassThruProtocolGuid,
                    (VOID *)&ExtScsiPassThru
                    );
    if (EFI_ERROR (Status) || (ExtScsiPassThru == NULL)) {
      continue;
    }

    InfoTypesBuffer     = NULL;
    InfoTypeBufferCount = 0;
    Status              = Aip->GetSupportedTypes (Aip, &InfoTypesBuffer, &InfoTypeBufferCount);
    if (EFI_ERROR (Status) || (InfoTypesBuffer == NULL)) {
      continue;
    }

    //
    // Check whether the AIP instance has Network boot information block.
    //
    Supported = FALSE;
    for (TypeIndex = 0; TypeIndex < InfoTypeBufferCount; TypeIndex++) {
      if (CompareGuid (&InfoTypesBuffer[TypeIndex], &gEfiAdapterInfoNetworkBootGuid)) {
        Supported = TRUE;
        break;
      }
    }

    FreePool (InfoTypesBuffer);
    if (!Supported) {
      continue;
    }

    //
    // We now have network boot information block.
    //
    InfoBlock     = NULL;
    InfoBlockSize = 0;
    Status        = Aip->GetInformation (Aip, &gEfiAdapterInfoNetworkBootGuid, &InfoBlock, &InfoBlockSize);
    if (EFI_ERROR (Status) || (InfoBlock == NULL)) {
      continue;
    }

    //
    // Check whether the network boot policy matches.
    //
    NetworkBoot       = (EFI_ADAPTER_INFO_NETWORK_BOOT *)InfoBlock;
    NetworkBootPolicy = PcdGet8 (PcdIScsiAIPNetworkBootPolicy);

    if (NetworkBootPolicy == STOP_UEFI_ISCSI_IF_HBA_INSTALL_AIP) {
      Status = EFI_SUCCESS;
      goto Exit;
    }

    if ((((NetworkBootPolicy & STOP_UEFI_ISCSI_IF_AIP_SUPPORT_IP4) != 0) &&
         !NetworkBoot->iScsiIpv4BootCapablity) ||
        (((NetworkBootPolicy & STOP_UEFI_ISCSI_IF_AIP_SUPPORT_IP6) != 0) &&
         !NetworkBoot->iScsiIpv6BootCapablity) ||
        (((NetworkBootPolicy & STOP_UEFI_ISCSI_IF_AIP_SUPPORT_OFFLOAD) != 0) &&
         !NetworkBoot->OffloadCapability) ||
        (((NetworkBootPolicy & STOP_UEFI_ISCSI_IF_AIP_SUPPORT_MPIO) != 0) &&
         !NetworkBoot->iScsiMpioCapability) ||
        (((NetworkBootPolicy & STOP_UEFI_ISCSI_IF_AIP_CONFIGURED_IP4) != 0) &&
         !NetworkBoot->iScsiIpv4Boot) ||
        (((NetworkBootPolicy & STOP_UEFI_ISCSI_IF_AIP_CONFIGURED_IP6) != 0) &&
         !NetworkBoot->iScsiIpv6Boot))
    {
      FreePool (InfoBlock);
      continue;
    }

    Status = EFI_SUCCESS;
    goto Exit;
  }

  Status = EFI_NOT_FOUND;

Exit:
  if (InfoBlock != NULL) {
    FreePool (InfoBlock);
  }

  if (AipHandleBuffer != NULL) {
    FreePool (AipHandleBuffer);
  }

  return Status;
}

/**
  Tests to see if this driver supports a given controller. This is the worker function for
  IScsiIp4(6)DriverBindingSupported.

  @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  A pointer to the remaining portion of a device path.  This
                                   parameter is ignored by device drivers, and is optional for bus
                                   drivers. For bus drivers, if this parameter is not NULL, then
                                   the bus driver must determine if the bus controller specified
                                   by ControllerHandle and the child controller specified
                                   by RemainingDevicePath are both supported by this
                                   bus driver.
  @param[in]  IpVersion            IP_VERSION_4 or IP_VERSION_6.

  @retval EFI_SUCCESS              The device specified by ControllerHandle and
                                   RemainingDevicePath is supported by the driver specified by This.
  @retval EFI_ALREADY_STARTED      The device specified by ControllerHandle and
                                   RemainingDevicePath is already being managed by the driver
                                   specified by This.
  @retval EFI_UNSUPPORTED          The device specified by ControllerHandle and
                                   RemainingDevicePath is not supported by the driver specified by This.
**/
EFI_STATUS
EFIAPI
IScsiSupported (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   ControllerHandle,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL,
  IN UINT8                        IpVersion
  )
{
  EFI_STATUS  Status;
  EFI_GUID    *IScsiServiceBindingGuid;
  EFI_GUID    *TcpServiceBindingGuid;
  EFI_GUID    *DhcpServiceBindingGuid;
  EFI_GUID    *DnsServiceBindingGuid;

  if (IpVersion == IP_VERSION_4) {
    IScsiServiceBindingGuid = &gIScsiV4PrivateGuid;
    TcpServiceBindingGuid   = &gEfiTcp4ServiceBindingProtocolGuid;
    DhcpServiceBindingGuid  = &gEfiDhcp4ServiceBindingProtocolGuid;
    DnsServiceBindingGuid   = &gEfiDns4ServiceBindingProtocolGuid;
  } else {
    IScsiServiceBindingGuid = &gIScsiV6PrivateGuid;
    TcpServiceBindingGuid   = &gEfiTcp6ServiceBindingProtocolGuid;
    DhcpServiceBindingGuid  = &gEfiDhcp6ServiceBindingProtocolGuid;
    DnsServiceBindingGuid   = &gEfiDns6ServiceBindingProtocolGuid;
  }

  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  IScsiServiceBindingGuid,
                  NULL,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL
                  );
  if (!EFI_ERROR (Status)) {
    return EFI_ALREADY_STARTED;
  }

  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  TcpServiceBindingGuid,
                  NULL,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    return EFI_UNSUPPORTED;
  }

  Status = IScsiIsDevicePathSupported (RemainingDevicePath);
  if (EFI_ERROR (Status)) {
    return EFI_UNSUPPORTED;
  }

  if (IScsiDhcpIsConfigured (ControllerHandle, IpVersion)) {
    Status = gBS->OpenProtocol (
                    ControllerHandle,
                    DhcpServiceBindingGuid,
                    NULL,
                    This->DriverBindingHandle,
                    ControllerHandle,
                    EFI_OPEN_PROTOCOL_TEST_PROTOCOL
                    );
    if (EFI_ERROR (Status)) {
      return EFI_UNSUPPORTED;
    }
  }

  if (IScsiDnsIsConfigured (ControllerHandle)) {
    Status = gBS->OpenProtocol (
                    ControllerHandle,
                    DnsServiceBindingGuid,
                    NULL,
                    This->DriverBindingHandle,
                    ControllerHandle,
                    EFI_OPEN_PROTOCOL_TEST_PROTOCOL
                    );
    if (EFI_ERROR (Status)) {
      return EFI_UNSUPPORTED;
    }
  }

  return EFI_SUCCESS;
}

/**
  Start to manage the controller. This is the worker function for
  IScsiIp4(6)DriverBindingStart.

  @param[in]  Image                Handle of the image.
  @param[in]  ControllerHandle     Handle of the controller.
  @param[in]  IpVersion            IP_VERSION_4 or IP_VERSION_6.

  @retval EFI_SUCCESS           This driver was started.
  @retval EFI_ALREADY_STARTED   This driver is already running on this device.
  @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
  @retval EFI_NOT_FOUND         There is no sufficient information to establish
                                the iScsi session.
  @retval EFI_OUT_OF_RESOURCES  Failed to allocate memory.
  @retval EFI_DEVICE_ERROR      Failed to get TCP connection device path.
  @retval EFI_ACCESS_DENIED     The protocol could not be removed from the Handle
                                because its interfaces are being used.

**/
EFI_STATUS
IScsiStart (
  IN EFI_HANDLE  Image,
  IN EFI_HANDLE  ControllerHandle,
  IN UINT8       IpVersion
  )
{
  EFI_STATUS                       Status;
  ISCSI_DRIVER_DATA                *Private;
  LIST_ENTRY                       *Entry;
  LIST_ENTRY                       *NextEntry;
  ISCSI_ATTEMPT_CONFIG_NVDATA      *AttemptConfigData;
  ISCSI_SESSION                    *Session;
  UINT8                            Index;
  EFI_EXT_SCSI_PASS_THRU_PROTOCOL  *ExistIScsiExtScsiPassThru;
  ISCSI_DRIVER_DATA                *ExistPrivate;
  UINT8                            *AttemptConfigOrder;
  UINTN                            AttemptConfigOrderSize;
  UINT8                            BootSelected;
  EFI_HANDLE                       *HandleBuffer;
  UINTN                            NumberOfHandles;
  EFI_DEVICE_PATH_PROTOCOL         *DevicePath;
  EFI_GUID                         *IScsiPrivateGuid;
  EFI_GUID                         *TcpServiceBindingGuid;
  BOOLEAN                          NeedUpdate;
  VOID                             *Interface;
  EFI_GUID                         *ProtocolGuid;
  UINT8                            NetworkBootPolicy;
  ISCSI_SESSION_CONFIG_NVDATA      *NvData;

  //
  // Test to see if iSCSI driver supports the given controller.
  //

  if (IpVersion == IP_VERSION_4) {
    IScsiPrivateGuid      = &gIScsiV4PrivateGuid;
    TcpServiceBindingGuid = &gEfiTcp4ServiceBindingProtocolGuid;
    ProtocolGuid          = &gEfiTcp4ProtocolGuid;
  } else if (IpVersion == IP_VERSION_6) {
    IScsiPrivateGuid      = &gIScsiV6PrivateGuid;
    TcpServiceBindingGuid = &gEfiTcp6ServiceBindingProtocolGuid;
    ProtocolGuid          = &gEfiTcp6ProtocolGuid;
  } else {
    return EFI_INVALID_PARAMETER;
  }

  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  IScsiPrivateGuid,
                  NULL,
                  Image,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL
                  );
  if (!EFI_ERROR (Status)) {
    return EFI_ALREADY_STARTED;
  }

  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  TcpServiceBindingGuid,
                  NULL,
                  Image,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    return EFI_UNSUPPORTED;
  }

  NetworkBootPolicy = PcdGet8 (PcdIScsiAIPNetworkBootPolicy);
  if (NetworkBootPolicy == ALWAYS_USE_ISCSI_HBA_AND_IGNORE_UEFI_ISCSI) {
    return EFI_ABORTED;
  }

  if (NetworkBootPolicy != ALWAYS_USE_UEFI_ISCSI_AND_IGNORE_ISCSI_HBA) {
    //
    // Check existing iSCSI AIP.
    //
    Status = IScsiCheckAip ();
    if (!EFI_ERROR (Status)) {
      //
      // Find iSCSI AIP with specified network boot policy. return EFI_ABORTED.
      //
      return EFI_ABORTED;
    }
  }

  //
  // Record the incoming NIC info.
  //
  Status = IScsiAddNic (ControllerHandle, Image);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Create the instance private data.
  //
  Private = IScsiCreateDriverData (Image, ControllerHandle);
  if (Private == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Create a underlayer child instance, but not need to configure it. Just open ChildHandle
  // via BY_DRIVER. That is, establishing the relationship between ControllerHandle and ChildHandle.
  // Therefore, when DisconnectController(), especially VLAN virtual controller handle,
  // IScsiDriverBindingStop() will be called.
  //
  Status = NetLibCreateServiceChild (
             ControllerHandle,
             Image,
             TcpServiceBindingGuid,
             &Private->ChildHandle
             );

  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  Status = gBS->OpenProtocol (
                  Private->ChildHandle, /// Default Tcp child
                  ProtocolGuid,
                  &Interface,
                  Image,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );

  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  //
  // Always install private protocol no matter what happens later. We need to
  // keep the relationship between ControllerHandle and ChildHandle.
  //
  Status = gBS->InstallProtocolInterface (
                  &ControllerHandle,
                  IScsiPrivateGuid,
                  EFI_NATIVE_INTERFACE,
                  &Private->IScsiIdentifier
                  );
  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  if (IpVersion == IP_VERSION_4) {
    mPrivate->Ipv6Flag = FALSE;
  } else {
    mPrivate->Ipv6Flag = TRUE;
  }

  //
  // Get the current iSCSI configuration data.
  //
  Status = IScsiGetConfigData (Private);
  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  //
  // If there is already a successul attempt, check whether this attempt is the
  // first "enabled for MPIO" attempt. If not, still try the first attempt.
  // In single path mode, try all attempts.
  //
  ExistPrivate = NULL;
  Status       = EFI_NOT_FOUND;

  if (mPrivate->OneSessionEstablished && mPrivate->EnableMpio) {
    AttemptConfigData = NULL;
    NET_LIST_FOR_EACH (Entry, &mPrivate->AttemptConfigs) {
      AttemptConfigData = NET_LIST_USER_STRUCT (Entry, ISCSI_ATTEMPT_CONFIG_NVDATA, Link);
      if (AttemptConfigData->SessionConfigData.Enabled == ISCSI_ENABLED_FOR_MPIO) {
        break;
      }
    }

    if (AttemptConfigData == NULL) {
      goto ON_ERROR;
    }

    if (AttemptConfigData->AttemptConfigIndex == mPrivate->BootSelectedIndex) {
      goto ON_EXIT;
    }

    //
    // Uninstall the original ExtScsiPassThru first.
    //

    //
    // Locate all ExtScsiPassThru protocol instances.
    //
    Status = gBS->LocateHandleBuffer (
                    ByProtocol,
                    &gEfiExtScsiPassThruProtocolGuid,
                    NULL,
                    &NumberOfHandles,
                    &HandleBuffer
                    );
    if (EFI_ERROR (Status)) {
      goto ON_ERROR;
    }

    //
    // Find ExtScsiPassThru protocol instance produced by this driver.
    //
    ExistIScsiExtScsiPassThru = NULL;
    for (Index = 0; Index < NumberOfHandles && ExistIScsiExtScsiPassThru == NULL; Index++) {
      Status = gBS->HandleProtocol (
                      HandleBuffer[Index],
                      &gEfiDevicePathProtocolGuid,
                      (VOID **)&DevicePath
                      );
      if (EFI_ERROR (Status)) {
        continue;
      }

      while (!IsDevicePathEnd (DevicePath)) {
        if ((DevicePath->Type == MESSAGING_DEVICE_PATH) && (DevicePath->SubType == MSG_MAC_ADDR_DP)) {
          //
          // Get the ExtScsiPassThru protocol instance.
          //
          Status = gBS->HandleProtocol (
                          HandleBuffer[Index],
                          &gEfiExtScsiPassThruProtocolGuid,
                          (VOID **)&ExistIScsiExtScsiPassThru
                          );
          ASSERT_EFI_ERROR (Status);
          break;
        }

        DevicePath = NextDevicePathNode (DevicePath);
      }
    }

    FreePool (HandleBuffer);

    if (ExistIScsiExtScsiPassThru == NULL) {
      Status = EFI_NOT_FOUND;
      goto ON_ERROR;
    }

    ExistPrivate = ISCSI_DRIVER_DATA_FROM_EXT_SCSI_PASS_THRU (ExistIScsiExtScsiPassThru);

    Status = gBS->UninstallProtocolInterface (
                    ExistPrivate->ExtScsiPassThruHandle,
                    &gEfiExtScsiPassThruProtocolGuid,
                    &ExistPrivate->IScsiExtScsiPassThru
                    );
    if (EFI_ERROR (Status)) {
      goto ON_ERROR;
    }
  }

  //
  // Install the Ext SCSI PASS THRU protocol.
  //
  Status = gBS->InstallProtocolInterface (
                  &Private->ExtScsiPassThruHandle,
                  &gEfiExtScsiPassThruProtocolGuid,
                  EFI_NATIVE_INTERFACE,
                  &Private->IScsiExtScsiPassThru
                  );
  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  BootSelected = 0;

  NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &mPrivate->AttemptConfigs) {
    AttemptConfigData = NET_LIST_USER_STRUCT (Entry, ISCSI_ATTEMPT_CONFIG_NVDATA, Link);
    //
    // Don't process the attempt that does not associate with the current NIC or
    // this attempt is disabled or established.
    //
    if ((AttemptConfigData->NicIndex != mPrivate->CurrentNic) ||
        (AttemptConfigData->SessionConfigData.Enabled == ISCSI_DISABLED) ||
        AttemptConfigData->ValidPath)
    {
      continue;
    }

    //
    // In multipath mode, don't process attempts configured for single path.
    // In default single path mode, don't process attempts configured for multipath.
    //
    if ((mPrivate->EnableMpio &&
         (AttemptConfigData->SessionConfigData.Enabled != ISCSI_ENABLED_FOR_MPIO)) ||
        (!mPrivate->EnableMpio &&
         (AttemptConfigData->SessionConfigData.Enabled != ISCSI_ENABLED)))
    {
      continue;
    }

    //
    // Don't process the attempt that fails to get the init/target information from DHCP.
    //
    if (AttemptConfigData->SessionConfigData.InitiatorInfoFromDhcp &&
        !AttemptConfigData->DhcpSuccess)
    {
      if (!mPrivate->EnableMpio && (mPrivate->ValidSinglePathCount > 0)) {
        mPrivate->ValidSinglePathCount--;
      }

      continue;
    }

    //
    // Don't process the autoconfigure path if it is already established.
    //
    if ((AttemptConfigData->SessionConfigData.IpMode == IP_MODE_AUTOCONFIG) &&
        AttemptConfigData->AutoConfigureSuccess)
    {
      continue;
    }

    //
    // Don't process the attempt if its IP mode is not in the current IP version.
    //
    if (!mPrivate->Ipv6Flag) {
      if (AttemptConfigData->SessionConfigData.IpMode == IP_MODE_IP6) {
        continue;
      }

      if ((AttemptConfigData->SessionConfigData.IpMode == IP_MODE_AUTOCONFIG) &&
          (AttemptConfigData->AutoConfigureMode == IP_MODE_AUTOCONFIG_IP6))
      {
        continue;
      }
    } else {
      if (AttemptConfigData->SessionConfigData.IpMode == IP_MODE_IP4) {
        continue;
      }

      if ((AttemptConfigData->SessionConfigData.IpMode == IP_MODE_AUTOCONFIG) &&
          (AttemptConfigData->AutoConfigureMode == IP_MODE_AUTOCONFIG_IP4))
      {
        continue;
      }
    }

    //
    // Fill in the Session and init it.
    //
    Session = (ISCSI_SESSION *)AllocateZeroPool (sizeof (ISCSI_SESSION));
    if (Session == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto ON_ERROR;
    }

    Session->Private    = Private;
    Session->ConfigData = AttemptConfigData;
    Session->AuthType   = AttemptConfigData->AuthenticationType;

    UnicodeSPrint (
      mPrivate->PortString,
      (UINTN)ISCSI_NAME_IFR_MAX_SIZE,
      L"Attempt %d",
      (UINTN)AttemptConfigData->AttemptConfigIndex
      );

    if (Session->AuthType == ISCSI_AUTH_TYPE_CHAP) {
      Session->AuthData.CHAP.AuthConfig = &AttemptConfigData->AuthConfigData.CHAP;
    }

    IScsiSessionInit (Session, FALSE);

    //
    // Try to login and create an iSCSI session according to the configuration.
    //
    Status = IScsiSessionLogin (Session);
    if (Status == EFI_MEDIA_CHANGED) {
      //
      // The specified target is not available, and the redirection information is
      // received. Login the session again with the updated target address.
      //
      Status = IScsiSessionLogin (Session);
    } else if (Status == EFI_NOT_READY) {
      Status = IScsiSessionReLogin (Session);
    }

    //
    // Restore the original user setting which specifies the proxy/virtual iSCSI target to NV region.
    //
    NvData = &AttemptConfigData->SessionConfigData;
    if (NvData->RedirectFlag) {
      NvData->TargetPort = NvData->OriginalTargetPort;
      CopyMem (&NvData->TargetIp, &NvData->OriginalTargetIp, sizeof (EFI_IP_ADDRESS));
      NvData->RedirectFlag = FALSE;

      gRT->SetVariable (
             mPrivate->PortString,
             &gEfiIScsiInitiatorNameProtocolGuid,
             ISCSI_CONFIG_VAR_ATTR,
             sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA),
             AttemptConfigData
             );
    }

    if (EFI_ERROR (Status)) {
      //
      // In Single path mode, only the successful attempt will be recorded in iBFT;
      // in multi-path mode, all the attempt entries in MPIO will be recorded in iBFT.
      //
      if (!mPrivate->EnableMpio && (mPrivate->ValidSinglePathCount > 0)) {
        mPrivate->ValidSinglePathCount--;
      }

      FreePool (Session);
    } else {
      AttemptConfigData->ValidPath = TRUE;

      //
      // Do not record the attempt in iBFT if it login with KRB5.
      // TODO: record KRB5 attempt information in the iSCSI device path.
      //
      if (Session->AuthType == ISCSI_AUTH_TYPE_KRB) {
        if (!mPrivate->EnableMpio && (mPrivate->ValidSinglePathCount > 0)) {
          mPrivate->ValidSinglePathCount--;
        }

        AttemptConfigData->ValidiBFTPath = FALSE;
      } else {
        AttemptConfigData->ValidiBFTPath = TRUE;
      }

      //
      // IScsi session success. Update the attempt state to NVR.
      //
      if (AttemptConfigData->SessionConfigData.IpMode == IP_MODE_AUTOCONFIG) {
        AttemptConfigData->AutoConfigureSuccess = TRUE;
      }

      gRT->SetVariable (
             mPrivate->PortString,
             &gEfiIScsiInitiatorNameProtocolGuid,
             ISCSI_CONFIG_VAR_ATTR,
             sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA),
             AttemptConfigData
             );

      //
      // Select the first login session. Abort others.
      //
      if (Private->Session == NULL) {
        Private->Session = Session;
        BootSelected     = AttemptConfigData->AttemptConfigIndex;
        //
        // Don't validate other attempt in multipath mode if one is success.
        //
        if (mPrivate->EnableMpio) {
          break;
        }
      } else {
        IScsiSessionAbort (Session);
        FreePool (Session);
      }
    }
  }

  //
  // All attempts configured for this driver instance are not valid.
  //
  if (Private->Session == NULL) {
    Status = gBS->UninstallProtocolInterface (
                    Private->ExtScsiPassThruHandle,
                    &gEfiExtScsiPassThruProtocolGuid,
                    &Private->IScsiExtScsiPassThru
                    );
    ASSERT_EFI_ERROR (Status);
    Private->ExtScsiPassThruHandle = NULL;

    //
    // Reinstall the original ExtScsiPassThru back.
    //
    if (mPrivate->OneSessionEstablished && (ExistPrivate != NULL)) {
      Status = gBS->InstallProtocolInterface (
                      &ExistPrivate->ExtScsiPassThruHandle,
                      &gEfiExtScsiPassThruProtocolGuid,
                      EFI_NATIVE_INTERFACE,
                      &ExistPrivate->IScsiExtScsiPassThru
                      );
      if (EFI_ERROR (Status)) {
        goto ON_ERROR;
      }

      goto ON_EXIT;
    }

    Status = EFI_NOT_FOUND;

    goto ON_ERROR;
  }

  NeedUpdate = TRUE;
  //
  // More than one attempt successes.
  //
  if ((Private->Session != NULL) && mPrivate->OneSessionEstablished) {
    AttemptConfigOrder = IScsiGetVariableAndSize (
                           L"AttemptOrder",
                           &gIScsiConfigGuid,
                           &AttemptConfigOrderSize
                           );
    if (AttemptConfigOrder == NULL) {
      goto ON_ERROR;
    }

    for (Index = 0; Index < AttemptConfigOrderSize / sizeof (UINT8); Index++) {
      if ((AttemptConfigOrder[Index] == mPrivate->BootSelectedIndex) ||
          (AttemptConfigOrder[Index] == BootSelected))
      {
        break;
      }
    }

    if (mPrivate->EnableMpio) {
      //
      // Use the attempt in earlier order. Abort the later one in MPIO.
      //
      if (AttemptConfigOrder[Index] == mPrivate->BootSelectedIndex) {
        IScsiSessionAbort (Private->Session);
        FreePool (Private->Session);
        Private->Session = NULL;
        gBS->UninstallProtocolInterface (
               Private->ExtScsiPassThruHandle,
               &gEfiExtScsiPassThruProtocolGuid,
               &Private->IScsiExtScsiPassThru
               );
        Private->ExtScsiPassThruHandle = NULL;

        //
        // Reinstall the original ExtScsiPassThru back.
        //
        Status = gBS->InstallProtocolInterface (
                        &ExistPrivate->ExtScsiPassThruHandle,
                        &gEfiExtScsiPassThruProtocolGuid,
                        EFI_NATIVE_INTERFACE,
                        &ExistPrivate->IScsiExtScsiPassThru
                        );
        if (EFI_ERROR (Status)) {
          goto ON_ERROR;
        }

        goto ON_EXIT;
      } else {
        if (AttemptConfigOrder[Index] != BootSelected) {
          goto ON_ERROR;
        }

        mPrivate->BootSelectedIndex = BootSelected;
        //
        // Clear the resource in ExistPrivate.
        //
        gBS->UninstallProtocolInterface (
               ExistPrivate->Controller,
               IScsiPrivateGuid,
               &ExistPrivate->IScsiIdentifier
               );

        IScsiRemoveNic (ExistPrivate->Controller);
        if (ExistPrivate->Session != NULL) {
          IScsiSessionAbort (ExistPrivate->Session);
        }

        if (ExistPrivate->DevicePath != NULL) {
          Status = gBS->UninstallProtocolInterface (
                          ExistPrivate->ExtScsiPassThruHandle,
                          &gEfiDevicePathProtocolGuid,
                          ExistPrivate->DevicePath
                          );
          if (EFI_ERROR (Status)) {
            goto ON_ERROR;
          }

          FreePool (ExistPrivate->DevicePath);
        }

        gBS->CloseEvent (ExistPrivate->ExitBootServiceEvent);
        FreePool (ExistPrivate);
      }
    } else {
      //
      // Use the attempt in earlier order as boot selected in single path mode.
      //
      if (AttemptConfigOrder[Index] == mPrivate->BootSelectedIndex) {
        NeedUpdate = FALSE;
      }
    }
  }

  if (NeedUpdate) {
    mPrivate->OneSessionEstablished = TRUE;
    mPrivate->BootSelectedIndex     = BootSelected;
  }

  //
  // Duplicate the Session's tcp connection device path. The source port field
  // will be set to zero as one iSCSI session is comprised of several iSCSI
  // connections.
  //
  Private->DevicePath = IScsiGetTcpConnDevicePath (Private->Session);
  if (Private->DevicePath == NULL) {
    Status = EFI_DEVICE_ERROR;
    goto ON_ERROR;
  }

  //
  // Install the updated device path onto the ExtScsiPassThruHandle.
  //
  Status = gBS->InstallProtocolInterface (
                  &Private->ExtScsiPassThruHandle,
                  &gEfiDevicePathProtocolGuid,
                  EFI_NATIVE_INTERFACE,
                  Private->DevicePath
                  );
  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  //
  // ISCSI children should share the default Tcp child, just open the default Tcp child via BY_CHILD_CONTROLLER.
  //
  Status = gBS->OpenProtocol (
                  Private->ChildHandle, /// Default Tcp child
                  ProtocolGuid,
                  &Interface,
                  Image,
                  Private->ExtScsiPassThruHandle,
                  EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
                  );
  if (EFI_ERROR (Status)) {
    gBS->UninstallMultipleProtocolInterfaces (
           Private->ExtScsiPassThruHandle,
           &gEfiExtScsiPassThruProtocolGuid,
           &Private->IScsiExtScsiPassThru,
           &gEfiDevicePathProtocolGuid,
           Private->DevicePath,
           NULL
           );

    goto ON_ERROR;
  }

ON_EXIT:

  //
  // Update/Publish the iSCSI Boot Firmware Table.
  //
  if (mPrivate->BootSelectedIndex != 0) {
    IScsiPublishIbft ();
  }

  return EFI_SUCCESS;

ON_ERROR:

  if (Private->Session != NULL) {
    IScsiSessionAbort (Private->Session);
  }

  return Status;
}

/**
  Stops a device controller or a bus controller. This is the worker function for
  IScsiIp4(6)DriverBindingStop.

  @param[in]  This              A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
  @param[in]  ControllerHandle  A handle to the device being stopped. The handle must
                                support a bus specific I/O protocol for the driver
                                to use to stop the device.
  @param[in]  NumberOfChildren  The number of child device handles in ChildHandleBuffer.
  @param[in]  ChildHandleBuffer An array of child handles to be freed. May be NULL
                                if NumberOfChildren is 0.
  @param[in]  IpVersion         IP_VERSION_4 or IP_VERSION_6.

  @retval EFI_SUCCESS           The device was stopped.
  @retval EFI_DEVICE_ERROR      The device could not be stopped due to a device error.
  @retval EFI_INVALID_PARAMETER Child handle is NULL.
  @retval EFI_ACCESS_DENIED     The protocol could not be removed from the Handle
                                because its interfaces are being used.

**/
EFI_STATUS
EFIAPI
IScsiStop (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   ControllerHandle,
  IN UINTN                        NumberOfChildren,
  IN EFI_HANDLE                   *ChildHandleBuffer OPTIONAL,
  IN UINT8                        IpVersion
  )
{
  EFI_HANDLE                       IScsiController;
  EFI_STATUS                       Status;
  ISCSI_PRIVATE_PROTOCOL           *IScsiIdentifier;
  ISCSI_DRIVER_DATA                *Private;
  EFI_EXT_SCSI_PASS_THRU_PROTOCOL  *PassThru;
  ISCSI_CONNECTION                 *Conn;
  EFI_GUID                         *ProtocolGuid;
  EFI_GUID                         *TcpServiceBindingGuid;
  EFI_GUID                         *TcpProtocolGuid;

  if (NumberOfChildren != 0) {
    //
    // We should have only one child.
    //
    Status = gBS->OpenProtocol (
                    ChildHandleBuffer[0],
                    &gEfiExtScsiPassThruProtocolGuid,
                    (VOID **)&PassThru,
                    This->DriverBindingHandle,
                    ControllerHandle,
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );
    if (EFI_ERROR (Status)) {
      return EFI_DEVICE_ERROR;
    }

    Private = ISCSI_DRIVER_DATA_FROM_EXT_SCSI_PASS_THRU (PassThru);
    Conn    = NET_LIST_HEAD (&Private->Session->Conns, ISCSI_CONNECTION, Link);

    //
    // Previously the TCP protocol is opened BY_CHILD_CONTROLLER. Just close
    // the protocol here, but do not uninstall the device path protocol and
    // EXT SCSI PASS THRU protocol installed on ExtScsiPassThruHandle.
    //
    if (IpVersion == IP_VERSION_4) {
      ProtocolGuid = &gEfiTcp4ProtocolGuid;
    } else {
      ProtocolGuid = &gEfiTcp6ProtocolGuid;
    }

    gBS->CloseProtocol (
           Private->ChildHandle,
           ProtocolGuid,
           Private->Image,
           Private->ExtScsiPassThruHandle
           );

    gBS->CloseProtocol (
           Conn->TcpIo.Handle,
           ProtocolGuid,
           Private->Image,
           Private->ExtScsiPassThruHandle
           );

    return EFI_SUCCESS;
  }

  //
  // Get the handle of the controller we are controlling.
  //
  if (IpVersion == IP_VERSION_4) {
    ProtocolGuid          = &gIScsiV4PrivateGuid;
    TcpProtocolGuid       = &gEfiTcp4ProtocolGuid;
    TcpServiceBindingGuid = &gEfiTcp4ServiceBindingProtocolGuid;
  } else {
    ProtocolGuid          = &gIScsiV6PrivateGuid;
    TcpProtocolGuid       = &gEfiTcp6ProtocolGuid;
    TcpServiceBindingGuid = &gEfiTcp6ServiceBindingProtocolGuid;
  }

  IScsiController = NetLibGetNicHandle (ControllerHandle, TcpProtocolGuid);
  if (IScsiController == NULL) {
    return EFI_SUCCESS;
  }

  Status = gBS->OpenProtocol (
                  IScsiController,
                  ProtocolGuid,
                  (VOID **)&IScsiIdentifier,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    return EFI_DEVICE_ERROR;
  }

  Private = ISCSI_DRIVER_DATA_FROM_IDENTIFIER (IScsiIdentifier);
  ASSERT (Private != NULL);

  if (Private->ChildHandle != NULL) {
    Status = gBS->CloseProtocol (
                    Private->ChildHandle,
                    TcpProtocolGuid,
                    This->DriverBindingHandle,
                    IScsiController
                    );

    ASSERT (!EFI_ERROR (Status));

    Status = NetLibDestroyServiceChild (
               IScsiController,
               This->DriverBindingHandle,
               TcpServiceBindingGuid,
               Private->ChildHandle
               );

    ASSERT (!EFI_ERROR (Status));
  }

  gBS->UninstallProtocolInterface (
         IScsiController,
         ProtocolGuid,
         &Private->IScsiIdentifier
         );

  //
  // Remove this NIC.
  //
  IScsiRemoveNic (IScsiController);

  //
  // Update the iSCSI Boot Firmware Table.
  //
  IScsiPublishIbft ();

  if (Private->Session != NULL) {
    IScsiSessionAbort (Private->Session);
  }

  Status = IScsiCleanDriverData (Private);

  if (EFI_ERROR (Status)) {
    return Status;
  }

  return EFI_SUCCESS;
}

/**
  Tests to see if this driver supports a given controller. If a child device is provided,
  it tests to see if this driver supports creating a handle for the specified child device.

  This function checks to see if the driver specified by This supports the device specified by
  ControllerHandle. Drivers typically use the device path attached to
  ControllerHandle and/or the services from the bus I/O abstraction attached to
  ControllerHandle to determine if the driver supports ControllerHandle. This function
  may be called many times during platform initialization. In order to reduce boot times, the tests
  performed by this function must be very small and take as little time as possible to execute. This
  function must not change the state of any hardware devices, and this function must be aware that the
  device specified by ControllerHandle may already be managed by the same driver or a
  different driver. This function must match its calls to AllocatePages() with FreePages(),
  AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
  Since ControllerHandle may have been previously started by the same driver, if a protocol is
  already in the opened state, then it must not be closed with CloseProtocol(). This is required
  to guarantee the state of ControllerHandle is not modified by this function.

  @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  A pointer to the remaining portion of a device path.  This
                                   parameter is ignored by device drivers, and is optional for bus
                                   drivers. For bus drivers, if this parameter is not NULL, then
                                   the bus driver must determine if the bus controller specified
                                   by ControllerHandle and the child controller specified
                                   by RemainingDevicePath are both supported by this
                                   bus driver.

  @retval EFI_SUCCESS              The device specified by ControllerHandle and
                                   RemainingDevicePath is supported by the driver specified by This.
  @retval EFI_ALREADY_STARTED      The device specified by ControllerHandle and
                                   RemainingDevicePath is already managed by the driver
                                   specified by This.
  @retval EFI_ACCESS_DENIED        The device specified by ControllerHandle and
                                   RemainingDevicePath is already managed by a different
                                   driver or an application that requires exclusive access.
                                   Currently not implemented.
  @retval EFI_UNSUPPORTED          The device specified by ControllerHandle and
                                   RemainingDevicePath is not supported by the driver specified by This.
**/
EFI_STATUS
EFIAPI
IScsiIp4DriverBindingSupported (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   ControllerHandle,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
  )
{
  return IScsiSupported (
           This,
           ControllerHandle,
           RemainingDevicePath,
           IP_VERSION_4
           );
}

/**
  Starts a device controller or a bus controller.

  The Start() function is designed to be invoked from the EFI boot service ConnectController().
  As a result, much of the error checking on the parameters to Start() has been moved into this
  common boot service. It is legal to call Start() from other locations,
  but the following calling restrictions must be followed or the system behavior will not be deterministic.
  1. ControllerHandle must be a valid EFI_HANDLE.
  2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
     EFI_DEVICE_PATH_PROTOCOL.
  3. Prior to calling Start(), the Supported() function for the driver specified by This must
     have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.

  @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              The device was started.
  @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
IScsiIp4DriverBindingStart (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   ControllerHandle,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
  )
{
  EFI_STATUS  Status;

  Status = IScsiStart (This->DriverBindingHandle, ControllerHandle, IP_VERSION_4);
  if (Status == EFI_ALREADY_STARTED) {
    Status = EFI_SUCCESS;
  }

  return Status;
}

/**
  Stops a device controller or a bus controller.

  The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
  As a result, much of the error checking on the parameters to Stop() has been moved
  into this common boot service. It is legal to call Stop() from other locations,
  but the following calling restrictions must be followed or the system behavior will not be deterministic.
  1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
     same driver's Start() function.
  2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
     EFI_HANDLE. In addition, all of these handles must have been created in this driver's
     Start() function, and the Start() function must have called OpenProtocol() on
     ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.

  @param[in]  This              A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
  @param[in]  ControllerHandle  A handle to the device being stopped. The handle must
                                support a bus specific I/O protocol for the driver
                                to use to stop the device.
  @param[in]  NumberOfChildren  The number of child device handles in ChildHandleBuffer.
  @param[in]  ChildHandleBuffer An array of child handles to be freed. May be NULL
                                if NumberOfChildren is 0.

  @retval EFI_SUCCESS           The device was stopped.
  @retval EFI_DEVICE_ERROR      The device could not be stopped due to a device error.

**/
EFI_STATUS
EFIAPI
IScsiIp4DriverBindingStop (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   ControllerHandle,
  IN UINTN                        NumberOfChildren,
  IN EFI_HANDLE                   *ChildHandleBuffer OPTIONAL
  )
{
  return IScsiStop (
           This,
           ControllerHandle,
           NumberOfChildren,
           ChildHandleBuffer,
           IP_VERSION_4
           );
}

/**
  Tests to see if this driver supports a given controller. If a child device is provided,
  it tests to see if this driver supports creating a handle for the specified child device.

  This function checks to see if the driver specified by This supports the device specified by
  ControllerHandle. Drivers typically use the device path attached to
  ControllerHandle and/or the services from the bus I/O abstraction attached to
  ControllerHandle to determine if the driver supports ControllerHandle. This function
  may be called many times during platform initialization. In order to reduce boot times, the tests
  performed by this function must be very small and take as little time as possible to execute. This
  function must not change the state of any hardware devices, and this function must be aware that the
  device specified by ControllerHandle may already be managed by the same driver or a
  different driver. This function must match its calls to AllocatePages() with FreePages(),
  AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
  Since ControllerHandle may have been previously started by the same driver, if a protocol is
  already in the opened state, then it must not be closed with CloseProtocol(). This is required
  to guarantee the state of ControllerHandle is not modified by this function.

  @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  A pointer to the remaining portion of a device path.  This
                                   parameter is ignored by device drivers, and is optional for bus
                                   drivers. For bus drivers, if this parameter is not NULL, then
                                   the bus driver must determine if the bus controller specified
                                   by ControllerHandle and the child controller specified
                                   by RemainingDevicePath are both supported by this
                                   bus driver.

  @retval EFI_SUCCESS              The device specified by ControllerHandle and
                                   RemainingDevicePath is supported by the driver specified by This.
  @retval EFI_ALREADY_STARTED      The device specified by ControllerHandle and
                                   RemainingDevicePath is already managed by the driver
                                   specified by This.
  @retval EFI_ACCESS_DENIED        The device specified by ControllerHandle and
                                   RemainingDevicePath is already managed by a different
                                   driver or an application that requires exclusive access.
                                   Currently not implemented.
  @retval EFI_UNSUPPORTED          The device specified by ControllerHandle and
                                   RemainingDevicePath is not supported by the driver specified by This.
**/
EFI_STATUS
EFIAPI
IScsiIp6DriverBindingSupported (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   ControllerHandle,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
  )
{
  return IScsiSupported (
           This,
           ControllerHandle,
           RemainingDevicePath,
           IP_VERSION_6
           );
}

/**
  Starts a device controller or a bus controller.

  The Start() function is designed to be invoked from the EFI boot service ConnectController().
  As a result, much of the error checking on the parameters to Start() has been moved into this
  common boot service. It is legal to call Start() from other locations,
  but the following calling restrictions must be followed or the system behavior will not be deterministic.
  1. ControllerHandle must be a valid EFI_HANDLE.
  2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
     EFI_DEVICE_PATH_PROTOCOL.
  3. Prior to calling Start(), the Supported() function for the driver specified by This must
     have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.

  @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              The device was started.
  @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
IScsiIp6DriverBindingStart (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   ControllerHandle,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
  )
{
  EFI_STATUS  Status;

  Status = IScsiStart (This->DriverBindingHandle, ControllerHandle, IP_VERSION_6);
  if (Status == EFI_ALREADY_STARTED) {
    Status = EFI_SUCCESS;
  }

  return Status;
}

/**
  Stops a device controller or a bus controller.

  The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
  As a result, much of the error checking on the parameters to Stop() has been moved
  into this common boot service. It is legal to call Stop() from other locations,
  but the following calling restrictions must be followed or the system behavior will not be deterministic.
  1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
     same driver's Start() function.
  2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
     EFI_HANDLE. In addition, all of these handles must have been created in this driver's
     Start() function, and the Start() function must have called OpenProtocol() on
     ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.

  @param[in]  This              A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
  @param[in]  ControllerHandle  A handle to the device being stopped. The handle must
                                support a bus specific I/O protocol for the driver
                                to use to stop the device.
  @param[in]  NumberOfChildren  The number of child device handles in ChildHandleBuffer.
  @param[in]  ChildHandleBuffer An array of child handles to be freed. May be NULL
                                if NumberOfChildren is 0.

  @retval EFI_SUCCESS           The device was stopped.
  @retval EFI_DEVICE_ERROR      The device could not be stopped due to a device error.

**/
EFI_STATUS
EFIAPI
IScsiIp6DriverBindingStop (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   ControllerHandle,
  IN UINTN                        NumberOfChildren,
  IN EFI_HANDLE                   *ChildHandleBuffer OPTIONAL
  )
{
  return IScsiStop (
           This,
           ControllerHandle,
           NumberOfChildren,
           ChildHandleBuffer,
           IP_VERSION_6
           );
}

/**
  Unload the iSCSI driver.

  @param[in]  ImageHandle          The handle of the driver image.

  @retval     EFI_SUCCESS          The driver is unloaded.
  @retval     EFI_DEVICE_ERROR     An unexpected error occurred.

**/
EFI_STATUS
EFIAPI
IScsiUnload (
  IN EFI_HANDLE  ImageHandle
  )
{
  EFI_STATUS                    Status;
  UINTN                         DeviceHandleCount;
  EFI_HANDLE                    *DeviceHandleBuffer;
  UINTN                         Index;
  EFI_COMPONENT_NAME_PROTOCOL   *ComponentName;
  EFI_COMPONENT_NAME2_PROTOCOL  *ComponentName2;

  //
  // Try to disconnect the driver from the devices it's controlling.
  //
  Status = gBS->LocateHandleBuffer (
                  AllHandles,
                  NULL,
                  NULL,
                  &DeviceHandleCount,
                  &DeviceHandleBuffer
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Disconnect the iSCSI4 driver from the controlled device.
  //
  for (Index = 0; Index < DeviceHandleCount; Index++) {
    Status = IScsiTestManagedDevice (
               DeviceHandleBuffer[Index],
               gIScsiIp4DriverBinding.DriverBindingHandle,
               &gEfiTcp4ProtocolGuid
               )
    ;
    if (EFI_ERROR (Status)) {
      continue;
    }

    Status = gBS->DisconnectController (
                    DeviceHandleBuffer[Index],
                    gIScsiIp4DriverBinding.DriverBindingHandle,
                    NULL
                    );
    if (EFI_ERROR (Status)) {
      goto ON_EXIT;
    }
  }

  //
  // Disconnect the iSCSI6 driver from the controlled device.
  //
  for (Index = 0; Index < DeviceHandleCount; Index++) {
    Status = IScsiTestManagedDevice (
               DeviceHandleBuffer[Index],
               gIScsiIp6DriverBinding.DriverBindingHandle,
               &gEfiTcp6ProtocolGuid
               );
    if (EFI_ERROR (Status)) {
      continue;
    }

    Status = gBS->DisconnectController (
                    DeviceHandleBuffer[Index],
                    gIScsiIp6DriverBinding.DriverBindingHandle,
                    NULL
                    );
    if (EFI_ERROR (Status)) {
      goto ON_EXIT;
    }
  }

  //
  // Unload the iSCSI configuration form.
  //
  Status = IScsiConfigFormUnload (gIScsiIp4DriverBinding.DriverBindingHandle);
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  //
  // Uninstall the protocols installed by iSCSI driver.
  //
  Status = gBS->UninstallMultipleProtocolInterfaces (
                  ImageHandle,
                  &gEfiAuthenticationInfoProtocolGuid,
                  &gIScsiAuthenticationInfo,
                  NULL
                  );
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  if (gIScsiControllerNameTable != NULL) {
    Status = FreeUnicodeStringTable (gIScsiControllerNameTable);
    if (EFI_ERROR (Status)) {
      goto ON_EXIT;
    }

    gIScsiControllerNameTable = NULL;
  }

  //
  // Uninstall the ComponentName and ComponentName2 protocol from iSCSI4 driver binding handle
  // if it has been installed.
  //
  Status = gBS->HandleProtocol (
                  gIScsiIp4DriverBinding.DriverBindingHandle,
                  &gEfiComponentNameProtocolGuid,
                  (VOID **)&ComponentName
                  );
  if (!EFI_ERROR (Status)) {
    Status = gBS->UninstallMultipleProtocolInterfaces (
                    gIScsiIp4DriverBinding.DriverBindingHandle,
                    &gEfiComponentNameProtocolGuid,
                    ComponentName,
                    NULL
                    );
    if (EFI_ERROR (Status)) {
      goto ON_EXIT;
    }
  }

  Status = gBS->HandleProtocol (
                  gIScsiIp4DriverBinding.DriverBindingHandle,
                  &gEfiComponentName2ProtocolGuid,
                  (VOID **)&ComponentName2
                  );
  if (!EFI_ERROR (Status)) {
    gBS->UninstallMultipleProtocolInterfaces (
           gIScsiIp4DriverBinding.DriverBindingHandle,
           &gEfiComponentName2ProtocolGuid,
           ComponentName2,
           NULL
           );
    if (EFI_ERROR (Status)) {
      goto ON_EXIT;
    }
  }

  //
  // Uninstall the ComponentName and ComponentName2 protocol from iSCSI6 driver binding handle
  // if it has been installed.
  //
  Status = gBS->HandleProtocol (
                  gIScsiIp6DriverBinding.DriverBindingHandle,
                  &gEfiComponentNameProtocolGuid,
                  (VOID **)&ComponentName
                  );
  if (!EFI_ERROR (Status)) {
    Status = gBS->UninstallMultipleProtocolInterfaces (
                    gIScsiIp6DriverBinding.DriverBindingHandle,
                    &gEfiComponentNameProtocolGuid,
                    ComponentName,
                    NULL
                    );
    if (EFI_ERROR (Status)) {
      goto ON_EXIT;
    }
  }

  Status = gBS->HandleProtocol (
                  gIScsiIp6DriverBinding.DriverBindingHandle,
                  &gEfiComponentName2ProtocolGuid,
                  (VOID **)&ComponentName2
                  );
  if (!EFI_ERROR (Status)) {
    gBS->UninstallMultipleProtocolInterfaces (
           gIScsiIp6DriverBinding.DriverBindingHandle,
           &gEfiComponentName2ProtocolGuid,
           ComponentName2,
           NULL
           );
    if (EFI_ERROR (Status)) {
      goto ON_EXIT;
    }
  }

  //
  // Uninstall the IScsiInitiatorNameProtocol and all the driver binding protocols.
  //
  Status = gBS->UninstallMultipleProtocolInterfaces (
                  gIScsiIp4DriverBinding.DriverBindingHandle,
                  &gEfiDriverBindingProtocolGuid,
                  &gIScsiIp4DriverBinding,
                  &gEfiIScsiInitiatorNameProtocolGuid,
                  &gIScsiInitiatorName,
                  NULL
                  );
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  Status = gBS->UninstallMultipleProtocolInterfaces (
                  gIScsiIp6DriverBinding.DriverBindingHandle,
                  &gEfiDriverBindingProtocolGuid,
                  &gIScsiIp6DriverBinding,
                  NULL
                  );

ON_EXIT:

  if (DeviceHandleBuffer != NULL) {
    FreePool (DeviceHandleBuffer);
  }

  return Status;
}

/**
  This is the declaration of an EFI image entry point. This entry point is
  the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
  both device drivers and bus drivers.

  The entry point for iSCSI driver which initializes the global variables and
  installs the driver binding, component name protocol, iSCSI initiator name
  protocol and Authentication Info protocol on its image.

  @param[in]  ImageHandle       The firmware allocated handle for the UEFI image.
  @param[in]  SystemTable       A pointer to the EFI System Table.

  @retval EFI_SUCCESS           The operation completed successfully.
  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.

**/
EFI_STATUS
EFIAPI
IScsiDriverEntryPoint (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS                         Status;
  EFI_ISCSI_INITIATOR_NAME_PROTOCOL  *IScsiInitiatorName;
  EFI_AUTHENTICATION_INFO_PROTOCOL   *AuthenticationInfo;

  //
  // There should be only one EFI_ISCSI_INITIATOR_NAME_PROTOCOL.
  //
  Status = gBS->LocateProtocol (
                  &gEfiIScsiInitiatorNameProtocolGuid,
                  NULL,
                  (VOID **)&IScsiInitiatorName
                  );
  if (!EFI_ERROR (Status)) {
    return EFI_ACCESS_DENIED;
  }

  //
  // Initialize the EFI Driver Library.
  //
  Status = EfiLibInstallDriverBindingComponentName2 (
             ImageHandle,
             SystemTable,
             &gIScsiIp4DriverBinding,
             ImageHandle,
             &gIScsiComponentName,
             &gIScsiComponentName2
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = EfiLibInstallDriverBindingComponentName2 (
             ImageHandle,
             SystemTable,
             &gIScsiIp6DriverBinding,
             NULL,
             &gIScsiComponentName,
             &gIScsiComponentName2
             );
  if (EFI_ERROR (Status)) {
    goto Error1;
  }

  //
  // Install the iSCSI Initiator Name Protocol.
  //
  Status = gBS->InstallProtocolInterface (
                  &ImageHandle,
                  &gEfiIScsiInitiatorNameProtocolGuid,
                  EFI_NATIVE_INTERFACE,
                  &gIScsiInitiatorName
                  );
  if (EFI_ERROR (Status)) {
    goto Error2;
  }

  //
  // Create the private data structures.
  //
  IScsiCHAPInitHashList ();

  mPrivate = AllocateZeroPool (sizeof (ISCSI_PRIVATE_DATA));
  if (mPrivate == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Error3;
  }

  InitializeListHead (&mPrivate->NicInfoList);
  InitializeListHead (&mPrivate->AttemptConfigs);

  //
  // Initialize the configuration form of iSCSI.
  //
  Status = IScsiConfigFormInit (gIScsiIp4DriverBinding.DriverBindingHandle);
  if (EFI_ERROR (Status)) {
    goto Error4;
  }

  //
  // Create the Maximum Attempts.
  //
  Status = IScsiCreateAttempts (PcdGet8 (PcdMaxIScsiAttemptNumber));
  if (EFI_ERROR (Status)) {
    goto Error5;
  }

  //
  // Create Keywords for all the Attempts.
  //
  Status = IScsiCreateKeywords (PcdGet8 (PcdMaxIScsiAttemptNumber));
  if (EFI_ERROR (Status)) {
    goto Error6;
  }

  //
  // There should be only one EFI_AUTHENTICATION_INFO_PROTOCOL. If already exists,
  // do not produce the protocol instance.
  //
  Status = gBS->LocateProtocol (
                  &gEfiAuthenticationInfoProtocolGuid,
                  NULL,
                  (VOID **)&AuthenticationInfo
                  );
  if (Status == EFI_NOT_FOUND) {
    Status = gBS->InstallProtocolInterface (
                    &ImageHandle,
                    &gEfiAuthenticationInfoProtocolGuid,
                    EFI_NATIVE_INTERFACE,
                    &gIScsiAuthenticationInfo
                    );
    if (EFI_ERROR (Status)) {
      goto Error6;
    }
  }

  return EFI_SUCCESS;

Error6:
  IScsiCleanAttemptVariable ();

Error5:
  IScsiConfigFormUnload (gIScsiIp4DriverBinding.DriverBindingHandle);

Error4:
  if (mPrivate != NULL) {
    FreePool (mPrivate);
    mPrivate = NULL;
  }

Error3:
  gBS->UninstallMultipleProtocolInterfaces (
         ImageHandle,
         &gEfiIScsiInitiatorNameProtocolGuid,
         &gIScsiInitiatorName,
         NULL
         );

Error2:
  EfiLibUninstallDriverBindingComponentName2 (
    &gIScsiIp6DriverBinding,
    &gIScsiComponentName,
    &gIScsiComponentName2
    );

Error1:
  EfiLibUninstallDriverBindingComponentName2 (
    &gIScsiIp4DriverBinding,
    &gIScsiComponentName,
    &gIScsiComponentName2
    );

  return Status;
}
