setserial hangs during 2.2.0-pre2 boot

Nick Holloway (alfie@alfie.demon.co.uk)
Fri, 1 Jan 1999 19:44:50 +0000


Fairly often, but not always, the setserial commands run by the Debian
2.0 boot scripts hang when booting 2.2.0-pre2. This means the whole boot
hangs, leading to a reset, and the associated fsck on the next boot :-(

I have seen this earlier in the 2.1.x cycle, but had put it down to SMP
kernel on a UP machine, and hadn't put in the effort to track it down.
One advantage of holidays is I've been able to spend some time today
looking into the cause.

It is caused by "setserial -b /dev/ttyS1 autoconfig", and when the device
is closed. What is happening is that rs_wait_until_close is being called
with a maximum timeout (MAX_SCHEDULE) by tty_wait_until_sent. The loop
in rs_wait_until_sent never thinks that the UART has finished sending,
and so repeatedly re-schedules.

With TTY_DEBUG_WAIT_UNTIL_SENT and SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
defined, the following is printed out (I put a hack in to break out of
the loop after ~10 iterations).

ttyS1 wait until sent...
waiting ttyS1...(0)
In rs_wait_until_sent(2147483647) check=1...jiff=3557...
lsr = 32 (jiff=3557)...
lsr = 32 (jiff=3558)...
lsr = 32 (jiff=3559)...
lsr = 32 (jiff=3560)...
lsr = 32 (jiff=3561)...
lsr = 32 (jiff=3562)...
lsr = 32 (jiff=3563)...
lsr = 32 (jiff=3564)...
lsr = 32 (jiff=3565)...
lsr = 32 (jiff=3566)...
lsr = 32 (jiff=3567)...
lsr = 32 (jiff=3568)...
giving up...
lsr = 32 (jiff=3569)...done

I think the reason this isn't triggered under 2.0.x is that the tty
layer doesn't call wait_until_sent if the number of characters in the
buffer is zero.

[from diff of 2.0.36 and 2.2.0-pre2 tty_ioctl.c]
- if (!tty->driver.chars_in_buffer ||
- !tty->driver.chars_in_buffer(tty))
+ if (!tty->driver.chars_in_buffer)
return;

I can see that there may be no characters in the tty buffer, but the
low-level wait_until_sent needs to be called to deal with devices with
large on-chip buffers. If that is the case, then shouldn't the test
for having a 'chars_in_buffer' call also be dropped?

I suspect that the real problem is that the rs_wait_until_sent can't
deal with the state of the UART just after configuration, and this has
been uncovered by the changes to the higher level tty code. On the
occasions that it doesn't hang, the value for lsr reported is 96.

In rs_wait_until_sent(2147483647) check=1...jiff=28867...
lsr = 96 (jiff=28867)...
done

The serial port is a 16550A with a powered up modem connected to it.
The kernel is UP, running on an Intel P133. The serial related parts
of the config are:

CONFIG_SERIAL=y
# CONFIG_SERIAL_CONSOLE is not set
# CONFIG_SERIAL_EXTENDED is not set
# CONFIG_SERIAL_NONSTANDARD is not set

-- 
 `O O'  | Home: Nick.Holloway@alfie.demon.co.uk  http://www.alfie.demon.co.uk/
// ^ \\ | Work: Nick.Holloway@parallax.co.uk

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/