diff options
author | Brian King <brking@linux.vnet.ibm.com> | 2013-04-12 17:25:17 +0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2013-05-02 22:57:24 +0400 |
commit | 55d29bf00f57200cc8b3d3e3e45614baaf5ca27d (patch) | |
tree | 7b9c12e6798b56adb247987fe3ce1b2fb5f4cd25 /drivers/scsi | |
parent | 93631b4aac7cac29a1ba9c0b849bf527b7e07028 (diff) | |
download | linux-55d29bf00f57200cc8b3d3e3e45614baaf5ca27d.tar.xz |
[SCSI] ibmvfc: Send cancel when link is down
If attempting to abort requests due to a fail fail timeout
or error handling while the link is down, we cannot send
an abort out on the fabric. We can, however, send a cancel
to the VIOS. This fixes ibmvfc to send a cancel in this
case to prevent error handling from failing and/or
escalating.
Signed-off-by: Brian King <brking@linux.vnet.ibm.com>
Acked-by: Robert Jennings <rcj@linux.vnet.ibm.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/ibmvscsi/ibmvfc.c | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c index 1221b760f49e..c0e06de36874 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.c +++ b/drivers/scsi/ibmvscsi/ibmvfc.c @@ -2179,7 +2179,7 @@ static int ibmvfc_cancel_all(struct scsi_device *sdev, int type) return 0; } - if (vhost->state == IBMVFC_ACTIVE) { + if (vhost->logged_in) { evt = ibmvfc_get_event(vhost); ibmvfc_init_event(evt, ibmvfc_sync_completion, IBMVFC_MAD_FORMAT); @@ -2190,7 +2190,10 @@ static int ibmvfc_cancel_all(struct scsi_device *sdev, int type) tmf->common.length = sizeof(*tmf); tmf->scsi_id = rport->port_id; int_to_scsilun(sdev->lun, &tmf->lun); - tmf->flags = (type | IBMVFC_TMF_LUA_VALID); + if (vhost->state == IBMVFC_ACTIVE) + tmf->flags = (type | IBMVFC_TMF_LUA_VALID); + else + tmf->flags = IBMVFC_TMF_LUA_VALID; tmf->cancel_key = (unsigned long)sdev->hostdata; tmf->my_cancel_key = (unsigned long)starget->hostdata; @@ -2389,7 +2392,7 @@ static int ibmvfc_eh_abort_handler(struct scsi_cmnd *cmd) { struct scsi_device *sdev = cmd->device; struct ibmvfc_host *vhost = shost_priv(sdev->host); - int cancel_rc, block_rc, abort_rc = 0; + int cancel_rc, block_rc; int rc = FAILED; ENTER; @@ -2397,11 +2400,11 @@ static int ibmvfc_eh_abort_handler(struct scsi_cmnd *cmd) ibmvfc_wait_while_resetting(vhost); if (block_rc != FAST_IO_FAIL) { cancel_rc = ibmvfc_cancel_all(sdev, IBMVFC_TMF_ABORT_TASK_SET); - abort_rc = ibmvfc_abort_task_set(sdev); + ibmvfc_abort_task_set(sdev); } else cancel_rc = ibmvfc_cancel_all(sdev, 0); - if (!cancel_rc && !abort_rc) + if (!cancel_rc) rc = ibmvfc_wait_for_ops(vhost, sdev, ibmvfc_match_lun); if (block_rc == FAST_IO_FAIL && rc != FAILED) |