ia64/xen-unstable

changeset 12040:c33272c2571c

[HVM] Fix Qemu-dm serial issues:
1. Retry transmit via a polling timer if a byte cannot be written
immediately to its destination.
2. Turn off output processing of raw serial lines.

Signed-off-by: Xiaowei Yang <xiaowei.yang@intel.com>
Signed-off-by: Yunhong Jiang <yunhong.jiang@intel.com>
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Mon Oct 30 09:45:17 2006 +0000 (2006-10-30)
parents b3d94f4ddffe
children 2b99c99f96e6
files tools/ioemu/hw/serial.c tools/ioemu/vl.c
line diff
     1.1 --- a/tools/ioemu/hw/serial.c	Sat Oct 28 12:30:38 2006 +0100
     1.2 +++ b/tools/ioemu/hw/serial.c	Mon Oct 30 09:45:17 2006 +0000
     1.3 @@ -93,6 +93,15 @@ struct SerialState {
     1.4      int last_break_enable;
     1.5      target_ulong base;
     1.6      int it_shift;
     1.7 +
     1.8 +    /*
     1.9 +     * If a character transmitted via UART cannot be written to its
    1.10 +     * destination immediately we remember it here and retry a few times via
    1.11 +     * a polling timer.
    1.12 +     */
    1.13 +    int write_retries;
    1.14 +    char write_chr;
    1.15 +    QEMUTimer *write_retry_timer;
    1.16  };
    1.17  
    1.18  static void serial_update_irq(SerialState *s)
    1.19 @@ -204,10 +213,32 @@ static void serial_get_token(void)
    1.20      tokens_avail--;
    1.21  }
    1.22  
    1.23 +static void serial_chr_write(void *opaque)
    1.24 +{
    1.25 +    SerialState *s = opaque;
    1.26 +
    1.27 +    qemu_del_timer(s->write_retry_timer);
    1.28 +
    1.29 +    /* Retry every 100ms for 300ms total. */
    1.30 +    if (qemu_chr_write(s->chr, &s->write_chr, 1) == -1) {
    1.31 +        if (s->write_retries++ >= 3)
    1.32 +            printf("serial: write error\n");
    1.33 +        else
    1.34 +            qemu_mod_timer(s->write_retry_timer,
    1.35 +                           qemu_get_clock(vm_clock) + ticks_per_sec / 10);
    1.36 +        return;
    1.37 +    }
    1.38 +
    1.39 +    /* Success: Notify guest that THR is empty. */
    1.40 +    s->thr_ipending = 1;
    1.41 +    s->lsr |= UART_LSR_THRE;
    1.42 +    s->lsr |= UART_LSR_TEMT;
    1.43 +    serial_update_irq(s);
    1.44 +}
    1.45 +
    1.46  static void serial_ioport_write(void *opaque, uint32_t addr, uint32_t val)
    1.47  {
    1.48      SerialState *s = opaque;
    1.49 -    unsigned char ch;
    1.50      
    1.51      addr &= 7;
    1.52  #ifdef DEBUG_SERIAL
    1.53 @@ -223,12 +254,9 @@ static void serial_ioport_write(void *op
    1.54              s->thr_ipending = 0;
    1.55              s->lsr &= ~UART_LSR_THRE;
    1.56              serial_update_irq(s);
    1.57 -            ch = val;
    1.58 -            qemu_chr_write(s->chr, &ch, 1);
    1.59 -            s->thr_ipending = 1;
    1.60 -            s->lsr |= UART_LSR_THRE;
    1.61 -            s->lsr |= UART_LSR_TEMT;
    1.62 -            serial_update_irq(s);
    1.63 +            s->write_chr = val;
    1.64 +            s->write_retries = 0;
    1.65 +            serial_chr_write(s);
    1.66          }
    1.67          break;
    1.68      case 1:
    1.69 @@ -424,6 +452,7 @@ SerialState *serial_init(SetIRQFunc *set
    1.70      s->lsr = UART_LSR_TEMT | UART_LSR_THRE;
    1.71      s->iir = UART_IIR_NO_INT;
    1.72      s->msr = UART_MSR_DCD | UART_MSR_DSR | UART_MSR_CTS;
    1.73 +    s->write_retry_timer = qemu_new_timer(vm_clock, serial_chr_write, s);
    1.74  
    1.75      register_savevm("serial", base, 1, serial_save, serial_load, s);
    1.76  
    1.77 @@ -511,6 +540,7 @@ SerialState *serial_mm_init (SetIRQFunc 
    1.78      s->msr = UART_MSR_DCD | UART_MSR_DSR | UART_MSR_CTS;
    1.79      s->base = base;
    1.80      s->it_shift = it_shift;
    1.81 +    s->write_retry_timer = qemu_new_timer(vm_clock, serial_chr_write, s);
    1.82  
    1.83      register_savevm("serial", base, 1, serial_save, serial_load, s);
    1.84  
     2.1 --- a/tools/ioemu/vl.c	Sat Oct 28 12:30:38 2006 +0100
     2.2 +++ b/tools/ioemu/vl.c	Mon Oct 30 09:45:17 2006 +0000
     2.3 @@ -1684,7 +1684,7 @@ static void tty_serial_init(int fd, int 
     2.4  
     2.5      tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
     2.6                            |INLCR|IGNCR|ICRNL|IXON);
     2.7 -    tty.c_oflag |= OPOST;
     2.8 +    tty.c_oflag &= ~OPOST; /* no output mangling of raw serial stream */
     2.9      tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN|ISIG);
    2.10      tty.c_cflag &= ~(CSIZE|PARENB|PARODD|CRTSCTS);
    2.11      switch(data_bits) {