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
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
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 | ... | ... |
vl.c
... | ... | @@ -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 | ... | ... |