From 8fdf30d5429605a4c30cc515c73e5eab140035de Mon Sep 17 00:00:00 2001 From: Christof Schmitt Date: Mon, 2 Mar 2009 13:09:01 +0100 Subject: [SCSI] zfcp: Send ELS ADISC from workqueue Issue ELS ADISC requests from workqueue. This allows the link test request to be sent when the request queue is full due to I/O load for other remote ports. It also simplifies request queue locking, zfcp_fsf_send_fcp_command_task is now the only function that has interrupts disabled from the caller. This is also a prereq for the FC passthrough support that issues ELS requests from userspace. Acked-by: Swen Schillig Signed-off-by: Christof Schmitt Signed-off-by: James Bottomley --- drivers/s390/scsi/zfcp_fc.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) (limited to 'drivers/s390/scsi/zfcp_fc.c') diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c index 67e6b717787..0f435ed9d1a 100644 --- a/drivers/s390/scsi/zfcp_fc.c +++ b/drivers/s390/scsi/zfcp_fc.c @@ -421,19 +421,12 @@ static int zfcp_fc_adisc(struct zfcp_port *port) return zfcp_fsf_send_els(&adisc->els); } -/** - * zfcp_test_link - lightweight link test procedure - * @port: port to be tested - * - * Test status of a link to a remote port using the ELS command ADISC. - * If there is a problem with the remote port, error recovery steps - * will be triggered. - */ -void zfcp_test_link(struct zfcp_port *port) +void zfcp_fc_link_test_work(struct work_struct *work) { + struct zfcp_port *port = + container_of(work, struct zfcp_port, test_link_work); int retval; - zfcp_port_get(port); retval = zfcp_fc_adisc(port); if (retval == 0) return; @@ -444,6 +437,21 @@ void zfcp_test_link(struct zfcp_port *port) zfcp_erp_port_forced_reopen(port, 0, 65, NULL); } +/** + * zfcp_test_link - lightweight link test procedure + * @port: port to be tested + * + * Test status of a link to a remote port using the ELS command ADISC. + * If there is a problem with the remote port, error recovery steps + * will be triggered. + */ +void zfcp_test_link(struct zfcp_port *port) +{ + zfcp_port_get(port); + if (!queue_work(zfcp_data.work_queue, &port->test_link_work)) + zfcp_port_put(port); +} + static void zfcp_free_sg_env(struct zfcp_gpn_ft *gpn_ft, int buf_num) { struct scatterlist *sg = &gpn_ft->sg_req; -- cgit v1.2.3