diff options
author | Brian King <brking@linux.vnet.ibm.com> | 2013-04-12 09:25:18 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2013-05-02 14:57:51 -0400 |
commit | 90f725dbb20557d30e6eb20959bb08cae2661a70 (patch) | |
tree | 14a759370b085fc4618ee3355e07460ad7cd4ca3 /drivers/scsi | |
parent | 55d29bf00f57200cc8b3d3e3e45614baaf5ca27d (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>
Diffstat (limited to 'drivers/scsi')
-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) | |||
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) | |||
2456 | static void ibmvfc_dev_cancel_all_noreset(struct scsi_device *sdev, void *data) | 2458 | static 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; |