Revert part of 23811:f1349a968a5a "ns16550: Simplify UART..."
authorKeir Fraser <keir@xen.org>
Wed, 12 Oct 2011 16:11:28 +0000 (17:11 +0100)
committerKeir Fraser <keir@xen.org>
Wed, 12 Oct 2011 16:11:28 +0000 (17:11 +0100)
The change to poll LSR.THRE in a loop from __ns16550_poll is a bug.
We can loop indefinitely if there are no chars to transmit.

Thanks to Jan for spotting it.

Signed-off-by: Keir Fraser <keir@xen.org>
xen/drivers/char/ns16550.c

index 492c9bf44dccae0935c46b48aa00ebaa6eb67b6a..e09e30ddef02d5a15ad759d571e8a114665680ef 100644 (file)
@@ -157,18 +157,15 @@ static void __ns16550_poll(struct cpu_user_regs *regs)
 {
     struct serial_port *port = this_cpu(poll_port);
     struct ns16550 *uart = port->uart;
-    char lsr;
 
     if ( uart->intr_works )
         return; /* Interrupts work - no more polling */
 
-    while ( (lsr = ns_read_reg(uart, LSR)) & (LSR_DR|LSR_THRE) )
-    {
-        if ( lsr & LSR_THRE )
-            serial_tx_interrupt(port, regs);
-        if ( lsr & LSR_DR )
-            serial_rx_interrupt(port, regs);
-    }
+    while ( ns_read_reg(uart, LSR) & LSR_DR )
+        serial_rx_interrupt(port, regs);
+
+    if ( ns_read_reg(uart, LSR) & LSR_THRE )
+        serial_tx_interrupt(port, regs);
 
     set_timer(&uart->timer, NOW() + MILLISECS(uart->timeout_ms));
 }