[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 8/8] drop tx_fifo_size


  • To: "xen-devel" <xen-devel@xxxxxxxxxxxxx>
  • From: "Jan Beulich" <JBeulich@xxxxxxxx>
  • Date: Tue, 11 Sep 2012 11:21:45 +0100
  • Delivery-date: Tue, 11 Sep 2012 10:22:03 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xen.org>

... in favor of having what so far was called tx_empty() return the
amount of space available.

Note that in the pl011.c case, original code and comment disagreed, and
I picked the conservative value for it's ->tx_ready() handler's return
value.

Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>

--- a/xen/drivers/char/ehci-dbgp.c
+++ b/xen/drivers/char/ehci-dbgp.c
@@ -1204,7 +1204,7 @@ static void ehci_dbgp_putc(struct serial
         ehci_dbgp_flush(port);
 }
 
-static int ehci_dbgp_tx_empty(struct serial_port *port)
+static unsigned int ehci_dbgp_tx_ready(struct serial_port *port)
 {
     struct ehci_dbgp *dbgp = port->uart;
 
@@ -1219,11 +1219,8 @@ static int ehci_dbgp_tx_empty(struct ser
     if ( dbgp->state != dbgp_idle && dbgp->out.chunk >= DBGP_MAX_PACKET )
         return 0;
 
-    port->tx_fifo_size = DBGP_MAX_PACKET - dbgp->out.chunk;
-    if ( dbgp->state == dbgp_idle )
-        port->tx_fifo_size += DBGP_MAX_PACKET;
-
-    return 1;
+    return DBGP_MAX_PACKET - dbgp->out.chunk +
+           (dbgp->state == dbgp_idle) * DBGP_MAX_PACKET;
 }
 
 static int ehci_dbgp_getc(struct serial_port *port, char *pc)
@@ -1347,7 +1344,6 @@ static void __init ehci_dbgp_init_preirq
     if ( ehci_dbgp_setup_preirq(dbgp) )
         ehci_dbgp_status(dbgp, "ehci_dbgp_init_preirq complete");
 
-    port->tx_fifo_size = DBGP_MAX_PACKET;
     dbgp->lock = &port->tx_lock;
 }
 
@@ -1448,7 +1444,7 @@ static struct uart_driver __read_mostly 
     .endboot      = ehci_dbgp_endboot,
     .suspend      = ehci_dbgp_suspend,
     .resume       = ehci_dbgp_resume,
-    .tx_empty     = ehci_dbgp_tx_empty,
+    .tx_ready     = ehci_dbgp_tx_ready,
     .putc         = ehci_dbgp_putc,
     .flush        = ehci_dbgp_flush,
     .getc         = ehci_dbgp_getc
--- a/xen/drivers/char/ns16550.c
+++ b/xen/drivers/char/ns16550.c
@@ -38,7 +38,7 @@ string_param("com1", opt_com1);
 string_param("com2", opt_com2);
 
 static struct ns16550 {
-    int baud, clock_hz, data_bits, parity, stop_bits, irq;
+    int baud, clock_hz, data_bits, parity, stop_bits, fifo_size, irq;
     unsigned long io_base;   /* I/O port or memory-mapped I/O address. */
     char __iomem *remapped_io_base;  /* Remapped virtual address of MMIO. */
     /* UART with IRQ line: interrupt-driven I/O. */
@@ -185,10 +185,11 @@ static void ns16550_poll(void *data)
 #endif
 }
 
-static int ns16550_tx_empty(struct serial_port *port)
+static unsigned int ns16550_tx_ready(struct serial_port *port)
 {
     struct ns16550 *uart = port->uart;
-    return !!(ns_read_reg(uart, LSR) & LSR_THRE);
+
+    return ns_read_reg(uart, LSR) & LSR_THRE ? uart->fifo_size : 0;
 }
 
 static void ns16550_putc(struct serial_port *port, char c)
@@ -288,7 +289,7 @@ static void __init ns16550_init_preirq(s
     /* Check this really is a 16550+. Otherwise we have no FIFOs. */
     if ( ((ns_read_reg(uart, IIR) & 0xc0) == 0xc0) &&
          ((ns_read_reg(uart, FCR) & FCR_TRG14) == FCR_TRG14) )
-        port->tx_fifo_size = 16;
+        uart->fifo_size = 16;
 }
 
 static void ns16550_setup_postirq(struct ns16550 *uart)
@@ -321,7 +322,7 @@ static void __init ns16550_init_postirq(
     /* 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);
+        unsigned int, 1, (bits * uart->fifo_size * 1000) / uart->baud);
 
     if ( uart->irq > 0 )
     {
@@ -388,7 +389,7 @@ static struct uart_driver __read_mostly 
     .endboot      = ns16550_endboot,
     .suspend      = ns16550_suspend,
     .resume       = ns16550_resume,
-    .tx_empty     = ns16550_tx_empty,
+    .tx_ready     = ns16550_tx_ready,
     .putc         = ns16550_putc,
     .getc         = ns16550_getc,
     .irq          = ns16550_irq
@@ -642,6 +643,8 @@ void __init ns16550_init(int index, stru
     uart->stop_bits = defaults->stop_bits;
     uart->irq       = defaults->irq;
     uart->io_base   = defaults->io_base;
+    /* Default is no transmit FIFO. */
+    uart->fifo_size = 1;
 
     ns16550_parse_port_config(uart, (index == 0) ? opt_com1 : opt_com2);
 }
--- a/xen/drivers/char/pl011.c
+++ b/xen/drivers/char/pl011.c
@@ -156,9 +156,6 @@ static void __init pl011_init_preirq(str
 
     /* Enable the UART for RX and TX; no flow ctrl */
     uart->regs[CR] = RXE | TXE | UARTEN;
-
-    /* Tell the serial framework about our fine 156-character FIFO */
-    port->tx_fifo_size = 16;
 }
 
 static void __init pl011_init_postirq(struct serial_port *port)
@@ -192,10 +189,10 @@ static void pl011_resume(struct serial_p
     BUG(); // XXX
 }
 
-static int pl011_tx_empty(struct serial_port *port)
+static unsigned int pl011_tx_ready(struct serial_port *port)
 {
     struct pl011 *uart = port->uart;
-    return !!(uart->regs[FR] & TXFE);
+    return uart->regs[FR] & TXFE ? 16 : 0;
 }
 
 static void pl011_putc(struct serial_port *port, char c)
@@ -227,7 +224,7 @@ static struct uart_driver __read_mostly 
     .endboot      = NULL,
     .suspend      = pl011_suspend,
     .resume       = pl011_resume,
-    .tx_empty     = pl011_tx_empty,
+    .tx_ready     = pl011_tx_ready,
     .putc         = pl011_putc,
     .getc         = pl011_getc,
     .irq          = pl011_irq
--- a/xen/drivers/char/serial.c
+++ b/xen/drivers/char/serial.c
@@ -59,7 +59,7 @@ void serial_rx_interrupt(struct serial_p
 
 void serial_tx_interrupt(struct serial_port *port, struct cpu_user_regs *regs)
 {
-    int i;
+    unsigned int i, n;
     unsigned long flags;
 
     local_irq_save(flags);
@@ -71,23 +71,20 @@ void serial_tx_interrupt(struct serial_p
      */
     while ( !spin_trylock(&port->tx_lock) )
     {
-        if ( !port->driver->tx_empty(port) )
+        if ( !port->driver->tx_ready(port) )
             goto out;
         cpu_relax();
     }
 
-    if ( port->driver->tx_empty(port) )
+    for ( i = 0, n = port->driver->tx_ready(port); i < n; i++ )
     {
-        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++)]);
-        }
-        if ( i && port->driver->flush )
-            port->driver->flush(port);
+        if ( port->txbufc == port->txbufp )
+            break;
+        port->driver->putc(
+            port, port->txbuf[mask_serial_txbuf_idx(port->txbufc++)]);
     }
+    if ( i && port->driver->flush )
+        port->driver->flush(port);
 
     spin_unlock(&port->tx_lock);
 
@@ -114,10 +111,11 @@ static void __serial_putc(struct serial_
             if ( port->tx_log_everything )
             {
                 /* Buffer is full: we spin waiting for space to appear. */
-                int i;
-                while ( !port->driver->tx_empty(port) )
+                unsigned int n;
+
+                while ( (n = port->driver->tx_ready(port)) == 0 )
                     cpu_relax();
-                for ( i = 0; i < port->tx_fifo_size; i++ )
+                while ( n-- )
                     port->driver->putc(
                         port,
                         port->txbuf[mask_serial_txbuf_idx(port->txbufc++)]);
@@ -132,7 +130,7 @@ static void __serial_putc(struct serial_
         }
 
         if ( ((port->txbufp - port->txbufc) == 0) &&
-                  port->driver->tx_empty(port) )
+             port->driver->tx_ready(port) )
         {
             /* Buffer and UART FIFO are both empty. */
             port->driver->putc(port, c);
@@ -143,10 +141,10 @@ static void __serial_putc(struct serial_
             port->txbuf[mask_serial_txbuf_idx(port->txbufp++)] = c;
         }
     }
-    else if ( port->driver->tx_empty )
+    else if ( port->driver->tx_ready )
     {
         /* Synchronous finite-capacity transmitter. */
-        while ( !port->driver->tx_empty(port) )
+        while ( !port->driver->tx_ready(port) )
             cpu_relax();
         port->driver->putc(port, c);
     }
@@ -386,7 +384,7 @@ void serial_start_sync(int handle)
     {
         while ( (port->txbufp - port->txbufc) != 0 )
         {
-            while ( !port->driver->tx_empty(port) )
+            while ( !port->driver->tx_ready(port) )
                 cpu_relax();
             port->driver->putc(
                 port, port->txbuf[mask_serial_txbuf_idx(port->txbufc++)]);
@@ -506,14 +504,11 @@ void __init serial_register_uart(int idx
     /* Store UART-specific info. */
     com[idx].driver = driver;
     com[idx].uart   = uart;
-
-    /* Default is no transmit FIFO. */
-    com[idx].tx_fifo_size = 1;
 }
 
 void __init serial_async_transmit(struct serial_port *port)
 {
-    BUG_ON(!port->driver->tx_empty);
+    BUG_ON(!port->driver->tx_ready);
     if ( port->txbuf != NULL )
         return;
     if ( serial_txbufsz < PAGE_SIZE )
--- a/xen/include/xen/serial.h
+++ b/xen/include/xen/serial.h
@@ -36,8 +36,6 @@ struct serial_port {
     struct uart_driver *driver;
     void               *uart;
     enum serial_port_state state;
-    /* Number of characters the port can hold for transmit. */
-    int                 tx_fifo_size;
     /* Transmit data buffer (interrupt-driven uart). */
     char               *txbuf;
     unsigned int        txbufp, txbufc;
@@ -63,8 +61,8 @@ struct uart_driver {
     /* Driver suspend/resume. */
     void (*suspend)(struct serial_port *);
     void (*resume)(struct serial_port *);
-    /* Transmit FIFO ready to receive up to @tx_fifo_size characters? */
-    int  (*tx_empty)(struct serial_port *);
+    /* Return number of characters the port can hold for transmit. */
+    unsigned int (*tx_ready)(struct serial_port *);
     /* Put a character onto the serial line. */
     void (*putc)(struct serial_port *, char);
     /* Flush accumulated characters. */


Attachment: sercon-drop-tx_fifo_size.patch
Description: Text document

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.