From bf3f837804997e5f5d9888051e9e5356961af0f2 Mon Sep 17 00:00:00 2001 From: Ursula Braun Date: Sat, 9 Feb 2008 18:24:32 +0100 Subject: [S390] qdio: avoid hang when establishing qdio queues If qdio establish runs in parallel with a channel error, ccw_device_start_timeout may not trigger the qdio_timeout_handler. In this case neither QDIO_IRQ_STATE_ESTABLISHED nor QDIO_IRQ_STATE_ERR is reached and the following wait_event hangs forever. Solution: do not make use of the timeout option with ccw_device_start, but add a timeout to the following wait_event. Signed-off-by: Ursula Braun Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/qdio.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) (limited to 'drivers/s390') diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c index e2a781b6b21d..097fc0967e9d 100644 --- a/drivers/s390/cio/qdio.c +++ b/drivers/s390/cio/qdio.c @@ -3189,13 +3189,11 @@ qdio_establish(struct qdio_initialize *init_data) spin_lock_irqsave(get_ccwdev_lock(cdev),saveflags); ccw_device_set_options_mask(cdev, 0); - result=ccw_device_start_timeout(cdev,&irq_ptr->ccw, - QDIO_DOING_ESTABLISH,0, 0, - QDIO_ESTABLISH_TIMEOUT); + result = ccw_device_start(cdev, &irq_ptr->ccw, + QDIO_DOING_ESTABLISH, 0, 0); if (result) { - result2=ccw_device_start_timeout(cdev,&irq_ptr->ccw, - QDIO_DOING_ESTABLISH,0,0, - QDIO_ESTABLISH_TIMEOUT); + result2 = ccw_device_start(cdev, &irq_ptr->ccw, + QDIO_DOING_ESTABLISH, 0, 0); sprintf(dbf_text,"eq:io%4x",result); QDIO_DBF_TEXT2(1,setup,dbf_text); if (result2) { @@ -3219,10 +3217,10 @@ qdio_establish(struct qdio_initialize *init_data) return result; } - /* Timeout is cared for already by using ccw_device_start_timeout(). */ - wait_event_interruptible(cdev->private->wait_q, - irq_ptr->state == QDIO_IRQ_STATE_ESTABLISHED || - irq_ptr->state == QDIO_IRQ_STATE_ERR); + wait_event_interruptible_timeout(cdev->private->wait_q, + irq_ptr->state == QDIO_IRQ_STATE_ESTABLISHED || + irq_ptr->state == QDIO_IRQ_STATE_ERR, + QDIO_ESTABLISH_TIMEOUT); if (irq_ptr->state == QDIO_IRQ_STATE_ESTABLISHED) result = 0; -- cgit v1.2.3