static int iscsit_dataout_post_crc_failed( struct iscsi_cmd *cmd, unsigned char *buf) { struct iscsi_conn *conn = cmd->conn; struct iscsi_pdu *pdu; struct iscsi_data *hdr = (struct iscsi_data *) buf; u32 payload_length = ntoh24(hdr->dlength); if (conn->sess->sess_ops->DataPDUInOrder) goto recover; /* * The rest of this function is only called when DataPDUInOrder=No. */ pdu = cmd->pdu_ptr; switch (pdu->status) { case ISCSI_PDU_NOT_RECEIVED: pdu->status = ISCSI_PDU_CRC_FAILED; break; case ISCSI_PDU_CRC_FAILED: break; case ISCSI_PDU_TIMED_OUT: pdu->status = ISCSI_PDU_CRC_FAILED; break; default: return DATAOUT_CANNOT_RECOVER; } recover: return iscsit_recover_dataout_sequence(cmd, be32_to_cpu(hdr->offset), payload_length); }
static int iscsit_dataout_pre_datapduinorder_yes( struct iscsi_cmd *cmd, unsigned char *buf) { int dump = 0, recovery = 0; struct iscsi_conn *conn = cmd->conn; struct iscsi_data *hdr = (struct iscsi_data *) buf; u32 payload_length = ntoh24(hdr->dlength); /* * For DataSequenceInOrder=Yes: If the offset is greater than the global * DataPDUInOrder=Yes offset counter in struct iscsi_cmd a protcol error has * occured and fail the connection. * * For DataSequenceInOrder=No: If the offset is greater than the per * sequence DataPDUInOrder=Yes offset counter in struct iscsi_seq a protocol * error has occured and fail the connection. */ if (conn->sess->sess_ops->DataSequenceInOrder) { if (hdr->offset != cmd->write_data_done) { pr_err("Command ITT: 0x%08x, received offset" " %u different than expected %u.\n", cmd->init_task_tag, hdr->offset, cmd->write_data_done); recovery = 1; goto recover; } } else { struct iscsi_seq *seq = cmd->seq_ptr; if (hdr->offset > seq->offset) { pr_err("Command ITT: 0x%08x, received offset" " %u greater than expected %u.\n", cmd->init_task_tag, hdr->offset, seq->offset); recovery = 1; goto recover; } else if (hdr->offset < seq->offset) { pr_err("Command ITT: 0x%08x, received offset" " %u less than expected %u, discarding payload.\n", cmd->init_task_tag, hdr->offset, seq->offset); dump = 1; goto dump; } } return DATAOUT_NORMAL; recover: if (!conn->sess->sess_ops->ErrorRecoveryLevel) { pr_err("Unable to perform within-command recovery" " while ERL=0.\n"); return DATAOUT_CANNOT_RECOVER; } dump: if (iscsit_dump_data_payload(conn, payload_length, 1) < 0) return DATAOUT_CANNOT_RECOVER; return (recovery) ? iscsit_recover_dataout_sequence(cmd, hdr->offset, payload_length) : (dump) ? DATAOUT_WITHIN_COMMAND_RECOVERY : DATAOUT_NORMAL; }