aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorChristof Schmitt <christof.schmitt@de.ibm.com>2009-08-18 09:43:11 -0400
committerJames Bottomley <James.Bottomley@suse.de>2009-09-05 09:49:13 -0400
commit14e242ea55a8b807dc1fb7654941caf68a20cd81 (patch)
tree8a11024d41ec344c88877d6c4127e5fd2b5a8fca /drivers
parent44f09f73766a97d9c1ff8bf787cfe6b932eabc2c (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')
-rw-r--r--drivers/s390/scsi/zfcp_def.h1
-rw-r--r--drivers/s390/scsi/zfcp_fc.c9
2 files changed, 10 insertions, 0 deletions
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h
index 601f5a575def..c1becfc1e7fe 100644
--- a/drivers/s390/scsi/zfcp_def.h
+++ b/drivers/s390/scsi/zfcp_def.h
@@ -232,6 +232,7 @@ struct zfcp_ls_adisc {
232 232
233/* remote port status */ 233/* remote port status */
234#define ZFCP_STATUS_PORT_PHYS_OPEN 0x00000001 234#define ZFCP_STATUS_PORT_PHYS_OPEN 0x00000001
235#define ZFCP_STATUS_PORT_LINK_TEST 0x00000002
235 236
236/* well known address (WKA) port status*/ 237/* well known address (WKA) port status*/
237enum zfcp_wka_status { 238enum zfcp_wka_status {
diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c
index 47daebfa7e59..94c13bd32b5f 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)
404 /* port is good, unblock rport without going through erp */ 404 /* port is good, unblock rport without going through erp */
405 zfcp_scsi_schedule_rport_register(port); 405 zfcp_scsi_schedule_rport_register(port);
406 out: 406 out:
407 atomic_clear_mask(ZFCP_STATUS_PORT_LINK_TEST, &port->status);
407 zfcp_port_put(port); 408 zfcp_port_put(port);
408 kfree(adisc); 409 kfree(adisc);
409} 410}
@@ -450,13 +451,21 @@ void zfcp_fc_link_test_work(struct work_struct *work)
450 port->rport_task = RPORT_DEL; 451 port->rport_task = RPORT_DEL;
451 zfcp_scsi_rport_work(&port->rport_work); 452 zfcp_scsi_rport_work(&port->rport_work);
452 453
454 /* only issue one test command at one time per port */
455 if (atomic_read(&port->status) & ZFCP_STATUS_PORT_LINK_TEST)
456 goto out;
457
458 atomic_set_mask(ZFCP_STATUS_PORT_LINK_TEST, &port->status);
459
453 retval = zfcp_fc_adisc(port); 460 retval = zfcp_fc_adisc(port);
454 if (retval == 0) 461 if (retval == 0)
455 return; 462 return;
456 463
457 /* send of ADISC was not possible */ 464 /* send of ADISC was not possible */
465 atomic_clear_mask(ZFCP_STATUS_PORT_LINK_TEST, &port->status);
458 zfcp_erp_port_forced_reopen(port, 0, "fcltwk1", NULL); 466 zfcp_erp_port_forced_reopen(port, 0, "fcltwk1", NULL);
459 467
468out:
460 zfcp_port_put(port); 469 zfcp_port_put(port);
461} 470}
462 471