Commit bd9bdce694ccb76facc882363e4c337e8a88c918

Authored by balrog
1 parent 1fc678cc

Add input buffer to mux chr (patch by Tristan Gingold).


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3735 c046a42c-6fe2-441c-8c8c-71466251a162
hw/mcf_uart.c
... ... @@ -88,6 +88,7 @@ uint32_t mcf_uart_read(void *opaque, target_phys_addr_t addr)
88 88 if (s->fifo_len == 0)
89 89 s->sr &= ~MCF_UART_RxRDY;
90 90 mcf_uart_update(s);
  91 + qemu_chr_accept_input(s->chr);
91 92 return val;
92 93 }
93 94 case 0x10:
... ...
hw/pl011.c
... ... @@ -78,6 +78,7 @@ static uint32_t pl011_read(void *opaque, target_phys_addr_t offset)
78 78 if (s->read_count == s->read_trigger - 1)
79 79 s->int_level &= ~ PL011_INT_RX;
80 80 pl011_update(s);
  81 + qemu_chr_accept_input(s->chr);
81 82 return c;
82 83 case 1: /* UARTCR */
83 84 return 0;
... ...
hw/serial.c
... ... @@ -223,6 +223,7 @@ static uint32_t serial_ioport_read(void *opaque, uint32_t addr)
223 223 ret = s->rbr;
224 224 s->lsr &= ~(UART_LSR_DR | UART_LSR_BI);
225 225 serial_update_irq(s);
  226 + qemu_chr_accept_input(s->chr);
226 227 }
227 228 break;
228 229 case 1:
... ...
hw/slavio_serial.c
... ... @@ -475,6 +475,7 @@ static uint32_t slavio_serial_mem_readb(void *opaque, target_phys_addr_t addr)
475 475 else
476 476 ret = s->rx;
477 477 SER_DPRINTF("Read channel %c, ch %d\n", CHN_C(s), ret);
  478 + qemu_chr_accept_input(s->chr);
478 479 return ret;
479 480 default:
480 481 break;
... ...
qemu-char.h
... ... @@ -40,6 +40,7 @@ struct CharDriverState {
40 40 void *handler_opaque;
41 41 void (*chr_send_event)(struct CharDriverState *chr, int event);
42 42 void (*chr_close)(struct CharDriverState *chr);
  43 + void (*chr_accept_input)(struct CharDriverState *chr);
43 44 void *opaque;
44 45 int focus;
45 46 QEMUBH *bh;
... ... @@ -59,6 +60,7 @@ int qemu_chr_ioctl(CharDriverState *s, int cmd, void *arg);
59 60 void qemu_chr_reset(CharDriverState *s);
60 61 int qemu_chr_can_read(CharDriverState *s);
61 62 void qemu_chr_read(CharDriverState *s, uint8_t *buf, int len);
  63 +void qemu_chr_accept_input(CharDriverState *s);
62 64  
63 65 /* async I/O support */
64 66  
... ...
... ... @@ -1594,6 +1594,11 @@ void qemu_chr_read(CharDriverState *s, uint8_t *buf, int len)
1594 1594 s->chr_read(s->handler_opaque, buf, len);
1595 1595 }
1596 1596  
  1597 +void qemu_chr_accept_input(CharDriverState *s)
  1598 +{
  1599 + if (s->chr_accept_input)
  1600 + s->chr_accept_input(s);
  1601 +}
1597 1602  
1598 1603 void qemu_chr_printf(CharDriverState *s, const char *fmt, ...)
1599 1604 {
... ... @@ -1645,12 +1650,17 @@ static CharDriverState *qemu_chr_open_null(void)
1645 1650 static int term_timestamps;
1646 1651 static int64_t term_timestamps_start;
1647 1652 #define MAX_MUX 4
  1653 +#define MUX_BUFFER_SIZE 32 /* Must be a power of 2. */
  1654 +#define MUX_BUFFER_MASK (MUX_BUFFER_SIZE - 1)
1648 1655 typedef struct {
1649 1656 IOCanRWHandler *chr_can_read[MAX_MUX];
1650 1657 IOReadHandler *chr_read[MAX_MUX];
1651 1658 IOEventHandler *chr_event[MAX_MUX];
1652 1659 void *ext_opaque[MAX_MUX];
1653 1660 CharDriverState *drv;
  1661 + unsigned char buffer[MUX_BUFFER_SIZE];
  1662 + int prod;
  1663 + int cons;
1654 1664 int mux_cnt;
1655 1665 int term_got_escape;
1656 1666 int max_size;
... ... @@ -1779,12 +1789,28 @@ static int mux_proc_byte(CharDriverState *chr, MuxDriver *d, int ch)
1779 1789 return 0;
1780 1790 }
1781 1791  
  1792 +static void mux_chr_accept_input(CharDriverState *chr)
  1793 +{
  1794 + int m = chr->focus;
  1795 + MuxDriver *d = chr->opaque;
  1796 +
  1797 + while (d->prod != d->cons &&
  1798 + d->chr_can_read[m] &&
  1799 + d->chr_can_read[m](d->ext_opaque[m])) {
  1800 + d->chr_read[m](d->ext_opaque[m],
  1801 + &d->buffer[d->cons++ & MUX_BUFFER_MASK], 1);
  1802 + }
  1803 +}
  1804 +
1782 1805 static int mux_chr_can_read(void *opaque)
1783 1806 {
1784 1807 CharDriverState *chr = opaque;
1785 1808 MuxDriver *d = chr->opaque;
  1809 +
  1810 + if ((d->prod - d->cons) < MUX_BUFFER_SIZE)
  1811 + return 1;
1786 1812 if (d->chr_can_read[chr->focus])
1787   - return d->chr_can_read[chr->focus](d->ext_opaque[chr->focus]);
  1813 + return d->chr_can_read[chr->focus](d->ext_opaque[chr->focus]);
1788 1814 return 0;
1789 1815 }
1790 1816  
... ... @@ -1792,10 +1818,20 @@ static void mux_chr_read(void *opaque, const uint8_t *buf, int size)
1792 1818 {
1793 1819 CharDriverState *chr = opaque;
1794 1820 MuxDriver *d = chr->opaque;
  1821 + int m = chr->focus;
1795 1822 int i;
  1823 +
  1824 + mux_chr_accept_input (opaque);
  1825 +
1796 1826 for(i = 0; i < size; i++)
1797   - if (mux_proc_byte(chr, d, buf[i]))
1798   - d->chr_read[chr->focus](d->ext_opaque[chr->focus], &buf[i], 1);
  1827 + if (mux_proc_byte(chr, d, buf[i])) {
  1828 + if (d->prod == d->cons &&
  1829 + d->chr_can_read[m] &&
  1830 + d->chr_can_read[m](d->ext_opaque[m]))
  1831 + d->chr_read[m](d->ext_opaque[m], &buf[i], 1);
  1832 + else
  1833 + d->buffer[d->prod++ & MUX_BUFFER_MASK] = buf[i];
  1834 + }
1799 1835 }
1800 1836  
1801 1837 static void mux_chr_event(void *opaque, int event)
... ... @@ -1850,6 +1886,7 @@ static CharDriverState *qemu_chr_open_mux(CharDriverState *drv)
1850 1886 chr->focus = -1;
1851 1887 chr->chr_write = mux_chr_write;
1852 1888 chr->chr_update_read_handler = mux_chr_update_read_handler;
  1889 + chr->chr_accept_input = mux_chr_accept_input;
1853 1890 return chr;
1854 1891 }
1855 1892  
... ...