Re: setserial hangs during 2.2.0-pre2 boot

tytso@mit.edu
Fri, 8 Jan 1999 08:29:21 -0500


Hi Linus,

Could you apply the following patch to the 2.2.0-pre tree? Nick
Holloway confirmed that this patch fixedhis problem with setserial
occasionally hanging on his hardware. Thanks!!

- Ted

Date: Sat, 2 Jan 1999 01:35:03 -0500
From: "Theodore Y. Ts'o" <tytso@MIT.EDU>
To: Nick Holloway <alfie@alfie.demon.co.uk>
Subject: Re: setserial hangs during 2.2.0-pre2 boot

Date: Fri, 1 Jan 1999 19:44:50 +0000
From: Nick Holloway <alfie@alfie.demon.co.uk>

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 :-(

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.

This appears to be a UART bug. The TEMT bit is supposed to be set
whenever the transmitter shift register is empty. Apparently, it's not
doing it for your UART after it leaves the automatic loopback state
(which is used by the UART configuration code). I can't duplicate it on
my system, but your debugging traces clearly point to that as the
problem.

I've enclosed a patch below which should fix the problem. Could you
please test it and let me know how it works for you? Thanks!!

- Ted

Patch generated: on Sat Jan 2 01:34:46 EST 1999 by tytso@rsts-11.mit.edu
against Linux version 2.2.0

===================================================================
RCS file: drivers/char/RCS/serial.c,v
retrieving revision 1.1
diff -u -r1.1 drivers/char/serial.c
--- drivers/char/serial.c 1999/01/02 06:14:35 1.1
+++ drivers/char/serial.c 1999/01/02 06:34:42
@@ -2356,6 +2356,17 @@
char_time = 1;
if (timeout)
char_time = MIN(char_time, timeout);
+ /*
+ * If the transmitter hasn't cleared in twice the approximate
+ * amount of time to send the entire FIFO, it probably won't
+ * ever clear. This assumes the UART isn't doing flow
+ * control, which is currently the case. Hence, if it ever
+ * takes longer than info->timeout, this is probably due to a
+ * UART bug of some kind. So, we clamp the timeout parameter at
+ * 2*info->timeout.
+ */
+ if (!timeout || timeout > 2*info->timeout)
+ timeout = 2*info->timeout;
#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
printk("In rs_wait_until_sent(%d) check=%lu...", timeout, char_time);
printk("jiff=%lu...", jiffies);

-
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/