WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH 1 of 1] Handle bogus serial ports that appear normal,

To: xen-devel@xxxxxxxxxxxxxxxxxxx, keir.fraser@xxxxxxxxxxxxx
Subject: [Xen-devel] [PATCH 1 of 1] Handle bogus serial ports that appear normal, but don't generate
From: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx>
Date: Mon, 14 Dec 2009 15:10:46 -0000
Cc: Gary.Grebus@xxxxxxxxxx
Delivery-date: Mon, 14 Dec 2009 07:31:22 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <patchbomb.1260803445@xxxxxxxxxxxxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
References: <patchbomb.1260803445@xxxxxxxxxxxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mercurial-patchbomb/1.3
# HG changeset patch
# User konrad@xxxxxxxxxxxxxxxxxxx
# Date 1260803272 18000
# Node ID 37cb71cbe3b4c02c2ea435b752eef888760ee2a6
# Parent  e75c840d7e7bb2bbbd6fdbabead529c5ad36d106
Handle bogus serial ports that appear normal, but don't generate
interrupts e.g. the "remote serial console" on Blades.

Authored-by: Gary Grebus <Gary.Grebus@xxxxxxxxxx>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx

diff -r e75c840d7e7b -r 37cb71cbe3b4 xen/drivers/char/ns16550.c
--- a/xen/drivers/char/ns16550.c        Fri Dec 11 11:12:10 2009 -0500
+++ b/xen/drivers/char/ns16550.c        Mon Dec 14 10:07:52 2009 -0500
@@ -39,6 +39,7 @@
     /* UART with no IRQ line: periodically-polled I/O. */
     struct timer timer;
     unsigned int timeout_ms;
+    int probing, intr_works;
 } ns16550_com[2] = { { 0 } };
 
 /* Register offsets */
@@ -127,6 +128,13 @@
     struct serial_port *port = dev_id;
     struct ns16550 *uart = port->uart;
 
+    if (uart->intr_works == 0)
+    {
+        uart->probing = 0;
+        uart->intr_works = 1;
+        stop_timer(&uart->timer);
+    }
+
     while ( !(ns_read_reg(uart, IIR) & IIR_NOINT) )
     {
         char lsr = ns_read_reg(uart, LSR);
@@ -143,6 +151,15 @@
     struct ns16550 *uart = port->uart;
     struct cpu_user_regs *regs = guest_cpu_user_regs();
 
+    if ( uart->intr_works )
+        return;     /* Interrupts work - no more polling */
+
+    if ( uart->probing ) {
+        uart->probing = 0;
+        if ( (ns_read_reg(uart, LSR) & 0xff) == 0xff )
+            return;     /* All bits set - probably no UART present */
+    }
+
     while ( ns_read_reg(uart, LSR) & LSR_DR )
         serial_rx_interrupt(port, regs);
 
@@ -230,15 +247,14 @@
 
     serial_async_transmit(port);
 
+    init_timer(&uart->timer, ns16550_poll, port, 0);
+    /* Calculate time to fill RX FIFO and/or empty TX FIFO for polling. */
+    bits = uart->data_bits + uart->stop_bits + !!uart->parity;
+    uart->timeout_ms = max_t(
+        unsigned int, 1, (bits * port->tx_fifo_size * 1000) / uart->baud);
+
     if ( uart->irq == 0 )
-    {
-        /* Polled mode. Calculate time to fill RX FIFO and/or empty TX FIFO. */
-        bits = uart->data_bits + uart->stop_bits + !!uart->parity;
-        uart->timeout_ms = max_t(
-            unsigned int, 1, (bits * port->tx_fifo_size * 1000) / uart->baud);
-        init_timer(&uart->timer, ns16550_poll, port, 0);
         set_timer(&uart->timer, NOW() + MILLISECS(uart->timeout_ms));
-    }
     else
     {
         uart->irqaction.handler = ns16550_interrupt;
@@ -252,6 +268,12 @@
 
         /* Enable receive and transmit interrupts. */
         ns_write_reg(uart, IER, IER_ERDAI | IER_ETHREI);
+
+        /* Do a timed write to make sure we are getting interrupts. */
+        uart->probing = 1;
+        uart->intr_works = 0;
+        ns_write_reg(uart, THR, 0xff);
+        set_timer(&uart->timer, NOW() + MILLISECS(uart->timeout_ms));
     }
 }
 



_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel