Commit bd9bdce694ccb76facc882363e4c337e8a88c918
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
Showing
6 changed files
with
46 additions
and
3 deletions
hw/mcf_uart.c
| @@ -88,6 +88,7 @@ uint32_t mcf_uart_read(void *opaque, target_phys_addr_t addr) | @@ -88,6 +88,7 @@ uint32_t mcf_uart_read(void *opaque, target_phys_addr_t addr) | ||
| 88 | if (s->fifo_len == 0) | 88 | if (s->fifo_len == 0) |
| 89 | s->sr &= ~MCF_UART_RxRDY; | 89 | s->sr &= ~MCF_UART_RxRDY; |
| 90 | mcf_uart_update(s); | 90 | mcf_uart_update(s); |
| 91 | + qemu_chr_accept_input(s->chr); | ||
| 91 | return val; | 92 | return val; |
| 92 | } | 93 | } |
| 93 | case 0x10: | 94 | case 0x10: |
hw/pl011.c
| @@ -78,6 +78,7 @@ static uint32_t pl011_read(void *opaque, target_phys_addr_t offset) | @@ -78,6 +78,7 @@ static uint32_t pl011_read(void *opaque, target_phys_addr_t offset) | ||
| 78 | if (s->read_count == s->read_trigger - 1) | 78 | if (s->read_count == s->read_trigger - 1) |
| 79 | s->int_level &= ~ PL011_INT_RX; | 79 | s->int_level &= ~ PL011_INT_RX; |
| 80 | pl011_update(s); | 80 | pl011_update(s); |
| 81 | + qemu_chr_accept_input(s->chr); | ||
| 81 | return c; | 82 | return c; |
| 82 | case 1: /* UARTCR */ | 83 | case 1: /* UARTCR */ |
| 83 | return 0; | 84 | return 0; |
hw/serial.c
| @@ -223,6 +223,7 @@ static uint32_t serial_ioport_read(void *opaque, uint32_t addr) | @@ -223,6 +223,7 @@ static uint32_t serial_ioport_read(void *opaque, uint32_t addr) | ||
| 223 | ret = s->rbr; | 223 | ret = s->rbr; |
| 224 | s->lsr &= ~(UART_LSR_DR | UART_LSR_BI); | 224 | s->lsr &= ~(UART_LSR_DR | UART_LSR_BI); |
| 225 | serial_update_irq(s); | 225 | serial_update_irq(s); |
| 226 | + qemu_chr_accept_input(s->chr); | ||
| 226 | } | 227 | } |
| 227 | break; | 228 | break; |
| 228 | case 1: | 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,6 +475,7 @@ static uint32_t slavio_serial_mem_readb(void *opaque, target_phys_addr_t addr) | ||
| 475 | else | 475 | else |
| 476 | ret = s->rx; | 476 | ret = s->rx; |
| 477 | SER_DPRINTF("Read channel %c, ch %d\n", CHN_C(s), ret); | 477 | SER_DPRINTF("Read channel %c, ch %d\n", CHN_C(s), ret); |
| 478 | + qemu_chr_accept_input(s->chr); | ||
| 478 | return ret; | 479 | return ret; |
| 479 | default: | 480 | default: |
| 480 | break; | 481 | break; |
qemu-char.h
| @@ -40,6 +40,7 @@ struct CharDriverState { | @@ -40,6 +40,7 @@ struct CharDriverState { | ||
| 40 | void *handler_opaque; | 40 | void *handler_opaque; |
| 41 | void (*chr_send_event)(struct CharDriverState *chr, int event); | 41 | void (*chr_send_event)(struct CharDriverState *chr, int event); |
| 42 | void (*chr_close)(struct CharDriverState *chr); | 42 | void (*chr_close)(struct CharDriverState *chr); |
| 43 | + void (*chr_accept_input)(struct CharDriverState *chr); | ||
| 43 | void *opaque; | 44 | void *opaque; |
| 44 | int focus; | 45 | int focus; |
| 45 | QEMUBH *bh; | 46 | QEMUBH *bh; |
| @@ -59,6 +60,7 @@ int qemu_chr_ioctl(CharDriverState *s, int cmd, void *arg); | @@ -59,6 +60,7 @@ int qemu_chr_ioctl(CharDriverState *s, int cmd, void *arg); | ||
| 59 | void qemu_chr_reset(CharDriverState *s); | 60 | void qemu_chr_reset(CharDriverState *s); |
| 60 | int qemu_chr_can_read(CharDriverState *s); | 61 | int qemu_chr_can_read(CharDriverState *s); |
| 61 | void qemu_chr_read(CharDriverState *s, uint8_t *buf, int len); | 62 | void qemu_chr_read(CharDriverState *s, uint8_t *buf, int len); |
| 63 | +void qemu_chr_accept_input(CharDriverState *s); | ||
| 62 | 64 | ||
| 63 | /* async I/O support */ | 65 | /* async I/O support */ |
| 64 | 66 |
vl.c
| @@ -1594,6 +1594,11 @@ void qemu_chr_read(CharDriverState *s, uint8_t *buf, int len) | @@ -1594,6 +1594,11 @@ void qemu_chr_read(CharDriverState *s, uint8_t *buf, int len) | ||
| 1594 | s->chr_read(s->handler_opaque, buf, len); | 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 | void qemu_chr_printf(CharDriverState *s, const char *fmt, ...) | 1603 | void qemu_chr_printf(CharDriverState *s, const char *fmt, ...) |
| 1599 | { | 1604 | { |
| @@ -1645,12 +1650,17 @@ static CharDriverState *qemu_chr_open_null(void) | @@ -1645,12 +1650,17 @@ static CharDriverState *qemu_chr_open_null(void) | ||
| 1645 | static int term_timestamps; | 1650 | static int term_timestamps; |
| 1646 | static int64_t term_timestamps_start; | 1651 | static int64_t term_timestamps_start; |
| 1647 | #define MAX_MUX 4 | 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 | typedef struct { | 1655 | typedef struct { |
| 1649 | IOCanRWHandler *chr_can_read[MAX_MUX]; | 1656 | IOCanRWHandler *chr_can_read[MAX_MUX]; |
| 1650 | IOReadHandler *chr_read[MAX_MUX]; | 1657 | IOReadHandler *chr_read[MAX_MUX]; |
| 1651 | IOEventHandler *chr_event[MAX_MUX]; | 1658 | IOEventHandler *chr_event[MAX_MUX]; |
| 1652 | void *ext_opaque[MAX_MUX]; | 1659 | void *ext_opaque[MAX_MUX]; |
| 1653 | CharDriverState *drv; | 1660 | CharDriverState *drv; |
| 1661 | + unsigned char buffer[MUX_BUFFER_SIZE]; | ||
| 1662 | + int prod; | ||
| 1663 | + int cons; | ||
| 1654 | int mux_cnt; | 1664 | int mux_cnt; |
| 1655 | int term_got_escape; | 1665 | int term_got_escape; |
| 1656 | int max_size; | 1666 | int max_size; |
| @@ -1779,12 +1789,28 @@ static int mux_proc_byte(CharDriverState *chr, MuxDriver *d, int ch) | @@ -1779,12 +1789,28 @@ static int mux_proc_byte(CharDriverState *chr, MuxDriver *d, int ch) | ||
| 1779 | return 0; | 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 | static int mux_chr_can_read(void *opaque) | 1805 | static int mux_chr_can_read(void *opaque) |
| 1783 | { | 1806 | { |
| 1784 | CharDriverState *chr = opaque; | 1807 | CharDriverState *chr = opaque; |
| 1785 | MuxDriver *d = chr->opaque; | 1808 | MuxDriver *d = chr->opaque; |
| 1809 | + | ||
| 1810 | + if ((d->prod - d->cons) < MUX_BUFFER_SIZE) | ||
| 1811 | + return 1; | ||
| 1786 | if (d->chr_can_read[chr->focus]) | 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 | return 0; | 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,10 +1818,20 @@ static void mux_chr_read(void *opaque, const uint8_t *buf, int size) | ||
| 1792 | { | 1818 | { |
| 1793 | CharDriverState *chr = opaque; | 1819 | CharDriverState *chr = opaque; |
| 1794 | MuxDriver *d = chr->opaque; | 1820 | MuxDriver *d = chr->opaque; |
| 1821 | + int m = chr->focus; | ||
| 1795 | int i; | 1822 | int i; |
| 1823 | + | ||
| 1824 | + mux_chr_accept_input (opaque); | ||
| 1825 | + | ||
| 1796 | for(i = 0; i < size; i++) | 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 | static void mux_chr_event(void *opaque, int event) | 1837 | static void mux_chr_event(void *opaque, int event) |
| @@ -1850,6 +1886,7 @@ static CharDriverState *qemu_chr_open_mux(CharDriverState *drv) | @@ -1850,6 +1886,7 @@ static CharDriverState *qemu_chr_open_mux(CharDriverState *drv) | ||
| 1850 | chr->focus = -1; | 1886 | chr->focus = -1; |
| 1851 | chr->chr_write = mux_chr_write; | 1887 | chr->chr_write = mux_chr_write; |
| 1852 | chr->chr_update_read_handler = mux_chr_update_read_handler; | 1888 | chr->chr_update_read_handler = mux_chr_update_read_handler; |
| 1889 | + chr->chr_accept_input = mux_chr_accept_input; | ||
| 1853 | return chr; | 1890 | return chr; |
| 1854 | } | 1891 | } |
| 1855 | 1892 |