[PATCH RFC] serial: core: Don't clobber the baud rate on hangup via B0
From: Maciej W. Rozycki
Date: Sun May 24 2026 - 19:15:36 EST
Requesting hangup via the B0 baud rate has this nasty side effect of
clobbering the previously set rate for the port unless it happens to be
9600bps. Consequently if there's a consumer still active at the other
end, then it receives garbled data from any other producers outputting
messages to the port, such as init(8) or the kernel console.
There doesn't appear to be any particular reason for this clobbering
other than that we have been doing it since 2.1.131, so take a saner
approach and try to retain the old baud rate where available before
resorting to 9600bps.
Signed-off-by: Maciej W. Rozycki <macro@xxxxxxxxxxx>
---
Ted,
This code ultimately evolved from a patch of yours[1], so would you be
able by any chance to recreate your rationale beyond resetting the baud
rate to 9600bps rather than just keeping the old one for B0?
Otherwise, does anyone know or can come up with any actual use case for
this baud rate setting? There seems no sensible way to restore the baud
rate required by init(8) and the kernel console other than by hand, while
I can't see a way for software that actually issued a hangup request via
the B0 artificial baud rate to withdraw the request other than by choosing
another explicit baud rate. So there appears to me to be no usable way
there of relying on the implicit 9600bps baud rate set via the B0 baud
rate.
Have I missed anything?
I have dug into this having been irritated by the occasional clobbering
of init(8)/console output observed and now finding a reproducible way to
clobber the port in the course of working on a recent set of changes for
the sb1250-duart driver. This change has made messages get through with
no damage. Many of my systems in the lab actually use the baud rate of
9600bps, which covers the issue, but the CFE firmware sets the baud rate
to 115200bps for systems that use the sb1250-duart driver.
Maciej
References:
[1] "Was: patch to drivers/char/serial.c to fix kernel lock-up",
<https://lkml.org/lkml/1998/12/5/126>
---
drivers/tty/serial/serial_core.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
linux-serial-uart-get-baud-rate-hup.diff
Index: linux-macro/drivers/tty/serial/serial_core.c
===================================================================
--- linux-macro.orig/drivers/tty/serial/serial_core.c
+++ linux-macro/drivers/tty/serial/serial_core.c
@@ -461,8 +461,8 @@ EXPORT_SYMBOL(uart_update_timeout);
* @max: maximum acceptable baud rate
*
* Decode the termios structure into a numeric baud rate, taking account of the
- * magic 38400 baud rate (with spd_* flags), and mapping the %B0 rate to 9600
- * baud.
+ * magic 38400 baud rate (with spd_* flags), and mapping the %B0 rate to the
+ * rate provided by the @old termios setting if available, otherwise 9600 baud.
*
* If the new baud rate is invalid, try the @old termios setting. If it's still
* invalid, we try 9600 baud. If that is also invalid 0 is returned.
@@ -516,7 +516,7 @@ uart_get_baud_rate(struct uart_port *por
*/
if (baud == 0) {
hung_up = 1;
- baud = 9600;
+ baud = old ? tty_termios_baud_rate(old) : 9600;
}
if (baud >= min && baud <= max)