diff options
author | Christof Schmitt <christof.schmitt@de.ibm.com> | 2009-08-18 15:43:11 +0200 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2009-09-05 08:49:13 -0500 |
commit | 14e242ea55a8b807dc1fb7654941caf68a20cd81 (patch) | |
tree | 8a11024d41ec344c88877d6c4127e5fd2b5a8fca /drivers/s390 | |
parent | 44f09f73766a97d9c1ff8bf787cfe6b932eabc2c (diff) |
[SCSI] zfcp: Only issue one test link command per port
When the FCP channel returns a series of commands with the error
status "test link", zfcp will send a series of ELS ADISC commands.
This is technically no problem, but it is enough to only issue one
test command per remote port. So, track whether a ELS ADISC command is
already pending, and do not send a new one if there is already a
pending command.
Reviewed-by: Swen Schillig <swen@vnet.ibm.com>
Signed-off-by: Christof Schmitt <christof.schmitt@de.ibm.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/s390')
-rw-r--r-- | drivers/s390/scsi/zfcp_def.h | 1 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_fc.c | 9 |
2 files changed, 10 insertions, 0 deletions
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h index 601f5a575de..c1becfc1e7f 100644 --- a/drivers/s390/scsi/zfcp_def.h +++ b/drivers/s390/scsi/zfcp_def.h @@ -232,6 +232,7 @@ struct zfcp_ls_adisc { /* remote port status */ #define ZFCP_STATUS_PORT_PHYS_OPEN 0x00000001 +#define ZFCP_STATUS_PORT_LINK_TEST 0x00000002 /* well known address (WKA) port status*/ enum zfcp_wka_status { diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c index 47daebfa7e5..94c13bd32b5 100644 --- a/drivers/s390/scsi/zfcp_fc.c +++ b/drivers/s390/scsi/zfcp_fc.c @@ -404,6 +404,7 @@ static void zfcp_fc_adisc_handler(unsigned long data) /* port is good, unblock rport without going through erp */ zfcp_scsi_schedule_rport_register(port); out: + atomic_clear_mask(ZFCP_STATUS_PORT_LINK_TEST, &port->status); zfcp_port_put(port); kfree(adisc); } @@ -450,13 +451,21 @@ void zfcp_fc_link_test_work(struct work_struct *work) port->rport_task = RPORT_DEL; zfcp_scsi_rport_work(&port->rport_work); + /* only issue one test command at one time per port */ + if (atomic_read(&port->status) & ZFCP_STATUS_PORT_LINK_TEST) + goto out; + + atomic_set_mask(ZFCP_STATUS_PORT_LINK_TEST, &port->status); + retval = zfcp_fc_adisc(port); if (retval == 0) return; /* send of ADISC was not possible */ + atomic_clear_mask(ZFCP_STATUS_PORT_LINK_TEST, &port->status); zfcp_erp_port_forced_reopen(port, 0, "fcltwk1", NULL); +out: zfcp_port_put(port); } |