aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/libfc/fc_fcp.c47
1 files changed, 28 insertions, 19 deletions
diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c
index 17396c708b08..39f18e39125c 100644
--- a/drivers/scsi/libfc/fc_fcp.c
+++ b/drivers/scsi/libfc/fc_fcp.c
@@ -97,7 +97,7 @@ static void fc_fcp_resp(struct fc_fcp_pkt *, struct fc_frame *);
97static void fc_fcp_complete_locked(struct fc_fcp_pkt *); 97static void fc_fcp_complete_locked(struct fc_fcp_pkt *);
98static void fc_tm_done(struct fc_seq *, struct fc_frame *, void *); 98static void fc_tm_done(struct fc_seq *, struct fc_frame *, void *);
99static void fc_fcp_error(struct fc_fcp_pkt *, struct fc_frame *); 99static void fc_fcp_error(struct fc_fcp_pkt *, struct fc_frame *);
100static void fc_timeout_error(struct fc_fcp_pkt *); 100static void fc_fcp_recovery(struct fc_fcp_pkt *);
101static void fc_fcp_timeout(unsigned long); 101static void fc_fcp_timeout(unsigned long);
102static void fc_fcp_rec(struct fc_fcp_pkt *); 102static void fc_fcp_rec(struct fc_fcp_pkt *);
103static void fc_fcp_rec_error(struct fc_fcp_pkt *, struct fc_frame *); 103static 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 *);
121#define FC_DATA_UNDRUN 7 121#define FC_DATA_UNDRUN 7
122#define FC_ERROR 8 122#define FC_ERROR 8
123#define FC_HRD_ERROR 9 123#define FC_HRD_ERROR 9
124#define FC_CMD_TIME_OUT 10 124#define FC_CMD_RECOVERY 10
125 125
126/* 126/*
127 * Error recovery timeout values. 127 * Error recovery timeout values.
@@ -446,9 +446,16 @@ static void fc_fcp_recv_data(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
446 len = fr_len(fp) - sizeof(*fh); 446 len = fr_len(fp) - sizeof(*fh);
447 buf = fc_frame_payload_get(fp, 0); 447 buf = fc_frame_payload_get(fp, 0);
448 448
449 /* if this I/O is ddped, update xfer len */ 449 /*
450 fc_fcp_ddp_done(fsp); 450 * if this I/O is ddped then clear it
451 451 * and initiate recovery since data
452 * frames are expected to be placed
453 * directly in that case.
454 */
455 if (fsp->xfer_ddp != FC_XID_UNKNOWN) {
456 fc_fcp_ddp_done(fsp);
457 goto err;
458 }
452 if (offset + len > fsp->data_len) { 459 if (offset + len > fsp->data_len) {
453 /* this should never happen */ 460 /* this should never happen */
454 if ((fr_flags(fp) & FCPHF_CRC_UNCHECKED) && 461 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)
456 goto crc_err; 463 goto crc_err;
457 FC_FCP_DBG(fsp, "data received past end. len %zx offset %zx " 464 FC_FCP_DBG(fsp, "data received past end. len %zx offset %zx "
458 "data_len %x\n", len, offset, fsp->data_len); 465 "data_len %x\n", len, offset, fsp->data_len);
459 fc_fcp_retry_cmd(fsp); 466 goto err;
460 return;
461 } 467 }
462 if (offset != fsp->xfer_len) 468 if (offset != fsp->xfer_len)
463 fsp->state |= FC_SRB_DISCONTIG; 469 fsp->state |= FC_SRB_DISCONTIG;
@@ -493,7 +499,7 @@ crc_err:
493 * Otherwise, ignore it. 499 * Otherwise, ignore it.
494 */ 500 */
495 if (fsp->state & FC_SRB_DISCONTIG) 501 if (fsp->state & FC_SRB_DISCONTIG)
496 fc_fcp_retry_cmd(fsp); 502 goto err;
497 return; 503 return;
498 } 504 }
499 } 505 }
@@ -509,6 +515,9 @@ crc_err:
509 if (unlikely(fsp->state & FC_SRB_RCV_STATUS) && 515 if (unlikely(fsp->state & FC_SRB_RCV_STATUS) &&
510 fsp->xfer_len == fsp->data_len - fsp->scsi_resid) 516 fsp->xfer_len == fsp->data_len - fsp->scsi_resid)
511 fc_fcp_complete_locked(fsp); 517 fc_fcp_complete_locked(fsp);
518 return;
519err:
520 fc_fcp_recovery(fsp);
512} 521}
513 522
514/** 523/**
@@ -1341,7 +1350,7 @@ static void fc_fcp_timeout(unsigned long data)
1341 else if (fsp->state & FC_SRB_RCV_STATUS) 1350 else if (fsp->state & FC_SRB_RCV_STATUS)
1342 fc_fcp_complete_locked(fsp); 1351 fc_fcp_complete_locked(fsp);
1343 else 1352 else
1344 fc_timeout_error(fsp); 1353 fc_fcp_recovery(fsp);
1345 fsp->state &= ~FC_SRB_FCP_PROCESSING_TMO; 1354 fsp->state &= ~FC_SRB_FCP_PROCESSING_TMO;
1346unlock: 1355unlock:
1347 fc_fcp_unlock_pkt(fsp); 1356 fc_fcp_unlock_pkt(fsp);
@@ -1385,7 +1394,7 @@ retry:
1385 if (fsp->recov_retry++ < FC_MAX_RECOV_RETRY) 1394 if (fsp->recov_retry++ < FC_MAX_RECOV_RETRY)
1386 fc_fcp_timer_set(fsp, FC_SCSI_REC_TOV); 1395 fc_fcp_timer_set(fsp, FC_SCSI_REC_TOV);
1387 else 1396 else
1388 fc_timeout_error(fsp); 1397 fc_fcp_recovery(fsp);
1389} 1398}
1390 1399
1391/** 1400/**
@@ -1454,7 +1463,7 @@ static void fc_fcp_rec_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg)
1454 fc_fcp_retry_cmd(fsp); 1463 fc_fcp_retry_cmd(fsp);
1455 break; 1464 break;
1456 } 1465 }
1457 fc_timeout_error(fsp); 1466 fc_fcp_recovery(fsp);
1458 break; 1467 break;
1459 } 1468 }
1460 } else if (opcode == ELS_LS_ACC) { 1469 } 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)
1569 if (fsp->recov_retry++ < FC_MAX_RECOV_RETRY) 1578 if (fsp->recov_retry++ < FC_MAX_RECOV_RETRY)
1570 fc_fcp_rec(fsp); 1579 fc_fcp_rec(fsp);
1571 else 1580 else
1572 fc_timeout_error(fsp); 1581 fc_fcp_recovery(fsp);
1573 break; 1582 break;
1574 } 1583 }
1575 fc_fcp_unlock_pkt(fsp); 1584 fc_fcp_unlock_pkt(fsp);
@@ -1578,12 +1587,12 @@ out:
1578} 1587}
1579 1588
1580/** 1589/**
1581 * fc_timeout_error() - Handler for fcp_pkt timeouts 1590 * fc_fcp_recovery() - Handler for fcp_pkt recovery
1582 * @fsp: The FCP packt that has timed out 1591 * @fsp: The FCP pkt that needs to be aborted
1583 */ 1592 */
1584static void fc_timeout_error(struct fc_fcp_pkt *fsp) 1593static void fc_fcp_recovery(struct fc_fcp_pkt *fsp)
1585{ 1594{
1586 fsp->status_code = FC_CMD_TIME_OUT; 1595 fsp->status_code = FC_CMD_RECOVERY;
1587 fsp->cdb_status = 0; 1596 fsp->cdb_status = 0;
1588 fsp->io_status = 0; 1597 fsp->io_status = 0;
1589 /* 1598 /*
@@ -1689,7 +1698,7 @@ static void fc_fcp_srr_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg)
1689 break; 1698 break;
1690 case ELS_LS_RJT: 1699 case ELS_LS_RJT:
1691 default: 1700 default:
1692 fc_timeout_error(fsp); 1701 fc_fcp_recovery(fsp);
1693 break; 1702 break;
1694 } 1703 }
1695 fc_fcp_unlock_pkt(fsp); 1704 fc_fcp_unlock_pkt(fsp);
@@ -1715,7 +1724,7 @@ static void fc_fcp_srr_error(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
1715 if (fsp->recov_retry++ < FC_MAX_RECOV_RETRY) 1724 if (fsp->recov_retry++ < FC_MAX_RECOV_RETRY)
1716 fc_fcp_rec(fsp); 1725 fc_fcp_rec(fsp);
1717 else 1726 else
1718 fc_timeout_error(fsp); 1727 fc_fcp_recovery(fsp);
1719 break; 1728 break;
1720 case -FC_EX_CLOSED: /* e.g., link failure */ 1729 case -FC_EX_CLOSED: /* e.g., link failure */
1721 /* fall through */ 1730 /* fall through */
@@ -1934,7 +1943,7 @@ static void fc_io_compl(struct fc_fcp_pkt *fsp)
1934 case FC_CMD_ABORTED: 1943 case FC_CMD_ABORTED:
1935 sc_cmd->result = (DID_ERROR << 16) | fsp->io_status; 1944 sc_cmd->result = (DID_ERROR << 16) | fsp->io_status;
1936 break; 1945 break;
1937 case FC_CMD_TIME_OUT: 1946 case FC_CMD_RECOVERY:
1938 sc_cmd->result = (DID_BUS_BUSY << 16) | fsp->io_status; 1947 sc_cmd->result = (DID_BUS_BUSY << 16) | fsp->io_status;
1939 break; 1948 break;
1940 case FC_CMD_RESET: 1949 case FC_CMD_RESET: