From mboxrd@z Thu Jan 1 00:00:00 1970 From: Konrad Rzeszutek Wilk Subject: [PATCH 1 of 1] Handle bogus serial ports that appear normal, but don't generate Date: Mon, 14 Dec 2009 15:10:46 -0000 Message-ID: <37cb71cbe3b4c02c2ea4.1260803446@phenom.dumpdata.com> References: Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xensource.com Errors-To: xen-devel-bounces@lists.xensource.com To: xen-devel@lists.xensource.com, keir.fraser@eu.citrix.com Cc: Gary.Grebus@oracle.com List-Id: xen-devel@lists.xenproject.org # HG changeset patch # User konrad@phenom.dumpdata.com # 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 Signed-off-by: Konrad Rzeszutek Wilk 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)); } }