From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:54030) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bF0CW-00089O-US for qemu-devel@nongnu.org; Mon, 20 Jun 2016 10:29:22 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bF0CM-0003Az-Rr for qemu-devel@nongnu.org; Mon, 20 Jun 2016 10:29:19 -0400 Received: from mail-wm0-x243.google.com ([2a00:1450:400c:c09::243]:36300) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bF0CM-0003Av-Kt for qemu-devel@nongnu.org; Mon, 20 Jun 2016 10:29:10 -0400 Received: by mail-wm0-x243.google.com with SMTP id c82so11608396wme.3 for ; Mon, 20 Jun 2016 07:29:10 -0700 (PDT) Sender: Paolo Bonzini From: Paolo Bonzini Date: Mon, 20 Jun 2016 16:29:01 +0200 Message-Id: <1466432945-28682-3-git-send-email-pbonzini@redhat.com> In-Reply-To: <1466432945-28682-1-git-send-email-pbonzini@redhat.com> References: <1466432945-28682-1-git-send-email-pbonzini@redhat.com> Subject: [Qemu-devel] [PATCH 2/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, bcketchum@gmail.com Otherwise, a serial port can get stuck if it is migrated while flow control is in effect. Signed-off-by: Paolo Bonzini --- hw/char/serial.c | 16 ++++++++++++++-- include/hw/char/serial.h | 1 + 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/hw/char/serial.c b/hw/char/serial.c index e65e9e0..6f0a49e 100644 --- a/hw/char/serial.c +++ b/hw/char/serial.c @@ -639,8 +639,20 @@ 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) { + return -1; + } + + assert(s->watch_tag == 0); + s->watch_tag = qemu_chr_fe_add_watch(s->chr, G_IO_OUT|G_IO_HUP, serial_xmit, s); + } else { + /* tsr_retry == 0 implies LSR.TEMT = 1 (transmitter empty). */ + if (!(s->lsr & UART_LSR_TEMT)) { + return -1; + } } s->last_break_enable = (s->lcr >> 6) & 1; diff --git a/include/hw/char/serial.h b/include/hw/char/serial.h index ef90615..2ab835c 100644 --- a/include/hw/char/serial.h +++ b/include/hw/char/serial.h @@ -56,6 +56,7 @@ struct SerialState { int it_shift; int baudbase; unsigned tsr_retry; + unsigned watch_tag; uint32_t wakeup; /* Time when the last byte was successfully sent out of the tsr */ -- 2.5.5