E.2.2. Initiator Algorithms
E.2.2. 이니시에이터 알고리즘
Recover-Data-if-Possible(LastRequiredDataSN, TCB)
{
if (operational ErrorRecoveryLevel > 0) {
if (# of missing PDUs is trackable) {
[@E Note the missing DataSNs in TCB. @E]
[@K TCB에 누락된 DataSN이 있습니다. @K]
if (the task spanned a change in
MaxRecvDataSegmentLength) {
if (TCB.StatusXferd is TRUE)
drop the status PDU;
Build-And-Send-RDSnack(TCB);
} else {
Build-And-Send-DSnack(TCB);
}
} else {
TCB.Reason = "Protocol service CRC error";
}
} else {
TCB.Reason = "Protocol service CRC error";
}
if (TCB.Reason == "Protocol service CRC error") {
[@E Clear the missing PDU list in the TCB. @E]
[@K TCB에서 누락된 PDU 목록을 지웁니다. @K]
if (TCB.StatusXferd is not TRUE)
Build-And-Send-Abort(TCB);
}
}
Receive-a-In-PDU(Connection, CurrentPDU)
{
check-basic-validity(CurrentPDU);
if (Header-Digest-Bad) discard, return;
Retrieve TCB for CurrentPDU.InitiatorTaskTag.
if ((CurrentPDU.type == Data)
or (CurrentPDU.type = R2T)) {
if (Data-Digest-Bad for Data) {
send-data-SNACK = TRUE;
LastRequiredDataSN = CurrentPDU.DataSN;
} else {
if (TCB.SoFarInOrder = TRUE) {
if (current DataSN is expected) {
Increment TCB.ExpectedDataSN.
} else {
TCB.SoFarInOrder = FALSE;
send-data-SNACK = TRUE;
}
} else {
if (current DataSN was considered missing) {
remove current DataSN from missing PDU list.
} else if (current DataSN is higher than expected)
{
send-data-SNACK = TRUE;
} else {
discard, return;
}
Adjust TCB.ExpectedDataSN if appropriate.
}
LastRequiredDataSN = CurrentPDU.DataSN - 1;
}
if (send-data-SNACK is TRUE and
task is not already considered failed) {
Recover-Data-if-Possible(LastRequiredDataSN, TCB);
}
if (missing data PDU list is empty) {
TCB.SoFarInOrder = TRUE;
}
if (CurrentPDU.type == R2T) {
Increment ActiveR2Ts for this task.
Create a data-descriptor for the data burst.
Build-And-Send-A-Data-Burst(Connection, data-descriptor,
TCB);
}
} else if (CurrentPDU.type == Response) {
if (Data-Digest-Bad) {
send-status-SNACK = TRUE;
} else {
TCB.StatusXferd = TRUE;
Store the status information in TCB.
if (ExpDataSN does not match) {
TCB.SoFarInOrder = FALSE;
Recover-Data-if-Possible(current DataSN, TCB);
}
if (missing data PDU list is empty) {
TCB.SoFarInOrder = TRUE;
}
}
} else { /* REST UNRELATED TO WITHIN-COMMAND-RECOVERY, NOT
SHOWN */
}
if ((TCB.SoFarInOrder == TRUE) and
(TCB.StatusXferd == TRUE)) {
SCSI-Task-Completion(TCB);
}
}