s390/3215: fix hanging console issue
The ccw_device_start in raw3215_start_io can fail. raw3215_try_io does not check if the request could be started and removes any pending timer. This can leave the system in a hanging state. Check for pending request after raw3215_start_io and start a timer if necessary. Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
parent
e2213e04c1
commit
26d766c60f
1 changed files with 17 additions and 15 deletions
|
@ -288,12 +288,16 @@ static void raw3215_timeout(unsigned long __data)
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
|
spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
|
||||||
if (raw->flags & RAW3215_TIMER_RUNS) {
|
raw->flags &= ~RAW3215_TIMER_RUNS;
|
||||||
del_timer(&raw->timer);
|
if (!(raw->port.flags & ASYNC_SUSPENDED)) {
|
||||||
raw->flags &= ~RAW3215_TIMER_RUNS;
|
raw3215_mk_write_req(raw);
|
||||||
if (!(raw->port.flags & ASYNC_SUSPENDED)) {
|
raw3215_start_io(raw);
|
||||||
raw3215_mk_write_req(raw);
|
if ((raw->queued_read || raw->queued_write) &&
|
||||||
raw3215_start_io(raw);
|
!(raw->flags & RAW3215_WORKING) &&
|
||||||
|
!(raw->flags & RAW3215_TIMER_RUNS)) {
|
||||||
|
raw->timer.expires = RAW3215_TIMEOUT + jiffies;
|
||||||
|
add_timer(&raw->timer);
|
||||||
|
raw->flags |= RAW3215_TIMER_RUNS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
|
spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
|
||||||
|
@ -317,17 +321,15 @@ static inline void raw3215_try_io(struct raw3215_info *raw)
|
||||||
(raw->flags & RAW3215_FLUSHING)) {
|
(raw->flags & RAW3215_FLUSHING)) {
|
||||||
/* execute write requests bigger than minimum size */
|
/* execute write requests bigger than minimum size */
|
||||||
raw3215_start_io(raw);
|
raw3215_start_io(raw);
|
||||||
if (raw->flags & RAW3215_TIMER_RUNS) {
|
|
||||||
del_timer(&raw->timer);
|
|
||||||
raw->flags &= ~RAW3215_TIMER_RUNS;
|
|
||||||
}
|
|
||||||
} else if (!(raw->flags & RAW3215_TIMER_RUNS)) {
|
|
||||||
/* delay small writes */
|
|
||||||
raw->timer.expires = RAW3215_TIMEOUT + jiffies;
|
|
||||||
add_timer(&raw->timer);
|
|
||||||
raw->flags |= RAW3215_TIMER_RUNS;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ((raw->queued_read || raw->queued_write) &&
|
||||||
|
!(raw->flags & RAW3215_WORKING) &&
|
||||||
|
!(raw->flags & RAW3215_TIMER_RUNS)) {
|
||||||
|
raw->timer.expires = RAW3215_TIMEOUT + jiffies;
|
||||||
|
add_timer(&raw->timer);
|
||||||
|
raw->flags |= RAW3215_TIMER_RUNS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Add table
Reference in a new issue