From: Peter Hurley <peter@hurleysoftware.com>
Date: Sun, 10 Jan 2016 22:39:32 +0000 (-0800)
Subject: serial: 8250: Fix lost rx state
X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=d22f8f10683c;p=linux.git

serial: 8250: Fix lost rx state

When max_count is reached, the rx loop exits. However, UART_LSR has
already been read so those char flags are lost, and subsequent rx
status will be for the wrong byte until the rx fifo drains.

Reported-by: George Spelvin <linux@horizon.com>
Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---

diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
index 7580d713cde5b..48680565c9914 100644
--- a/drivers/tty/serial/8250/8250_port.c
+++ b/drivers/tty/serial/8250/8250_port.c
@@ -1478,16 +1478,17 @@ static void serial8250_read_char(struct uart_8250_port *up, unsigned char lsr)
  * value, and returns the remaining LSR bits not handled
  * by this Rx routine.
  */
-unsigned char
-serial8250_rx_chars(struct uart_8250_port *up, unsigned char lsr)
+unsigned char serial8250_rx_chars(struct uart_8250_port *up, unsigned char lsr)
 {
 	struct uart_port *port = &up->port;
 	int max_count = 256;
 
 	do {
 		serial8250_read_char(up, lsr);
+		if (--max_count == 0)
+			break;
 		lsr = serial_in(up, UART_LSR);
-	} while ((lsr & (UART_LSR_DR | UART_LSR_BI)) && (--max_count > 0));
+	} while (lsr & (UART_LSR_DR | UART_LSR_BI));
 	spin_unlock(&port->lock);
 	tty_flip_buffer_push(&port->state->port);
 	spin_lock(&port->lock);