diff options
author | Aristeu Rozanski <arozansk@redhat.com> | 2008-07-24 00:29:45 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-24 13:47:29 -0400 |
commit | 7500b1f602aad75901774a67a687ee985d85893f (patch) | |
tree | 52afbdf19a5186e307fa9da68a1070431ad46b3a /drivers | |
parent | 920519c1c31ca46ef6caab1a4be102ed0dfb5fbc (diff) |
8250: fix break handling for Intel 82571
Intel 82571 has a "Serial Over LAN" feature that doesn't properly
implements the receiving of break characters. When a break is received,
it doesn't set UART_LSR_DR and unless another character is received, the
break won't be received by the application.
Signed-off-by: Aristeu Rozanski <arozansk@redhat.com>
Acked-by: Alan Cox <alan@lxorguk.ukuu.org.uk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/serial/8250.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index 27f34a9f9cb7..a97f1ae11f78 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c | |||
@@ -1293,7 +1293,18 @@ receive_chars(struct uart_8250_port *up, unsigned int *status) | |||
1293 | char flag; | 1293 | char flag; |
1294 | 1294 | ||
1295 | do { | 1295 | do { |
1296 | ch = serial_inp(up, UART_RX); | 1296 | if (likely(lsr & UART_LSR_DR)) |
1297 | ch = serial_inp(up, UART_RX); | ||
1298 | else | ||
1299 | /* | ||
1300 | * Intel 82571 has a Serial Over Lan device that will | ||
1301 | * set UART_LSR_BI without setting UART_LSR_DR when | ||
1302 | * it receives a break. To avoid reading from the | ||
1303 | * receive buffer without UART_LSR_DR bit set, we | ||
1304 | * just force the read character to be 0 | ||
1305 | */ | ||
1306 | ch = 0; | ||
1307 | |||
1297 | flag = TTY_NORMAL; | 1308 | flag = TTY_NORMAL; |
1298 | up->port.icount.rx++; | 1309 | up->port.icount.rx++; |
1299 | 1310 | ||
@@ -1342,7 +1353,7 @@ receive_chars(struct uart_8250_port *up, unsigned int *status) | |||
1342 | 1353 | ||
1343 | ignore_char: | 1354 | ignore_char: |
1344 | lsr = serial_inp(up, UART_LSR); | 1355 | lsr = serial_inp(up, UART_LSR); |
1345 | } while ((lsr & UART_LSR_DR) && (max_count-- > 0)); | 1356 | } while ((lsr & (UART_LSR_DR | UART_LSR_BI)) && (max_count-- > 0)); |
1346 | spin_unlock(&up->port.lock); | 1357 | spin_unlock(&up->port.lock); |
1347 | tty_flip_buffer_push(tty); | 1358 | tty_flip_buffer_push(tty); |
1348 | spin_lock(&up->port.lock); | 1359 | spin_lock(&up->port.lock); |
@@ -1425,7 +1436,7 @@ serial8250_handle_port(struct uart_8250_port *up) | |||
1425 | 1436 | ||
1426 | DEBUG_INTR("status = %x...", status); | 1437 | DEBUG_INTR("status = %x...", status); |
1427 | 1438 | ||
1428 | if (status & UART_LSR_DR) | 1439 | if (status & (UART_LSR_DR | UART_LSR_BI)) |
1429 | receive_chars(up, &status); | 1440 | receive_chars(up, &status); |
1430 | check_modem_status(up); | 1441 | check_modem_status(up); |
1431 | if (status & UART_LSR_THRE) | 1442 | if (status & UART_LSR_THRE) |