Skip to content

Commit d91f98b

Browse files
jognessgregkh
authored andcommitted
serial: 8250: Adjust the timeout for FIFO mode
After a console has written a record into UART_TX, it uses wait_for_xmitr() to wait until the data has been sent out before returning. However, wait_for_xmitr() will timeout after 10ms, regardless if the data has been transmitted or not. For single bytes, this timeout is sufficient even at very slow baud rates, such as 1200bps. However, when FIFO mode is used, there may be 64 bytes pushed into the FIFO at once. At a baud rate of 115200bps, the 10ms timeout is still sufficient. But when using lower baud rates (such as 57600bps), the timeout is _not_ sufficient. This causes longer lines to be cut off, resulting in lost and horribly misformatted output on the console. When using FIFO mode, take the number of bytes into account to determine an appropriate maximum timeout. Increasing the timeout does not affect performance since ideally the timeout never occurs. Fixes: 8f3631f ("serial/8250: Use fifo in 8250 console driver") Signed-off-by: John Ogness <[email protected]> Reviewed-by: Andy Shevchenko <[email protected]> Reviewed-by: Wander Lairson Costa <[email protected]> Reviewed-by: Petr Mladek <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent ac753e1 commit d91f98b

File tree

1 file changed

+26
-6
lines changed

1 file changed

+26
-6
lines changed

drivers/tty/serial/8250/8250_port.c

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2078,7 +2078,8 @@ static void serial8250_break_ctl(struct uart_port *port, int break_state)
20782078
serial8250_rpm_put(up);
20792079
}
20802080

2081-
static void wait_for_lsr(struct uart_8250_port *up, int bits)
2081+
/* Returns true if @bits were set, false on timeout */
2082+
static bool wait_for_lsr(struct uart_8250_port *up, int bits)
20822083
{
20832084
unsigned int status, tmout = 10000;
20842085

@@ -2093,11 +2094,11 @@ static void wait_for_lsr(struct uart_8250_port *up, int bits)
20932094
udelay(1);
20942095
touch_nmi_watchdog();
20952096
}
2097+
2098+
return (tmout != 0);
20962099
}
20972100

2098-
/*
2099-
* Wait for transmitter & holding register to empty
2100-
*/
2101+
/* Wait for transmitter and holding register to empty with timeout */
21012102
static void wait_for_xmitr(struct uart_8250_port *up, int bits)
21022103
{
21032104
unsigned int tmout;
@@ -3322,6 +3323,16 @@ static void serial8250_console_restore(struct uart_8250_port *up)
33223323
serial8250_out_MCR(up, up->mcr | UART_MCR_DTR | UART_MCR_RTS);
33233324
}
33243325

3326+
static void fifo_wait_for_lsr(struct uart_8250_port *up, unsigned int count)
3327+
{
3328+
unsigned int i;
3329+
3330+
for (i = 0; i < count; i++) {
3331+
if (wait_for_lsr(up, UART_LSR_THRE))
3332+
return;
3333+
}
3334+
}
3335+
33253336
/*
33263337
* Print a string to the serial port using the device FIFO
33273338
*
@@ -3331,13 +3342,15 @@ static void serial8250_console_restore(struct uart_8250_port *up)
33313342
static void serial8250_console_fifo_write(struct uart_8250_port *up,
33323343
const char *s, unsigned int count)
33333344
{
3334-
int i;
33353345
const char *end = s + count;
33363346
unsigned int fifosize = up->tx_loadsz;
3347+
unsigned int tx_count = 0;
33373348
bool cr_sent = false;
3349+
unsigned int i;
33383350

33393351
while (s != end) {
3340-
wait_for_lsr(up, UART_LSR_THRE);
3352+
/* Allow timeout for each byte of a possibly full FIFO */
3353+
fifo_wait_for_lsr(up, fifosize);
33413354

33423355
for (i = 0; i < fifosize && s != end; ++i) {
33433356
if (*s == '\n' && !cr_sent) {
@@ -3348,7 +3361,14 @@ static void serial8250_console_fifo_write(struct uart_8250_port *up,
33483361
cr_sent = false;
33493362
}
33503363
}
3364+
tx_count = i;
33513365
}
3366+
3367+
/*
3368+
* Allow timeout for each byte written since the caller will only wait
3369+
* for UART_LSR_BOTH_EMPTY using the timeout of a single character
3370+
*/
3371+
fifo_wait_for_lsr(up, tx_count);
33523372
}
33533373

33543374
/*

0 commit comments

Comments
 (0)