/** @file
  The implementation of iSCSI protocol based on RFC3720.

Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "IScsiImpl.h"

UINT32  mDataSegPad = 0;

/**
  Attach the iSCSI connection to the iSCSI session.

  @param[in, out]  Session The iSCSI session.
  @param[in, out]  Conn    The iSCSI connection.

**/
VOID
IScsiAttatchConnection (
  IN OUT ISCSI_SESSION     *Session,
  IN OUT ISCSI_CONNECTION  *Conn
  )
{
  InsertTailList (&Session->Conns, &Conn->Link);
  Conn->Session = Session;
  Session->NumConns++;
}

/**
  Detach the iSCSI connection from the session it belongs to.

  @param[in, out]  Conn The iSCSI connection.

**/
VOID
IScsiDetatchConnection (
  IN OUT ISCSI_CONNECTION  *Conn
  )
{
  RemoveEntryList (&Conn->Link);
  Conn->Session->NumConns--;
  Conn->Session = NULL;
}

/**
  Check the sequence number according to RFC3720.

  @param[in, out]  ExpSN   The currently expected sequence number.
  @param[in]       NewSN   The sequence number to check.

  @retval EFI_SUCCESS         The check passed and the ExpSN is increased.
  @retval EFI_NOT_READY       Response was sent due to a retransmission request.
  @retval EFI_PROTOCOL_ERROR  Some kind of iSCSI protocol error occurred.

**/
EFI_STATUS
IScsiCheckSN (
  IN OUT UINT32  *ExpSN,
  IN UINT32      NewSN
  )
{
  if (!ISCSI_SEQ_EQ (NewSN, *ExpSN)) {
    if (ISCSI_SEQ_LT (NewSN, *ExpSN)) {
      //
      // Duplicate
      //
      return EFI_NOT_READY;
    } else {
      return EFI_PROTOCOL_ERROR;
    }
  } else {
    //
    // Advance the ExpSN
    //
    (*ExpSN)++;
    return EFI_SUCCESS;
  }
}

/**
  Update the sequence numbers for the iSCSI command.

  @param[in, out]  Session  The iSCSI session.
  @param[in]       MaxCmdSN Maximum CmdSN from the target.
  @param[in]       ExpCmdSN Next expected CmdSN from the target.

**/
VOID
IScsiUpdateCmdSN (
  IN OUT ISCSI_SESSION  *Session,
  IN UINT32             MaxCmdSN,
  IN UINT32             ExpCmdSN
  )
{
  if (ISCSI_SEQ_LT (MaxCmdSN, ExpCmdSN - 1)) {
    return;
  }

  if (ISCSI_SEQ_GT (MaxCmdSN, Session->MaxCmdSN)) {
    Session->MaxCmdSN = MaxCmdSN;
  }

  if (ISCSI_SEQ_GT (ExpCmdSN, Session->ExpCmdSN)) {
    Session->ExpCmdSN = ExpCmdSN;
  }
}

/**
  This function does the iSCSI connection login.

  @param[in, out]  Conn      The iSCSI connection to login.
  @param           Timeout   The timeout value in millisecond.

  @retval EFI_SUCCESS        The iSCSI connection is logged into the iSCSI target.
  @retval EFI_TIMEOUT        Timeout occurred during the login procedure.
  @retval Others             Other errors as indicated.

**/
EFI_STATUS
IScsiConnLogin (
  IN OUT ISCSI_CONNECTION  *Conn,
  IN     UINT16            Timeout
  )
{
  EFI_STATUS  Status;

  //
  // Start the timer, and wait Timeout seconds to establish the TCP connection.
  //
  Status = gBS->SetTimer (
                  Conn->TimeoutEvent,
                  TimerRelative,
                  MultU64x32 (Timeout, TICKS_PER_MS)
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Try to establish the tcp connection.
  //
  Status = TcpIoConnect (&Conn->TcpIo, Conn->TimeoutEvent);
  gBS->SetTimer (Conn->TimeoutEvent, TimerCancel, 0);

  if (EFI_ERROR (Status)) {
    return Status;
  }

  Conn->State = CONN_STATE_IN_LOGIN;

  //
  // Connection is established, start the iSCSI Login.
  //
  do {
    Status = IScsiSendLoginReq (Conn);
    if (EFI_ERROR (Status)) {
      break;
    }

    Status = IScsiReceiveLoginRsp (Conn);
    if (EFI_ERROR (Status)) {
      break;
    }
  } while (Conn->CurrentStage != ISCSI_FULL_FEATURE_PHASE);

  return Status;
}

/**
  Reset the iSCSI connection.

  @param[in, out]  Conn The iSCSI connection to reset.

**/
VOID
IScsiConnReset (
  IN OUT ISCSI_CONNECTION  *Conn
  )
{
  TcpIoReset (&Conn->TcpIo);
}

/**
  Create a TCP connection for the iSCSI session.

  @param[in]  Session Points to the iSCSI session.

  @return The newly created iSCSI connection.

**/
ISCSI_CONNECTION *
IScsiCreateConnection (
  IN ISCSI_SESSION  *Session
  )
{
  ISCSI_DRIVER_DATA            *Private;
  ISCSI_SESSION_CONFIG_NVDATA  *NvData;
  ISCSI_CONNECTION             *Conn;
  TCP_IO_CONFIG_DATA           TcpIoConfig;
  TCP4_IO_CONFIG_DATA          *Tcp4IoConfig;
  TCP6_IO_CONFIG_DATA          *Tcp6IoConfig;
  EFI_STATUS                   Status;

  Private = Session->Private;
  NvData  = &Session->ConfigData->SessionConfigData;

  Conn = AllocateZeroPool (sizeof (ISCSI_CONNECTION));
  if (Conn == NULL) {
    return NULL;
  }

  Conn->Signature       = ISCSI_CONNECTION_SIGNATURE;
  Conn->State           = CONN_STATE_FREE;
  Conn->CurrentStage    = ISCSI_SECURITY_NEGOTIATION;
  Conn->NextStage       = ISCSI_LOGIN_OPERATIONAL_NEGOTIATION;
  Conn->AuthStep        = ISCSI_AUTH_INITIAL;
  Conn->ExpStatSN       = 0;
  Conn->PartialReqSent  = FALSE;
  Conn->PartialRspRcvd  = FALSE;
  Conn->ParamNegotiated = FALSE;
  Conn->Cid             = Session->NextCid++;
  Conn->Ipv6Flag        = NvData->IpMode == IP_MODE_IP6 || Session->ConfigData->AutoConfigureMode == IP_MODE_AUTOCONFIG_IP6;

  Status = gBS->CreateEvent (
                  EVT_TIMER,
                  TPL_CALLBACK,
                  NULL,
                  NULL,
                  &Conn->TimeoutEvent
                  );
  if (EFI_ERROR (Status)) {
    FreePool (Conn);
    return NULL;
  }

  NetbufQueInit (&Conn->RspQue);

  //
  // Set the default connection-only parameters.
  //
  Conn->MaxRecvDataSegmentLength = DEFAULT_MAX_RECV_DATA_SEG_LEN;
  Conn->HeaderDigest             = IScsiDigestNone;
  Conn->DataDigest               = IScsiDigestNone;

  if (NvData->DnsMode) {
    //
    // perform dns process if target address expressed by domain name.
    //
    if (!Conn->Ipv6Flag) {
      Status = IScsiDns4 (Private->Image, Private->Controller, NvData);
    } else {
      Status = IScsiDns6 (Private->Image, Private->Controller, NvData);
    }

    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "The configuration of Target address or DNS server address is invalid!\n"));
      FreePool (Conn);
      return NULL;
    }
  }

  if (!Conn->Ipv6Flag) {
    Tcp4IoConfig = &TcpIoConfig.Tcp4IoConfigData;

    CopyMem (&Tcp4IoConfig->LocalIp, &NvData->LocalIp, sizeof (EFI_IPv4_ADDRESS));
    CopyMem (&Tcp4IoConfig->SubnetMask, &NvData->SubnetMask, sizeof (EFI_IPv4_ADDRESS));
    CopyMem (&Tcp4IoConfig->Gateway, &NvData->Gateway, sizeof (EFI_IPv4_ADDRESS));
    CopyMem (&Tcp4IoConfig->RemoteIp, &NvData->TargetIp, sizeof (EFI_IPv4_ADDRESS));

    Tcp4IoConfig->RemotePort  = NvData->TargetPort;
    Tcp4IoConfig->ActiveFlag  = TRUE;
    Tcp4IoConfig->StationPort = 0;
  } else {
    Tcp6IoConfig = &TcpIoConfig.Tcp6IoConfigData;

    CopyMem (&Tcp6IoConfig->RemoteIp, &NvData->TargetIp, sizeof (EFI_IPv6_ADDRESS));
    Tcp6IoConfig->RemotePort  = NvData->TargetPort;
    Tcp6IoConfig->ActiveFlag  = TRUE;
    Tcp6IoConfig->StationPort = 0;
  }

  //
  // Create the TCP IO for this connection.
  //
  Status = TcpIoCreateSocket (
             Private->Image,
             Private->Controller,
             (UINT8)(!Conn->Ipv6Flag ? TCP_VERSION_4 : TCP_VERSION_6),
             &TcpIoConfig,
             &Conn->TcpIo
             );
  if (EFI_ERROR (Status)) {
    gBS->CloseEvent (Conn->TimeoutEvent);
    FreePool (Conn);
    Conn = NULL;
  }

  return Conn;
}

/**
  Destroy an iSCSI connection.

  @param[in]  Conn The connection to destroy.

**/
VOID
IScsiDestroyConnection (
  IN ISCSI_CONNECTION  *Conn
  )
{
  TcpIoDestroySocket (&Conn->TcpIo);

  NetbufQueFlush (&Conn->RspQue);
  gBS->CloseEvent (Conn->TimeoutEvent);
  FreePool (Conn);
}

/**
  Retrieve the IPv6 Address/Prefix/Gateway from the established TCP connection, these informations
  will be filled in the iSCSI Boot Firmware Table.

  @param[in]  Conn             The connection used in the iSCSI login phase.

  @retval     EFI_SUCCESS      Get the NIC information successfully.
  @retval     Others           Other errors as indicated.

**/
EFI_STATUS
IScsiGetIp6NicInfo (
  IN ISCSI_CONNECTION  *Conn
  )
{
  ISCSI_SESSION_CONFIG_NVDATA  *NvData;
  EFI_TCP6_PROTOCOL            *Tcp6;
  EFI_IP6_MODE_DATA            Ip6ModeData;
  EFI_STATUS                   Status;
  EFI_IPv6_ADDRESS             *TargetIp;
  UINTN                        Index;
  UINT8                        SubnetPrefixLength;
  UINTN                        RouteEntry;

  NvData   = &Conn->Session->ConfigData->SessionConfigData;
  TargetIp = &NvData->TargetIp.v6;
  Tcp6     = Conn->TcpIo.Tcp.Tcp6;

  ZeroMem (&Ip6ModeData, sizeof (EFI_IP6_MODE_DATA));
  Status = Tcp6->GetModeData (
                   Tcp6,
                   NULL,
                   NULL,
                   &Ip6ModeData,
                   NULL,
                   NULL
                   );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  if (!Ip6ModeData.IsConfigured) {
    Status = EFI_ABORTED;
    goto ON_EXIT;
  }

  IP6_COPY_ADDRESS (&NvData->LocalIp, &Ip6ModeData.ConfigData.StationAddress);

  NvData->PrefixLength = 0;
  for (Index = 0; Index < Ip6ModeData.AddressCount; Index++) {
    if (EFI_IP6_EQUAL (&NvData->LocalIp.v6, &Ip6ModeData.AddressList[Index].Address)) {
      NvData->PrefixLength = Ip6ModeData.AddressList[Index].PrefixLength;
      break;
    }
  }

  SubnetPrefixLength = 0;
  RouteEntry         = Ip6ModeData.RouteCount;
  for (Index = 0; Index < Ip6ModeData.RouteCount; Index++) {
    if (NetIp6IsNetEqual (TargetIp, &Ip6ModeData.RouteTable[Index].Destination, Ip6ModeData.RouteTable[Index].PrefixLength)) {
      if (SubnetPrefixLength < Ip6ModeData.RouteTable[Index].PrefixLength) {
        SubnetPrefixLength = Ip6ModeData.RouteTable[Index].PrefixLength;
        RouteEntry         = Index;
      }
    }
  }

  if (RouteEntry != Ip6ModeData.RouteCount) {
    IP6_COPY_ADDRESS (&NvData->Gateway, &Ip6ModeData.RouteTable[RouteEntry].Gateway);
  }

ON_EXIT:
  if (Ip6ModeData.AddressList != NULL) {
    FreePool (Ip6ModeData.AddressList);
  }

  if (Ip6ModeData.GroupTable != NULL) {
    FreePool (Ip6ModeData.GroupTable);
  }

  if (Ip6ModeData.RouteTable != NULL) {
    FreePool (Ip6ModeData.RouteTable);
  }

  if (Ip6ModeData.NeighborCache != NULL) {
    FreePool (Ip6ModeData.NeighborCache);
  }

  if (Ip6ModeData.PrefixTable != NULL) {
    FreePool (Ip6ModeData.PrefixTable);
  }

  if (Ip6ModeData.IcmpTypeList != NULL) {
    FreePool (Ip6ModeData.IcmpTypeList);
  }

  return Status;
}

/**
  Re-set any stateful session-level authentication information that is used by
  the leading login / leading connection.

  (Note that this driver only supports a single connection per session -- see
  ISCSI_MAX_CONNS_PER_SESSION.)

  @param[in,out] Session  The iSCSI session.
**/
STATIC
VOID
IScsiSessionResetAuthData (
  IN OUT ISCSI_SESSION  *Session
  )
{
  if (Session->AuthType == ISCSI_AUTH_TYPE_CHAP) {
    Session->AuthData.CHAP.Hash = NULL;
  }
}

/**
  Login the iSCSI session.

  @param[in]  Session           The iSCSI session.

  @retval EFI_SUCCESS           The iSCSI session login procedure finished.
  @retval EFI_OUT_OF_RESOURCES  Failed to allocate memory.
  @retval EFI_NO_MEDIA          There was a media error.
  @retval Others                Other errors as indicated.

**/
EFI_STATUS
IScsiSessionLogin (
  IN ISCSI_SESSION  *Session
  )
{
  EFI_STATUS        Status;
  ISCSI_CONNECTION  *Conn;
  VOID              *Tcp;
  EFI_GUID          *ProtocolGuid;
  UINT8             RetryCount;
  EFI_STATUS        MediaStatus;

  //
  // Check media status before session login.
  //
  MediaStatus = EFI_SUCCESS;
  NetLibDetectMediaWaitTimeout (Session->Private->Controller, ISCSI_CHECK_MEDIA_LOGIN_WAITING_TIME, &MediaStatus);
  if (MediaStatus != EFI_SUCCESS) {
    return EFI_NO_MEDIA;
  }

  //
  // Set session identifier
  //
  CopyMem (Session->Isid, Session->ConfigData->SessionConfigData.IsId, 6);

  RetryCount = 0;

  do {
    //
    // Create a connection for the session.
    //
    Conn = IScsiCreateConnection (Session);
    if (Conn == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    IScsiAttatchConnection (Session, Conn);

    //
    // Login through the newly created connection.
    //
    IScsiSessionResetAuthData (Session);
    Status = IScsiConnLogin (Conn, Session->ConfigData->SessionConfigData.ConnectTimeout);
    if (EFI_ERROR (Status)) {
      IScsiConnReset (Conn);
      IScsiDetatchConnection (Conn);
      IScsiDestroyConnection (Conn);
    }

    if (Status != EFI_TIMEOUT) {
      break;
    }

    RetryCount++;
  } while (RetryCount <= Session->ConfigData->SessionConfigData.ConnectRetryCount);

  if (!EFI_ERROR (Status)) {
    Session->State = SESSION_STATE_LOGGED_IN;

    if (!Conn->Ipv6Flag) {
      ProtocolGuid = &gEfiTcp4ProtocolGuid;
    } else {
      ProtocolGuid = &gEfiTcp6ProtocolGuid;
    }

    Status = gBS->OpenProtocol (
                    Conn->TcpIo.Handle,
                    ProtocolGuid,
                    (VOID **)&Tcp,
                    Session->Private->Image,
                    Session->Private->ExtScsiPassThruHandle,
                    EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
                    );

    ASSERT_EFI_ERROR (Status);

    if (Conn->Ipv6Flag) {
      Status = IScsiGetIp6NicInfo (Conn);
    }
  }

  return Status;
}

/**
  Wait for IPsec negotiation, then try to login the iSCSI session again.

  @param[in]  Session           The iSCSI session.

  @retval EFI_SUCCESS           The iSCSI session login procedure finished.
  @retval EFI_OUT_OF_RESOURCES  Failed to allocate memory.
  @retval EFI_PROTOCOL_ERROR    Some kind of iSCSI protocol error occurred.

**/
EFI_STATUS
IScsiSessionReLogin (
  IN ISCSI_SESSION  *Session
  )
{
  EFI_STATUS  Status;
  EFI_STATUS  TimerStatus;
  EFI_EVENT   Timer;

  Status = gBS->CreateEvent (EVT_TIMER, TPL_CALLBACK, NULL, NULL, &Timer);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = gBS->SetTimer (
                  Timer,
                  TimerRelative,
                  ISCSI_WAIT_IPSEC_TIMEOUT
                  );

  if (EFI_ERROR (Status)) {
    gBS->CloseEvent (Timer);
    return Status;
  }

  do {
    TimerStatus = gBS->CheckEvent (Timer);

    if (!EFI_ERROR (TimerStatus)) {
      Status = IScsiSessionLogin (Session);
    }
  } while (TimerStatus == EFI_NOT_READY);

  gBS->CloseEvent (Timer);
  return Status;
}

/**
  Build and send the iSCSI login request to the iSCSI target according to
  the current login stage.

  @param[in]  Conn             The connection in the iSCSI login phase.

  @retval EFI_SUCCESS          The iSCSI login request PDU is built and sent on this
                               connection.
  @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
  @retval EFI_DEVICE_ERROR     Some kind of device error occurred.

**/
EFI_STATUS
IScsiSendLoginReq (
  IN ISCSI_CONNECTION  *Conn
  )
{
  NET_BUF     *Pdu;
  EFI_STATUS  Status;

  //
  // Build the Login Request PDU.
  //
  Pdu = IScsiPrepareLoginReq (Conn);
  if (Pdu == NULL) {
    return EFI_DEVICE_ERROR;
  }

  //
  // Send it to the iSCSI target.
  //
  Status = TcpIoTransmit (&Conn->TcpIo, Pdu);

  NetbufFree (Pdu);

  return Status;
}

/**
  Receive and process the iSCSI login response.

  @param[in]  Conn             The connection in the iSCSI login phase.

  @retval EFI_SUCCESS          The iSCSI login response PDU is received and processed.
  @retval Others               Other errors as indicated.

**/
EFI_STATUS
IScsiReceiveLoginRsp (
  IN ISCSI_CONNECTION  *Conn
  )
{
  EFI_STATUS  Status;
  NET_BUF     *Pdu;

  Pdu = NULL;

  //
  // Receive the iSCSI login response.
  //
  Status = IScsiReceivePdu (Conn, &Pdu, NULL, FALSE, FALSE, NULL);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  ASSERT (Pdu != NULL);

  //
  // A Login Response is received; process it.
  //
  Status = IScsiProcessLoginRsp (Conn, Pdu);

  NetbufFree (Pdu);

  return Status;
}

/**
  Add an iSCSI key-value pair as a string into the data segment of the Login Request PDU.
  The DataSegmentLength and the actual size of the net buffer containing this PDU will be
  updated.

  @param[in, out]  Pdu         The iSCSI PDU whose data segment the key-value pair will
                               be added to.
  @param[in]       Key         The key name string.
  @param[in]       Value       The value string.

  @retval EFI_SUCCESS          The key-value pair is added to the PDU's data segment and
                               the correspondence length fields are updated.
  @retval EFI_OUT_OF_RESOURCES There is not enough space in the PDU to add the key-value
                               pair.
  @retval EFI_PROTOCOL_ERROR   There is no such data in the net buffer.
**/
EFI_STATUS
IScsiAddKeyValuePair (
  IN OUT NET_BUF  *Pdu,
  IN CHAR8        *Key,
  IN CHAR8        *Value
  )
{
  UINT32               DataSegLen;
  UINT32               KeyLen;
  UINT32               ValueLen;
  UINT32               TotalLen;
  ISCSI_LOGIN_REQUEST  *LoginReq;
  CHAR8                *Data;

  LoginReq = (ISCSI_LOGIN_REQUEST *)NetbufGetByte (Pdu, 0, NULL);
  if (LoginReq == NULL) {
    return EFI_PROTOCOL_ERROR;
  }

  DataSegLen = NTOH24 (LoginReq->DataSegmentLength);

  KeyLen   = (UINT32)AsciiStrLen (Key);
  ValueLen = (UINT32)AsciiStrLen (Value);

  //
  // 1 byte for the key value separator '=' and 1 byte for the null
  // delimiter after the value.
  //
  TotalLen = KeyLen + 1 + ValueLen + 1;

  //
  // Allocate the space for the key-value pair.
  //
  Data = (CHAR8 *)NetbufAllocSpace (Pdu, TotalLen, NET_BUF_TAIL);
  if (Data == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Add the key.
  //
  CopyMem (Data, Key, KeyLen);
  Data += KeyLen;

  *Data = '=';
  Data++;

  //
  // Add the value.
  //
  CopyMem (Data, Value, ValueLen);
  Data += ValueLen;

  *Data = '\0';

  //
  // Update the DataSegmentLength
  //
  ISCSI_SET_DATASEG_LEN (LoginReq, DataSegLen + TotalLen);

  return EFI_SUCCESS;
}

/**
  Prepare the iSCSI login request to be sent according to the current login status.

  @param[in, out]  Conn The connection in the iSCSI login phase.

  @return The pointer to the net buffer containing the iSCSI login request built.
  @retval NULL     Other errors as indicated.

**/
NET_BUF *
IScsiPrepareLoginReq (
  IN OUT ISCSI_CONNECTION  *Conn
  )
{
  ISCSI_SESSION        *Session;
  NET_BUF              *Nbuf;
  ISCSI_LOGIN_REQUEST  *LoginReq;
  EFI_STATUS           Status;

  Session = Conn->Session;

  Nbuf = NetbufAlloc (sizeof (ISCSI_LOGIN_REQUEST) + DEFAULT_MAX_RECV_DATA_SEG_LEN);
  if (Nbuf == NULL) {
    return NULL;
  }

  LoginReq = (ISCSI_LOGIN_REQUEST *)NetbufAllocSpace (Nbuf, sizeof (ISCSI_LOGIN_REQUEST), NET_BUF_TAIL);
  if (LoginReq == NULL) {
    NetbufFree (Nbuf);
    return NULL;
  }

  ZeroMem (LoginReq, sizeof (ISCSI_LOGIN_REQUEST));

  //
  // Init the login request pdu
  //
  ISCSI_SET_OPCODE (LoginReq, ISCSI_OPCODE_LOGIN_REQ, ISCSI_REQ_IMMEDIATE);
  ISCSI_SET_STAGES (LoginReq, Conn->CurrentStage, Conn->NextStage);
  LoginReq->VersionMax       = ISCSI_VERSION_MAX;
  LoginReq->VersionMin       = ISCSI_VERSION_MIN;
  LoginReq->Tsih             = HTONS (Session->Tsih);
  LoginReq->InitiatorTaskTag = HTONL (Session->InitiatorTaskTag);
  LoginReq->Cid              = HTONS (Conn->Cid);
  LoginReq->CmdSN            = HTONL (Session->CmdSN);

  //
  // For the first Login Request on a connection this is ExpStatSN for the
  // old connection, and this field is only valid if the Login Request restarts
  // a connection.
  // For subsequent Login Requests it is used to acknowledge the Login Responses
  // with their increasing StatSN values.
  //
  LoginReq->ExpStatSN = HTONL (Conn->ExpStatSN);
  CopyMem (LoginReq->Isid, Session->Isid, sizeof (LoginReq->Isid));

  if (Conn->PartialRspRcvd) {
    //
    // A partial response. The initiator must send an empty Login Request.
    //
    return Nbuf;
  }

  Status = EFI_SUCCESS;

  switch (Conn->CurrentStage) {
    case ISCSI_SECURITY_NEGOTIATION:
      //
      // Both none authentication and CHAP authentication share the CHAP path.
      //
      //
      if (Session->AuthType != ISCSI_AUTH_TYPE_KRB) {
        Status = IScsiCHAPToSendReq (Conn, Nbuf);
      }

      break;

    case ISCSI_LOGIN_OPERATIONAL_NEGOTIATION:
      //
      // Only negotiate the parameter once.
      //
      if (!Conn->ParamNegotiated) {
        IScsiFillOpParams (Conn, Nbuf);
      }

      ISCSI_SET_FLAG (LoginReq, ISCSI_LOGIN_REQ_PDU_FLAG_TRANSIT);
      break;

    default:
      //
      // An error occurs...
      //
      Status = EFI_DEVICE_ERROR;
      break;
  }

  if (EFI_ERROR (Status)) {
    NetbufFree (Nbuf);
    Nbuf = NULL;
  } else {
    //
    // Pad the data segment if needed.
    //
    IScsiPadSegment (Nbuf, ISCSI_GET_DATASEG_LEN (LoginReq));
    //
    // Check whether we will issue the stage transition signal?
    //
    Conn->TransitInitiated = ISCSI_FLAG_ON (LoginReq, ISCSI_LOGIN_REQ_PDU_FLAG_TRANSIT);
  }

  return Nbuf;
}

/**
  Process the iSCSI Login Response.

  @param[in, out]  Conn The connection on which the iSCSI login response is received.
  @param[in, out]  Pdu  The iSCSI login response PDU.

  @retval EFI_SUCCESS        The iSCSI login response PDU is processed, and all checks are passed.
  @retval EFI_PROTOCOL_ERROR Some kind of iSCSI protocol error occurred.
  @retval EFI_MEDIA_CHANGED  Target is redirected.
  @retval Others             Other errors as indicated.

**/
EFI_STATUS
IScsiProcessLoginRsp (
  IN OUT ISCSI_CONNECTION  *Conn,
  IN OUT NET_BUF           *Pdu
  )
{
  EFI_STATUS            Status;
  ISCSI_SESSION         *Session;
  ISCSI_LOGIN_RESPONSE  *LoginRsp;
  BOOLEAN               Transit;
  BOOLEAN               Continue;
  UINT8                 CurrentStage;
  UINT8                 NextStage;
  UINT8                 *DataSeg;
  UINT32                DataSegLen;

  Status  = EFI_SUCCESS;
  Session = Conn->Session;

  LoginRsp = (ISCSI_LOGIN_RESPONSE *)NetbufGetByte (Pdu, 0, NULL);
  if (LoginRsp == NULL) {
    return EFI_PROTOCOL_ERROR;
  }

  if (!ISCSI_CHECK_OPCODE (LoginRsp, ISCSI_OPCODE_LOGIN_RSP)) {
    //
    // It is not a Login Response.
    //
    return EFI_PROTOCOL_ERROR;
  }

  //
  // Get the data segment, if any.
  //
  DataSegLen = ISCSI_GET_DATASEG_LEN (LoginRsp);
  if (DataSegLen != 0) {
    DataSeg = NetbufGetByte (Pdu, sizeof (ISCSI_LOGIN_RESPONSE), NULL);
  } else {
    DataSeg = NULL;
  }

  //
  // Check the status class in the login response PDU.
  //
  switch (LoginRsp->StatusClass) {
    case ISCSI_LOGIN_STATUS_SUCCESS:
      //
      // Just break here; the response and the data segment will be processed later.
      //
      break;

    case ISCSI_LOGIN_STATUS_REDIRECTION:
      //
      // The target may be moved to a different address.
      //
      if (DataSeg == NULL) {
        return EFI_PROTOCOL_ERROR;
      }

      //
      // Process the TargetAddress key-value strings in the data segment to update the
      // target address info.
      //
      Status = IScsiUpdateTargetAddress (Session, (CHAR8 *)DataSeg, DataSegLen);
      if (EFI_ERROR (Status)) {
        return Status;
      }

      //
      // Session will be restarted on this error status because the Target is
      // redirected by this Login Response.
      //
      return EFI_MEDIA_CHANGED;

    default:
      //
      // Initiator Error, Target Error, or any other undefined error code.
      //
      return EFI_PROTOCOL_ERROR;
  }

  //
  // The status is success; extract the wanted fields from the header segment.
  //
  Transit  = ISCSI_FLAG_ON (LoginRsp, ISCSI_LOGIN_RSP_PDU_FLAG_TRANSIT);
  Continue = ISCSI_FLAG_ON (LoginRsp, ISCSI_LOGIN_RSP_PDU_FLAG_CONTINUE);

  CurrentStage = ISCSI_GET_CURRENT_STAGE (LoginRsp);
  NextStage    = ISCSI_GET_NEXT_STAGE (LoginRsp);

  LoginRsp->InitiatorTaskTag = NTOHL (LoginRsp->InitiatorTaskTag);

  if ((Transit && Continue) ||
      (CurrentStage != Conn->CurrentStage) ||
      (!Conn->TransitInitiated && Transit) ||
      (Transit && (NextStage != Conn->NextStage)) ||
      (CompareMem (Session->Isid, LoginRsp->Isid, sizeof (LoginRsp->Isid)) != 0) ||
      (LoginRsp->InitiatorTaskTag != Session->InitiatorTaskTag)
      )
  {
    //
    // A Login Response with the C bit set to 1 MUST have the T bit set to 0.
    // The CSG in the Login Response MUST be the same with the I-end of this connection.
    // The T bit can't be 1 if the last Login Response sent by the initiator doesn't
    // initiate the transition.
    // The NSG MUST be the same with the I-end of this connection if Transit is required.
    // The ISID in the Login Response MUST be the same with this session.
    //
    return EFI_PROTOCOL_ERROR;
  }

  LoginRsp->StatSN   = NTOHL (LoginRsp->StatSN);
  LoginRsp->ExpCmdSN = NTOHL (LoginRsp->ExpCmdSN);
  LoginRsp->MaxCmdSN = NTOHL (LoginRsp->MaxCmdSN);

  if ((Conn->CurrentStage == ISCSI_SECURITY_NEGOTIATION) && (Conn->AuthStep == ISCSI_AUTH_INITIAL)) {
    //
    // If the Login Request is a leading Login Request, the target MUST use
    // the value presented in CmdSN as the target value for ExpCmdSN.
    //
    if ((Session->State == SESSION_STATE_FREE) && (Session->CmdSN != LoginRsp->ExpCmdSN)) {
      return EFI_PROTOCOL_ERROR;
    }

    //
    // It's the initial Login Response, initialize the local ExpStatSN, MaxCmdSN
    // and ExpCmdSN.
    //
    Conn->ExpStatSN   = LoginRsp->StatSN + 1;
    Session->MaxCmdSN = LoginRsp->MaxCmdSN;
    Session->ExpCmdSN = LoginRsp->ExpCmdSN;
  } else {
    //
    // Check the StatSN of this PDU.
    //
    Status = IScsiCheckSN (&Conn->ExpStatSN, LoginRsp->StatSN);
    if (!EFI_ERROR (Status)) {
      //
      // Update the MaxCmdSN and ExpCmdSN.
      //
      IScsiUpdateCmdSN (Session, LoginRsp->MaxCmdSN, LoginRsp->ExpCmdSN);
    } else {
      return Status;
    }
  }

  //
  // Trim off the header segment.
  //
  NetbufTrim (Pdu, sizeof (ISCSI_LOGIN_RESPONSE), NET_BUF_HEAD);

  //
  // Queue this login response first in case it's a partial response so that
  // later when the full response list is received we can combine these scattered
  // responses' data segment and then process it.
  //
  NET_GET_REF (Pdu);
  NetbufQueAppend (&Conn->RspQue, Pdu);

  Conn->PartialRspRcvd = Continue;
  if (Continue) {
    //
    // It is a partial response; must wait for another or more Request/Response
    // conversations to get the full response.
    //
    return EFI_SUCCESS;
  }

  switch (CurrentStage) {
    case ISCSI_SECURITY_NEGOTIATION:
      //
      // In security negotiation stage, let CHAP module handle it.
      //
      if (Session->AuthType != ISCSI_AUTH_TYPE_KRB) {
        Status = IScsiCHAPOnRspReceived (Conn);
      }

      break;

    case ISCSI_LOGIN_OPERATIONAL_NEGOTIATION:
      //
      // Response received with negotiation response on iSCSI parameters: check them.
      //
      Status = IScsiCheckOpParams (Conn);
      if (!EFI_ERROR (Status)) {
        Conn->ParamNegotiated = TRUE;
      }

      break;

    default:
      //
      // Should never get here.
      //
      Status = EFI_PROTOCOL_ERROR;
      break;
  }

  if (Transit && (Status == EFI_SUCCESS)) {
    //
    // Do the state transition.
    //
    Conn->CurrentStage = Conn->NextStage;

    if (Conn->CurrentStage == ISCSI_LOGIN_OPERATIONAL_NEGOTIATION) {
      Conn->NextStage = ISCSI_FULL_FEATURE_PHASE;
    } else {
      //
      // CurrentStage is iSCSI Full Feature. It is the Login-Final Response;
      // get the TSIH from the Login Response.
      //
      Session->Tsih = NTOHS (LoginRsp->Tsih);
    }
  }

  //
  // Flush the response(s) received.
  //
  NetbufQueFlush (&Conn->RspQue);

  return Status;
}

/**
  Updated the target information according the data received in the iSCSI
  login response with an target redirection status.

  @param[in, out] Session      The iSCSI session.
  @param[in]      Data         The data segment that should contain the
                               TargetAddress key-value list.
  @param[in]      Len          Length of the data.

  @retval EFI_SUCCESS          The target address is updated.
  @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
  @retval EFI_NOT_FOUND        The TargetAddress key is not found.
  @retval Others               Other errors as indicated.

**/
EFI_STATUS
IScsiUpdateTargetAddress (
  IN OUT ISCSI_SESSION  *Session,
  IN     CHAR8          *Data,
  IN     UINT32         Len
  )
{
  LIST_ENTRY                   *KeyValueList;
  CHAR8                        *TargetAddress;
  CHAR8                        *IpStr;
  EFI_STATUS                   Status;
  UINTN                        Number;
  UINT8                        IpMode;
  ISCSI_SESSION_CONFIG_NVDATA  *NvData;

  KeyValueList = IScsiBuildKeyValueList (Data, Len);
  if (KeyValueList == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Status = EFI_NOT_FOUND;
  NvData = &Session->ConfigData->SessionConfigData;

  while (TRUE) {
    TargetAddress = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_TARGET_ADDRESS);
    if (TargetAddress == NULL) {
      break;
    }

    //
    // RFC 3720 defines format of the TargetAddress=domainname[:port][,portal-group-tag]
    // The domainname can be specified as either a DNS host name, adotted-decimal IPv4 address,
    // or a bracketed IPv6 address as specified in [RFC2732].
    //
    if (NET_IS_DIGIT (TargetAddress[0])) {
      //
      // The domainname of the target is presented in a dotted-decimal IPv4 address format.
      //
      IpStr = TargetAddress;

      while ((*TargetAddress != '\0') && (*TargetAddress != ':') && (*TargetAddress != ',')) {
        //
        // NULL, ':', or ',' ends the IPv4 string.
        //
        TargetAddress++;
      }
    } else if (*TargetAddress == ISCSI_REDIRECT_ADDR_START_DELIMITER) {
      //
      // The domainname of the target is presented in a bracketed IPv6 address format.
      //
      TargetAddress++;
      IpStr = TargetAddress;
      while ((*TargetAddress != '\0') && (*TargetAddress != ISCSI_REDIRECT_ADDR_END_DELIMITER)) {
        //
        // ']' ends the IPv6 string.
        //
        TargetAddress++;
      }

      if (*TargetAddress != ISCSI_REDIRECT_ADDR_END_DELIMITER) {
        continue;
      }

      *TargetAddress = '\0';
      TargetAddress++;
    } else {
      //
      // The domainname of the target is presented in the format of a DNS host name.
      //
      IpStr = TargetAddress;

      while ((*TargetAddress != '\0') && (*TargetAddress != ':') && (*TargetAddress != ',')) {
        TargetAddress++;
      }

      NvData->DnsMode = TRUE;
    }

    //
    // Save the original user setting which specifies the proxy/virtual iSCSI target.
    //
    NvData->OriginalTargetPort = NvData->TargetPort;

    if (*TargetAddress == ',') {
      //
      // Comma and the portal group tag MUST be omitted if the TargetAddress is sent
      // as the result of a redirection.
      //
      continue;
    } else if (*TargetAddress == ':') {
      *TargetAddress = '\0';

      TargetAddress++;

      Number = AsciiStrDecimalToUintn (TargetAddress);
      if (Number > 0xFFFF) {
        continue;
      } else {
        NvData->TargetPort = (UINT16)Number;
      }
    } else {
      //
      // The string only contains the Target address. Use the well-known port.
      //
      NvData->TargetPort = ISCSI_WELL_KNOWN_PORT;
    }

    //
    // Save the original user setting which specifies the proxy/virtual iSCSI target.
    //
    CopyMem (&NvData->OriginalTargetIp, &NvData->TargetIp, sizeof (EFI_IP_ADDRESS));

    //
    // Update the target IP address.
    //
    if (NvData->IpMode < IP_MODE_AUTOCONFIG) {
      IpMode = NvData->IpMode;
    } else {
      IpMode = Session->ConfigData->AutoConfigureMode;
    }

    if (NvData->DnsMode) {
      //
      // Target address is expressed as URL format, just save it and
      // do DNS resolution when creating a TCP connection.
      //
      if (AsciiStrSize (IpStr) > sizeof (Session->ConfigData->SessionConfigData.TargetUrl)) {
        return EFI_INVALID_PARAMETER;
      }

      CopyMem (&Session->ConfigData->SessionConfigData.TargetUrl, IpStr, AsciiStrSize (IpStr));
    } else {
      Status = IScsiAsciiStrToIp (
                 IpStr,
                 IpMode,
                 &Session->ConfigData->SessionConfigData.TargetIp
                 );

      if (EFI_ERROR (Status)) {
        continue;
      } else {
        NvData->RedirectFlag = TRUE;
        break;
      }
    }
  }

  IScsiFreeKeyValueList (KeyValueList);

  return Status;
}

/**
  The callback function to free the net buffer list.

  @param[in]  Arg The opaque parameter.

**/
VOID
EFIAPI
IScsiFreeNbufList (
  VOID  *Arg
  )
{
  ASSERT (Arg != NULL);

  NetbufFreeList ((LIST_ENTRY *)Arg);
  FreePool (Arg);
}

/**
  The callback function called in NetBufFree; it does nothing.

  @param[in]   Arg  The opaque parameter.

**/
VOID
EFIAPI
IScsiNbufExtFree (
  VOID  *Arg
  )
{
}

/**
  Receive an iSCSI response PDU. An iSCSI response PDU contains an iSCSI PDU header and
  an optional data segment. The two parts will be put into two blocks of buffers in the
  net buffer. The digest check will be conducted in this function if needed and the digests
  will be trimmed from the PDU buffer.

  @param[in]  Conn         The iSCSI connection to receive data from.
  @param[out] Pdu          The received iSCSI pdu.
  @param[in]  Context      The context used to describe information on the caller provided
                           buffer to receive data segment of the iSCSI pdu. It is optional.
  @param[in]  HeaderDigest Whether there will be header digest received.
  @param[in]  DataDigest   Whether there will be data digest.
  @param[in]  TimeoutEvent The timeout event. It is optional.

  @retval EFI_SUCCESS          An iSCSI pdu is received.
  @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
  @retval EFI_PROTOCOL_ERROR   Some kind of iSCSI protocol error occurred.
  @retval Others               Other errors as indicated.

**/
EFI_STATUS
IScsiReceivePdu (
  IN ISCSI_CONNECTION         *Conn,
  OUT NET_BUF                 **Pdu,
  IN ISCSI_IN_BUFFER_CONTEXT  *Context  OPTIONAL,
  IN BOOLEAN                  HeaderDigest,
  IN BOOLEAN                  DataDigest,
  IN EFI_EVENT                TimeoutEvent OPTIONAL
  )
{
  LIST_ENTRY    *NbufList;
  UINT32        Len;
  NET_BUF       *PduHdr;
  UINT8         *Header;
  EFI_STATUS    Status;
  UINT32        PadLen;
  UINT32        InDataOffset;
  NET_FRAGMENT  Fragment[2];
  UINT32        FragmentCount;
  NET_BUF       *DataSeg;
  UINT32        PadAndCRC32[2];

  NbufList = AllocatePool (sizeof (LIST_ENTRY));
  if (NbufList == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  InitializeListHead (NbufList);

  //
  // The header digest will be received together with the PDU header, if exists.
  //
  Len    = sizeof (ISCSI_BASIC_HEADER) + (HeaderDigest ? sizeof (UINT32) : 0);
  PduHdr = NetbufAlloc (Len);
  if (PduHdr == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_EXIT;
  }

  Header = NetbufAllocSpace (PduHdr, Len, NET_BUF_TAIL);
  if (Header == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_EXIT;
  }

  InsertTailList (NbufList, &PduHdr->List);

  //
  // First step, receive the BHS of the PDU.
  //
  Status = TcpIoReceive (&Conn->TcpIo, PduHdr, FALSE, TimeoutEvent);

  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  if (HeaderDigest) {
    //
    // TODO: check the header-digest.
    //
    //
    // Trim off the digest.
    //
    NetbufTrim (PduHdr, sizeof (UINT32), NET_BUF_TAIL);
  }

  Len = ISCSI_GET_DATASEG_LEN (Header);
  if (Len == 0) {
    //
    // No data segment.
    //
    goto FORM_PDU;
  }

  //
  // Get the length of the padding bytes of the data segment.
  //
  PadLen = ISCSI_GET_PAD_LEN (Len);

  switch (ISCSI_GET_OPCODE (Header)) {
    case ISCSI_OPCODE_SCSI_DATA_IN:
      //
      // To reduce memory copy overhead, try to use the buffer described by Context
      // if the PDU is an iSCSI SCSI data.
      //
      InDataOffset = ISCSI_GET_BUFFER_OFFSET (Header);
      if ((Context == NULL) || ((InDataOffset + Len) > Context->InDataLen)) {
        Status = EFI_PROTOCOL_ERROR;
        goto ON_EXIT;
      }

      Fragment[0].Len  = Len;
      Fragment[0].Bulk = Context->InData + InDataOffset;

      if (DataDigest || (PadLen != 0)) {
        //
        // The data segment is padded. Use two fragments to receive it:
        // the first to receive the useful data; the second to receive the padding.
        //
        Fragment[1].Len  = PadLen + (DataDigest ? sizeof (UINT32) : 0);
        Fragment[1].Bulk = (UINT8 *)PadAndCRC32 + (4 - PadLen);

        FragmentCount = 2;
      } else {
        FragmentCount = 1;
      }

      DataSeg = NetbufFromExt (&Fragment[0], FragmentCount, 0, 0, IScsiNbufExtFree, NULL);
      if (DataSeg == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        goto ON_EXIT;
      }

      break;

    case ISCSI_OPCODE_SCSI_RSP:
    case ISCSI_OPCODE_NOP_IN:
    case ISCSI_OPCODE_LOGIN_RSP:
    case ISCSI_OPCODE_TEXT_RSP:
    case ISCSI_OPCODE_ASYNC_MSG:
    case ISCSI_OPCODE_REJECT:
    case ISCSI_OPCODE_VENDOR_T0:
    case ISCSI_OPCODE_VENDOR_T1:
    case ISCSI_OPCODE_VENDOR_T2:
      //
      // Allocate buffer to receive the data segment.
      //
      Len    += PadLen + (DataDigest ? sizeof (UINT32) : 0);
      DataSeg = NetbufAlloc (Len);
      if (DataSeg == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        goto ON_EXIT;
      }

      NetbufAllocSpace (DataSeg, Len, NET_BUF_TAIL);
      break;

    default:
      Status = EFI_PROTOCOL_ERROR;
      goto ON_EXIT;
  }

  InsertTailList (NbufList, &DataSeg->List);

  //
  // Receive the data segment with the data digest, if any.
  //
  Status = TcpIoReceive (&Conn->TcpIo, DataSeg, FALSE, TimeoutEvent);

  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  if (DataDigest) {
    //
    // TODO: Check the data digest.
    //
    NetbufTrim (DataSeg, sizeof (UINT32), NET_BUF_TAIL);
  }

  if (PadLen != 0) {
    //
    // Trim off the padding bytes in the data segment.
    //
    NetbufTrim (DataSeg, PadLen, NET_BUF_TAIL);
  }

FORM_PDU:
  //
  // Form the pdu from a list of pdu segments.
  //
  *Pdu = NetbufFromBufList (NbufList, 0, 0, IScsiFreeNbufList, NbufList);
  if (*Pdu == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
  }

ON_EXIT:

  if (EFI_ERROR (Status)) {
    //
    // Free the Nbufs in this NbufList and the NbufList itself.
    //
    IScsiFreeNbufList (NbufList);
  }

  return Status;
}

/**
  Check and get the result of the parameter negotiation.

  @param[in, out]  Conn          The connection in iSCSI login.

  @retval EFI_SUCCESS          The parameter check is passed and negotiation is finished.
  @retval EFI_PROTOCOL_ERROR   Some kind of iSCSI protocol error occurred.
  @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.

**/
EFI_STATUS
IScsiCheckOpParams (
  IN OUT ISCSI_CONNECTION  *Conn
  )
{
  EFI_STATUS     Status;
  LIST_ENTRY     *KeyValueList;
  CHAR8          *Data;
  UINT32         Len;
  ISCSI_SESSION  *Session;
  CHAR8          *Value;
  UINTN          NumericValue;

  ASSERT (Conn->RspQue.BufNum != 0);

  Session = Conn->Session;

  Len  = Conn->RspQue.BufSize;
  Data = AllocatePool (Len);
  if (Data == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  NetbufQueCopy (&Conn->RspQue, 0, Len, (UINT8 *)Data);

  Status = EFI_PROTOCOL_ERROR;

  //
  // Extract the Key-Value pairs into a list.
  //
  KeyValueList = IScsiBuildKeyValueList (Data, Len);
  if (KeyValueList == NULL) {
    FreePool (Data);
    return Status;
  }

  //
  // HeaderDigest
  //
  Value = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_HEADER_DIGEST);
  if (Value == NULL) {
    goto ON_ERROR;
  }

  if (AsciiStrCmp (Value, "CRC32") == 0) {
    if (Conn->HeaderDigest != IScsiDigestCRC32) {
      goto ON_ERROR;
    }
  } else if (AsciiStrCmp (Value, ISCSI_KEY_VALUE_NONE) == 0) {
    Conn->HeaderDigest = IScsiDigestNone;
  } else {
    goto ON_ERROR;
  }

  //
  // DataDigest
  //
  Value = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_DATA_DIGEST);
  if (Value == NULL) {
    goto ON_ERROR;
  }

  if (AsciiStrCmp (Value, "CRC32") == 0) {
    if (Conn->DataDigest != IScsiDigestCRC32) {
      goto ON_ERROR;
    }
  } else if (AsciiStrCmp (Value, ISCSI_KEY_VALUE_NONE) == 0) {
    Conn->DataDigest = IScsiDigestNone;
  } else {
    goto ON_ERROR;
  }

  //
  // ErrorRecoveryLevel: result function is Minimum.
  //
  Value = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_ERROR_RECOVERY_LEVEL);
  if (Value == NULL) {
    goto ON_ERROR;
  }

  NumericValue = IScsiNetNtoi (Value);
  if (NumericValue > 2) {
    goto ON_ERROR;
  }

  Session->ErrorRecoveryLevel = (UINT8)MIN (Session->ErrorRecoveryLevel, NumericValue);

  //
  // InitialR2T: result function is OR.
  //
  if (!Session->InitialR2T) {
    Value = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_INITIAL_R2T);
    if (Value == NULL) {
      goto ON_ERROR;
    }

    Session->InitialR2T = (BOOLEAN)(AsciiStrCmp (Value, "Yes") == 0);
  }

  //
  // ImmediateData: result function is AND.
  //
  Value = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_IMMEDIATE_DATA);
  if (Value == NULL) {
    goto ON_ERROR;
  }

  Session->ImmediateData = (BOOLEAN)(Session->ImmediateData && (BOOLEAN)(AsciiStrCmp (Value, "Yes") == 0));

  //
  // MaxRecvDataSegmentLength is declarative.
  //
  Value = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_MAX_RECV_DATA_SEGMENT_LENGTH);
  if (Value != NULL) {
    Conn->MaxRecvDataSegmentLength = (UINT32)IScsiNetNtoi (Value);
  }

  //
  // MaxBurstLength: result function is Minimum.
  //
  Value = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_MAX_BURST_LENGTH);
  if (Value == NULL) {
    goto ON_ERROR;
  }

  NumericValue            = IScsiNetNtoi (Value);
  Session->MaxBurstLength = (UINT32)MIN (Session->MaxBurstLength, NumericValue);

  //
  // FirstBurstLength: result function is Minimum. Irrelevant when InitialR2T=Yes and
  // ImmediateData=No.
  //
  if (!(Session->InitialR2T && !Session->ImmediateData)) {
    Value = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_FIRST_BURST_LENGTH);
    if (Value == NULL) {
      goto ON_ERROR;
    }

    NumericValue              = IScsiNetNtoi (Value);
    Session->FirstBurstLength = (UINT32)MIN (Session->FirstBurstLength, NumericValue);
  }

  //
  // MaxConnections: result function is Minimum.
  //
  Value = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_MAX_CONNECTIONS);
  if (Value == NULL) {
    goto ON_ERROR;
  }

  NumericValue = IScsiNetNtoi (Value);
  if ((NumericValue == 0) || (NumericValue > 65535)) {
    goto ON_ERROR;
  }

  Session->MaxConnections = (UINT32)MIN (Session->MaxConnections, NumericValue);

  //
  // DataPDUInOrder: result function is OR.
  //
  if (!Session->DataPDUInOrder) {
    Value = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_DATA_PDU_IN_ORDER);
    if (Value == NULL) {
      goto ON_ERROR;
    }

    Session->DataPDUInOrder = (BOOLEAN)(AsciiStrCmp (Value, "Yes") == 0);
  }

  //
  // DataSequenceInorder: result function is OR.
  //
  if (!Session->DataSequenceInOrder) {
    Value = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_DATA_SEQUENCE_IN_ORDER);
    if (Value == NULL) {
      goto ON_ERROR;
    }

    Session->DataSequenceInOrder = (BOOLEAN)(AsciiStrCmp (Value, "Yes") == 0);
  }

  //
  // DefaultTime2Wait: result function is Maximum.
  //
  Value = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_DEFAULT_TIME2WAIT);
  if (Value == NULL) {
    goto ON_ERROR;
  }

  NumericValue = IScsiNetNtoi (Value);
  if (NumericValue == 0) {
    Session->DefaultTime2Wait = 0;
  } else if (NumericValue > 3600) {
    goto ON_ERROR;
  } else {
    Session->DefaultTime2Wait = (UINT32)MAX (Session->DefaultTime2Wait, NumericValue);
  }

  //
  // DefaultTime2Retain: result function is Minimum.
  //
  Value = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_DEFAULT_TIME2RETAIN);
  if (Value == NULL) {
    goto ON_ERROR;
  }

  NumericValue = IScsiNetNtoi (Value);
  if (NumericValue == 0) {
    Session->DefaultTime2Retain = 0;
  } else if (NumericValue > 3600) {
    goto ON_ERROR;
  } else {
    Session->DefaultTime2Retain = (UINT32)MIN (Session->DefaultTime2Retain, NumericValue);
  }

  //
  // MaxOutstandingR2T: result function is Minimum.
  //
  Value = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_MAX_OUTSTANDING_R2T);
  if (Value == NULL) {
    goto ON_ERROR;
  }

  NumericValue = IScsiNetNtoi (Value);
  if ((NumericValue == 0) || (NumericValue > 65535)) {
    goto ON_ERROR;
  }

  Session->MaxOutstandingR2T = (UINT16)MIN (Session->MaxOutstandingR2T, NumericValue);

  //
  // Remove declarative key-value pairs, if any.
  //
  IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_SESSION_TYPE);
  IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_TARGET_ALIAS);
  IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_TARGET_PORTAL_GROUP_TAG);

  //
  // Remove the key-value that may not needed for result function is OR.
  //
  IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_INITIAL_R2T);
  IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_DATA_PDU_IN_ORDER);
  IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_DATA_SEQUENCE_IN_ORDER);

  //
  // Remove irrelevant parameter, if any.
  //
  if (Session->InitialR2T && !Session->ImmediateData) {
    IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_FIRST_BURST_LENGTH);
  }

  if (IsListEmpty (KeyValueList)) {
    //
    // Succeed if no more keys in the list.
    //
    Status = EFI_SUCCESS;
  }

ON_ERROR:

  IScsiFreeKeyValueList (KeyValueList);

  FreePool (Data);

  return Status;
}

/**
  Fill the operational parameters.

  @param[in]       Conn    The connection in iSCSI login.
  @param[in, out]  Pdu     The iSCSI login request PDU to fill the parameters.

**/
VOID
IScsiFillOpParams (
  IN     ISCSI_CONNECTION  *Conn,
  IN OUT NET_BUF           *Pdu
  )
{
  ISCSI_SESSION  *Session;
  CHAR8          Value[256];

  Session = Conn->Session;

  AsciiSPrint (Value, sizeof (Value), "%a", (Conn->HeaderDigest == IScsiDigestCRC32) ? "None,CRC32" : "None");
  IScsiAddKeyValuePair (Pdu, ISCSI_KEY_HEADER_DIGEST, Value);

  AsciiSPrint (Value, sizeof (Value), "%a", (Conn->DataDigest == IScsiDigestCRC32) ? "None,CRC32" : "None");
  IScsiAddKeyValuePair (Pdu, ISCSI_KEY_DATA_DIGEST, Value);

  AsciiSPrint (Value, sizeof (Value), "%d", Session->ErrorRecoveryLevel);
  IScsiAddKeyValuePair (Pdu, ISCSI_KEY_ERROR_RECOVERY_LEVEL, Value);

  AsciiSPrint (Value, sizeof (Value), "%a", Session->InitialR2T ? "Yes" : "No");
  IScsiAddKeyValuePair (Pdu, ISCSI_KEY_INITIAL_R2T, Value);

  AsciiSPrint (Value, sizeof (Value), "%a", Session->ImmediateData ? "Yes" : "No");
  IScsiAddKeyValuePair (Pdu, ISCSI_KEY_IMMEDIATE_DATA, Value);

  AsciiSPrint (Value, sizeof (Value), "%d", MAX_RECV_DATA_SEG_LEN_IN_FFP);
  IScsiAddKeyValuePair (Pdu, ISCSI_KEY_MAX_RECV_DATA_SEGMENT_LENGTH, Value);

  AsciiSPrint (Value, sizeof (Value), "%d", Session->MaxBurstLength);
  IScsiAddKeyValuePair (Pdu, ISCSI_KEY_MAX_BURST_LENGTH, Value);

  AsciiSPrint (Value, sizeof (Value), "%d", Session->FirstBurstLength);
  IScsiAddKeyValuePair (Pdu, ISCSI_KEY_FIRST_BURST_LENGTH, Value);

  AsciiSPrint (Value, sizeof (Value), "%d", Session->MaxConnections);
  IScsiAddKeyValuePair (Pdu, ISCSI_KEY_MAX_CONNECTIONS, Value);

  AsciiSPrint (Value, sizeof (Value), "%a", Session->DataPDUInOrder ? "Yes" : "No");
  IScsiAddKeyValuePair (Pdu, ISCSI_KEY_DATA_PDU_IN_ORDER, Value);

  AsciiSPrint (Value, sizeof (Value), "%a", Session->DataSequenceInOrder ? "Yes" : "No");
  IScsiAddKeyValuePair (Pdu, ISCSI_KEY_DATA_SEQUENCE_IN_ORDER, Value);

  AsciiSPrint (Value, sizeof (Value), "%d", Session->DefaultTime2Wait);
  IScsiAddKeyValuePair (Pdu, ISCSI_KEY_DEFAULT_TIME2WAIT, Value);

  AsciiSPrint (Value, sizeof (Value), "%d", Session->DefaultTime2Retain);
  IScsiAddKeyValuePair (Pdu, ISCSI_KEY_DEFAULT_TIME2RETAIN, Value);

  AsciiSPrint (Value, sizeof (Value), "%d", Session->MaxOutstandingR2T);
  IScsiAddKeyValuePair (Pdu, ISCSI_KEY_MAX_OUTSTANDING_R2T, Value);
}

/**
  Pad the iSCSI AHS or data segment to an integer number of 4 byte words.

  @param[in, out]  Pdu         The iSCSI pdu which contains segments to pad.
  @param[in]       Len         The length of the last segment in the PDU.

  @retval EFI_SUCCESS          The segment is padded or there is no need to pad it.
  @retval EFI_OUT_OF_RESOURCES There is not enough remaining free space to add the
                               padding bytes.
**/
EFI_STATUS
IScsiPadSegment (
  IN OUT NET_BUF  *Pdu,
  IN     UINT32   Len
  )
{
  UINT32  PadLen;
  UINT8   *Data;

  PadLen = ISCSI_GET_PAD_LEN (Len);

  if (PadLen != 0) {
    Data = NetbufAllocSpace (Pdu, PadLen, NET_BUF_TAIL);
    if (Data == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    ZeroMem (Data, PadLen);
  }

  return EFI_SUCCESS;
}

/**
  Build a key-value list from the data segment.

  @param[in]  Data The data segment containing the key-value pairs.
  @param[in]  Len  Length of the data segment.

  @return The key-value list.
  @retval NULL Other errors as indicated.

**/
LIST_ENTRY *
IScsiBuildKeyValueList (
  IN CHAR8   *Data,
  IN UINT32  Len
  )
{
  LIST_ENTRY            *ListHead;
  ISCSI_KEY_VALUE_PAIR  *KeyValuePair;

  ListHead = AllocatePool (sizeof (LIST_ENTRY));
  if (ListHead == NULL) {
    return NULL;
  }

  InitializeListHead (ListHead);

  while (Len > 0) {
    KeyValuePair = AllocatePool (sizeof (ISCSI_KEY_VALUE_PAIR));
    if (KeyValuePair == NULL) {
      goto ON_ERROR;
    }

    InitializeListHead (&KeyValuePair->List);

    KeyValuePair->Key = Data;

    while ((Len > 0) && (*Data != '=')) {
      Len--;
      Data++;
    }

    if (*Data == '=') {
      *Data = '\0';

      Data++;
      Len--;
    } else {
      FreePool (KeyValuePair);
      goto ON_ERROR;
    }

    KeyValuePair->Value = Data;

    InsertTailList (ListHead, &KeyValuePair->List);

    Data += AsciiStrLen (KeyValuePair->Value) + 1;
    Len  -= (UINT32)AsciiStrLen (KeyValuePair->Value) + 1;
  }

  return ListHead;

ON_ERROR:

  IScsiFreeKeyValueList (ListHead);

  return NULL;
}

/**
  Get the value string by the key name from the key-value list. If found,
  the key-value entry will be removed from the list.

  @param[in, out]  KeyValueList  The key-value list.
  @param[in]       Key           The key name to find.

  @return The value string.
  @retval NULL The key value pair cannot be found.

**/
CHAR8 *
IScsiGetValueByKeyFromList (
  IN OUT LIST_ENTRY  *KeyValueList,
  IN     CHAR8       *Key
  )
{
  LIST_ENTRY            *Entry;
  ISCSI_KEY_VALUE_PAIR  *KeyValuePair;
  CHAR8                 *Value;

  Value = NULL;

  NET_LIST_FOR_EACH (Entry, KeyValueList) {
    KeyValuePair = NET_LIST_USER_STRUCT (Entry, ISCSI_KEY_VALUE_PAIR, List);

    if (AsciiStrCmp (KeyValuePair->Key, Key) == 0) {
      Value = KeyValuePair->Value;

      RemoveEntryList (&KeyValuePair->List);
      FreePool (KeyValuePair);
      break;
    }
  }

  return Value;
}

/**
  Free the key-value list.

  @param[in]  KeyValueList The key-value list.

**/
VOID
IScsiFreeKeyValueList (
  IN LIST_ENTRY  *KeyValueList
  )
{
  LIST_ENTRY            *Entry;
  ISCSI_KEY_VALUE_PAIR  *KeyValuePair;

  while (!IsListEmpty (KeyValueList)) {
    Entry        = NetListRemoveHead (KeyValueList);
    KeyValuePair = NET_LIST_USER_STRUCT (Entry, ISCSI_KEY_VALUE_PAIR, List);

    FreePool (KeyValuePair);
  }

  FreePool (KeyValueList);
}

/**
  Normalize the iSCSI name according to RFC.

  @param[in, out]  Name       The iSCSI name.
  @param[in]       Len        Length of the iSCSI name.

  @retval EFI_SUCCESS        The iSCSI name is valid and normalized.
  @retval EFI_PROTOCOL_ERROR The iSCSI name is malformatted or not in the IQN format.

**/
EFI_STATUS
IScsiNormalizeName (
  IN OUT CHAR8  *Name,
  IN     UINTN  Len
  )
{
  UINTN  Index;

  for (Index = 0; Index < Len; Index++) {
    if (NET_IS_UPPER_CASE_CHAR (Name[Index])) {
      //
      // Convert the upper-case characters to lower-case ones.
      //
      Name[Index] = (CHAR8)(Name[Index] - 'A' + 'a');
    }

    if (!NET_IS_LOWER_CASE_CHAR (Name[Index]) &&
        !NET_IS_DIGIT (Name[Index]) &&
        (Name[Index] != '-') &&
        (Name[Index] != '.') &&
        (Name[Index] != ':')
        )
    {
      //
      // ASCII dash, dot, colon lower-case characters and digit characters
      // are allowed.
      //
      return EFI_PROTOCOL_ERROR;
    }
  }

  if ((Len < 4) || (CompareMem (Name, "iqn.", 4) != 0)) {
    //
    // Only IQN format is accepted now.
    //
    return EFI_PROTOCOL_ERROR;
  }

  return EFI_SUCCESS;
}

/**
  Create an iSCSI task control block.

  @param[in]   Conn           The connection on which the task control block will be created.
  @param[out]  Tcb            The newly created task control block.

  @retval EFI_SUCCESS          The task control block is created.
  @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
  @retval EFI_NOT_READY        The target cannot accept new commands.

**/
EFI_STATUS
IScsiNewTcb (
  IN  ISCSI_CONNECTION  *Conn,
  OUT ISCSI_TCB         **Tcb
  )
{
  ISCSI_SESSION  *Session;
  ISCSI_TCB      *NewTcb;

  ASSERT (Tcb != NULL);

  Session = Conn->Session;

  if (ISCSI_SEQ_GT (Session->CmdSN, Session->MaxCmdSN)) {
    return EFI_NOT_READY;
  }

  NewTcb = AllocateZeroPool (sizeof (ISCSI_TCB));
  if (NewTcb == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  InitializeListHead (&NewTcb->Link);

  NewTcb->SoFarInOrder     = TRUE;
  NewTcb->InitiatorTaskTag = Session->InitiatorTaskTag;
  NewTcb->CmdSN            = Session->CmdSN;
  NewTcb->Conn             = Conn;

  InsertTailList (&Session->TcbList, &NewTcb->Link);

  //
  // Advance the initiator task tag.
  //
  Session->InitiatorTaskTag++;
  Session->CmdSN++;

  *Tcb = NewTcb;

  return EFI_SUCCESS;
}

/**
  Delete the tcb from the connection and destroy it.

  @param[in]  Tcb The tcb to delete.

**/
VOID
IScsiDelTcb (
  IN ISCSI_TCB  *Tcb
  )
{
  RemoveEntryList (&Tcb->Link);

  FreePool (Tcb);
}

/**
  Create a data segment, pad it, and calculate the CRC if needed.

  @param[in]  Data       The data to fill into the data segment.
  @param[in]  Len        Length of the data.
  @param[in]  DataDigest Whether to calculate CRC for this data segment.

  @return The net buffer wrapping the data segment.

**/
NET_BUF *
IScsiNewDataSegment (
  IN UINT8    *Data,
  IN UINT32   Len,
  IN BOOLEAN  DataDigest
  )
{
  NET_FRAGMENT  Fragment[2];
  UINT32        FragmentCount;
  UINT32        PadLen;
  NET_BUF       *DataSeg;

  Fragment[0].Len  = Len;
  Fragment[0].Bulk = Data;

  PadLen = ISCSI_GET_PAD_LEN (Len);
  if (PadLen != 0) {
    Fragment[1].Len  = PadLen;
    Fragment[1].Bulk = (UINT8 *)&mDataSegPad;

    FragmentCount = 2;
  } else {
    FragmentCount = 1;
  }

  DataSeg = NetbufFromExt (&Fragment[0], FragmentCount, 0, 0, IScsiNbufExtFree, NULL);

  return DataSeg;
}

/**
  Create a iSCSI SCSI command PDU to encapsulate the command issued
  by SCSI through the EXT SCSI PASS THRU Protocol.

  @param[in]  Packet The EXT SCSI PASS THRU request packet containing the SCSI command.
  @param[in]  Lun    The LUN.
  @param[in]  Tcb    The tcb associated with this SCSI command.

  @return The  created iSCSI SCSI command PDU.
  @retval NULL Other errors as indicated.

**/
NET_BUF *
IScsiNewScsiCmdPdu (
  IN EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET  *Packet,
  IN UINT64                                      Lun,
  IN ISCSI_TCB                                   *Tcb
  )
{
  LIST_ENTRY                      *NbufList;
  NET_BUF                         *Pdu;
  NET_BUF                         *PduHeader;
  NET_BUF                         *DataSeg;
  SCSI_COMMAND                    *ScsiCmd;
  UINT8                           AHSLength;
  UINT32                          Length;
  ISCSI_ADDITIONAL_HEADER         *Header;
  ISCSI_BI_EXP_READ_DATA_LEN_AHS  *BiExpReadDataLenAHS;
  ISCSI_SESSION                   *Session;
  UINT32                          ImmediateDataLen;

  AHSLength = 0;

  if (Packet->DataDirection == DataBi) {
    //
    // Bidirectional Read/Write command, the bidirectional expected
    // read data length AHS is required.
    //
    AHSLength += sizeof (ISCSI_BI_EXP_READ_DATA_LEN_AHS);
  }

  if (Packet->CdbLength > 16) {
    //
    // The CDB exceeds 16 bytes. An extended CDB AHS is required.
    //
    AHSLength = (UINT8)(AHSLength + ISCSI_ROUNDUP (Packet->CdbLength - 16) + sizeof (ISCSI_ADDITIONAL_HEADER));
  }

  Length    = sizeof (SCSI_COMMAND) + AHSLength;
  PduHeader = NetbufAlloc (Length);
  if (PduHeader == NULL) {
    return NULL;
  }

  ScsiCmd = (SCSI_COMMAND *)NetbufAllocSpace (PduHeader, Length, NET_BUF_TAIL);
  if (ScsiCmd == NULL) {
    NetbufFree (PduHeader);
    return NULL;
  }

  Header = (ISCSI_ADDITIONAL_HEADER *)(ScsiCmd + 1);

  ZeroMem (ScsiCmd, Length);

  ISCSI_SET_OPCODE (ScsiCmd, ISCSI_OPCODE_SCSI_CMD, 0);
  ISCSI_SET_FLAG (ScsiCmd, ISCSI_TASK_ATTR_SIMPLE);

  //
  // Set the READ/WRITE flags according to the IO type of this request.
  //
  switch (Packet->DataDirection) {
    case DataIn:
      ISCSI_SET_FLAG (ScsiCmd, SCSI_CMD_PDU_FLAG_READ);
      ScsiCmd->ExpDataXferLength = NTOHL (Packet->InTransferLength);
      break;

    case DataOut:
      ISCSI_SET_FLAG (ScsiCmd, SCSI_CMD_PDU_FLAG_WRITE);
      ScsiCmd->ExpDataXferLength = NTOHL (Packet->OutTransferLength);
      break;

    case DataBi:
      ISCSI_SET_FLAG (ScsiCmd, SCSI_CMD_PDU_FLAG_READ | SCSI_CMD_PDU_FLAG_WRITE);
      ScsiCmd->ExpDataXferLength = NTOHL (Packet->OutTransferLength);

      //
      // Fill the bidirectional expected read data length AHS.
      //
      BiExpReadDataLenAHS = (ISCSI_BI_EXP_READ_DATA_LEN_AHS *)Header;
      Header              = (ISCSI_ADDITIONAL_HEADER *)(BiExpReadDataLenAHS + 1);

      BiExpReadDataLenAHS->Length            = NTOHS (5);
      BiExpReadDataLenAHS->Type              = ISCSI_AHS_TYPE_BI_EXP_READ_DATA_LEN;
      BiExpReadDataLenAHS->ExpReadDataLength = NTOHL (Packet->InTransferLength);

      break;
  }

  ScsiCmd->TotalAHSLength = AHSLength;
  CopyMem (ScsiCmd->Lun, &Lun, sizeof (ScsiCmd->Lun));
  ScsiCmd->InitiatorTaskTag = NTOHL (Tcb->InitiatorTaskTag);
  ScsiCmd->CmdSN            = NTOHL (Tcb->CmdSN);
  ScsiCmd->ExpStatSN        = NTOHL (Tcb->Conn->ExpStatSN);

  CopyMem (ScsiCmd->Cdb, Packet->Cdb, sizeof (ScsiCmd->Cdb));

  if (Packet->CdbLength > 16) {
    Header->Length = NTOHS ((UINT16)(Packet->CdbLength - 15));
    Header->Type   = ISCSI_AHS_TYPE_EXT_CDB;

    CopyMem (Header + 1, (UINT8 *)Packet->Cdb + 16, Packet->CdbLength - 16);
  }

  Pdu              = PduHeader;
  Session          = Tcb->Conn->Session;
  ImmediateDataLen = 0;

  if (Session->ImmediateData && (Packet->OutTransferLength != 0)) {
    //
    // Send immediate data in this SCSI Command PDU. The length of the immediate
    // data is the minimum of FirstBurstLength, the data length to be xfered, and
    // the MaxRecvdataSegmentLength on this connection.
    //
    ImmediateDataLen = MIN (Session->FirstBurstLength, Packet->OutTransferLength);
    ImmediateDataLen = MIN (ImmediateDataLen, Tcb->Conn->MaxRecvDataSegmentLength);

    //
    // Update the data segment length in the PDU header.
    //
    ISCSI_SET_DATASEG_LEN (ScsiCmd, ImmediateDataLen);

    //
    // Create the data segment.
    //
    DataSeg = IScsiNewDataSegment ((UINT8 *)Packet->OutDataBuffer, ImmediateDataLen, FALSE);
    if (DataSeg == NULL) {
      NetbufFree (PduHeader);
      Pdu = NULL;
      goto ON_EXIT;
    }

    NbufList = AllocatePool (sizeof (LIST_ENTRY));
    if (NbufList == NULL) {
      NetbufFree (PduHeader);
      NetbufFree (DataSeg);

      Pdu = NULL;
      goto ON_EXIT;
    }

    InitializeListHead (NbufList);
    InsertTailList (NbufList, &PduHeader->List);
    InsertTailList (NbufList, &DataSeg->List);

    Pdu = NetbufFromBufList (NbufList, 0, 0, IScsiFreeNbufList, NbufList);
    if (Pdu == NULL) {
      IScsiFreeNbufList (NbufList);
    }
  }

  if (Session->InitialR2T ||
      (ImmediateDataLen == Session->FirstBurstLength) ||
      (ImmediateDataLen == Packet->OutTransferLength)
      )
  {
    //
    // Unsolicited data out sequence is not allowed,
    // or FirstBustLength data is already sent out by immediate data,
    // or all the OUT data accompany this SCSI packet are sent as
    // immediate data. The final flag should be set on this SCSI Command
    // PDU.
    //
    ISCSI_SET_FLAG (ScsiCmd, ISCSI_BHS_FLAG_FINAL);
  }

ON_EXIT:

  return Pdu;
}

/**
  Create a new iSCSI SCSI Data Out PDU.

  @param[in]  Data   The data to put into the Data Out PDU.
  @param[in]  Len    Length of the data.
  @param[in]  DataSN The DataSN of the Data Out PDU.
  @param[in]  Tcb    The task control block of this Data Out PDU.
  @param[in]  Lun    The LUN.

  @return The net buffer wrapping the Data Out PDU.
  @retval NULL Other errors as indicated.

**/
NET_BUF *
IScsiNewDataOutPdu (
  IN UINT8      *Data,
  IN UINT32     Len,
  IN UINT32     DataSN,
  IN ISCSI_TCB  *Tcb,
  IN UINT64     Lun
  )
{
  LIST_ENTRY           *NbufList;
  NET_BUF              *PduHdr;
  NET_BUF              *DataSeg;
  NET_BUF              *Pdu;
  ISCSI_SCSI_DATA_OUT  *DataOutHdr;
  ISCSI_XFER_CONTEXT   *XferContext;

  NbufList = AllocatePool (sizeof (LIST_ENTRY));
  if (NbufList == NULL) {
    return NULL;
  }

  InitializeListHead (NbufList);

  //
  // Allocate memory for the BHS.
  //
  PduHdr = NetbufAlloc (sizeof (ISCSI_SCSI_DATA_OUT));
  if (PduHdr == NULL) {
    FreePool (NbufList);
    return NULL;
  }

  //
  // Insert the BHS into the buffer list.
  //
  InsertTailList (NbufList, &PduHdr->List);

  DataOutHdr = (ISCSI_SCSI_DATA_OUT *)NetbufAllocSpace (PduHdr, sizeof (ISCSI_SCSI_DATA_OUT), NET_BUF_TAIL);
  if (DataOutHdr == NULL) {
    IScsiFreeNbufList (NbufList);
    return NULL;
  }

  XferContext = &Tcb->XferContext;

  ZeroMem (DataOutHdr, sizeof (ISCSI_SCSI_DATA_OUT));

  //
  // Set the flags and fields of the Data Out PDU BHS.
  //
  ISCSI_SET_OPCODE (DataOutHdr, ISCSI_OPCODE_SCSI_DATA_OUT, 0);
  ISCSI_SET_DATASEG_LEN (DataOutHdr, Len);

  DataOutHdr->InitiatorTaskTag  = HTONL (Tcb->InitiatorTaskTag);
  DataOutHdr->TargetTransferTag = HTONL (XferContext->TargetTransferTag);
  DataOutHdr->ExpStatSN         = HTONL (Tcb->Conn->ExpStatSN);
  DataOutHdr->DataSN            = HTONL (DataSN);
  DataOutHdr->BufferOffset      = HTONL (XferContext->Offset);

  if (XferContext->TargetTransferTag != ISCSI_RESERVED_TAG) {
    CopyMem (&DataOutHdr->Lun, &Lun, sizeof (DataOutHdr->Lun));
  }

  //
  // Build the data segment for this Data Out PDU.
  //
  DataSeg = IScsiNewDataSegment (Data, Len, FALSE);
  if (DataSeg == NULL) {
    IScsiFreeNbufList (NbufList);
    return NULL;
  }

  //
  // Put the data segment into the buffer list and combine it with the BHS
  // into a full Data Out PDU.
  //
  InsertTailList (NbufList, &DataSeg->List);
  Pdu = NetbufFromBufList (NbufList, 0, 0, IScsiFreeNbufList, NbufList);
  if (Pdu == NULL) {
    IScsiFreeNbufList (NbufList);
  }

  return Pdu;
}

/**
  Generate a consecutive sequence of iSCSI SCSI Data Out PDUs.

  @param[in]  Data The data  which will be carried by the sequence of iSCSI SCSI Data Out PDUs.
  @param[in]  Tcb  The task control block of the data to send out.
  @param[in]  Lun  The LUN the data will be sent to.

  @return A list of net buffers with each of them wrapping an iSCSI SCSI Data Out PDU.
  @retval NULL Other errors as indicated.

**/
LIST_ENTRY *
IScsiGenerateDataOutPduSequence (
  IN UINT8      *Data,
  IN ISCSI_TCB  *Tcb,
  IN UINT64     Lun
  )
{
  LIST_ENTRY          *PduList;
  UINT32              DataSN;
  UINT32              DataLen;
  NET_BUF             *DataOutPdu;
  ISCSI_CONNECTION    *Conn;
  ISCSI_XFER_CONTEXT  *XferContext;
  UINT8               *DataOutPacket;

  PduList = AllocatePool (sizeof (LIST_ENTRY));
  if (PduList == NULL) {
    return NULL;
  }

  InitializeListHead (PduList);

  DataSN      = 0;
  Conn        = Tcb->Conn;
  DataOutPdu  = NULL;
  XferContext = &Tcb->XferContext;

  while (XferContext->DesiredLength > 0) {
    //
    // Determine the length of data this Data Out PDU can carry.
    //
    DataLen = MIN (XferContext->DesiredLength, Conn->MaxRecvDataSegmentLength);

    //
    // Create a Data Out PDU.
    //
    DataOutPdu = IScsiNewDataOutPdu (Data, DataLen, DataSN, Tcb, Lun);
    if (DataOutPdu == NULL) {
      IScsiFreeNbufList (PduList);
      PduList = NULL;

      goto ON_EXIT;
    }

    InsertTailList (PduList, &DataOutPdu->List);

    //
    // Update the context and DataSN.
    //
    Data                       += DataLen;
    XferContext->Offset        += DataLen;
    XferContext->DesiredLength -= DataLen;
    DataSN++;
  }

  //
  // Set the F bit for the last data out PDU in this sequence.
  //
  DataOutPacket = NetbufGetByte (DataOutPdu, 0, NULL);
  if (DataOutPacket == NULL) {
    IScsiFreeNbufList (PduList);
    PduList = NULL;
    goto ON_EXIT;
  }

  ISCSI_SET_FLAG (DataOutPacket, ISCSI_BHS_FLAG_FINAL);

ON_EXIT:

  return PduList;
}

/**
  Send the Data in a sequence of Data Out PDUs one by one.

  @param[in]  Data            The data to carry by Data Out PDUs.
  @param[in]  Lun             The LUN the data will be sent to.
  @param[in]  Tcb             The task control block.

  @retval EFI_SUCCESS          The data is sent out to the LUN.
  @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
  @retval Others               Other errors as indicated.

**/
EFI_STATUS
IScsiSendDataOutPduSequence (
  IN UINT8      *Data,
  IN UINT64     Lun,
  IN ISCSI_TCB  *Tcb
  )
{
  LIST_ENTRY  *DataOutPduList;
  LIST_ENTRY  *Entry;
  NET_BUF     *Pdu;
  EFI_STATUS  Status;

  //
  // Generate the Data Out PDU sequence.
  //
  DataOutPduList = IScsiGenerateDataOutPduSequence (Data, Tcb, Lun);
  if (DataOutPduList == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Status = EFI_SUCCESS;

  //
  // Send the Data Out PDU's one by one.
  //
  NET_LIST_FOR_EACH (Entry, DataOutPduList) {
    Pdu = NET_LIST_USER_STRUCT (Entry, NET_BUF, List);

    Status = TcpIoTransmit (&Tcb->Conn->TcpIo, Pdu);

    if (EFI_ERROR (Status)) {
      break;
    }
  }

  IScsiFreeNbufList (DataOutPduList);

  return Status;
}

/**
  Process the received iSCSI SCSI Data In PDU.

  @param[in]        Pdu      The Data In PDU received.
  @param[in]        Tcb      The task control block.
  @param[in, out]   Packet   The EXT SCSI PASS THRU request packet.

  @retval EFI_SUCCESS          The check on the Data IN PDU is passed and some update
                               actions are taken.
  @retval EFI_PROTOCOL_ERROR   Some kind of iSCSI protocol error occurred.
  @retval EFI_BAD_BUFFER_SIZEE The buffer was not the proper size for the request.
  @retval Others               Other errors as indicated.

**/
EFI_STATUS
IScsiOnDataInRcvd (
  IN NET_BUF                                         *Pdu,
  IN ISCSI_TCB                                       *Tcb,
  IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET  *Packet
  )
{
  ISCSI_SCSI_DATA_IN  *DataInHdr;
  EFI_STATUS          Status;

  DataInHdr = (ISCSI_SCSI_DATA_IN *)NetbufGetByte (Pdu, 0, NULL);
  if (DataInHdr == NULL) {
    return EFI_PROTOCOL_ERROR;
  }

  DataInHdr->InitiatorTaskTag = NTOHL (DataInHdr->InitiatorTaskTag);
  DataInHdr->ExpCmdSN         = NTOHL (DataInHdr->ExpCmdSN);
  DataInHdr->MaxCmdSN         = NTOHL (DataInHdr->MaxCmdSN);
  DataInHdr->DataSN           = NTOHL (DataInHdr->DataSN);

  //
  // Check the DataSN.
  //
  Status = IScsiCheckSN (&Tcb->ExpDataSN, DataInHdr->DataSN);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  if (DataInHdr->InitiatorTaskTag != Tcb->InitiatorTaskTag) {
    return EFI_PROTOCOL_ERROR;
  }

  //
  // Update the command related sequence numbers.
  //
  IScsiUpdateCmdSN (Tcb->Conn->Session, DataInHdr->MaxCmdSN, DataInHdr->ExpCmdSN);

  if (ISCSI_FLAG_ON (DataInHdr, SCSI_DATA_IN_PDU_FLAG_STATUS_VALID)) {
    if (!ISCSI_FLAG_ON (DataInHdr, ISCSI_BHS_FLAG_FINAL)) {
      //
      // The S bit is on but the F bit is off.
      //
      return EFI_PROTOCOL_ERROR;
    }

    Tcb->StatusXferd = TRUE;

    if (ISCSI_FLAG_ON (DataInHdr, SCSI_DATA_IN_PDU_FLAG_OVERFLOW | SCSI_DATA_IN_PDU_FLAG_UNDERFLOW)) {
      //
      // Underflow and Overflow are mutual flags.
      //
      return EFI_PROTOCOL_ERROR;
    }

    //
    // S bit is on, the StatSN is valid.
    //
    Status = IScsiCheckSN (&Tcb->Conn->ExpStatSN, NTOHL (DataInHdr->StatSN));
    if (EFI_ERROR (Status)) {
      return Status;
    }

    Packet->HostAdapterStatus = 0;
    Packet->TargetStatus      = DataInHdr->Status;

    if (ISCSI_FLAG_ON (DataInHdr, SCSI_RSP_PDU_FLAG_OVERFLOW)) {
      Packet->InTransferLength += NTOHL (DataInHdr->ResidualCount);
      Status                    = EFI_BAD_BUFFER_SIZE;
    }

    if (ISCSI_FLAG_ON (DataInHdr, SCSI_RSP_PDU_FLAG_UNDERFLOW)) {
      Packet->InTransferLength -= NTOHL (DataInHdr->ResidualCount);
    }
  }

  return Status;
}

/**
  Process the received iSCSI R2T PDU.

  @param[in]       Pdu       The R2T PDU received.
  @param[in]       Tcb       The task control block.
  @param[in]       Lun       The Lun.
  @param[in, out]  Packet    The EXT SCSI PASS THRU request packet.

  @retval EFI_SUCCESS        The R2T PDU is valid and the solicited data is sent out.
  @retval EFI_PROTOCOL_ERROR Some kind of iSCSI protocol error occurred.
  @retval Others             Other errors as indicated.

**/
EFI_STATUS
IScsiOnR2TRcvd (
  IN NET_BUF                                         *Pdu,
  IN ISCSI_TCB                                       *Tcb,
  IN UINT64                                          Lun,
  IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET  *Packet
  )
{
  ISCSI_READY_TO_TRANSFER  *R2THdr;
  EFI_STATUS               Status;
  ISCSI_XFER_CONTEXT       *XferContext;
  UINT8                    *Data;

  R2THdr = (ISCSI_READY_TO_TRANSFER *)NetbufGetByte (Pdu, 0, NULL);
  if (R2THdr == NULL) {
    return EFI_PROTOCOL_ERROR;
  }

  R2THdr->InitiatorTaskTag          = NTOHL (R2THdr->InitiatorTaskTag);
  R2THdr->TargetTransferTag         = NTOHL (R2THdr->TargetTransferTag);
  R2THdr->StatSN                    = NTOHL (R2THdr->StatSN);
  R2THdr->R2TSeqNum                 = NTOHL (R2THdr->R2TSeqNum);
  R2THdr->BufferOffset              = NTOHL (R2THdr->BufferOffset);
  R2THdr->DesiredDataTransferLength = NTOHL (R2THdr->DesiredDataTransferLength);

  if ((R2THdr->InitiatorTaskTag != Tcb->InitiatorTaskTag) || !ISCSI_SEQ_EQ (R2THdr->StatSN, Tcb->Conn->ExpStatSN)) {
    return EFI_PROTOCOL_ERROR;
  }

  //
  // Check the sequence number.
  //
  Status = IScsiCheckSN (&Tcb->ExpDataSN, R2THdr->R2TSeqNum);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  XferContext                    = &Tcb->XferContext;
  XferContext->TargetTransferTag = R2THdr->TargetTransferTag;
  XferContext->Offset            = R2THdr->BufferOffset;
  XferContext->DesiredLength     = R2THdr->DesiredDataTransferLength;

  if (((XferContext->Offset + XferContext->DesiredLength) > Packet->OutTransferLength) ||
      (XferContext->DesiredLength > Tcb->Conn->Session->MaxBurstLength)
      )
  {
    return EFI_PROTOCOL_ERROR;
  }

  //
  // Send the data solicited by this R2T.
  //
  Data   = (UINT8 *)Packet->OutDataBuffer + XferContext->Offset;
  Status = IScsiSendDataOutPduSequence (Data, Lun, Tcb);

  return Status;
}

/**
  Process the received iSCSI SCSI Response PDU.

  @param[in]       Pdu      The Response PDU received.
  @param[in]       Tcb      The task control block.
  @param[in, out]  Packet   The EXT SCSI PASS THRU request packet.

  @retval EFI_SUCCESS        The Response PDU is processed.
  @retval EFI_PROTOCOL_ERROR Some kind of iSCSI protocol error occurred.
  @retval EFI_BAD_BUFFER_SIZEE The buffer was not the proper size for the request.
  @retval Others             Other errors as indicated.

**/
EFI_STATUS
IScsiOnScsiRspRcvd (
  IN NET_BUF                                         *Pdu,
  IN ISCSI_TCB                                       *Tcb,
  IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET  *Packet
  )
{
  SCSI_RESPONSE     *ScsiRspHdr;
  ISCSI_SENSE_DATA  *SenseData;
  EFI_STATUS        Status;
  UINT32            DataSegLen;

  ScsiRspHdr = (SCSI_RESPONSE *)NetbufGetByte (Pdu, 0, NULL);
  if (ScsiRspHdr == NULL) {
    return EFI_PROTOCOL_ERROR;
  }

  ScsiRspHdr->InitiatorTaskTag = NTOHL (ScsiRspHdr->InitiatorTaskTag);
  if (ScsiRspHdr->InitiatorTaskTag != Tcb->InitiatorTaskTag) {
    return EFI_PROTOCOL_ERROR;
  }

  ScsiRspHdr->StatSN = NTOHL (ScsiRspHdr->StatSN);

  Status = IScsiCheckSN (&Tcb->Conn->ExpStatSN, ScsiRspHdr->StatSN);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  ScsiRspHdr->MaxCmdSN = NTOHL (ScsiRspHdr->MaxCmdSN);
  ScsiRspHdr->ExpCmdSN = NTOHL (ScsiRspHdr->ExpCmdSN);
  IScsiUpdateCmdSN (Tcb->Conn->Session, ScsiRspHdr->MaxCmdSN, ScsiRspHdr->ExpCmdSN);

  Tcb->StatusXferd = TRUE;

  Packet->HostAdapterStatus = ScsiRspHdr->Response;
  if (Packet->HostAdapterStatus != ISCSI_SERVICE_RSP_COMMAND_COMPLETE_AT_TARGET) {
    return EFI_SUCCESS;
  }

  Packet->TargetStatus = ScsiRspHdr->Status;

  if (ISCSI_FLAG_ON (ScsiRspHdr, SCSI_RSP_PDU_FLAG_BI_READ_OVERFLOW | SCSI_RSP_PDU_FLAG_BI_READ_UNDERFLOW) ||
      ISCSI_FLAG_ON (ScsiRspHdr, SCSI_RSP_PDU_FLAG_OVERFLOW | SCSI_RSP_PDU_FLAG_UNDERFLOW)
      )
  {
    return EFI_PROTOCOL_ERROR;
  }

  if (ISCSI_FLAG_ON (ScsiRspHdr, SCSI_RSP_PDU_FLAG_BI_READ_OVERFLOW)) {
    Packet->InTransferLength += NTOHL (ScsiRspHdr->BiReadResidualCount);
    Status                    = EFI_BAD_BUFFER_SIZE;
  }

  if (ISCSI_FLAG_ON (ScsiRspHdr, SCSI_RSP_PDU_FLAG_BI_READ_UNDERFLOW)) {
    Packet->InTransferLength -= NTOHL (ScsiRspHdr->BiReadResidualCount);
  }

  if (ISCSI_FLAG_ON (ScsiRspHdr, SCSI_RSP_PDU_FLAG_OVERFLOW)) {
    if (Packet->DataDirection == DataIn) {
      Packet->InTransferLength += NTOHL (ScsiRspHdr->ResidualCount);
    } else {
      Packet->OutTransferLength += NTOHL (ScsiRspHdr->ResidualCount);
    }

    Status = EFI_BAD_BUFFER_SIZE;
  }

  if (ISCSI_FLAG_ON (ScsiRspHdr, SCSI_RSP_PDU_FLAG_UNDERFLOW)) {
    if (Packet->DataDirection == DataIn) {
      Packet->InTransferLength -= NTOHL (ScsiRspHdr->ResidualCount);
    } else {
      Packet->OutTransferLength -= NTOHL (ScsiRspHdr->ResidualCount);
    }
  }

  DataSegLen = ISCSI_GET_DATASEG_LEN (ScsiRspHdr);
  if (DataSegLen != 0) {
    SenseData = (ISCSI_SENSE_DATA *)NetbufGetByte (Pdu, sizeof (SCSI_RESPONSE), NULL);
    if (SenseData == NULL) {
      return EFI_PROTOCOL_ERROR;
    }

    SenseData->Length = NTOHS (SenseData->Length);

    Packet->SenseDataLength = (UINT8)MIN (SenseData->Length, Packet->SenseDataLength);
    if (Packet->SenseDataLength != 0) {
      CopyMem (Packet->SenseData, &SenseData->Data[0], Packet->SenseDataLength);
    }
  } else {
    Packet->SenseDataLength = 0;
  }

  return Status;
}

/**
  Process the received NOP In PDU.

  @param[in]  Pdu            The NOP In PDU received.
  @param[in]  Tcb            The task control block.

  @retval EFI_SUCCESS        The NOP In PDU is processed and the related sequence
                             numbers are updated.
  @retval EFI_PROTOCOL_ERROR Some kind of iSCSI protocol error occurred.

**/
EFI_STATUS
IScsiOnNopInRcvd (
  IN NET_BUF    *Pdu,
  IN ISCSI_TCB  *Tcb
  )
{
  ISCSI_NOP_IN  *NopInHdr;
  EFI_STATUS    Status;

  NopInHdr = (ISCSI_NOP_IN *)NetbufGetByte (Pdu, 0, NULL);
  if (NopInHdr == NULL) {
    return EFI_PROTOCOL_ERROR;
  }

  NopInHdr->StatSN   = NTOHL (NopInHdr->StatSN);
  NopInHdr->ExpCmdSN = NTOHL (NopInHdr->ExpCmdSN);
  NopInHdr->MaxCmdSN = NTOHL (NopInHdr->MaxCmdSN);

  if (NopInHdr->InitiatorTaskTag == ISCSI_RESERVED_TAG) {
    if (NopInHdr->StatSN != Tcb->Conn->ExpStatSN) {
      return EFI_PROTOCOL_ERROR;
    }
  } else {
    Status = IScsiCheckSN (&Tcb->Conn->ExpStatSN, NopInHdr->StatSN);
    if (EFI_ERROR (Status)) {
      return Status;
    }
  }

  IScsiUpdateCmdSN (Tcb->Conn->Session, NopInHdr->MaxCmdSN, NopInHdr->ExpCmdSN);

  return EFI_SUCCESS;
}

/**
  Execute the SCSI command issued through the EXT SCSI PASS THRU protocol.

  @param[in]       PassThru  The EXT SCSI PASS THRU protocol.
  @param[in]       Target    The target ID.
  @param[in]       Lun       The LUN.
  @param[in, out]  Packet    The request packet containing IO request, SCSI command
                             buffer and buffers to read/write.

  @retval EFI_SUCCESS          The SCSI command is executed and the result is updated to
                               the Packet.
  @retval EFI_DEVICE_ERROR     Session state was not as required.
  @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
  @retval EFI_PROTOCOL_ERROR   There is no such data in the net buffer.
  @retval EFI_NOT_READY        The target can not accept new commands.
  @retval Others               Other errors as indicated.

**/
EFI_STATUS
IScsiExecuteScsiCommand (
  IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL                 *PassThru,
  IN UINT8                                           *Target,
  IN UINT64                                          Lun,
  IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET  *Packet
  )
{
  EFI_STATUS               Status;
  ISCSI_DRIVER_DATA        *Private;
  ISCSI_SESSION            *Session;
  EFI_EVENT                TimeoutEvent;
  ISCSI_CONNECTION         *Conn;
  ISCSI_TCB                *Tcb;
  NET_BUF                  *Pdu;
  ISCSI_XFER_CONTEXT       *XferContext;
  UINT8                    *Data;
  ISCSI_IN_BUFFER_CONTEXT  InBufferContext;
  UINT64                   Timeout;
  UINT8                    *PduHdr;

  Private      = ISCSI_DRIVER_DATA_FROM_EXT_SCSI_PASS_THRU (PassThru);
  Session      = Private->Session;
  Status       = EFI_SUCCESS;
  Tcb          = NULL;
  TimeoutEvent = NULL;
  Timeout      = 0;

  if (Session->State != SESSION_STATE_LOGGED_IN) {
    Status = EFI_DEVICE_ERROR;
    goto ON_EXIT;
  }

  Conn = NET_LIST_USER_STRUCT_S (
           Session->Conns.ForwardLink,
           ISCSI_CONNECTION,
           Link,
           ISCSI_CONNECTION_SIGNATURE
           );

  if (Packet->Timeout != 0) {
    Timeout = MultU64x32 (Packet->Timeout, 4);
  }

  Status = IScsiNewTcb (Conn, &Tcb);
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  //
  // Encapsulate the SCSI request packet into an iSCSI SCSI Command PDU.
  //
  Pdu = IScsiNewScsiCmdPdu (Packet, Lun, Tcb);
  if (Pdu == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_EXIT;
  }

  XferContext = &Tcb->XferContext;
  PduHdr      = NetbufGetByte (Pdu, 0, NULL);
  if (PduHdr == NULL) {
    Status = EFI_PROTOCOL_ERROR;
    NetbufFree (Pdu);
    goto ON_EXIT;
  }

  XferContext->Offset = ISCSI_GET_DATASEG_LEN (PduHdr);

  //
  // Transmit the SCSI Command PDU.
  //
  Status = TcpIoTransmit (&Conn->TcpIo, Pdu);

  NetbufFree (Pdu);

  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  if (!Session->InitialR2T &&
      (XferContext->Offset < Session->FirstBurstLength) &&
      (XferContext->Offset < Packet->OutTransferLength)
      )
  {
    //
    // Unsolicited Data-Out sequence is allowed. There is remaining SCSI
    // OUT data, and the limit of FirstBurstLength is not reached.
    //
    XferContext->TargetTransferTag = ISCSI_RESERVED_TAG;
    XferContext->DesiredLength     = MIN (
                                       Session->FirstBurstLength,
                                       Packet->OutTransferLength - XferContext->Offset
                                       );

    Data   = (UINT8 *)Packet->OutDataBuffer + XferContext->Offset;
    Status = IScsiSendDataOutPduSequence (Data, Lun, Tcb);
    if (EFI_ERROR (Status)) {
      goto ON_EXIT;
    }
  }

  InBufferContext.InData    = (UINT8 *)Packet->InDataBuffer;
  InBufferContext.InDataLen = Packet->InTransferLength;

  while (!Tcb->StatusXferd) {
    //
    // Start the timeout timer.
    //
    if (Timeout != 0) {
      Status = gBS->SetTimer (Conn->TimeoutEvent, TimerRelative, Timeout);
      if (EFI_ERROR (Status)) {
        goto ON_EXIT;
      }

      TimeoutEvent = Conn->TimeoutEvent;
    }

    //
    // Try to receive PDU from target.
    //
    Status = IScsiReceivePdu (Conn, &Pdu, &InBufferContext, FALSE, FALSE, TimeoutEvent);
    if (EFI_ERROR (Status)) {
      goto ON_EXIT;
    }

    PduHdr = NetbufGetByte (Pdu, 0, NULL);
    if (PduHdr == NULL) {
      Status = EFI_PROTOCOL_ERROR;
      NetbufFree (Pdu);
      goto ON_EXIT;
    }

    switch (ISCSI_GET_OPCODE (PduHdr)) {
      case ISCSI_OPCODE_SCSI_DATA_IN:
        Status = IScsiOnDataInRcvd (Pdu, Tcb, Packet);
        break;

      case ISCSI_OPCODE_R2T:
        Status = IScsiOnR2TRcvd (Pdu, Tcb, Lun, Packet);
        break;

      case ISCSI_OPCODE_SCSI_RSP:
        Status = IScsiOnScsiRspRcvd (Pdu, Tcb, Packet);
        break;

      case ISCSI_OPCODE_NOP_IN:
        Status = IScsiOnNopInRcvd (Pdu, Tcb);
        break;

      case ISCSI_OPCODE_VENDOR_T0:
      case ISCSI_OPCODE_VENDOR_T1:
      case ISCSI_OPCODE_VENDOR_T2:
        //
        // These messages are vendor specific. Skip them.
        //
        break;

      default:
        Status = EFI_PROTOCOL_ERROR;
        break;
    }

    NetbufFree (Pdu);

    if (EFI_ERROR (Status)) {
      break;
    }
  }

ON_EXIT:

  if (TimeoutEvent != NULL) {
    gBS->SetTimer (TimeoutEvent, TimerCancel, 0);
  }

  if (Tcb != NULL) {
    IScsiDelTcb (Tcb);
  }

  return Status;
}

/**
  Reinstate the session on some error.

  @param[in]  Session           The iSCSI session

  @retval EFI_SUCCESS           The session is reinstated from some error.
  @retval Other                 Reinstatement failed.

**/
EFI_STATUS
IScsiSessionReinstatement (
  IN ISCSI_SESSION  *Session
  )
{
  EFI_STATUS  Status;

  ASSERT (Session->State != SESSION_STATE_FREE);

  //
  // Abort the session and re-init it.
  //
  IScsiSessionAbort (Session);
  IScsiSessionInit (Session, TRUE);

  //
  // Login again.
  //
  Status = IScsiSessionLogin (Session);

  return Status;
}

/**
  Initialize some session parameters before login.

  @param[in, out]  Session  The iSCSI session.
  @param[in]       Recovery Whether the request is from a fresh new start or recovery.

**/
VOID
IScsiSessionInit (
  IN OUT ISCSI_SESSION  *Session,
  IN BOOLEAN            Recovery
  )
{
  if (!Recovery) {
    Session->Signature = ISCSI_SESSION_SIGNATURE;
    Session->State     = SESSION_STATE_FREE;

    InitializeListHead (&Session->Conns);
    InitializeListHead (&Session->TcbList);
  }

  Session->Tsih = 0;

  Session->CmdSN            = 1;
  Session->InitiatorTaskTag = 1;
  Session->NextCid          = 1;

  Session->TargetPortalGroupTag = 0;
  Session->MaxConnections       = ISCSI_MAX_CONNS_PER_SESSION;
  Session->InitialR2T           = FALSE;
  Session->ImmediateData        = TRUE;
  Session->MaxBurstLength       = 262144;
  Session->FirstBurstLength     = MAX_RECV_DATA_SEG_LEN_IN_FFP;
  Session->DefaultTime2Wait     = 2;
  Session->DefaultTime2Retain   = 20;
  Session->MaxOutstandingR2T    = DEFAULT_MAX_OUTSTANDING_R2T;
  Session->DataPDUInOrder       = TRUE;
  Session->DataSequenceInOrder  = TRUE;
  Session->ErrorRecoveryLevel   = 0;
}

/**
  Abort the iSCSI session. That is, reset all the connection(s), and free the
  resources.

  @param[in, out]  Session The iSCSI session.

**/
VOID
IScsiSessionAbort (
  IN OUT ISCSI_SESSION  *Session
  )
{
  ISCSI_CONNECTION  *Conn;
  EFI_GUID          *ProtocolGuid;

  if (Session->State != SESSION_STATE_LOGGED_IN) {
    return;
  }

  ASSERT (!IsListEmpty (&Session->Conns));

  while (!IsListEmpty (&Session->Conns)) {
    Conn = NET_LIST_USER_STRUCT_S (
             Session->Conns.ForwardLink,
             ISCSI_CONNECTION,
             Link,
             ISCSI_CONNECTION_SIGNATURE
             );
    if (!Conn->Ipv6Flag) {
      ProtocolGuid = &gEfiTcp4ProtocolGuid;
    } else {
      ProtocolGuid = &gEfiTcp6ProtocolGuid;
    }

    gBS->CloseProtocol (
           Conn->TcpIo.Handle,
           ProtocolGuid,
           Session->Private->Image,
           Session->Private->ExtScsiPassThruHandle
           );

    IScsiConnReset (Conn);

    IScsiDetatchConnection (Conn);
    IScsiDestroyConnection (Conn);
  }

  Session->State = SESSION_STATE_FAILED;

  return;
}
