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] ns16550 interrupt handler should not return until the II

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] ns16550 interrupt handler should not return until the IIR indicates
From: BitKeeper Bot <riel@xxxxxxxxxxx>
Date: Sun, 05 Jun 2005 10:53:57 +0000
Delivery-date: Sun, 05 Jun 2005 11:01:44 +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 Development List <xen-devel@xxxxxxxxxxxxxxxxxxx>
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
ChangeSet 1.1675, 2005/06/05 11:53:57+01:00, kaf24@xxxxxxxxxxxxxxxxxxxx

        ns16550 interrupt handler should not return until the IIR indicates
        no pending interrupts. Also a few generic serial driver cleanups.
        Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>



 ns16550.c |   17 ++++++++++++----
 serial.c  |   65 +++++++++++++++++++++++++++++++++++---------------------------
 2 files changed, 50 insertions(+), 32 deletions(-)


diff -Nru a/xen/drivers/char/ns16550.c b/xen/drivers/char/ns16550.c
--- a/xen/drivers/char/ns16550.c        2005-06-05 07:02:39 -04:00
+++ b/xen/drivers/char/ns16550.c        2005-06-05 07:02:39 -04:00
@@ -49,7 +49,15 @@
 #define IER_ELSI        0x04    /* rx line status       */
 #define IER_EMSI        0x08    /* MODEM status         */
 
-/* FIFO control register */
+/* Interrupt Identification Register */
+#define IIR_NOINT       0x01    /* no interrupt pending */
+#define IIR_IMASK       0x06    /* interrupt identity:  */
+#define IIR_LSI         0x06    /*  - rx line status    */
+#define IIR_RDAI        0x04    /*  - rx data recv'd    */
+#define IIR_THREI       0x02    /*  - tx reg. empty     */
+#define IIR_MSI         0x00    /*  - MODEM status      */
+
+/* FIFO Control Register */
 #define FCR_ENABLE      0x01    /* enable FIFO          */
 #define FCR_CLRX        0x02    /* clear Rx FIFO        */
 #define FCR_CLTX        0x04    /* clear Tx FIFO        */
@@ -59,7 +67,7 @@
 #define FCR_TRG8        0x80    /* Rx FIFO trig lev 8   */
 #define FCR_TRG14       0xc0    /* Rx FIFO trig lev 14  */
 
-/* Line control register */
+/* Line Control Register */
 #define LCR_DLAB        0x80    /* Divisor Latch Access */
 
 /* Modem Control Register */
@@ -104,10 +112,11 @@
     struct serial_port *port = dev_id;
     struct ns16550 *uart = port->uart;
 
-    if ( (ns_read_reg(uart, IIR) & 7) == 2 )
+    while ( !(ns_read_reg(uart, IIR) & IIR_NOINT) )
+    {
         serial_tx_interrupt(port, regs);
-    else
         serial_rx_interrupt(port, regs);
+    }
 }
 
 static int ns16550_tx_empty(struct serial_port *port)
diff -Nru a/xen/drivers/char/serial.c b/xen/drivers/char/serial.c
--- a/xen/drivers/char/serial.c 2005-06-05 07:02:39 -04:00
+++ b/xen/drivers/char/serial.c 2005-06-05 07:02:39 -04:00
@@ -22,20 +22,13 @@
 void serial_rx_interrupt(struct serial_port *port, struct cpu_user_regs *regs)
 {
     char c;
-    serial_rx_fn fn;
+    serial_rx_fn fn = NULL;
     unsigned long flags;
 
-    BUG_ON(!port->driver);
-    BUG_ON(!port->driver->getc);
+    spin_lock_irqsave(&port->lock, flags);
 
-    for ( ; ; )
+    if ( port->driver->getc(port, &c) )
     {
-        spin_lock_irqsave(&port->lock, flags);
-
-        if ( !port->driver->getc(port, &c) )
-            break;
-
-        fn = NULL;
         if ( port->rx != NULL )
             fn = port->rx;
         else if ( (c & 0x80) && (port->rx_hi != NULL) )
@@ -44,16 +37,12 @@
             fn = port->rx_lo;
         else if ( (port->rxbufp - port->rxbufc) != SERIAL_RXBUFSZ )
             port->rxbuf[MASK_SERIAL_RXBUF_IDX(port->rxbufp++)] = c;            
-
-        spin_unlock_irqrestore(&port->lock, flags);
-
-        if ( fn != NULL )
-            (*fn)(c & 0x7f, regs);
-
-        cpu_relax();
     }
 
     spin_unlock_irqrestore(&port->lock, flags);
+
+    if ( fn != NULL )
+        (*fn)(c & 0x7f, regs);
 }
 
 void serial_tx_interrupt(struct serial_port *port, struct cpu_user_regs *regs)
@@ -61,18 +50,17 @@
     int i;
     unsigned long flags;
 
-    BUG_ON(!port->driver);
-    BUG_ON(!port->driver->tx_empty);
-    BUG_ON(!port->driver->putc);
-
     spin_lock_irqsave(&port->lock, flags);
 
-    for ( i = 0; i < port->tx_fifo_size; i++ )
+    if ( port->driver->tx_empty(port) )
     {
-        if ( port->txbufc == port->txbufp )
-            break;
-        port->driver->putc(
-            port, port->txbuf[MASK_SERIAL_TXBUF_IDX(port->txbufc++)]);
+        for ( i = 0; i < port->tx_fifo_size; i++ )
+        {
+            if ( port->txbufc == port->txbufp )
+                break;
+            port->driver->putc(
+                port, port->txbuf[MASK_SERIAL_TXBUF_IDX(port->txbufc++)]);
+        }
     }
 
     spin_unlock_irqrestore(&port->lock, flags);
@@ -146,8 +134,29 @@
 
 void serial_puts(int handle, const char *s)
 {
-    while ( *s != '\0' )
-        serial_putc(handle, *s++);
+    struct serial_port *port = &com[handle & SERHND_IDX];
+    unsigned long flags;
+    char c;
+
+    if ( (handle == -1) || !port->driver || !port->driver->putc )
+        return;
+
+    spin_lock_irqsave(&port->lock, flags);
+
+    while ( (c = *s++) != '\0' )
+    {
+        if ( (c == '\n') && (handle & SERHND_COOKED) )
+            __serial_putc(port, '\r');
+
+        if ( handle & SERHND_HI )
+            c |= 0x80;
+        else if ( handle & SERHND_LO )
+            c &= 0x7f;
+
+        __serial_putc(port, c);
+    }
+
+    spin_unlock_irqrestore(&port->lock, flags);
 }
 
 char serial_getc(int handle)

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] ns16550 interrupt handler should not return until the IIR indicates, BitKeeper Bot <=