From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:57346) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bG8Kl-0003OF-Jr for qemu-devel@nongnu.org; Thu, 23 Jun 2016 13:22:37 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bG8Kk-0006Vz-Lv for qemu-devel@nongnu.org; Thu, 23 Jun 2016 13:22:31 -0400 Received: from mx1.redhat.com ([209.132.183.28]:39436) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bG8Kk-0006Vs-Fl for qemu-devel@nongnu.org; Thu, 23 Jun 2016 13:22:30 -0400 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 10E083B717 for ; Thu, 23 Jun 2016 17:22:30 +0000 (UTC) From: Paolo Bonzini Date: Thu, 23 Jun 2016 19:22:19 +0200 Message-Id: <1466702539-17607-7-git-send-email-pbonzini@redhat.com> In-Reply-To: <1466702539-17607-1-git-send-email-pbonzini@redhat.com> References: <1466702539-17607-1-git-send-email-pbonzini@redhat.com> Subject: [Qemu-devel] [PATCH v2 6/6] serial: reinstate watch after migration List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: dgilbert@redhat.com Otherwise, a serial port can get stuck if it is migrated while flow control is in effect. Tested-by: Bret Ketchum Signed-off-by: Paolo Bonzini --- hw/char/serial.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/hw/char/serial.c b/hw/char/serial.c index af39e8f..3442f47 100644 --- a/hw/char/serial.c +++ b/hw/char/serial.c @@ -644,8 +644,29 @@ static int serial_post_load(void *opaque, int version_id) if (s->thr_ipending == -1) { s->thr_ipending = ((s->iir & UART_IIR_ID) == UART_IIR_THRI); } - if (s->tsr_retry > MAX_XMIT_RETRY) { - s->tsr_retry = MAX_XMIT_RETRY; + + if (s->tsr_retry > 0) { + /* tsr_retry > 0 implies LSR.TEMT = 0 (transmitter not empty). */ + if (s->lsr & UART_LSR_TEMT) { + error_report("inconsistent state in serial device " + "(tsr empty, tsr_retry=%d", s->tsr_retry); + return -1; + } + + if (s->tsr_retry > MAX_XMIT_RETRY) { + s->tsr_retry = MAX_XMIT_RETRY; + } + + assert(s->watch_tag == 0); + s->watch_tag = qemu_chr_fe_add_watch(s->chr, G_IO_OUT|G_IO_HUP, + serial_watch_cb, s); + } else { + /* tsr_retry == 0 implies LSR.TEMT = 1 (transmitter empty). */ + if (!(s->lsr & UART_LSR_TEMT)) { + error_report("inconsistent state in serial device " + "(tsr not empty, tsr_retry=0"); + return -1; + } } s->last_break_enable = (s->lcr >> 6) & 1; -- 2.5.5