Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 26d766c6 authored by Martin Schwidefsky's avatar Martin Schwidefsky
Browse files

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: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent e2213e04
Loading
Loading
Loading
Loading
+17 −15
Original line number Diff line number Diff line
@@ -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);
		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,18 +321,16 @@ 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 */
	}
	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;
	}
}
}

/*
 * Call tty_wakeup from tasklet context