Commit 90f725db authored by Brian King's avatar Brian King Committed by James Bottomley

[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: default avatarBrian King <brking@linux.vnet.ibm.com>
Acked-by: default avatarRobert Jennings <rcj@linux.vnet.ibm.com>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent 55d29bf0
...@@ -2190,10 +2190,12 @@ static int ibmvfc_cancel_all(struct scsi_device *sdev, int type) ...@@ -2190,10 +2190,12 @@ static int ibmvfc_cancel_all(struct scsi_device *sdev, int type)
tmf->common.length = sizeof(*tmf); tmf->common.length = sizeof(*tmf);
tmf->scsi_id = rport->port_id; tmf->scsi_id = rport->port_id;
int_to_scsilun(sdev->lun, &tmf->lun); 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) if (vhost->state == IBMVFC_ACTIVE)
tmf->flags = (type | IBMVFC_TMF_LUA_VALID); tmf->flags = (type | IBMVFC_TMF_LUA_VALID);
else 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->cancel_key = (unsigned long)sdev->hostdata;
tmf->my_cancel_key = (unsigned long)starget->hostdata; tmf->my_cancel_key = (unsigned long)starget->hostdata;
...@@ -2402,7 +2404,7 @@ static int ibmvfc_eh_abort_handler(struct scsi_cmnd *cmd) ...@@ -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); cancel_rc = ibmvfc_cancel_all(sdev, IBMVFC_TMF_ABORT_TASK_SET);
ibmvfc_abort_task_set(sdev); ibmvfc_abort_task_set(sdev);
} else } else
cancel_rc = ibmvfc_cancel_all(sdev, 0); cancel_rc = ibmvfc_cancel_all(sdev, IBMVFC_TMF_SUPPRESS_ABTS);
if (!cancel_rc) if (!cancel_rc)
rc = ibmvfc_wait_for_ops(vhost, sdev, ibmvfc_match_lun); 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,7 +2437,7 @@ static int ibmvfc_eh_device_reset_handler(struct scsi_cmnd *cmd)
cancel_rc = ibmvfc_cancel_all(sdev, IBMVFC_TMF_LUN_RESET); cancel_rc = ibmvfc_cancel_all(sdev, IBMVFC_TMF_LUN_RESET);
reset_rc = ibmvfc_reset_device(sdev, IBMVFC_LUN_RESET, "LUN"); reset_rc = ibmvfc_reset_device(sdev, IBMVFC_LUN_RESET, "LUN");
} else } else
cancel_rc = ibmvfc_cancel_all(sdev, 0); cancel_rc = ibmvfc_cancel_all(sdev, IBMVFC_TMF_SUPPRESS_ABTS);
if (!cancel_rc && !reset_rc) if (!cancel_rc && !reset_rc)
rc = ibmvfc_wait_for_ops(vhost, sdev, ibmvfc_match_lun); 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,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) static void ibmvfc_dev_cancel_all_noreset(struct scsi_device *sdev, void *data)
{ {
unsigned long *rc = 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) ...@@ -2547,8 +2549,7 @@ static void ibmvfc_terminate_rport_io(struct fc_rport *rport)
dev_rport = starget_to_rport(scsi_target(sdev)); dev_rport = starget_to_rport(scsi_target(sdev));
if (dev_rport != rport) if (dev_rport != rport)
continue; continue;
ibmvfc_cancel_all(sdev, IBMVFC_TMF_ABORT_TASK_SET); ibmvfc_cancel_all(sdev, IBMVFC_TMF_SUPPRESS_ABTS);
ibmvfc_abort_task_set(sdev);
} }
rc = ibmvfc_wait_for_ops(vhost, rport, ibmvfc_match_rport); rc = ibmvfc_wait_for_ops(vhost, rport, ibmvfc_match_rport);
......
...@@ -208,10 +208,10 @@ struct ibmvfc_npiv_login_resp { ...@@ -208,10 +208,10 @@ struct ibmvfc_npiv_login_resp {
u16 error; u16 error;
u32 flags; u32 flags;
#define IBMVFC_NATIVE_FC 0x01 #define IBMVFC_NATIVE_FC 0x01
#define IBMVFC_CAN_FLUSH_ON_HALT 0x08
u32 reserved; u32 reserved;
u64 capabilities; u64 capabilities;
#define IBMVFC_CAN_FLUSH_ON_HALT 0x08 #define IBMVFC_CAN_FLUSH_ON_HALT 0x08
#define IBMVFC_CAN_SUPPRESS_ABTS 0x10
u32 max_cmds; u32 max_cmds;
u32 scsi_id_sz; u32 scsi_id_sz;
u64 max_dma_len; u64 max_dma_len;
...@@ -351,6 +351,7 @@ struct ibmvfc_tmf { ...@@ -351,6 +351,7 @@ struct ibmvfc_tmf {
#define IBMVFC_TMF_LUN_RESET 0x10 #define IBMVFC_TMF_LUN_RESET 0x10
#define IBMVFC_TMF_TGT_RESET 0x20 #define IBMVFC_TMF_TGT_RESET 0x20
#define IBMVFC_TMF_LUA_VALID 0x40 #define IBMVFC_TMF_LUA_VALID 0x40
#define IBMVFC_TMF_SUPPRESS_ABTS 0x80
u32 cancel_key; u32 cancel_key;
u32 my_cancel_key; u32 my_cancel_key;
u32 pad; u32 pad;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment