Messing with the FIFO depths and trigger levels seems to help, as does messing with the interrupt enable state at various points. The latter might be better handled via the start/stop_tx hooks which were added a while ago.
Signed-off-by: Ian Campbell <ian.campb...@citrix.com> --- xen/drivers/char/ns16550.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/xen/drivers/char/ns16550.c b/xen/drivers/char/ns16550.c index 44045d7..3b32f40 100644 --- a/xen/drivers/char/ns16550.c +++ b/xen/drivers/char/ns16550.c @@ -401,7 +401,14 @@ static void ns16550_interrupt( { char lsr = ns_read_reg(uart, UART_LSR); if ( (lsr & uart->lsr_mask) == uart->lsr_mask ) + { serial_tx_interrupt(port, regs); + if ( port->txbufc == port->txbufp ) { + u8 reg; + reg = ns_read_reg(uart, UART_IER); + ns_write_reg(uart, UART_IER, reg & (~UART_IER_ETHREI)); + } + } if ( lsr & UART_LSR_DR ) serial_rx_interrupt(port, regs); } @@ -450,6 +457,13 @@ static int ns16550_tx_ready(struct serial_port *port) if ( ns16550_ioport_invalid(uart) ) return -EIO; + if ( 1 ) + { + u8 reg; + reg = ns_read_reg(uart, UART_IER); + ns_write_reg(uart, UART_IER, reg | UART_IER_ETHREI); + } + return ( (ns_read_reg(uart, UART_LSR) & uart->lsr_mask ) == uart->lsr_mask ) ? uart->fifo_size : 0; } @@ -539,7 +553,7 @@ static void ns16550_setup_preirq(struct ns16550 *uart) /* Enable and clear the FIFOs. Set a large trigger threshold. */ ns_write_reg(uart, UART_FCR, - UART_FCR_ENABLE | UART_FCR_CLRX | UART_FCR_CLTX | UART_FCR_TRG14); + UART_FCR_ENABLE | UART_FCR_CLRX | UART_FCR_CLTX | UART_FCR_TRG1/*UART_FCR_TRG14*/); } static void __init ns16550_init_preirq(struct serial_port *port) -- 2.1.4 _______________________________________________ Xen-devel mailing list Xen-devel@lists.xen.org http://lists.xen.org/xen-devel