diff options
author | Ursula Braun <braunu@de.ibm.com> | 2008-02-09 12:24:32 -0500 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2008-02-09 12:24:39 -0500 |
commit | bf3f837804997e5f5d9888051e9e5356961af0f2 (patch) | |
tree | 4d2c70d51edae38b92803f38fa025ee4875e0a34 /drivers | |
parent | 522d8dc08b16deb51c128d544ab1cb9c621c950e (diff) |
[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 <braunu@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/s390/cio/qdio.c | 18 |
1 files changed, 8 insertions, 10 deletions
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) | |||
3189 | spin_lock_irqsave(get_ccwdev_lock(cdev),saveflags); | 3189 | spin_lock_irqsave(get_ccwdev_lock(cdev),saveflags); |
3190 | 3190 | ||
3191 | ccw_device_set_options_mask(cdev, 0); | 3191 | ccw_device_set_options_mask(cdev, 0); |
3192 | result=ccw_device_start_timeout(cdev,&irq_ptr->ccw, | 3192 | result = ccw_device_start(cdev, &irq_ptr->ccw, |
3193 | QDIO_DOING_ESTABLISH,0, 0, | 3193 | QDIO_DOING_ESTABLISH, 0, 0); |
3194 | QDIO_ESTABLISH_TIMEOUT); | ||
3195 | if (result) { | 3194 | if (result) { |
3196 | result2=ccw_device_start_timeout(cdev,&irq_ptr->ccw, | 3195 | result2 = ccw_device_start(cdev, &irq_ptr->ccw, |
3197 | QDIO_DOING_ESTABLISH,0,0, | 3196 | QDIO_DOING_ESTABLISH, 0, 0); |
3198 | QDIO_ESTABLISH_TIMEOUT); | ||
3199 | sprintf(dbf_text,"eq:io%4x",result); | 3197 | sprintf(dbf_text,"eq:io%4x",result); |
3200 | QDIO_DBF_TEXT2(1,setup,dbf_text); | 3198 | QDIO_DBF_TEXT2(1,setup,dbf_text); |
3201 | if (result2) { | 3199 | if (result2) { |
@@ -3219,10 +3217,10 @@ qdio_establish(struct qdio_initialize *init_data) | |||
3219 | return result; | 3217 | return result; |
3220 | } | 3218 | } |
3221 | 3219 | ||
3222 | /* Timeout is cared for already by using ccw_device_start_timeout(). */ | 3220 | wait_event_interruptible_timeout(cdev->private->wait_q, |
3223 | wait_event_interruptible(cdev->private->wait_q, | 3221 | irq_ptr->state == QDIO_IRQ_STATE_ESTABLISHED || |
3224 | irq_ptr->state == QDIO_IRQ_STATE_ESTABLISHED || | 3222 | irq_ptr->state == QDIO_IRQ_STATE_ERR, |
3225 | irq_ptr->state == QDIO_IRQ_STATE_ERR); | 3223 | QDIO_ESTABLISH_TIMEOUT); |
3226 | 3224 | ||
3227 | if (irq_ptr->state == QDIO_IRQ_STATE_ESTABLISHED) | 3225 | if (irq_ptr->state == QDIO_IRQ_STATE_ESTABLISHED) |
3228 | result = 0; | 3226 | result = 0; |