diff options
author | Brian King <brking@linux.vnet.ibm.com> | 2013-04-12 09:25:17 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2013-05-02 14:57:24 -0400 |
commit | 55d29bf00f57200cc8b3d3e3e45614baaf5ca27d (patch) | |
tree | 7b9c12e6798b56adb247987fe3ce1b2fb5f4cd25 /drivers/scsi/ibmvscsi/ibmvfc.c | |
parent | 93631b4aac7cac29a1ba9c0b849bf527b7e07028 (diff) |
[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/ibmvscsi/ibmvfc.c')
-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) | |||
2179 | return 0; | 2179 | return 0; |
2180 | } | 2180 | } |
2181 | 2181 | ||
2182 | if (vhost->state == IBMVFC_ACTIVE) { | 2182 | if (vhost->logged_in) { |
2183 | evt = ibmvfc_get_event(vhost); | 2183 | evt = ibmvfc_get_event(vhost); |
2184 | ibmvfc_init_event(evt, ibmvfc_sync_completion, IBMVFC_MAD_FORMAT); | 2184 | ibmvfc_init_event(evt, ibmvfc_sync_completion, IBMVFC_MAD_FORMAT); |
2185 | 2185 | ||
@@ -2190,7 +2190,10 @@ static int ibmvfc_cancel_all(struct scsi_device *sdev, int type) | |||
2190 | tmf->common.length = sizeof(*tmf); | 2190 | tmf->common.length = sizeof(*tmf); |
2191 | tmf->scsi_id = rport->port_id; | 2191 | tmf->scsi_id = rport->port_id; |
2192 | int_to_scsilun(sdev->lun, &tmf->lun); | 2192 | int_to_scsilun(sdev->lun, &tmf->lun); |
2193 | tmf->flags = (type | IBMVFC_TMF_LUA_VALID); | 2193 | if (vhost->state == IBMVFC_ACTIVE) |
2194 | tmf->flags = (type | IBMVFC_TMF_LUA_VALID); | ||
2195 | else | ||
2196 | tmf->flags = IBMVFC_TMF_LUA_VALID; | ||
2194 | tmf->cancel_key = (unsigned long)sdev->hostdata; | 2197 | tmf->cancel_key = (unsigned long)sdev->hostdata; |
2195 | tmf->my_cancel_key = (unsigned long)starget->hostdata; | 2198 | tmf->my_cancel_key = (unsigned long)starget->hostdata; |
2196 | 2199 | ||
@@ -2389,7 +2392,7 @@ static int ibmvfc_eh_abort_handler(struct scsi_cmnd *cmd) | |||
2389 | { | 2392 | { |
2390 | struct scsi_device *sdev = cmd->device; | 2393 | struct scsi_device *sdev = cmd->device; |
2391 | struct ibmvfc_host *vhost = shost_priv(sdev->host); | 2394 | struct ibmvfc_host *vhost = shost_priv(sdev->host); |
2392 | int cancel_rc, block_rc, abort_rc = 0; | 2395 | int cancel_rc, block_rc; |
2393 | int rc = FAILED; | 2396 | int rc = FAILED; |
2394 | 2397 | ||
2395 | ENTER; | 2398 | ENTER; |
@@ -2397,11 +2400,11 @@ static int ibmvfc_eh_abort_handler(struct scsi_cmnd *cmd) | |||
2397 | ibmvfc_wait_while_resetting(vhost); | 2400 | ibmvfc_wait_while_resetting(vhost); |
2398 | if (block_rc != FAST_IO_FAIL) { | 2401 | if (block_rc != FAST_IO_FAIL) { |
2399 | cancel_rc = ibmvfc_cancel_all(sdev, IBMVFC_TMF_ABORT_TASK_SET); | 2402 | cancel_rc = ibmvfc_cancel_all(sdev, IBMVFC_TMF_ABORT_TASK_SET); |
2400 | abort_rc = ibmvfc_abort_task_set(sdev); | 2403 | ibmvfc_abort_task_set(sdev); |
2401 | } else | 2404 | } else |
2402 | cancel_rc = ibmvfc_cancel_all(sdev, 0); | 2405 | cancel_rc = ibmvfc_cancel_all(sdev, 0); |
2403 | 2406 | ||
2404 | if (!cancel_rc && !abort_rc) | 2407 | if (!cancel_rc) |
2405 | rc = ibmvfc_wait_for_ops(vhost, sdev, ibmvfc_match_lun); | 2408 | rc = ibmvfc_wait_for_ops(vhost, sdev, ibmvfc_match_lun); |
2406 | 2409 | ||
2407 | if (block_rc == FAST_IO_FAIL && rc != FAILED) | 2410 | if (block_rc == FAST_IO_FAIL && rc != FAILED) |