]> git.proxmox.com Git - mirror_edk2.git/blobdiff - NetworkPkg/IScsiDxe/IScsiProto.c
NetworkPkg/IScsiDxe: support multiple hash algorithms for CHAP
[mirror_edk2.git] / NetworkPkg / IScsiDxe / IScsiProto.c
index 02953c3bac5b4d80293c918bb3ff93e2af822d4a..e62736bc041f8ec665ef35832189f27fedcc0ead 100644 (file)
@@ -1,14 +1,8 @@
 /** @file\r
   The implementation of iSCSI protocol based on RFC3720.\r
 \r
-Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution.  The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
@@ -17,7 +11,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 UINT32 mDataSegPad = 0;\r
 \r
 /**\r
-  Attach the iSCSI connection to the iSCSI session. \r
+  Attach the iSCSI connection to the iSCSI session.\r
 \r
   @param[in, out]  Session The iSCSI session.\r
   @param[in, out]  Conn    The iSCSI connection.\r
@@ -35,7 +29,7 @@ IScsiAttatchConnection (
 }\r
 \r
 /**\r
-  Detach the iSCSI connection from the session it belongs to. \r
+  Detach the iSCSI connection from the session it belongs to.\r
 \r
   @param[in, out]  Conn The iSCSI connection.\r
 \r
@@ -52,7 +46,7 @@ IScsiDetatchConnection (
 \r
 \r
 /**\r
-  Check the sequence number according to RFC3720. \r
+  Check the sequence number according to RFC3720.\r
 \r
   @param[in, out]  ExpSN   The currently expected sequence number.\r
   @param[in]       NewSN   The sequence number to check.\r
@@ -124,7 +118,7 @@ IScsiUpdateCmdSN (
 \r
   @retval EFI_SUCCESS        The iSCSI connection is logged into the iSCSI target.\r
   @retval EFI_TIMEOUT        Timeout occurred during the login procedure.\r
-  @retval Others             Other errors as indicated.  \r
+  @retval Others             Other errors as indicated.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -138,7 +132,11 @@ IScsiConnLogin (
   //\r
   // Start the timer, and wait Timeout seconds to establish the TCP connection.\r
   //\r
-  Status = gBS->SetTimer (Conn->TimeoutEvent, TimerRelative, Timeout * TICKS_PER_MS);\r
+  Status = gBS->SetTimer (\r
+                  Conn->TimeoutEvent,\r
+                  TimerRelative,\r
+                  MultU64x32 (Timeout, TICKS_PER_MS)\r
+                  );\r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
@@ -228,7 +226,7 @@ IScsiCreateConnection (
   Conn->PartialRspRcvd  = FALSE;\r
   Conn->ParamNegotiated = FALSE;\r
   Conn->Cid             = Session->NextCid++;\r
-  Conn->Ipv6Flag        = mPrivate->Ipv6Flag;\r
+  Conn->Ipv6Flag        = NvData->IpMode == IP_MODE_IP6 || Session->ConfigData->AutoConfigureMode == IP_MODE_AUTOCONFIG_IP6;\r
 \r
   Status = gBS->CreateEvent (\r
                   EVT_TIMER,\r
@@ -251,23 +249,41 @@ IScsiCreateConnection (
   Conn->HeaderDigest              = IScsiDigestNone;\r
   Conn->DataDigest                = IScsiDigestNone;\r
 \r
+  if (NvData->DnsMode) {\r
+    //\r
+    // perform dns process if target address expressed by domain name.\r
+    //\r
+    if (!Conn->Ipv6Flag) {\r
+      Status = IScsiDns4 (Private->Image, Private->Controller, NvData);\r
+    } else {\r
+      Status = IScsiDns6 (Private->Image, Private->Controller, NvData);\r
+    }\r
+\r
+    if (EFI_ERROR(Status)) {\r
+      DEBUG ((EFI_D_ERROR, "The configuration of Target address or DNS server address is invalid!\n"));\r
+      FreePool (Conn);\r
+      return NULL;\r
+    }\r
+  }\r
+\r
   if (!Conn->Ipv6Flag) {\r
     Tcp4IoConfig = &TcpIoConfig.Tcp4IoConfigData;\r
-    \r
+\r
     CopyMem (&Tcp4IoConfig->LocalIp, &NvData->LocalIp, sizeof (EFI_IPv4_ADDRESS));\r
     CopyMem (&Tcp4IoConfig->SubnetMask, &NvData->SubnetMask, sizeof (EFI_IPv4_ADDRESS));\r
     CopyMem (&Tcp4IoConfig->Gateway, &NvData->Gateway, sizeof (EFI_IPv4_ADDRESS));\r
     CopyMem (&Tcp4IoConfig->RemoteIp, &NvData->TargetIp, sizeof (EFI_IPv4_ADDRESS));\r
 \r
-    Tcp4IoConfig->RemotePort = NvData->TargetPort;\r
-    Tcp4IoConfig->ActiveFlag = TRUE;\r
-\r
+    Tcp4IoConfig->RemotePort  = NvData->TargetPort;\r
+    Tcp4IoConfig->ActiveFlag  = TRUE;\r
+    Tcp4IoConfig->StationPort = 0;\r
   } else {\r
     Tcp6IoConfig = &TcpIoConfig.Tcp6IoConfigData;\r
-  \r
+\r
     CopyMem (&Tcp6IoConfig->RemoteIp, &NvData->TargetIp, sizeof (EFI_IPv6_ADDRESS));\r
-    Tcp6IoConfig->RemotePort = NvData->TargetPort;\r
-    Tcp6IoConfig->ActiveFlag = TRUE;\r
+    Tcp6IoConfig->RemotePort  = NvData->TargetPort;\r
+    Tcp6IoConfig->ActiveFlag  = TRUE;\r
+    Tcp6IoConfig->StationPort = 0;\r
   }\r
 \r
   //\r
@@ -316,7 +332,7 @@ IScsiDestroyConnection (
 \r
   @retval     EFI_SUCCESS      Get the NIC information successfully.\r
   @retval     Others           Other errors as indicated.\r
-  \r
+\r
 **/\r
 EFI_STATUS\r
 IScsiGetIp6NicInfo (\r
@@ -401,6 +417,26 @@ ON_EXIT:
   return Status;\r
 }\r
 \r
+/**\r
+  Re-set any stateful session-level authentication information that is used by\r
+  the leading login / leading connection.\r
+\r
+  (Note that this driver only supports a single connection per session -- see\r
+  ISCSI_MAX_CONNS_PER_SESSION.)\r
+\r
+  @param[in,out] Session  The iSCSI session.\r
+**/\r
+STATIC\r
+VOID\r
+IScsiSessionResetAuthData (\r
+  IN OUT ISCSI_SESSION *Session\r
+  )\r
+{\r
+  if (Session->AuthType == ISCSI_AUTH_TYPE_CHAP) {\r
+    Session->AuthData.CHAP.Hash = NULL;\r
+  }\r
+}\r
+\r
 /**\r
   Login the iSCSI session.\r
 \r
@@ -422,14 +458,14 @@ IScsiSessionLogin (
   VOID              *Tcp;\r
   EFI_GUID          *ProtocolGuid;\r
   UINT8             RetryCount;\r
-  BOOLEAN           MediaPresent;\r
+  EFI_STATUS        MediaStatus;\r
 \r
   //\r
   // Check media status before session login.\r
   //\r
-  MediaPresent = TRUE;\r
-  NetLibDetectMedia (Session->Private->Controller, &MediaPresent);\r
-  if (!MediaPresent) {\r
+  MediaStatus = EFI_SUCCESS;\r
+  NetLibDetectMediaWaitTimeout (Session->Private->Controller, ISCSI_CHECK_MEDIA_LOGIN_WAITING_TIME, &MediaStatus);\r
+  if (MediaStatus != EFI_SUCCESS) {\r
     return EFI_NO_MEDIA;\r
   }\r
 \r
@@ -452,8 +488,9 @@ IScsiSessionLogin (
     IScsiAttatchConnection (Session, Conn);\r
 \r
     //\r
-    // Login througth the newly created connection.\r
+    // Login through the newly created connection.\r
     //\r
+    IScsiSessionResetAuthData (Session);\r
     Status = IScsiConnLogin (Conn, Session->ConfigData->SessionConfigData.ConnectTimeout);\r
     if (EFI_ERROR (Status)) {\r
       IScsiConnReset (Conn);\r
@@ -471,8 +508,8 @@ IScsiSessionLogin (
   if (!EFI_ERROR (Status)) {\r
     Session->State = SESSION_STATE_LOGGED_IN;\r
 \r
-    if (!mPrivate->Ipv6Flag) {\r
-      ProtocolGuid = &gEfiTcp4ProtocolGuid;      \r
+    if (!Conn->Ipv6Flag) {\r
+      ProtocolGuid = &gEfiTcp4ProtocolGuid;\r
     } else {\r
       ProtocolGuid = &gEfiTcp6ProtocolGuid;\r
     }\r
@@ -483,12 +520,12 @@ IScsiSessionLogin (
                     (VOID **) &Tcp,\r
                     Session->Private->Image,\r
                     Session->Private->ExtScsiPassThruHandle,\r
-                    EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER                    \r
+                    EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
                     );\r
 \r
     ASSERT_EFI_ERROR (Status);\r
 \r
-    if (mPrivate->Ipv6Flag) {\r
+    if (Conn->Ipv6Flag) {\r
       Status = IScsiGetIp6NicInfo (Conn);\r
     }\r
   }\r
@@ -590,7 +627,7 @@ IScsiSendLoginReq (
   Receive and process the iSCSI login response.\r
 \r
   @param[in]  Conn             The connection in the iSCSI login phase.\r
-  \r
+\r
   @retval EFI_SUCCESS          The iSCSI login response PDU is received and processed.\r
   @retval Others               Other errors as indicated.\r
 \r
@@ -603,6 +640,8 @@ IScsiReceiveLoginRsp (
   EFI_STATUS  Status;\r
   NET_BUF     *Pdu;\r
 \r
+  Pdu = NULL;\r
+\r
   //\r
   // Receive the iSCSI login response.\r
   //\r
@@ -728,7 +767,10 @@ IScsiPrepareLoginReq (
   }\r
 \r
   LoginReq = (ISCSI_LOGIN_REQUEST *) NetbufAllocSpace (Nbuf, sizeof (ISCSI_LOGIN_REQUEST), NET_BUF_TAIL);\r
-  ASSERT (LoginReq != NULL);\r
+  if (LoginReq == NULL) {\r
+    NetbufFree (Nbuf);\r
+    return NULL;\r
+  }\r
   ZeroMem (LoginReq, sizeof (ISCSI_LOGIN_REQUEST));\r
 \r
   //\r
@@ -744,7 +786,7 @@ IScsiPrepareLoginReq (
   LoginReq->CmdSN             = HTONL (Session->CmdSN);\r
 \r
   //\r
-  // For the first Login Request on a coonection this is ExpStatSN for the\r
+  // For the first Login Request on a connection this is ExpStatSN for the\r
   // old connection, and this field is only valid if the Login Request restarts\r
   // a connection.\r
   // For subsequent Login Requests it is used to acknowledge the Login Responses\r
@@ -766,7 +808,7 @@ IScsiPrepareLoginReq (
   case ISCSI_SECURITY_NEGOTIATION:\r
     //\r
     // Both none authentication and CHAP authentication share the CHAP path.\r
-    // \r
+    //\r
     //\r
     if (Session->AuthType != ISCSI_AUTH_TYPE_KRB) {\r
       Status = IScsiCHAPToSendReq (Conn, Nbuf);\r
@@ -776,12 +818,12 @@ IScsiPrepareLoginReq (
 \r
   case ISCSI_LOGIN_OPERATIONAL_NEGOTIATION:\r
     //\r
-    // Only negotiate the paramter once.\r
+    // Only negotiate the parameter once.\r
     //\r
     if (!Conn->ParamNegotiated) {\r
       IScsiFillOpParams (Conn, Nbuf);\r
     }\r
-    \r
+\r
     ISCSI_SET_FLAG (LoginReq, ISCSI_LOGIN_REQ_PDU_FLAG_TRANSIT);\r
     break;\r
 \r
@@ -920,7 +962,7 @@ IScsiProcessLoginRsp (
     // A Login Response with the C bit set to 1 MUST have the T bit set to 0.\r
     // The CSG in the Login Response MUST be the same with the I-end of this connection.\r
     // The T bit can't be 1 if the last Login Response sent by the initiator doesn't\r
-    // initiate the transistion.\r
+    // initiate the transition.\r
     // The NSG MUST be the same with the I-end of this connection if Transit is required.\r
     // The ISID in the Login Response MUST be the same with this session.\r
     //\r
@@ -937,7 +979,7 @@ IScsiProcessLoginRsp (
     // the value presented in CmdSN as the target value for ExpCmdSN.\r
     //\r
     if ((Session->State == SESSION_STATE_FREE) && (Session->CmdSN != LoginRsp->ExpCmdSN)) {\r
-      return EFI_PROTOCOL_ERROR;     \r
+      return EFI_PROTOCOL_ERROR;\r
     }\r
 \r
     //\r
@@ -1045,7 +1087,7 @@ IScsiProcessLoginRsp (
   @param[in]      Data         The data segment that should contain the\r
                                TargetAddress key-value list.\r
   @param[in]      Len          Length of the data.\r
-  \r
+\r
   @retval EFI_SUCCESS          The target address is updated.\r
   @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
   @retval EFI_NOT_FOUND        The TargetAddress key is not found.\r
@@ -1059,12 +1101,13 @@ IScsiUpdateTargetAddress (
   IN     UINT32                Len\r
   )\r
 {\r
-  LIST_ENTRY      *KeyValueList;\r
-  CHAR8           *TargetAddress;\r
-  CHAR8           *IpStr;\r
-  EFI_STATUS      Status;\r
-  UINTN           Number;\r
-  UINT8           IpMode;\r
+  LIST_ENTRY                   *KeyValueList;\r
+  CHAR8                        *TargetAddress;\r
+  CHAR8                        *IpStr;\r
+  EFI_STATUS                   Status;\r
+  UINTN                        Number;\r
+  UINT8                        IpMode;\r
+  ISCSI_SESSION_CONFIG_NVDATA  *NvData;\r
 \r
   KeyValueList = IScsiBuildKeyValueList (Data, Len);\r
   if (KeyValueList == NULL) {\r
@@ -1072,6 +1115,7 @@ IScsiUpdateTargetAddress (
   }\r
 \r
   Status = EFI_NOT_FOUND;\r
+  NvData = &Session->ConfigData->SessionConfigData;\r
 \r
   while (TRUE) {\r
     TargetAddress = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_TARGET_ADDRESS);\r
@@ -1079,27 +1123,63 @@ IScsiUpdateTargetAddress (
       break;\r
     }\r
 \r
-    if (!NET_IS_DIGIT (TargetAddress[0])) {\r
+    //\r
+    // RFC 3720 defines format of the TargetAddress=domainname[:port][,portal-group-tag]\r
+    // The domainname can be specified as either a DNS host name, adotted-decimal IPv4 address,\r
+    // or a bracketed IPv6 address as specified in [RFC2732].\r
+    //\r
+    if (NET_IS_DIGIT (TargetAddress[0])) {\r
       //\r
-      // The domainname of the target may be presented in three formats: a DNS host name,\r
-      // a dotted-decimal IPv4 address, or a bracketed IPv6 address. Only accept dotted\r
-      // IPv4 address.\r
+      // The domainname of the target is presented in a dotted-decimal IPv4 address format.\r
       //\r
-      continue;\r
-    }\r
+      IpStr = TargetAddress;\r
+\r
+      while ((*TargetAddress != '\0') && (*TargetAddress != ':') && (*TargetAddress != ',')) {\r
+        //\r
+        // NULL, ':', or ',' ends the IPv4 string.\r
+        //\r
+        TargetAddress++;\r
+      }\r
+    } else if (*TargetAddress == ISCSI_REDIRECT_ADDR_START_DELIMITER){\r
+      //\r
+      // The domainname of the target is presented in a bracketed IPv6 address format.\r
+      //\r
+      TargetAddress ++;\r
+      IpStr = TargetAddress;\r
+      while ((*TargetAddress != '\0') && (*TargetAddress != ISCSI_REDIRECT_ADDR_END_DELIMITER)) {\r
+        //\r
+        // ']' ends the IPv6 string.\r
+        //\r
+        TargetAddress++;\r
+      }\r
 \r
-    IpStr = TargetAddress;\r
+      if (*TargetAddress != ISCSI_REDIRECT_ADDR_END_DELIMITER) {\r
+        continue;\r
+      }\r
 \r
-    while ((*TargetAddress != 0) && (*TargetAddress != ':') && (*TargetAddress != ',')) {\r
+      *TargetAddress = '\0';\r
+      TargetAddress ++;\r
+\r
+    } else {\r
       //\r
-      // NULL, ':', or ',' ends the IPv4 string.\r
+      // The domainname of the target is presented in the format of a DNS host name.\r
       //\r
-      TargetAddress++;\r
+      IpStr = TargetAddress;\r
+\r
+      while ((*TargetAddress != '\0') && (*TargetAddress != ':') && (*TargetAddress != ',')) {\r
+        TargetAddress++;\r
+      }\r
+      NvData->DnsMode = TRUE;\r
     }\r
 \r
+    //\r
+    // Save the original user setting which specifies the proxy/virtual iSCSI target.\r
+    //\r
+    NvData->OriginalTargetPort = NvData->TargetPort;\r
+\r
     if (*TargetAddress == ',') {\r
       //\r
-      // Comma and the portal group tag MUST be ommitted if the TargetAddress is sent\r
+      // Comma and the portal group tag MUST be omitted if the TargetAddress is sent\r
       // as the result of a redirection.\r
       //\r
       continue;\r
@@ -1112,33 +1192,51 @@ IScsiUpdateTargetAddress (
       if (Number > 0xFFFF) {\r
         continue;\r
       } else {\r
-        Session->ConfigData->SessionConfigData.TargetPort = (UINT16) Number;\r
+        NvData->TargetPort = (UINT16) Number;\r
       }\r
     } else {\r
       //\r
-      // The string only contains the IPv4 address. Use the well-known port.\r
+      // The string only contains the Target address. Use the well-known port.\r
       //\r
-      Session->ConfigData->SessionConfigData.TargetPort = ISCSI_WELL_KNOWN_PORT;\r
+      NvData->TargetPort = ISCSI_WELL_KNOWN_PORT;\r
     }\r
+\r
+    //\r
+    // Save the original user setting which specifies the proxy/virtual iSCSI target.\r
+    //\r
+    CopyMem (&NvData->OriginalTargetIp, &NvData->TargetIp, sizeof (EFI_IP_ADDRESS));\r
+\r
     //\r
     // Update the target IP address.\r
     //\r
-    if (Session->ConfigData->SessionConfigData.IpMode < IP_MODE_AUTOCONFIG) {\r
-      IpMode = Session->ConfigData->SessionConfigData.IpMode;\r
+    if (NvData->IpMode < IP_MODE_AUTOCONFIG) {\r
+      IpMode = NvData->IpMode;\r
     } else {\r
       IpMode = Session->ConfigData->AutoConfigureMode;\r
     }\r
 \r
-    Status = IScsiAsciiStrToIp (\r
-               IpStr,\r
-               IpMode,\r
-               &Session->ConfigData->SessionConfigData.TargetIp\r
-               );\r
-\r
-    if (EFI_ERROR (Status)) {\r
-      continue;\r
+    if (NvData->DnsMode) {\r
+      //\r
+      // Target address is expressed as URL format, just save it and\r
+      // do DNS resolution when creating a TCP connection.\r
+      //\r
+      if (AsciiStrSize (IpStr) > sizeof (Session->ConfigData->SessionConfigData.TargetUrl)){\r
+        return EFI_INVALID_PARAMETER;\r
+      }\r
+      CopyMem (&Session->ConfigData->SessionConfigData.TargetUrl, IpStr, AsciiStrSize (IpStr));\r
     } else {\r
-      break;\r
+      Status = IScsiAsciiStrToIp (\r
+                 IpStr,\r
+                 IpMode,\r
+                 &Session->ConfigData->SessionConfigData.TargetIp\r
+                 );\r
+\r
+      if (EFI_ERROR (Status)) {\r
+        continue;\r
+      } else {\r
+        NvData->RedirectFlag = TRUE;\r
+        break;\r
+      }\r
     }\r
   }\r
 \r
@@ -1242,7 +1340,10 @@ IScsiReceivePdu (
   }\r
 \r
   Header = NetbufAllocSpace (PduHdr, Len, NET_BUF_TAIL);\r
-  ASSERT (Header != NULL);\r
+  if (Header == NULL) {\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+    goto ON_EXIT;\r
+  }\r
   InsertTailList (NbufList, &PduHdr->List);\r
 \r
   //\r
@@ -1279,7 +1380,7 @@ IScsiReceivePdu (
   switch (ISCSI_GET_OPCODE (Header)) {\r
   case ISCSI_OPCODE_SCSI_DATA_IN:\r
     //\r
-    // To reduce memory copy overhead, try to use the buffer described by Context \r
+    // To reduce memory copy overhead, try to use the buffer described by Context\r
     // if the PDU is an iSCSI SCSI data.\r
     //\r
     InDataOffset = ISCSI_GET_BUFFER_OFFSET (Header);\r
@@ -1391,7 +1492,7 @@ ON_EXIT:
 \r
   @param[in, out]  Conn          The connection in iSCSI login.\r
 \r
-  @retval EFI_SUCCESS          The parmeter check is passed and negotiation is finished.\r
+  @retval EFI_SUCCESS          The parameter check is passed and negotiation is finished.\r
   @retval EFI_PROTOCOL_ERROR   Some kind of iSCSI protocol error occurred.\r
   @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
 \r
@@ -1466,7 +1567,7 @@ IScsiCheckOpParams (
     goto ON_ERROR;\r
   }\r
   //\r
-  // ErrorRecoveryLevel: result fuction is Minimum.\r
+  // ErrorRecoveryLevel: result function is Minimum.\r
   //\r
   Value = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_ERROR_RECOVERY_LEVEL);\r
   if (Value == NULL) {\r
@@ -1510,7 +1611,7 @@ IScsiCheckOpParams (
     Conn->MaxRecvDataSegmentLength = (UINT32) IScsiNetNtoi (Value);\r
   }\r
   //\r
-  // MaxBurstLength: result funtion is Mininum.\r
+  // MaxBurstLength: result function is Minimum.\r
   //\r
   Value = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_MAX_BURST_LENGTH);\r
   if (Value == NULL) {\r
@@ -1627,7 +1728,7 @@ IScsiCheckOpParams (
   IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_TARGET_ALIAS);\r
   IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_TARGET_PORTAL_GROUP_TAG);\r
 \r
-  \r
+\r
   //\r
   // Remove the key-value that may not needed for result function is OR.\r
   //\r
@@ -2010,39 +2111,6 @@ IScsiDelTcb (
 }\r
 \r
 \r
-/**\r
-  Find the task control block by the initator task tag.\r
-\r
-  @param[in]  TcbList         The tcb list.\r
-  @param[in]  InitiatorTaskTag The initiator task tag.\r
-\r
-  @return The task control block found.\r
-  @retval NULL The task control block cannot be found.\r
-\r
-**/\r
-ISCSI_TCB *\r
-IScsiFindTcbByITT (\r
-  IN LIST_ENTRY      *TcbList,\r
-  IN UINT32          InitiatorTaskTag\r
-  )\r
-{\r
-  ISCSI_TCB       *Tcb;\r
-  LIST_ENTRY      *Entry;\r
-\r
-  Tcb = NULL;\r
-\r
-  NET_LIST_FOR_EACH (Entry, TcbList) {\r
-    Tcb = NET_LIST_USER_STRUCT (Entry, ISCSI_TCB, Link);\r
-\r
-    if (Tcb->InitiatorTaskTag == InitiatorTaskTag) {\r
-      break;\r
-    }\r
-  }\r
-\r
-  return Tcb;\r
-}\r
-\r
-\r
 /**\r
   Create a data segment, pad it, and calculate the CRC if needed.\r
 \r
@@ -2090,7 +2158,7 @@ IScsiNewDataSegment (
 \r
   @param[in]  Packet The EXT SCSI PASS THRU request packet containing the SCSI command.\r
   @param[in]  Lun    The LUN.\r
-  @param[in]  Tcb    The tcb assocated with this SCSI command.\r
+  @param[in]  Tcb    The tcb associated with this SCSI command.\r
 \r
   @return The  created iSCSI SCSI command PDU.\r
   @retval NULL Other errors as indicated.\r
@@ -2142,7 +2210,7 @@ IScsiNewScsiCmdPdu (
   if (ScsiCmd == NULL) {\r
     NetbufFree (PduHeader);\r
     return NULL;\r
-  }    \r
+  }\r
   Header  = (ISCSI_ADDITIONAL_HEADER *) (ScsiCmd + 1);\r
 \r
   ZeroMem (ScsiCmd, Length);\r
@@ -2202,7 +2270,7 @@ IScsiNewScsiCmdPdu (
 \r
   if (Session->ImmediateData && (Packet->OutTransferLength != 0)) {\r
     //\r
-    // Send immediate data in this SCSI Command PDU. The length of the immeidate\r
+    // Send immediate data in this SCSI Command PDU. The length of the immediate\r
     // data is the minimum of FirstBurstLength, the data length to be xfered, and\r
     // the MaxRecvdataSegmentLength on this connection.\r
     //\r
@@ -2313,7 +2381,10 @@ IScsiNewDataOutPdu (
   InsertTailList (NbufList, &PduHdr->List);\r
 \r
   DataOutHdr  = (ISCSI_SCSI_DATA_OUT *) NetbufAllocSpace (PduHdr, sizeof (ISCSI_SCSI_DATA_OUT), NET_BUF_TAIL);\r
-  ASSERT (DataOutHdr != NULL);\r
+  if (DataOutHdr == NULL) {\r
+    IScsiFreeNbufList (NbufList);\r
+    return NULL;\r
+  }\r
   XferContext = &Tcb->XferContext;\r
 \r
   ZeroMem (DataOutHdr, sizeof (ISCSI_SCSI_DATA_OUT));\r
@@ -2444,7 +2515,7 @@ ON_EXIT:
   @param[in]  Lun             The LUN the data will be sent to.\r
   @param[in]  Tcb             The task control block.\r
 \r
-  @retval EFI_SUCCES           The data is sent out to the LUN.\r
+  @retval EFI_SUCCESS          The data is sent out to the LUN.\r
   @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
   @retval Others               Other errors as indicated.\r
 \r
@@ -2497,9 +2568,9 @@ IScsiSendDataOutPduSequence (
   @param[in]        Tcb      The task control block.\r
   @param[in, out]   Packet   The EXT SCSI PASS THRU request packet.\r
 \r
-  @retval EFI_SUCCES           The check on the Data IN PDU is passed and some update\r
+  @retval EFI_SUCCESS          The check on the Data IN PDU is passed and some update\r
                                actions are taken.\r
-  @retval EFI_PROTOCOL_ERROR   Some kind of iSCSI protocol errror occurred.\r
+  @retval EFI_PROTOCOL_ERROR   Some kind of iSCSI protocol error occurred.\r
   @retval EFI_BAD_BUFFER_SIZEE The buffer was not the proper size for the request.\r
   @retval Others               Other errors as indicated.\r
 \r
@@ -2589,8 +2660,8 @@ IScsiOnDataInRcvd (
   @param[in]       Lun       The Lun.\r
   @param[in, out]  Packet    The EXT SCSI PASS THRU request packet.\r
 \r
-  @retval EFI_SUCCES         The R2T PDU is valid and the solicited data is sent out.\r
-  @retval EFI_PROTOCOL_ERROR Some kind of iSCSI protocol errror occurred.\r
+  @retval EFI_SUCCESS        The R2T PDU is valid and the solicited data is sent out.\r
+  @retval EFI_PROTOCOL_ERROR Some kind of iSCSI protocol error occurred.\r
   @retval Others             Other errors as indicated.\r
 \r
 **/\r
@@ -2657,8 +2728,8 @@ IScsiOnR2TRcvd (
   @param[in]       Tcb      The task control block.\r
   @param[in, out]  Packet   The EXT SCSI PASS THRU request packet.\r
 \r
-  @retval EFI_SUCCES         The Response PDU is processed.\r
-  @retval EFI_PROTOCOL_ERROR Some kind of iSCSI protocol errror occurred.\r
+  @retval EFI_SUCCESS        The Response PDU is processed.\r
+  @retval EFI_PROTOCOL_ERROR Some kind of iSCSI protocol error occurred.\r
   @retval EFI_BAD_BUFFER_SIZEE The buffer was not the proper size for the request.\r
   @retval Others             Other errors as indicated.\r
 \r
@@ -2765,9 +2836,9 @@ IScsiOnScsiRspRcvd (
   @param[in]  Pdu            The NOP In PDU received.\r
   @param[in]  Tcb            The task control block.\r
 \r
-  @retval EFI_SUCCES         The NOP In PDU is processed and the related sequence\r
+  @retval EFI_SUCCESS        The NOP In PDU is processed and the related sequence\r
                              numbers are updated.\r
-  @retval EFI_PROTOCOL_ERROR Some kind of iSCSI protocol errror occurred.\r
+  @retval EFI_PROTOCOL_ERROR Some kind of iSCSI protocol error occurred.\r
 \r
 **/\r
 EFI_STATUS\r
@@ -2813,12 +2884,13 @@ IScsiOnNopInRcvd (
   @param[in]       Lun       The LUN.\r
   @param[in, out]  Packet    The request packet containing IO request, SCSI command\r
                              buffer and buffers to read/write.\r
-                             \r
-  @retval EFI_SUCCES           The SCSI command is executed and the result is updated to \r
+\r
+  @retval EFI_SUCCESS          The SCSI command is executed and the result is updated to\r
                                the Packet.\r
   @retval EFI_DEVICE_ERROR     Session state was not as required.\r
   @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
   @retval EFI_PROTOCOL_ERROR   There is no such data in the net buffer.\r
+  @retval EFI_NOT_READY        The target can not accept new commands.\r
   @retval Others               Other errors as indicated.\r
 \r
 **/\r
@@ -2997,15 +3069,6 @@ ON_EXIT:
     IScsiDelTcb (Tcb);\r
   }\r
 \r
-  if ((Status != EFI_SUCCESS) && (Status != EFI_NOT_READY)) {\r
-    //\r
-    // Reinstate the session.\r
-    //\r
-    if (EFI_ERROR (IScsiSessionReinstatement (Session))) {\r
-      Status = EFI_DEVICE_ERROR;\r
-    }\r
-  }\r
-\r
   return Status;\r
 }\r
 \r
@@ -3116,7 +3179,7 @@ IScsiSessionAbort (
     if (!Conn->Ipv6Flag) {\r
       ProtocolGuid = &gEfiTcp4ProtocolGuid;\r
     } else {\r
-      ProtocolGuid = &gEfiTcp6ProtocolGuid;    \r
+      ProtocolGuid = &gEfiTcp6ProtocolGuid;\r
     }\r
 \r
     gBS->CloseProtocol (\r