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:
Martin Schwidefsky 2014-07-15 17:53:12 +02:00
parent e2213e04c1
commit 26d766c60f

View File

@ -288,12 +288,16 @@ static void raw3215_timeout(unsigned long __data)
unsigned long flags;
spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
if (raw->flags & RAW3215_TIMER_RUNS) {
del_timer(&raw->timer);
raw->flags &= ~RAW3215_TIMER_RUNS;
if (!(raw->port.flags & ASYNC_SUSPENDED)) {
raw3215_mk_write_req(raw);
raw3215_start_io(raw);
raw->flags &= ~RAW3215_TIMER_RUNS;
if (!(raw->port.flags & ASYNC_SUSPENDED)) {
raw3215_mk_write_req(raw);
raw3215_start_io(raw);
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;
}
}
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)) {
/* execute write requests bigger than minimum size */
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;
}
}
/*