From patchwork Thu Jan 28 23:13:31 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Justin T. Gibbs" X-Patchwork-Id: 43888 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 4DFE1B7D10 for ; Fri, 29 Jan 2010 16:31:39 +1100 (EST) Received: from localhost ([127.0.0.1]:39408 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NajSC-000754-AK for incoming@patchwork.ozlabs.org; Fri, 29 Jan 2010 00:31:36 -0500 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1NadYV-0006qr-Kj for qemu-devel@nongnu.org; Thu, 28 Jan 2010 18:13:43 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1NadYT-0006py-CD for qemu-devel@nongnu.org; Thu, 28 Jan 2010 18:13:42 -0500 Received: from [199.232.76.173] (port=47787 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NadYT-0006pt-7l for qemu-devel@nongnu.org; Thu, 28 Jan 2010 18:13:41 -0500 Received: from ns1.scsiguy.com ([70.89.174.89]:64344 helo=aslan.scsiguy.com) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1NadYS-0006N7-Ii for qemu-devel@nongnu.org; Thu, 28 Jan 2010 18:13:40 -0500 Received: from [192.168.3.59] (spectra2.spectralogic.com [63.172.79.253] (may be forged)) (authenticated bits=0) by aslan.scsiguy.com (8.14.3/8.14.3) with ESMTP id o0SNDauj015638 (version=TLSv1/SSLv3 cipher=DHE-RSA-CAMELLIA256-SHA bits=256 verify=NO) for ; Thu, 28 Jan 2010 16:13:37 -0700 (MST) (envelope-from gibbs@FreeBSD.org) Message-ID: <4B621A1B.6090309@FreeBSD.org> Date: Thu, 28 Jan 2010 16:13:31 -0700 From: "Justin T. Gibbs" Organization: The FreeBSD Project User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.7) Gecko/20100111 Thunderbird/3.0.1 MIME-Version: 1.0 To: qemu-devel@nongnu.org X-detected-operating-system: by monty-python.gnu.org: Genre and OS details not recognized. X-Mailman-Approved-At: Fri, 29 Jan 2010 00:30:16 -0500 Subject: [Qemu-devel] [PATCH] Fix lost serial TX interrupts. Report receive overruns. X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: gibbs@FreeBSD.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org This patch compliments the patch submitted by Jergen Lock and further improves the performance of QEMU's serial emulation with FreeBSD's uart(9) driver. o Implement receive overrun status. The FreeBSD uart driver relies on this status in it's probe routine to determine the size of the FIFO supported. o As per the 16550 spec, do not overwrite the RX FIFO on an RX overrun. o Do not allow TX or RX FIFO overruns to increment the data valid count beyond the size of the FIFO. o For reads of the IIR register, only clear the "TX holding register emtpy interrupt" if the read reports this interrupt. This is required by the specification and avoids losing TX interrupts when other, higher priority interrupts (usually RX) are reported first. Signed-off-by: Justin T. Gibbs } --- serial.c.orig Thu Jan 14 15:18:00 2010 +++ serial.c Thu Jan 28 15:36:04 2010 @@ -169,11 +169,19 @@ { SerialFIFO *f = (fifo) ? &s->recv_fifo : &s->xmit_fifo; - f->data[f->head++] = chr; + /* Receive overruns do not overwrite FIFO contents. */ + if (fifo == XMIT_FIFO || f->count < UART_FIFO_LENGTH) { - if (f->head == UART_FIFO_LENGTH) - f->head = 0; - f->count++; + f->data[f->head++] = chr; + + if (f->head == UART_FIFO_LENGTH) + f->head = 0; + } + + if (f->count < UART_FIFO_LENGTH) + f->count++; + else if (fifo == RECV_FIFO) + s->lsr |= UART_LSR_OE; return 1; } @@ -533,8 +541,10 @@ break; case 2: ret = s->iir; + if (ret & UART_IIR_THRI) { s->thr_ipending = 0; - serial_update_irq(s); + serial_update_irq(s); + } break; case 3: ret = s->lcr; @@ -544,9 +554,9 @@ break; case 5: ret = s->lsr; - /* Clear break interrupt */ - if (s->lsr & UART_LSR_BI) { - s->lsr &= ~UART_LSR_BI; + /* Clear break and overrun interrupts */ + if (s->lsr & (UART_LSR_BI|UART_LSR_OE)) { + s->lsr &= ~(UART_LSR_BI|UART_LSR_OE); serial_update_irq(s); } break; @@ -629,6 +639,8 @@ /* call the timeout receive callback in 4 char transmit time */ qemu_mod_timer(s->fifo_timeout_timer, qemu_get_clock (vm_clock) + s->char_transmit_time * 4); } else { + if (s->lsr & UART_LSR_DR) + s->lsr |= UART_LSR_OE; s->rbr = buf[0]; s->lsr |= UART_LSR_DR;