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-changelog

[Xen-changelog] Adds ac_timer based polling to the ns16550 UART driver.

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] Adds ac_timer based polling to the ns16550 UART driver. This is
From: Xen patchbot -unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 24 Nov 2005 12:30:08 +0000
Delivery-date: Thu, 24 Nov 2005 12:30:35 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 188a4fb5ea1f1f937b864dd05393fc1e011a9d5d
# Parent  e1728d3c18ca63ccc29b599caf24997cb93cf191
Adds ac_timer based polling to the ns16550 UART driver.  This is
useful when the interrupt line is not connected in hardware or the
mechanism to enable it is not readily available in the hypervisor.
Polling is only enabled when the UART IRQ is set to zero.

Signed-off-by: Alex Williamson <alex.williamson@xxxxxx>
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>

diff -r e1728d3c18ca -r 188a4fb5ea1f xen/drivers/char/ns16550.c
--- a/xen/drivers/char/ns16550.c        Thu Nov 24 10:17:20 2005
+++ b/xen/drivers/char/ns16550.c        Thu Nov 24 11:06:07 2005
@@ -29,7 +29,11 @@
     int baud, data_bits, parity, stop_bits, irq;
     unsigned long io_base;   /* I/O port or memory-mapped I/O address. */
     char *remapped_io_base;  /* Remapped virtual address of mmap I/O.  */ 
+    /* UART with IRQ line: interrupt-driven I/O. */
     struct irqaction irqaction;
+    /* UART with no IRQ line: periodically-polled I/O. */
+    struct ac_timer timer;
+    unsigned int timeout_ms;
 } ns16550_com[2] = { { 0 } };
 
 /* Register offsets */
@@ -121,6 +125,21 @@
     }
 }
 
+static void ns16550_poll(void *data)
+{
+    struct serial_port *port = data;
+    struct ns16550 *uart = port->uart;
+    struct cpu_user_regs *regs = guest_cpu_user_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_ac_timer(&uart->timer, NOW() + MILLISECS(uart->timeout_ms));
+}
+
 static int ns16550_tx_empty(struct serial_port *port)
 {
     struct ns16550 *uart = port->uart;
@@ -181,24 +200,35 @@
 static void ns16550_init_postirq(struct serial_port *port)
 {
     struct ns16550 *uart = port->uart;
-    int rc;
-
-    if ( uart->irq <= 0 )
+    int rc, bits;
+
+    if ( uart->irq < 0 )
         return;
 
     serial_async_transmit(port);
 
-    uart->irqaction.handler = ns16550_interrupt;
-    uart->irqaction.name    = "ns16550";
-    uart->irqaction.dev_id  = port;
-    if ( (rc = setup_irq(uart->irq, &uart->irqaction)) != 0 )
-        printk("ERROR: Failed to allocate na16550 IRQ %d\n", uart->irq);
-
-    /* Master interrupt enable; also keep DTR/RTS asserted. */
-    ns_write_reg(uart, MCR, MCR_OUT2 | MCR_DTR | MCR_RTS);
-
-    /* Enable receive and transmit interrupts. */
-    ns_write_reg(uart, IER, IER_ERDAI | IER_ETHREI);
+    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 = (bits * port->tx_fifo_size * 1000) / uart->baud;
+        init_ac_timer(&uart->timer, ns16550_poll, port, 0);
+        set_ac_timer(&uart->timer, NOW() + MILLISECS(uart->timeout_ms));
+    }
+    else
+    {
+        uart->irqaction.handler = ns16550_interrupt;
+        uart->irqaction.name    = "ns16550";
+        uart->irqaction.dev_id  = port;
+        if ( (rc = setup_irq(uart->irq, &uart->irqaction)) != 0 )
+            printk("ERROR: Failed to allocate na16550 IRQ %d\n", uart->irq);
+
+        /* Master interrupt enable; also keep DTR/RTS asserted. */
+        ns_write_reg(uart, MCR, MCR_OUT2 | MCR_DTR | MCR_RTS);
+
+        /* Enable receive and transmit interrupts. */
+        ns_write_reg(uart, IER, IER_ERDAI | IER_ETHREI);
+    }
 }
 
 #ifdef CONFIG_X86

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] Adds ac_timer based polling to the ns16550 UART driver. This is, Xen patchbot -unstable <=