/** @file\r
The implementation of iSCSI protocol based on RFC3720.\r
\r
-Copyright (c) 2004 - 2012, 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
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
}\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
\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
\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
//\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
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
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
\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
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
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
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
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
(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
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
EFI_STATUS Status;\r
NET_BUF *Pdu;\r
\r
+ Pdu = NULL;\r
+\r
//\r
// Receive the iSCSI login response.\r
//\r
}\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
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
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
\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
// 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
// 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
NetbufQueAppend (&Conn->RspQue, Pdu);\r
\r
Conn->PartialRspRcvd = Continue;\r
- if ((!Transit) || Continue) {\r
+ if (Continue) {\r
//\r
// It is a partial response; must wait for another or more Request/Response\r
// conversations to get the full response.\r
@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
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
}\r
\r
Status = EFI_NOT_FOUND;\r
+ NvData = &Session->ConfigData->SessionConfigData;\r
\r
while (TRUE) {\r
TargetAddress = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_TARGET_ADDRESS);\r
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 is presented in a dotted-decimal IPv4 address format.\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 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 bracketed IPv6 address format.\r
//\r
- continue;\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
+ *TargetAddress = '\0';\r
+ TargetAddress ++;\r
\r
- while ((*TargetAddress != 0) && (*TargetAddress != ':') && (*TargetAddress != ',')) {\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
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
}\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
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
\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
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
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
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
}\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
\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
if (ScsiCmd == NULL) {\r
NetbufFree (PduHeader);\r
return NULL;\r
- } \r
+ }\r
Header = (ISCSI_ADDITIONAL_HEADER *) (ScsiCmd + 1);\r
\r
ZeroMem (ScsiCmd, Length);\r
\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
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
@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
@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
@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
@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
@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
@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
Timeout = 0;\r
\r
if (Session->State != SESSION_STATE_LOGGED_IN) {\r
- return EFI_DEVICE_ERROR;\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto ON_EXIT;\r
}\r
\r
Conn = NET_LIST_USER_STRUCT_S (\r
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
{\r
EFI_STATUS Status;\r
\r
- ASSERT (Session->State == SESSION_STATE_LOGGED_IN);\r
+ ASSERT (Session->State != SESSION_STATE_FREE);\r
\r
//\r
// Abort the session and re-init it.\r
if (!Conn->Ipv6Flag) {\r
ProtocolGuid = &gEfiTcp4ProtocolGuid;\r
} else {\r
- ProtocolGuid = &gEfiTcp6ProtocolGuid; \r
+ ProtocolGuid = &gEfiTcp6ProtocolGuid;\r
}\r
\r
gBS->CloseProtocol (\r