aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian King <brking@linux.vnet.ibm.com>2013-04-12 09:25:18 -0400
committerJames Bottomley <JBottomley@Parallels.com>2013-05-02 14:57:51 -0400
commit90f725dbb20557d30e6eb20959bb08cae2661a70 (patch)
tree14a759370b085fc4618ee3355e07460ad7cd4ca3
parent55d29bf00f57200cc8b3d3e3e45614baaf5ca27d (diff)
[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.c13
-rw-r--r--drivers/scsi/ibmvscsi/ibmvfc.h3
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)
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 if (!(vhost->login_buf->resp.capabilities & IBMVFC_CAN_SUPPRESS_ABTS))
2194 type &= ~IBMVFC_TMF_SUPPRESS_ABTS;
2193 if (vhost->state == IBMVFC_ACTIVE) 2195 if (vhost->state == IBMVFC_ACTIVE)
2194 tmf->flags = (type | IBMVFC_TMF_LUA_VALID); 2196 tmf->flags = (type | IBMVFC_TMF_LUA_VALID);
2195 else 2197 else
2196 tmf->flags = IBMVFC_TMF_LUA_VALID; 2198 tmf->flags = ((type & IBMVFC_TMF_SUPPRESS_ABTS) | IBMVFC_TMF_LUA_VALID);
2197 tmf->cancel_key = (unsigned long)sdev->hostdata; 2199 tmf->cancel_key = (unsigned long)sdev->hostdata;
2198 tmf->my_cancel_key = (unsigned long)starget->hostdata; 2200 tmf->my_cancel_key = (unsigned long)starget->hostdata;
2199 2201
@@ -2402,7 +2404,7 @@ static int ibmvfc_eh_abort_handler(struct scsi_cmnd *cmd)
2402 cancel_rc = ibmvfc_cancel_all(sdev, IBMVFC_TMF_ABORT_TASK_SET); 2404 cancel_rc = ibmvfc_cancel_all(sdev, IBMVFC_TMF_ABORT_TASK_SET);
2403 ibmvfc_abort_task_set(sdev); 2405 ibmvfc_abort_task_set(sdev);
2404 } else 2406 } else
2405 cancel_rc = ibmvfc_cancel_all(sdev, 0); 2407 cancel_rc = ibmvfc_cancel_all(sdev, IBMVFC_TMF_SUPPRESS_ABTS);
2406 2408
2407 if (!cancel_rc) 2409 if (!cancel_rc)
2408 rc = ibmvfc_wait_for_ops(vhost, sdev, ibmvfc_match_lun); 2410 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)
2435 cancel_rc = ibmvfc_cancel_all(sdev, IBMVFC_TMF_LUN_RESET); 2437 cancel_rc = ibmvfc_cancel_all(sdev, IBMVFC_TMF_LUN_RESET);
2436 reset_rc = ibmvfc_reset_device(sdev, IBMVFC_LUN_RESET, "LUN"); 2438 reset_rc = ibmvfc_reset_device(sdev, IBMVFC_LUN_RESET, "LUN");
2437 } else 2439 } else
2438 cancel_rc = ibmvfc_cancel_all(sdev, 0); 2440 cancel_rc = ibmvfc_cancel_all(sdev, IBMVFC_TMF_SUPPRESS_ABTS);
2439 2441
2440 if (!cancel_rc && !reset_rc) 2442 if (!cancel_rc && !reset_rc)
2441 rc = ibmvfc_wait_for_ops(vhost, sdev, ibmvfc_match_lun); 2443 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)
2456static void ibmvfc_dev_cancel_all_noreset(struct scsi_device *sdev, void *data) 2458static void ibmvfc_dev_cancel_all_noreset(struct scsi_device *sdev, void *data)
2457{ 2459{
2458 unsigned long *rc = data; 2460 unsigned long *rc = data;
2459 *rc |= ibmvfc_cancel_all(sdev, 0); 2461 *rc |= ibmvfc_cancel_all(sdev, IBMVFC_TMF_SUPPRESS_ABTS);
2460} 2462}
2461 2463
2462/** 2464/**
@@ -2547,8 +2549,7 @@ static void ibmvfc_terminate_rport_io(struct fc_rport *rport)
2547 dev_rport = starget_to_rport(scsi_target(sdev)); 2549 dev_rport = starget_to_rport(scsi_target(sdev));
2548 if (dev_rport != rport) 2550 if (dev_rport != rport)
2549 continue; 2551 continue;
2550 ibmvfc_cancel_all(sdev, IBMVFC_TMF_ABORT_TASK_SET); 2552 ibmvfc_cancel_all(sdev, IBMVFC_TMF_SUPPRESS_ABTS);
2551 ibmvfc_abort_task_set(sdev);
2552 } 2553 }
2553 2554
2554 rc = ibmvfc_wait_for_ops(vhost, rport, ibmvfc_match_rport); 2555 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 {
208 u16 error; 208 u16 error;
209 u32 flags; 209 u32 flags;
210#define IBMVFC_NATIVE_FC 0x01 210#define IBMVFC_NATIVE_FC 0x01
211#define IBMVFC_CAN_FLUSH_ON_HALT 0x08
212 u32 reserved; 211 u32 reserved;
213 u64 capabilities; 212 u64 capabilities;
214#define IBMVFC_CAN_FLUSH_ON_HALT 0x08 213#define IBMVFC_CAN_FLUSH_ON_HALT 0x08
214#define IBMVFC_CAN_SUPPRESS_ABTS 0x10
215 u32 max_cmds; 215 u32 max_cmds;
216 u32 scsi_id_sz; 216 u32 scsi_id_sz;
217 u64 max_dma_len; 217 u64 max_dma_len;
@@ -351,6 +351,7 @@ struct ibmvfc_tmf {
351#define IBMVFC_TMF_LUN_RESET 0x10 351#define IBMVFC_TMF_LUN_RESET 0x10
352#define IBMVFC_TMF_TGT_RESET 0x20 352#define IBMVFC_TMF_TGT_RESET 0x20
353#define IBMVFC_TMF_LUA_VALID 0x40 353#define IBMVFC_TMF_LUA_VALID 0x40
354#define IBMVFC_TMF_SUPPRESS_ABTS 0x80
354 u32 cancel_key; 355 u32 cancel_key;
355 u32 my_cancel_key; 356 u32 my_cancel_key;
356 u32 pad; 357 u32 pad;