|
@@ -97,7 +97,7 @@ static void fc_fcp_resp(struct fc_fcp_pkt *, struct fc_frame *);
|
|
|
static void fc_fcp_complete_locked(struct fc_fcp_pkt *);
|
|
|
static void fc_tm_done(struct fc_seq *, struct fc_frame *, void *);
|
|
|
static void fc_fcp_error(struct fc_fcp_pkt *, struct fc_frame *);
|
|
|
-static void fc_timeout_error(struct fc_fcp_pkt *);
|
|
|
+static void fc_fcp_recovery(struct fc_fcp_pkt *);
|
|
|
static void fc_fcp_timeout(unsigned long);
|
|
|
static void fc_fcp_rec(struct fc_fcp_pkt *);
|
|
|
static void fc_fcp_rec_error(struct fc_fcp_pkt *, struct fc_frame *);
|
|
@@ -121,7 +121,7 @@ static void fc_fcp_srr_error(struct fc_fcp_pkt *, struct fc_frame *);
|
|
|
#define FC_DATA_UNDRUN 7
|
|
|
#define FC_ERROR 8
|
|
|
#define FC_HRD_ERROR 9
|
|
|
-#define FC_CMD_TIME_OUT 10
|
|
|
+#define FC_CMD_RECOVERY 10
|
|
|
|
|
|
/*
|
|
|
* Error recovery timeout values.
|
|
@@ -446,9 +446,16 @@ static void fc_fcp_recv_data(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
|
|
|
len = fr_len(fp) - sizeof(*fh);
|
|
|
buf = fc_frame_payload_get(fp, 0);
|
|
|
|
|
|
- /* if this I/O is ddped, update xfer len */
|
|
|
- fc_fcp_ddp_done(fsp);
|
|
|
-
|
|
|
+ /*
|
|
|
+ * if this I/O is ddped then clear it
|
|
|
+ * and initiate recovery since data
|
|
|
+ * frames are expected to be placed
|
|
|
+ * directly in that case.
|
|
|
+ */
|
|
|
+ if (fsp->xfer_ddp != FC_XID_UNKNOWN) {
|
|
|
+ fc_fcp_ddp_done(fsp);
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
if (offset + len > fsp->data_len) {
|
|
|
/* this should never happen */
|
|
|
if ((fr_flags(fp) & FCPHF_CRC_UNCHECKED) &&
|
|
@@ -456,8 +463,7 @@ static void fc_fcp_recv_data(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
|
|
|
goto crc_err;
|
|
|
FC_FCP_DBG(fsp, "data received past end. len %zx offset %zx "
|
|
|
"data_len %x\n", len, offset, fsp->data_len);
|
|
|
- fc_fcp_retry_cmd(fsp);
|
|
|
- return;
|
|
|
+ goto err;
|
|
|
}
|
|
|
if (offset != fsp->xfer_len)
|
|
|
fsp->state |= FC_SRB_DISCONTIG;
|
|
@@ -493,7 +499,7 @@ crc_err:
|
|
|
* Otherwise, ignore it.
|
|
|
*/
|
|
|
if (fsp->state & FC_SRB_DISCONTIG)
|
|
|
- fc_fcp_retry_cmd(fsp);
|
|
|
+ goto err;
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
@@ -509,6 +515,9 @@ crc_err:
|
|
|
if (unlikely(fsp->state & FC_SRB_RCV_STATUS) &&
|
|
|
fsp->xfer_len == fsp->data_len - fsp->scsi_resid)
|
|
|
fc_fcp_complete_locked(fsp);
|
|
|
+ return;
|
|
|
+err:
|
|
|
+ fc_fcp_recovery(fsp);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -1341,7 +1350,7 @@ static void fc_fcp_timeout(unsigned long data)
|
|
|
else if (fsp->state & FC_SRB_RCV_STATUS)
|
|
|
fc_fcp_complete_locked(fsp);
|
|
|
else
|
|
|
- fc_timeout_error(fsp);
|
|
|
+ fc_fcp_recovery(fsp);
|
|
|
fsp->state &= ~FC_SRB_FCP_PROCESSING_TMO;
|
|
|
unlock:
|
|
|
fc_fcp_unlock_pkt(fsp);
|
|
@@ -1385,7 +1394,7 @@ retry:
|
|
|
if (fsp->recov_retry++ < FC_MAX_RECOV_RETRY)
|
|
|
fc_fcp_timer_set(fsp, FC_SCSI_REC_TOV);
|
|
|
else
|
|
|
- fc_timeout_error(fsp);
|
|
|
+ fc_fcp_recovery(fsp);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -1454,7 +1463,7 @@ static void fc_fcp_rec_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg)
|
|
|
fc_fcp_retry_cmd(fsp);
|
|
|
break;
|
|
|
}
|
|
|
- fc_timeout_error(fsp);
|
|
|
+ fc_fcp_recovery(fsp);
|
|
|
break;
|
|
|
}
|
|
|
} else if (opcode == ELS_LS_ACC) {
|
|
@@ -1569,7 +1578,7 @@ static void fc_fcp_rec_error(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
|
|
|
if (fsp->recov_retry++ < FC_MAX_RECOV_RETRY)
|
|
|
fc_fcp_rec(fsp);
|
|
|
else
|
|
|
- fc_timeout_error(fsp);
|
|
|
+ fc_fcp_recovery(fsp);
|
|
|
break;
|
|
|
}
|
|
|
fc_fcp_unlock_pkt(fsp);
|
|
@@ -1578,12 +1587,12 @@ out:
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * fc_timeout_error() - Handler for fcp_pkt timeouts
|
|
|
- * @fsp: The FCP packt that has timed out
|
|
|
+ * fc_fcp_recovery() - Handler for fcp_pkt recovery
|
|
|
+ * @fsp: The FCP pkt that needs to be aborted
|
|
|
*/
|
|
|
-static void fc_timeout_error(struct fc_fcp_pkt *fsp)
|
|
|
+static void fc_fcp_recovery(struct fc_fcp_pkt *fsp)
|
|
|
{
|
|
|
- fsp->status_code = FC_CMD_TIME_OUT;
|
|
|
+ fsp->status_code = FC_CMD_RECOVERY;
|
|
|
fsp->cdb_status = 0;
|
|
|
fsp->io_status = 0;
|
|
|
/*
|
|
@@ -1689,7 +1698,7 @@ static void fc_fcp_srr_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg)
|
|
|
break;
|
|
|
case ELS_LS_RJT:
|
|
|
default:
|
|
|
- fc_timeout_error(fsp);
|
|
|
+ fc_fcp_recovery(fsp);
|
|
|
break;
|
|
|
}
|
|
|
fc_fcp_unlock_pkt(fsp);
|
|
@@ -1715,7 +1724,7 @@ static void fc_fcp_srr_error(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
|
|
|
if (fsp->recov_retry++ < FC_MAX_RECOV_RETRY)
|
|
|
fc_fcp_rec(fsp);
|
|
|
else
|
|
|
- fc_timeout_error(fsp);
|
|
|
+ fc_fcp_recovery(fsp);
|
|
|
break;
|
|
|
case -FC_EX_CLOSED: /* e.g., link failure */
|
|
|
/* fall through */
|
|
@@ -1934,7 +1943,7 @@ static void fc_io_compl(struct fc_fcp_pkt *fsp)
|
|
|
case FC_CMD_ABORTED:
|
|
|
sc_cmd->result = (DID_ERROR << 16) | fsp->io_status;
|
|
|
break;
|
|
|
- case FC_CMD_TIME_OUT:
|
|
|
+ case FC_CMD_RECOVERY:
|
|
|
sc_cmd->result = (DID_BUS_BUSY << 16) | fsp->io_status;
|
|
|
break;
|
|
|
case FC_CMD_RESET:
|