From patchwork Fri Dec 12 12:44:01 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 420455 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id E0715140081 for ; Fri, 12 Dec 2014 23:48:41 +1100 (AEDT) Received: from localhost ([::1]:56901 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XzPeC-0003Ye-78 for incoming@patchwork.ozlabs.org; Fri, 12 Dec 2014 07:48:40 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39904) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XzPaB-0006uU-Tj for qemu-devel@nongnu.org; Fri, 12 Dec 2014 07:44:42 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XzPZv-0001lq-9K for qemu-devel@nongnu.org; Fri, 12 Dec 2014 07:44:29 -0500 Received: from mail-wg0-x234.google.com ([2a00:1450:400c:c00::234]:56378) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XzPZv-0001lm-2M for qemu-devel@nongnu.org; Fri, 12 Dec 2014 07:44:15 -0500 Received: by mail-wg0-f52.google.com with SMTP id x12so8949768wgg.25 for ; Fri, 12 Dec 2014 04:44:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=bNYkaomD/Rbf2l8g+BFkosDWOX454yIaQwERv77lLFw=; b=TckIPpMXf2CLCDGMcEJfgTQb1Yp2y1v75rDKlKFOnBBBRajFNbUahrKHzPVqhK6qEe 21C5ktHc96OLwHpay6RNXDRRHShO9Ri2II1VubYPW12iPQJ48zrQ0/vsmLqvCnjGKLbm Uet8fYX4PcOj67+ulKXpn66zY231DOseJop53AHrQ04OIkdQd4WOttxBM1DbzA5HTGvn /asqS5Le+4k3oVxpN+V+4ILeAgeTZGUbEphDv/lPlotZXdOGeMEzhmapvX1WjTIEih9H 7Rr+lEEh+kbDTIBijsDnGX094uNqm7Cg3FFOmNdJSX0+vkZOSYPcSiz4AE31gy7d/9ra lWag== X-Received: by 10.194.189.240 with SMTP id gl16mr26136772wjc.119.1418388254385; Fri, 12 Dec 2014 04:44:14 -0800 (PST) Received: from playground.station (net-2-35-193-40.cust.vodafonedsl.it. [2.35.193.40]) by mx.google.com with ESMTPSA id hn2sm1716801wjc.5.2014.12.12.04.44.12 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 12 Dec 2014 04:44:13 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Fri, 12 Dec 2014 13:44:01 +0100 Message-Id: <1418388243-1886-3-git-send-email-pbonzini@redhat.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1418388243-1886-1-git-send-email-pbonzini@redhat.com> References: <1418388243-1886-1-git-send-email-pbonzini@redhat.com> X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2a00:1450:400c:c00::234 Cc: imammedo@redhat.com, andrey@xdel.ru, dgilbert@redhat.com, batuzovk@ispras.ru Subject: [Qemu-devel] [PATCH v3 2/4] serial: clean up THRE/TEMT handling X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org - assert THRE cleared and FIFO not empty (if enabled) before sending a character. Also assert TEMT cleared, since it is the combination of THRE && transmitter shift register empty. - raise THRI immediately after setting THRE - check THRE to see if another character has to be sent, which makes the assertions more obvious and also means TEMT has to be set as soon as the loop ends - clear TEMT together with THRE even in the non-FIFO case There are certainly a couple bugfixes in here, but nothing that squashes known bugs. Signed-off-by: Paolo Bonzini Reviewed-by: Dr. David Alan Gilbert --- hw/char/serial.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/hw/char/serial.c b/hw/char/serial.c index 8c42d03..4bce268 100644 --- a/hw/char/serial.c +++ b/hw/char/serial.c @@ -224,21 +224,23 @@ static gboolean serial_xmit(GIOChannel *chan, GIOCondition cond, void *opaque) SerialState *s = opaque; do { + assert(!(s->lsr & UART_LSR_TEMT)); + assert(!(s->lsr & UART_LSR_THRE)); + if (s->tsr_retry <= 0) { if (s->fcr & UART_FCR_FE) { - if (fifo8_is_empty(&s->xmit_fifo)) { - return FALSE; - } + assert(!fifo8_is_empty(&s->xmit_fifo)); s->tsr = fifo8_pop(&s->xmit_fifo); if (!s->xmit_fifo.num) { s->lsr |= UART_LSR_THRE; } - } else if ((s->lsr & UART_LSR_THRE)) { - return FALSE; } else { s->tsr = s->thr; s->lsr |= UART_LSR_THRE; - s->lsr &= ~UART_LSR_TEMT; + } + if ((s->lsr & UART_LSR_THRE) && !s->thr_ipending) { + s->thr_ipending = 1; + serial_update_irq(s); } } @@ -256,17 +258,13 @@ static gboolean serial_xmit(GIOChannel *chan, GIOCondition cond, void *opaque) } else { s->tsr_retry = 0; } + /* Transmit another byte if it is already available. It is only possible when FIFO is enabled and not empty. */ - } while ((s->fcr & UART_FCR_FE) && !fifo8_is_empty(&s->xmit_fifo)); + } while (!(s->lsr & UART_LSR_THRE)); s->last_xmit_ts = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); - - if (s->lsr & UART_LSR_THRE) { - s->lsr |= UART_LSR_TEMT; - s->thr_ipending = 1; - serial_update_irq(s); - } + s->lsr |= UART_LSR_TEMT; return FALSE; } @@ -323,10 +321,10 @@ static void serial_ioport_write(void *opaque, hwaddr addr, uint64_t val, fifo8_pop(&s->xmit_fifo); } fifo8_push(&s->xmit_fifo, s->thr); - s->lsr &= ~UART_LSR_TEMT; } s->thr_ipending = 0; s->lsr &= ~UART_LSR_THRE; + s->lsr &= ~UART_LSR_TEMT; serial_update_irq(s); if (s->tsr_retry <= 0) { serial_xmit(NULL, G_IO_OUT, s);