4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The implementation of iSCSI protocol based on RFC3720.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncCopyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncThis program and the accompanying materials
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncare licensed and made available under the terms and conditions of the BSD License
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncwhich accompanies this distribution. The full text of the license may be found at
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Attach the iSCSI connection to the iSCSI session.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] Session The iSCSI session.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] Conn The iSCSI connection.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Detach the iSCSI connection from the session it belongs to.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] Conn The iSCSI connection.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Check the sequence number according to RFC3720.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] ExpSN The currently expected sequence number.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] NewSN The sequence number to check.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The check passed and the ExpSN is increased.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_READY Response was sent due to a retransmission request.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_PROTOCOL_ERROR Some kind of iSCSI protocol error occurred.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Duplicate
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Advance the ExpSN
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Update the sequence numbers for the iSCSI command.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] Session The iSCSI session.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] MaxCmdSN Maximum CmdSN from the target.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] ExpCmdSN Next expected CmdSN from the target.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This function does the iSCSI connection login.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] Conn The iSCSI connection to login.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param Timeout The timeout value in millisecond.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The iSCSI connection is logged into the iSCSI target.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_TIMEOUT Timeout occurred during the login procedure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval Others Other errors as indicated.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Start the timer, and wait Timeout seconds to establish the TCP connection.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->SetTimer (Conn->TimeoutEvent, TimerRelative, Timeout * TICKS_PER_MS);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Try to establish the tcp connection.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = TcpIoConnect (&Conn->TcpIo, Conn->TimeoutEvent);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->SetTimer (Conn->TimeoutEvent, TimerCancel, 0);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Connection is established, start the iSCSI Login.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } while (Conn->CurrentStage != ISCSI_FULL_FEATURE_PHASE);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Reset the iSCSI connection.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] Conn The iSCSI connection to reset.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Create a TCP connection for the iSCSI session.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Session Points to the iSCSI session.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return The newly created iSCSI connection.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Conn = AllocateZeroPool (sizeof (ISCSI_CONNECTION));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Conn->NextStage = ISCSI_LOGIN_OPERATIONAL_NEGOTIATION;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Set the default connection-only parameters.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Conn->MaxRecvDataSegmentLength = DEFAULT_MAX_RECV_DATA_SEG_LEN;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (&Tcp4IoConfig->LocalIp, &NvData->LocalIp, sizeof (EFI_IPv4_ADDRESS));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (&Tcp4IoConfig->SubnetMask, &NvData->SubnetMask, sizeof (EFI_IPv4_ADDRESS));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (&Tcp4IoConfig->Gateway, &NvData->Gateway, sizeof (EFI_IPv4_ADDRESS));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (&Tcp4IoConfig->RemoteIp, &NvData->TargetIp, sizeof (EFI_IPv4_ADDRESS));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (&Tcp6IoConfig->RemoteIp, &NvData->TargetIp, sizeof (EFI_IPv6_ADDRESS));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Create the TCP IO for this connection.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (UINT8) (!Conn->Ipv6Flag ? TCP_VERSION_4: TCP_VERSION_6),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Destroy an iSCSI connection.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Conn The connection to destroy.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Login the iSCSI session.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Session The iSCSI session.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The iSCSI session login procedure finished.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NO_MEDIA There was a media error.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval Others Other errors as indicated.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check media status before session login.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetLibDetectMedia (Session->Private->Controller, &MediaPresent);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Set session identifier
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (Session->Isid, Session->ConfigData->SessionConfigData.IsId, 6);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Create a connection for the session.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Login througth the newly created connection.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = IScsiConnLogin (Conn, Session->ConfigData->SessionConfigData.ConnectTimeout);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } while (RetryCount <= Session->ConfigData->SessionConfigData.ConnectRetryCount);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Wait for IPsec negotiation, then try to login the iSCSI session again.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Session The iSCSI session.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The iSCSI session login procedure finished.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_PROTOCOL_ERROR Some kind of iSCSI protocol error occurred.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->CreateEvent (EVT_TIMER, TPL_CALLBACK, NULL, NULL, &Timer);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Build and send the iSCSI login request to the iSCSI target according to
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the current login stage.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Conn The connection in the iSCSI login phase.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The iSCSI login request PDU is built and sent on this
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync connection.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_DEVICE_ERROR Some kind of device error occurred.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Build the Login Request PDU.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Send it to the iSCSI target.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Receive and process the iSCSI login response.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Conn The connection in the iSCSI login phase.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The iSCSI login response PDU is received and processed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval Others Other errors as indicated.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Receive the iSCSI login response.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = IScsiReceivePdu (Conn, &Pdu, NULL, FALSE, FALSE, NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // A Login Response is received; process it.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Add an iSCSI key-value pair as a string into the data segment of the Login Request PDU.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The DataSegmentLength and the actual size of the net buffer containing this PDU will be
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] Pdu The iSCSI PDU whose data segment the key-value pair will
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync be added to.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Key The key name string.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Value The value string.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The key-value pair is added to the PDU's data segment and
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the correspondence length fields are updated.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCES There is not enough space in the PDU to add the key-value
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_PROTOCOL_ERROR There is no such data in the net buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LoginReq = (ISCSI_LOGIN_REQUEST *) NetbufGetByte (Pdu, 0, NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // 1 byte for the key value separator '=' and 1 byte for the null
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // delimiter after the value.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Allocate the space for the key-value pair.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Data = (CHAR8 *) NetbufAllocSpace (Pdu, TotalLen, NET_BUF_TAIL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Add the key.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Add the value.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Update the DataSegmentLength
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ISCSI_SET_DATASEG_LEN (LoginReq, DataSegLen + TotalLen);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Prepare the iSCSI login request to be sent according to the current login status.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] Conn The connection in the iSCSI login phase.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return The pointer to the net buffer containing the iSCSI login request built.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval NULL Other errors as indicated.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Nbuf = NetbufAlloc (sizeof (ISCSI_LOGIN_REQUEST) + DEFAULT_MAX_RECV_DATA_SEG_LEN);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LoginReq = (ISCSI_LOGIN_REQUEST *) NetbufAllocSpace (Nbuf, sizeof (ISCSI_LOGIN_REQUEST), NET_BUF_TAIL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Init the login request pdu
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ISCSI_SET_OPCODE (LoginReq, ISCSI_OPCODE_LOGIN_REQ, ISCSI_REQ_IMMEDIATE);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ISCSI_SET_STAGES (LoginReq, Conn->CurrentStage, Conn->NextStage);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LoginReq->InitiatorTaskTag = HTONL (Session->InitiatorTaskTag);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // For the first Login Request on a coonection this is ExpStatSN for the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // old connection, and this field is only valid if the Login Request restarts
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // a connection.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // For subsequent Login Requests it is used to acknowledge the Login Responses
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // with their increasing StatSN values.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (LoginReq->Isid, Session->Isid, sizeof (LoginReq->Isid));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // A partial response. The initiator must send an empty Login Request.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Both none authentication and CHAP authentication share the CHAP path.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Only negotiate the paramter once.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ISCSI_SET_FLAG (LoginReq, ISCSI_LOGIN_REQ_PDU_FLAG_TRANSIT);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // An error occurs...
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Pad the data segment if needed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IScsiPadSegment (Nbuf, ISCSI_GET_DATASEG_LEN (LoginReq));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check whether we will issue the stage transition signal?
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Conn->TransitInitiated = ISCSI_FLAG_ON (LoginReq, ISCSI_LOGIN_REQ_PDU_FLAG_TRANSIT);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Process the iSCSI Login Response.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] Conn The connection on which the iSCSI login response is received.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] Pdu The iSCSI login response PDU.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The iSCSI login response PDU is processed, and all checks are passed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_PROTOCOL_ERROR Some kind of iSCSI protocol error occurred.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_MEDIA_CHANGED Target is redirected.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval Others Other errors as indicated.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LoginRsp = (ISCSI_LOGIN_RESPONSE *) NetbufGetByte (Pdu, 0, NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!ISCSI_CHECK_OPCODE (LoginRsp, ISCSI_OPCODE_LOGIN_RSP)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // It is not a Login Response.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Get the data segment, if any.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DataSeg = NetbufGetByte (Pdu, sizeof (ISCSI_LOGIN_RESPONSE), NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check the status class in the login response PDU.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Just break here; the response and the data segment will be processed later.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The target may be moved to a different address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Process the TargetAddress key-value strings in the data segment to update the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // target address info.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = IScsiUpdateTargetAddress (Session, (CHAR8 *) DataSeg, DataSegLen);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Session will be restarted on this error status because the Target is
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // redirected by this Login Response.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Initiator Error, Target Error, or any other undefined error code.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The status is success; extract the wanted fields from the header segment.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Transit = ISCSI_FLAG_ON (LoginRsp, ISCSI_LOGIN_RSP_PDU_FLAG_TRANSIT);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Continue = ISCSI_FLAG_ON (LoginRsp, ISCSI_LOGIN_RSP_PDU_FLAG_CONTINUE);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LoginRsp->InitiatorTaskTag = NTOHL (LoginRsp->InitiatorTaskTag);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (CompareMem (Session->Isid, LoginRsp->Isid, sizeof (LoginRsp->Isid)) != 0) ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (LoginRsp->InitiatorTaskTag != Session->InitiatorTaskTag)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // A Login Response with the C bit set to 1 MUST have the T bit set to 0.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The CSG in the Login Response MUST be the same with the I-end of this connection.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The T bit can't be 1 if the last Login Response sent by the initiator doesn't
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // initiate the transistion.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The NSG MUST be the same with the I-end of this connection if Transit is required.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The ISID in the Login Response MUST be the same with this session.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((Conn->CurrentStage == ISCSI_SECURITY_NEGOTIATION) && (Conn->AuthStep == ISCSI_AUTH_INITIAL)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If the Login Request is a leading Login Request, the target MUST use
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // the value presented in CmdSN as the target value for ExpCmdSN.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((Session->State == SESSION_STATE_FREE) && (Session->CmdSN != LoginRsp->ExpCmdSN)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // It's the initial Login Response, initialize the local ExpStatSN, MaxCmdSN
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // and ExpCmdSN.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check the StatSN of this PDU.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = IScsiCheckSN (&Conn->ExpStatSN, LoginRsp->StatSN);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Update the MaxCmdSN and ExpCmdSN.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IScsiUpdateCmdSN (Session, LoginRsp->MaxCmdSN, LoginRsp->ExpCmdSN);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Trim off the header segment.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetbufTrim (Pdu, sizeof (ISCSI_LOGIN_RESPONSE), NET_BUF_HEAD);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Queue this login response first in case it's a partial response so that
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // later when the full response list is received we can combine these scattered
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // responses' data segment and then process it.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // It is a partial response; must wait for another or more Request/Response
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // conversations to get the full response.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // In security negotiation stage, let CHAP module handle it.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Response received with negotiation response on iSCSI parameters: check them.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Should never get here.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Do the state transition.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Conn->CurrentStage == ISCSI_LOGIN_OPERATIONAL_NEGOTIATION) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // CurrentStage is iSCSI Full Feature. It is the Login-Final Response;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // get the TSIH from the Login Response.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Flush the response(s) received.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Updated the target information according the data received in the iSCSI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync login response with an target redirection status.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] Session The iSCSI session.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Data The data segment that should contain the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TargetAddress key-value list.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Len Length of the data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The target address is updated.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_FOUND The TargetAddress key is not found.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval Others Other errors as indicated.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TargetAddress = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_TARGET_ADDRESS);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The domainname of the target may be presented in three formats: a DNS host name,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // a dotted-decimal IPv4 address, or a bracketed IPv6 address. Only accept dotted
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // IPv4 address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while ((*TargetAddress != 0) && (*TargetAddress != ':') && (*TargetAddress != ',')) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // NULL, ':', or ',' ends the IPv4 string.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Comma and the portal group tag MUST be ommitted if the TargetAddress is sent
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // as the result of a redirection.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Session->ConfigData->SessionConfigData.TargetPort = (UINT16) Number;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The string only contains the IPv4 address. Use the well-known port.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Session->ConfigData->SessionConfigData.TargetPort = ISCSI_WELL_KNOWN_PORT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Update the target IP address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Session->ConfigData->SessionConfigData.IpMode < IP_MODE_AUTOCONFIG) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpMode = Session->ConfigData->SessionConfigData.IpMode;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The callback function to free the net buffer list.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Arg The opaque parameter.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The callback function called in NetBufFree; it does nothing.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Arg The opaque parameter.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Receive an iSCSI response PDU. An iSCSI response PDU contains an iSCSI PDU header and
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync an optional data segment. The two parts will be put into two blocks of buffers in the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync net buffer. The digest check will be conducted in this function if needed and the digests
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync will be trimmed from the PDU buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Conn The iSCSI connection to receive data from.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[out] Pdu The received iSCSI pdu.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Context The context used to describe information on the caller provided
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync buffer to receive data segment of the iSCSI pdu. It is optional.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] HeaderDigest Whether there will be header digest received.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] DataDigest Whether there will be data digest.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] TimeoutEvent The timeout event. It is optional.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS An iSCSI pdu is received.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_PROTOCOL_ERROR Some kind of iSCSI protocol error occurred.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval Others Other errors as indicated.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The header digest will be received together with the PDU header, if exists.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Len = sizeof (ISCSI_BASIC_HEADER) + (HeaderDigest ? sizeof (UINT32) : 0);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Header = NetbufAllocSpace (PduHdr, Len, NET_BUF_TAIL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // First step, receive the BHS of the PDU.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = TcpIoReceive (&Conn->TcpIo, PduHdr, FALSE, TimeoutEvent);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // TODO: check the header-digest.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Trim off the digest.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetbufTrim (PduHdr, sizeof (UINT32), NET_BUF_TAIL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Len == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // No data segment.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Get the length of the padding bytes of the data segment.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // To reduce memory copy overhead, try to use the buffer described by Context
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // if the PDU is an iSCSI SCSI data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((Context == NULL) || ((InDataOffset + Len) > Context->InDataLen)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The data segment is padded. Use two fragments to receive it:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // the first to receive the useful data; the second to receive the padding.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Fragment[1].Len = PadLen + (DataDigest ? sizeof (UINT32) : 0);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Fragment[1].Bulk = (UINT8 *)PadAndCRC32 + (4 - PadLen);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DataSeg = NetbufFromExt (&Fragment[0], FragmentCount, 0, 0, IScsiNbufExtFree, NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Allocate buffer to receive the data segment.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Len += PadLen + (DataDigest ? sizeof (UINT32) : 0);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Receive the data segment with the data digest, if any.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = TcpIoReceive (&Conn->TcpIo, DataSeg, FALSE, TimeoutEvent);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // TODO: Check the data digest.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetbufTrim (DataSeg, sizeof (UINT32), NET_BUF_TAIL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Trim off the padding bytes in the data segment.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Form the pdu from a list of pdu segments.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *Pdu = NetbufFromBufList (NbufList, 0, 0, IScsiFreeNbufList, NbufList);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Free the Nbufs in this NbufList and the NbufList itself.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Check and get the result of the parameter negotiation.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] Conn The connection in iSCSI login.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The parmeter check is passed and negotiation is finished.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_PROTOCOL_ERROR Some kind of iSCSI protocol error occurred.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetbufQueCopy (&Conn->RspQue, 0, Len, (UINT8 *) Data);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Extract the Key-Value pairs into a list.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // HeaderDigest
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Value = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_HEADER_DIGEST);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (AsciiStrCmp (Value, ISCSI_KEY_VALUE_NONE) == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // DataDigest
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Value = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_DATA_DIGEST);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (AsciiStrCmp (Value, ISCSI_KEY_VALUE_NONE) == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // ErrorRecoveryLevel: result fuction is Minimum.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Value = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_ERROR_RECOVERY_LEVEL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Session->ErrorRecoveryLevel = (UINT8) MIN (Session->ErrorRecoveryLevel, NumericValue);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // InitialR2T: result function is OR.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Value = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_INITIAL_R2T);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Session->InitialR2T = (BOOLEAN) (AsciiStrCmp (Value, "Yes") == 0);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // ImmediateData: result function is AND.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Value = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_IMMEDIATE_DATA);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Session->ImmediateData = (BOOLEAN) (Session->ImmediateData && (BOOLEAN) (AsciiStrCmp (Value, "Yes") == 0));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // MaxRecvDataSegmentLength is declarative.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Value = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_MAX_RECV_DATA_SEGMENT_LENGTH);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Conn->MaxRecvDataSegmentLength = (UINT32) IScsiNetNtoi (Value);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // MaxBurstLength: result funtion is Mininum.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Value = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_MAX_BURST_LENGTH);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Session->MaxBurstLength = (UINT32) MIN (Session->MaxBurstLength, NumericValue);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // FirstBurstLength: result function is Minimum. Irrelevant when InitialR2T=Yes and
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // ImmediateData=No.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!(Session->InitialR2T && !Session->ImmediateData)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Value = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_FIRST_BURST_LENGTH);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Session->FirstBurstLength = (UINT32) MIN (Session->FirstBurstLength, NumericValue);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // MaxConnections: result function is Minimum.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Value = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_MAX_CONNECTIONS);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((NumericValue == 0) || (NumericValue > 65535)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Session->MaxConnections = (UINT32) MIN (Session->MaxConnections, NumericValue);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // DataPDUInOrder: result function is OR.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Value = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_DATA_PDU_IN_ORDER);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Session->DataPDUInOrder = (BOOLEAN) (AsciiStrCmp (Value, "Yes") == 0);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // DataSequenceInorder: result function is OR.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Value = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_DATA_SEQUENCE_IN_ORDER);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Session->DataSequenceInOrder = (BOOLEAN) (AsciiStrCmp (Value, "Yes") == 0);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // DefaultTime2Wait: result function is Maximum.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Value = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_DEFAULT_TIME2WAIT);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Session->DefaultTime2Wait = (UINT32) MAX (Session->DefaultTime2Wait, NumericValue);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // DefaultTime2Retain: result function is Minimum.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Value = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_DEFAULT_TIME2RETAIN);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Session->DefaultTime2Retain = (UINT32) MIN (Session->DefaultTime2Retain, NumericValue);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // MaxOutstandingR2T: result function is Minimum.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Value = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_MAX_OUTSTANDING_R2T);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((NumericValue == 0) || (NumericValue > 65535)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Session->MaxOutstandingR2T = (UINT16) MIN (Session->MaxOutstandingR2T, NumericValue);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Remove declarative key-value pairs, if any.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_SESSION_TYPE);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_TARGET_ALIAS);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_TARGET_PORTAL_GROUP_TAG);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Remove the key-value that may not needed for result function is OR.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_INITIAL_R2T);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_DATA_PDU_IN_ORDER);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_DATA_SEQUENCE_IN_ORDER);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Remove irrelevant parameter, if any.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Session->InitialR2T && !Session->ImmediateData) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_FIRST_BURST_LENGTH);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Succeed if no more keys in the list.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Fill the operational parameters.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Conn The connection in iSCSI login.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] Pdu The iSCSI login request PDU to fill the parameters.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AsciiSPrint (Value, sizeof (Value), "%a", (Conn->HeaderDigest == IScsiDigestCRC32) ? "None,CRC32" : "None");
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IScsiAddKeyValuePair (Pdu, ISCSI_KEY_HEADER_DIGEST, Value);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AsciiSPrint (Value, sizeof (Value), "%a", (Conn->DataDigest == IScsiDigestCRC32) ? "None,CRC32" : "None");
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IScsiAddKeyValuePair (Pdu, ISCSI_KEY_DATA_DIGEST, Value);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AsciiSPrint (Value, sizeof (Value), "%d", Session->ErrorRecoveryLevel);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IScsiAddKeyValuePair (Pdu, ISCSI_KEY_ERROR_RECOVERY_LEVEL, Value);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AsciiSPrint (Value, sizeof (Value), "%a", Session->InitialR2T ? "Yes" : "No");
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IScsiAddKeyValuePair (Pdu, ISCSI_KEY_INITIAL_R2T, Value);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AsciiSPrint (Value, sizeof (Value), "%a", Session->ImmediateData ? "Yes" : "No");
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IScsiAddKeyValuePair (Pdu, ISCSI_KEY_IMMEDIATE_DATA, Value);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AsciiSPrint (Value, sizeof (Value), "%d", MAX_RECV_DATA_SEG_LEN_IN_FFP);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IScsiAddKeyValuePair (Pdu, ISCSI_KEY_MAX_RECV_DATA_SEGMENT_LENGTH, Value);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AsciiSPrint (Value, sizeof (Value), "%d", Session->MaxBurstLength);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IScsiAddKeyValuePair (Pdu, ISCSI_KEY_MAX_BURST_LENGTH, Value);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AsciiSPrint (Value, sizeof (Value), "%d", Session->FirstBurstLength);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IScsiAddKeyValuePair (Pdu, ISCSI_KEY_FIRST_BURST_LENGTH, Value);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AsciiSPrint (Value, sizeof (Value), "%d", Session->MaxConnections);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IScsiAddKeyValuePair (Pdu, ISCSI_KEY_MAX_CONNECTIONS, Value);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AsciiSPrint (Value, sizeof (Value), "%a", Session->DataPDUInOrder ? "Yes" : "No");
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IScsiAddKeyValuePair (Pdu, ISCSI_KEY_DATA_PDU_IN_ORDER, Value);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AsciiSPrint (Value, sizeof (Value), "%a", Session->DataSequenceInOrder ? "Yes" : "No");
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IScsiAddKeyValuePair (Pdu, ISCSI_KEY_DATA_SEQUENCE_IN_ORDER, Value);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AsciiSPrint (Value, sizeof (Value), "%d", Session->DefaultTime2Wait);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IScsiAddKeyValuePair (Pdu, ISCSI_KEY_DEFAULT_TIME2WAIT, Value);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AsciiSPrint (Value, sizeof (Value), "%d", Session->DefaultTime2Retain);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IScsiAddKeyValuePair (Pdu, ISCSI_KEY_DEFAULT_TIME2RETAIN, Value);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AsciiSPrint (Value, sizeof (Value), "%d", Session->MaxOutstandingR2T);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IScsiAddKeyValuePair (Pdu, ISCSI_KEY_MAX_OUTSTANDING_R2T, Value);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Pad the iSCSI AHS or data segment to an integer number of 4 byte words.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] Pdu The iSCSI pdu which contains segments to pad.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Len The length of the last segment in the PDU.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The segment is padded or there is no need to pad it.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCES There is not enough remaining free space to add the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync padding bytes.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Data = NetbufAllocSpace (Pdu, PadLen, NET_BUF_TAIL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Build a key-value list from the data segment.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Data The data segment containing the key-value pairs.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Len Length of the data segment.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return The key-value list.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval NULL Other errors as indicated.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while (Len > 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync KeyValuePair = AllocatePool (sizeof (ISCSI_KEY_VALUE_PAIR));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Len -= (UINT32) AsciiStrLen (KeyValuePair->Value) + 1;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Get the value string by the key name from the key-value list. If found,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the key-value entry will be removed from the list.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] KeyValueList The key-value list.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Key The key name to find.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return The value string.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval NULL The key value pair cannot be found.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync KeyValuePair = NET_LIST_USER_STRUCT (Entry, ISCSI_KEY_VALUE_PAIR, List);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Free the key-value list.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] KeyValueList The key-value list.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync KeyValuePair = NET_LIST_USER_STRUCT (Entry, ISCSI_KEY_VALUE_PAIR, List);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Normalize the iSCSI name according to RFC.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] Name The iSCSI name.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Len Length of the iSCSI name.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The iSCSI name is valid and normalized.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_PROTOCOL_ERROR The iSCSI name is malformatted or not in the IQN format.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Convert the upper-case characters to lower-case ones.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // ASCII dash, dot, colon lower-case characters and digit characters
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // are allowed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((Len < 4) || (CompareMem (Name, "iqn.", 4) != 0)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Only IQN format is accepted now.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Create an iSCSI task control block.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Conn The connection on which the task control block will be created.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[out] Tcb The newly created task control block.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The task control block is created.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_READY The target cannot accept new commands.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (ISCSI_SEQ_GT (Session->CmdSN, Session->MaxCmdSN)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NewTcb->InitiatorTaskTag = Session->InitiatorTaskTag;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Advance the initiator task tag.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Delete the tcb from the connection and destroy it.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Tcb The tcb to delete.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Find the task control block by the initator task tag.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] TcbList The tcb list.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] InitiatorTaskTag The initiator task tag.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return The task control block found.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval NULL The task control block cannot be found.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Tcb = NET_LIST_USER_STRUCT (Entry, ISCSI_TCB, Link);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Create a data segment, pad it, and calculate the CRC if needed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Data The data to fill into the data segment.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Len Length of the data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] DataDigest Whether to calculate CRC for this data segment.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return The net buffer wrapping the data segment.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DataSeg = NetbufFromExt (&Fragment[0], FragmentCount, 0, 0, IScsiNbufExtFree, NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Create a iSCSI SCSI command PDU to encapsulate the command issued
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync by SCSI through the EXT SCSI PASS THRU Protocol.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Packet The EXT SCSI PASS THRU request packet containing the SCSI command.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Lun The LUN.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Tcb The tcb assocated with this SCSI command.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return The created iSCSI SCSI command PDU.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval NULL Other errors as indicated.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ISCSI_BI_EXP_READ_DATA_LEN_AHS *BiExpReadDataLenAHS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Bidirectional Read/Write command, the bidirectional expected
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // read data length AHS is required.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AHSLength += sizeof (ISCSI_BI_EXP_READ_DATA_LEN_AHS);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The CDB exceeds 16 bytes. An extended CDB AHS is required.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AHSLength = (UINT8) (AHSLength + ISCSI_ROUNDUP (Packet->CdbLength - 16) + sizeof (ISCSI_ADDITIONAL_HEADER));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ScsiCmd = (SCSI_COMMAND *) NetbufAllocSpace (PduHeader, Length, NET_BUF_TAIL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Header = (ISCSI_ADDITIONAL_HEADER *) (ScsiCmd + 1);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ISCSI_SET_OPCODE (ScsiCmd, ISCSI_OPCODE_SCSI_CMD, 0);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Set the READ/WRITE flags according to the IO type of this request.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ScsiCmd->ExpDataXferLength = NTOHL (Packet->InTransferLength);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ScsiCmd->ExpDataXferLength = NTOHL (Packet->OutTransferLength);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ISCSI_SET_FLAG (ScsiCmd, SCSI_CMD_PDU_FLAG_READ | SCSI_CMD_PDU_FLAG_WRITE);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ScsiCmd->ExpDataXferLength = NTOHL (Packet->OutTransferLength);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Fill the bidirectional expected read data length AHS.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BiExpReadDataLenAHS = (ISCSI_BI_EXP_READ_DATA_LEN_AHS *) Header;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Header = (ISCSI_ADDITIONAL_HEADER *) (BiExpReadDataLenAHS + 1);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BiExpReadDataLenAHS->Type = ISCSI_AHS_TYPE_BI_EXP_READ_DATA_LEN;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BiExpReadDataLenAHS->ExpReadDataLength = NTOHL (Packet->InTransferLength);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (ScsiCmd->Lun, &Lun, sizeof (ScsiCmd->Lun));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ScsiCmd->InitiatorTaskTag = NTOHL (Tcb->InitiatorTaskTag);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (ScsiCmd->Cdb, Packet->Cdb, sizeof (ScsiCmd->Cdb));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Header->Length = NTOHS ((UINT16) (Packet->CdbLength - 15));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (Header + 1, (UINT8 *) Packet->Cdb + 16, Packet->CdbLength - 16);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Session->ImmediateData && (Packet->OutTransferLength != 0)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Send immediate data in this SCSI Command PDU. The length of the immeidate
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // data is the minimum of FirstBurstLength, the data length to be xfered, and
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // the MaxRecvdataSegmentLength on this connection.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ImmediateDataLen = MIN (Session->FirstBurstLength, Packet->OutTransferLength);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ImmediateDataLen = MIN (ImmediateDataLen, Tcb->Conn->MaxRecvDataSegmentLength);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Update the data segment length in the PDU header.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Create the data segment.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DataSeg = IScsiNewDataSegment ((UINT8 *) Packet->OutDataBuffer, ImmediateDataLen, FALSE);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Pdu = NetbufFromBufList (NbufList, 0, 0, IScsiFreeNbufList, NbufList);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Unsolicited data out sequence is not allowed,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // or FirstBustLength data is already sent out by immediate data,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // or all the OUT data accompany this SCSI packet are sent as
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // immediate data. The final flag should be set on this SCSI Command
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Create a new iSCSI SCSI Data Out PDU.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Data The data to put into the Data Out PDU.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Len Length of the data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] DataSN The DataSN of the Data Out PDU.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Tcb The task control block of this Data Out PDU.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Lun The LUN.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return The net buffer wrapping the Data Out PDU.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval NULL Other errors as indicated.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Allocate memory for the BHS.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PduHdr = NetbufAlloc (sizeof (ISCSI_SCSI_DATA_OUT));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Insert the BHS into the buffer list.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DataOutHdr = (ISCSI_SCSI_DATA_OUT *) NetbufAllocSpace (PduHdr, sizeof (ISCSI_SCSI_DATA_OUT), NET_BUF_TAIL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ZeroMem (DataOutHdr, sizeof (ISCSI_SCSI_DATA_OUT));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Set the flags and fields of the Data Out PDU BHS.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ISCSI_SET_OPCODE (DataOutHdr, ISCSI_OPCODE_SCSI_DATA_OUT, 0);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DataOutHdr->InitiatorTaskTag = HTONL (Tcb->InitiatorTaskTag);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DataOutHdr->TargetTransferTag = HTONL (XferContext->TargetTransferTag);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DataOutHdr->ExpStatSN = HTONL (Tcb->Conn->ExpStatSN);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DataOutHdr->BufferOffset = HTONL (XferContext->Offset);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (XferContext->TargetTransferTag != ISCSI_RESERVED_TAG) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (&DataOutHdr->Lun, &Lun, sizeof (DataOutHdr->Lun));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Build the data segment for this Data Out PDU.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Put the data segment into the buffer list and combine it with the BHS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // into a full Data Out PDU.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Pdu = NetbufFromBufList (NbufList, 0, 0, IScsiFreeNbufList, NbufList);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Generate a consecutive sequence of iSCSI SCSI Data Out PDUs.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Data The data which will be carried by the sequence of iSCSI SCSI Data Out PDUs.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Tcb The task control block of the data to send out.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Lun The LUN the data will be sent to.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return A list of net buffers with each of them wrapping an iSCSI SCSI Data Out PDU.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval NULL Other errors as indicated.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Determine the length of data this Data Out PDU can carry.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DataLen = MIN (XferContext->DesiredLength, Conn->MaxRecvDataSegmentLength);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Create a Data Out PDU.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DataOutPdu = IScsiNewDataOutPdu (Data, DataLen, DataSN, Tcb, Lun);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Update the context and DataSN.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Set the F bit for the last data out PDU in this sequence.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DataOutPacket = NetbufGetByte (DataOutPdu, 0, NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ISCSI_SET_FLAG (DataOutPacket, ISCSI_BHS_FLAG_FINAL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Send the Data in a sequence of Data Out PDUs one by one.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Data The data to carry by Data Out PDUs.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Lun The LUN the data will be sent to.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Tcb The task control block.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCES The data is sent out to the LUN.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval Others Other errors as indicated.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Generate the Data Out PDU sequence.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DataOutPduList = IScsiGenerateDataOutPduSequence (Data, Tcb, Lun);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Send the Data Out PDU's one by one.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Process the received iSCSI SCSI Data In PDU.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Pdu The Data In PDU received.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Tcb The task control block.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] Packet The EXT SCSI PASS THRU request packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCES The check on the Data IN PDU is passed and some update
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync actions are taken.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_PROTOCOL_ERROR Some kind of iSCSI protocol errror occurred.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_BAD_BUFFER_SIZEE The buffer was not the proper size for the request.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval Others Other errors as indicated.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DataInHdr = (ISCSI_SCSI_DATA_IN *) NetbufGetByte (Pdu, 0, NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DataInHdr->InitiatorTaskTag = NTOHL (DataInHdr->InitiatorTaskTag);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check the DataSN.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = IScsiCheckSN (&Tcb->ExpDataSN, DataInHdr->DataSN);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (DataInHdr->InitiatorTaskTag != Tcb->InitiatorTaskTag) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Update the command related sequence numbers.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IScsiUpdateCmdSN (Tcb->Conn->Session, DataInHdr->MaxCmdSN, DataInHdr->ExpCmdSN);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (ISCSI_FLAG_ON (DataInHdr, SCSI_DATA_IN_PDU_FLAG_STATUS_VALID)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!ISCSI_FLAG_ON (DataInHdr, ISCSI_BHS_FLAG_FINAL)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The S bit is on but the F bit is off.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (ISCSI_FLAG_ON (DataInHdr, SCSI_DATA_IN_PDU_FLAG_OVERFLOW | SCSI_DATA_IN_PDU_FLAG_UNDERFLOW)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Underflow and Overflow are mutual flags.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // S bit is on, the StatSN is valid.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = IScsiCheckSN (&Tcb->Conn->ExpStatSN, NTOHL (DataInHdr->StatSN));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (ISCSI_FLAG_ON (DataInHdr, SCSI_RSP_PDU_FLAG_OVERFLOW)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Packet->InTransferLength += NTOHL (DataInHdr->ResidualCount);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (ISCSI_FLAG_ON (DataInHdr, SCSI_RSP_PDU_FLAG_UNDERFLOW)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Packet->InTransferLength -= NTOHL (DataInHdr->ResidualCount);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Process the received iSCSI R2T PDU.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Pdu The R2T PDU received.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Tcb The task control block.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Lun The Lun.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] Packet The EXT SCSI PASS THRU request packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCES The R2T PDU is valid and the solicited data is sent out.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_PROTOCOL_ERROR Some kind of iSCSI protocol errror occurred.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval Others Other errors as indicated.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync R2THdr = (ISCSI_READY_TO_TRANSFER *) NetbufGetByte (Pdu, 0, NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync R2THdr->InitiatorTaskTag = NTOHL (R2THdr->InitiatorTaskTag);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync R2THdr->TargetTransferTag = NTOHL (R2THdr->TargetTransferTag);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync R2THdr->BufferOffset = NTOHL (R2THdr->BufferOffset);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync R2THdr->DesiredDataTransferLength = NTOHL (R2THdr->DesiredDataTransferLength);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((R2THdr->InitiatorTaskTag != Tcb->InitiatorTaskTag) || !ISCSI_SEQ_EQ (R2THdr->StatSN, Tcb->Conn->ExpStatSN)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check the sequence number.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = IScsiCheckSN (&Tcb->ExpDataSN, R2THdr->R2TSeqNum);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync XferContext->TargetTransferTag = R2THdr->TargetTransferTag;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync XferContext->DesiredLength = R2THdr->DesiredDataTransferLength;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (((XferContext->Offset + XferContext->DesiredLength) > Packet->OutTransferLength) ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (XferContext->DesiredLength > Tcb->Conn->Session->MaxBurstLength)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Send the data solicited by this R2T.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Data = (UINT8 *) Packet->OutDataBuffer + XferContext->Offset;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = IScsiSendDataOutPduSequence (Data, Lun, Tcb);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Process the received iSCSI SCSI Response PDU.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Pdu The Response PDU received.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Tcb The task control block.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] Packet The EXT SCSI PASS THRU request packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCES The Response PDU is processed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_PROTOCOL_ERROR Some kind of iSCSI protocol errror occurred.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_BAD_BUFFER_SIZEE The buffer was not the proper size for the request.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval Others Other errors as indicated.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ScsiRspHdr = (SCSI_RESPONSE *) NetbufGetByte (Pdu, 0, NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ScsiRspHdr->InitiatorTaskTag = NTOHL (ScsiRspHdr->InitiatorTaskTag);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (ScsiRspHdr->InitiatorTaskTag != Tcb->InitiatorTaskTag) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = IScsiCheckSN (&Tcb->Conn->ExpStatSN, ScsiRspHdr->StatSN);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ScsiRspHdr->MaxCmdSN = NTOHL (ScsiRspHdr->MaxCmdSN);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ScsiRspHdr->ExpCmdSN = NTOHL (ScsiRspHdr->ExpCmdSN);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IScsiUpdateCmdSN (Tcb->Conn->Session, ScsiRspHdr->MaxCmdSN, ScsiRspHdr->ExpCmdSN);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Packet->HostAdapterStatus != ISCSI_SERVICE_RSP_COMMAND_COMPLETE_AT_TARGET) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (ISCSI_FLAG_ON (ScsiRspHdr, SCSI_RSP_PDU_FLAG_BI_READ_OVERFLOW | SCSI_RSP_PDU_FLAG_BI_READ_UNDERFLOW) ||
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ISCSI_FLAG_ON (ScsiRspHdr, SCSI_RSP_PDU_FLAG_OVERFLOW | SCSI_RSP_PDU_FLAG_UNDERFLOW)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (ISCSI_FLAG_ON (ScsiRspHdr, SCSI_RSP_PDU_FLAG_BI_READ_OVERFLOW)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Packet->InTransferLength += NTOHL (ScsiRspHdr->BiReadResidualCount);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (ISCSI_FLAG_ON (ScsiRspHdr, SCSI_RSP_PDU_FLAG_BI_READ_UNDERFLOW)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Packet->InTransferLength -= NTOHL (ScsiRspHdr->BiReadResidualCount);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (ISCSI_FLAG_ON (ScsiRspHdr, SCSI_RSP_PDU_FLAG_OVERFLOW)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Packet->InTransferLength += NTOHL (ScsiRspHdr->ResidualCount);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Packet->OutTransferLength += NTOHL (ScsiRspHdr->ResidualCount);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (ISCSI_FLAG_ON (ScsiRspHdr, SCSI_RSP_PDU_FLAG_UNDERFLOW)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Packet->InTransferLength -= NTOHL (ScsiRspHdr->ResidualCount);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Packet->OutTransferLength -= NTOHL (ScsiRspHdr->ResidualCount);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SenseData = (ISCSI_SENSE_DATA *) NetbufGetByte (Pdu, sizeof (SCSI_RESPONSE), NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Packet->SenseDataLength = (UINT8) MIN (SenseData->Length, Packet->SenseDataLength);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (Packet->SenseData, &SenseData->Data[0], Packet->SenseDataLength);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Process the received NOP In PDU.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Pdu The NOP In PDU received.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Tcb The task control block.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCES The NOP In PDU is processed and the related sequence
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync numbers are updated.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_PROTOCOL_ERROR Some kind of iSCSI protocol errror occurred.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NopInHdr = (ISCSI_NOP_IN *) NetbufGetByte (Pdu, 0, NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (NopInHdr->InitiatorTaskTag == ISCSI_RESERVED_TAG) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = IScsiCheckSN (&Tcb->Conn->ExpStatSN, NopInHdr->StatSN);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IScsiUpdateCmdSN (Tcb->Conn->Session, NopInHdr->MaxCmdSN, NopInHdr->ExpCmdSN);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Execute the SCSI command issued through the EXT SCSI PASS THRU protocol.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] PassThru The EXT SCSI PASS THRU protocol.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Target The target ID.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Lun The LUN.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] Packet The request packet containing IO request, SCSI command
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync buffer and buffers to read/write.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCES The SCSI command is executed and the result is updated to
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the Packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_DEVICE_ERROR Session state was not as required.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_PROTOCOL_ERROR There is no such data in the net buffer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval Others Other errors as indicated.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Private = ISCSI_DRIVER_DATA_FROM_EXT_SCSI_PASS_THRU (PassThru);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Encapsulate the SCSI request packet into an iSCSI SCSI Command PDU.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync XferContext->Offset = ISCSI_GET_DATASEG_LEN (PduHdr);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Transmit the SCSI Command PDU.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (XferContext->Offset < Session->FirstBurstLength) &&
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Unsolicited Data-Out sequence is allowed. There is remaining SCSI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // OUT data, and the limit of FirstBurstLength is not reached.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync XferContext->TargetTransferTag = ISCSI_RESERVED_TAG;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Data = (UINT8 *) Packet->OutDataBuffer + XferContext->Offset;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = IScsiSendDataOutPduSequence (Data, Lun, Tcb);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InBufferContext.InData = (UINT8 *) Packet->InDataBuffer;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InBufferContext.InDataLen = Packet->InTransferLength;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Start the timeout timer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->SetTimer (Conn->TimeoutEvent, TimerRelative, Timeout);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Try to receive PDU from target.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = IScsiReceivePdu (Conn, &Pdu, &InBufferContext, FALSE, FALSE, TimeoutEvent);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // These messages are vendor specific. Skip them.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((Status != EFI_SUCCESS) && (Status != EFI_NOT_READY)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Reinstate the session.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (IScsiSessionReinstatement (Session))) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Reinstate the session on some error.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Session The iSCSI session
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The session is reinstated from some error.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval Other Reinstatement failed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (Session->State == SESSION_STATE_LOGGED_IN);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Abort the session and re-init it.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Login again.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Initialize some session parameters before login.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] Session The iSCSI session.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Recovery Whether the request is from a fresh new start or recovery.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Session->MaxConnections = ISCSI_MAX_CONNS_PER_SESSION;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Session->FirstBurstLength = MAX_RECV_DATA_SEG_LEN_IN_FFP;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Session->MaxOutstandingR2T = DEFAULT_MAX_OUTSTANDING_R2T;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Abort the iSCSI session. That is, reset all the connection(s), and free the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] Session The iSCSI session.