diff -uNr xen-unstable.hg/tools/ioemu/hw/serial.c xen-unstable.hg-patched/tools/ioemu/hw/serial.c --- xen-unstable.hg/tools/ioemu/hw/serial.c 2007-12-08 22:23:57.345820400 +0100 +++ xen-unstable.hg-patched/tools/ioemu/hw/serial.c 2007-12-08 22:26:41.551177930 +0100 @@ -26,16 +26,11 @@ #include #include #include +#include +#include //#define DEBUG_SERIAL -#define TIOCM_DTR 0x002 -#define TIOCM_RTS 0x004 -#define TIOCM_CTS 0x020 -#define TIOCM_CAR 0x040 -#define TIOCM_RI 0x080 -#define TIOCM_DSR 0x100 - #define UART_LCR_DLAB 0x80 /* Divisor latch access bit */ #define UART_IER_MSI 0x08 /* Enable Modem status interrupt */ @@ -364,7 +359,7 @@ SerialState *s = opaque; uint64_t new_xmit_ts = qemu_get_clock(vm_clock); - if ( s->tsr_retry == 0 ) { + if ( s->tsr_retry <= 0 ) { if (s->fcr & UART_FCR_FE) { s->tsr = fifo_get(s,XMIT_FIFO); if ( !s->xmit_fifo.count ) @@ -376,16 +371,22 @@ } if ( qemu_chr_write(s->chr, &s->tsr, 1) != 1 ) { - s->tsr_retry++; - if ( s->tsr_retry <= MAX_XMIT_RETRY ) { + if ( ( s->tsr_retry > 0 ) && ( s->tsr_retry <= MAX_XMIT_RETRY ) ) { + s->tsr_retry++; qemu_mod_timer(s->transmit_timer, new_xmit_ts + s->char_transmit_time ); return; + } else if ( s->poll_msl < 0 ) { + /* If we exceed MAX_XMIT_RETRY and the backend is not a real serial port, then + drop any further failed writes instantly, until we get one that goes through. + This is to prevent guests that log to unconnected pipes or pty's from stalling. */ + s->tsr_retry = -1; } } - - s->tsr_retry = 0; - s->last_xmit_ts = qemu_get_clock(vm_clock); + else { + s->tsr_retry = 0; + } + s->last_xmit_ts = qemu_get_clock(vm_clock); if ( !(s->lsr & UART_LSR_THRE) ) qemu_mod_timer(s->transmit_timer, s->last_xmit_ts + s->char_transmit_time );