diff options
author | Brian King <brking@linux.vnet.ibm.com> | 2013-04-12 15:25:18 +0200 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2013-05-02 20:57:51 +0200 |
commit | 90f725dbb20557d30e6eb20959bb08cae2661a70 (patch) | |
tree | 14a759370b085fc4618ee3355e07460ad7cd4ca3 | |
parent | [SCSI] ibmvfc: Send cancel when link is down (diff) | |
download | linux-90f725dbb20557d30e6eb20959bb08cae2661a70.tar.xz linux-90f725dbb20557d30e6eb20959bb08cae2661a70.zip |
[SCSI] ibmvfc: Suppress ABTS if target gone
Adds support for a new VIOS feature that allows ibmvfc to
optimize terminate_rport_io by telling the VIOS the target
is no longer accessible on the fabric and that it should
not send an ABTS out on the fabric to the device.
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>
-rw-r--r-- | drivers/scsi/ibmvscsi/ibmvfc.c | 13 | ||||
-rw-r--r-- | drivers/scsi/ibmvscsi/ibmvfc.h | 3 |
2 files changed, 9 insertions, 7 deletions
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c index c0e06de36874..4e31caa21ddf 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.c +++ b/drivers/scsi/ibmvscsi/ibmvfc.c @@ -2190,10 +2190,12 @@ 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); + if (!(vhost->login_buf->resp.capabilities & IBMVFC_CAN_SUPPRESS_ABTS)) + type &= ~IBMVFC_TMF_SUPPRESS_ABTS; if (vhost->state == IBMVFC_ACTIVE) tmf->flags = (type | IBMVFC_TMF_LUA_VALID); else - tmf->flags = IBMVFC_TMF_LUA_VALID; + tmf->flags = ((type & IBMVFC_TMF_SUPPRESS_ABTS) | IBMVFC_TMF_LUA_VALID); tmf->cancel_key = (unsigned long)sdev->hostdata; tmf->my_cancel_key = (unsigned long)starget->hostdata; @@ -2402,7 +2404,7 @@ static int ibmvfc_eh_abort_handler(struct scsi_cmnd *cmd) cancel_rc = ibmvfc_cancel_all(sdev, IBMVFC_TMF_ABORT_TASK_SET); ibmvfc_abort_task_set(sdev); } else - cancel_rc = ibmvfc_cancel_all(sdev, 0); + cancel_rc = ibmvfc_cancel_all(sdev, IBMVFC_TMF_SUPPRESS_ABTS); if (!cancel_rc) rc = ibmvfc_wait_for_ops(vhost, sdev, ibmvfc_match_lun); @@ -2435,7 +2437,7 @@ static int ibmvfc_eh_device_reset_handler(struct scsi_cmnd *cmd) cancel_rc = ibmvfc_cancel_all(sdev, IBMVFC_TMF_LUN_RESET); reset_rc = ibmvfc_reset_device(sdev, IBMVFC_LUN_RESET, "LUN"); } else - cancel_rc = ibmvfc_cancel_all(sdev, 0); + cancel_rc = ibmvfc_cancel_all(sdev, IBMVFC_TMF_SUPPRESS_ABTS); if (!cancel_rc && !reset_rc) rc = ibmvfc_wait_for_ops(vhost, sdev, ibmvfc_match_lun); @@ -2456,7 +2458,7 @@ static int ibmvfc_eh_device_reset_handler(struct scsi_cmnd *cmd) static void ibmvfc_dev_cancel_all_noreset(struct scsi_device *sdev, void *data) { unsigned long *rc = data; - *rc |= ibmvfc_cancel_all(sdev, 0); + *rc |= ibmvfc_cancel_all(sdev, IBMVFC_TMF_SUPPRESS_ABTS); } /** @@ -2547,8 +2549,7 @@ static void ibmvfc_terminate_rport_io(struct fc_rport *rport) dev_rport = starget_to_rport(scsi_target(sdev)); if (dev_rport != rport) continue; - ibmvfc_cancel_all(sdev, IBMVFC_TMF_ABORT_TASK_SET); - ibmvfc_abort_task_set(sdev); + ibmvfc_cancel_all(sdev, IBMVFC_TMF_SUPPRESS_ABTS); } rc = ibmvfc_wait_for_ops(vhost, rport, ibmvfc_match_rport); diff --git a/drivers/scsi/ibmvscsi/ibmvfc.h b/drivers/scsi/ibmvscsi/ibmvfc.h index 3be8af624e6f..219005da37c0 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.h +++ b/drivers/scsi/ibmvscsi/ibmvfc.h @@ -208,10 +208,10 @@ struct ibmvfc_npiv_login_resp { u16 error; u32 flags; #define IBMVFC_NATIVE_FC 0x01 -#define IBMVFC_CAN_FLUSH_ON_HALT 0x08 u32 reserved; u64 capabilities; #define IBMVFC_CAN_FLUSH_ON_HALT 0x08 +#define IBMVFC_CAN_SUPPRESS_ABTS 0x10 u32 max_cmds; u32 scsi_id_sz; u64 max_dma_len; @@ -351,6 +351,7 @@ struct ibmvfc_tmf { #define IBMVFC_TMF_LUN_RESET 0x10 #define IBMVFC_TMF_TGT_RESET 0x20 #define IBMVFC_TMF_LUA_VALID 0x40 +#define IBMVFC_TMF_SUPPRESS_ABTS 0x80 u32 cancel_key; u32 my_cancel_key; u32 pad; |