mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-07 01:33:56 -06:00
* serial port fixes (Paolo)
* Q35 modeling improvements (Paolo, Vasily) * chardev cleanup improvements (Marc-André) * iscsi bugfix (Peter L.) * cpu_exec patch from multi-arch patches (Peter C.) * pci-assign tweak (Lin Ma) -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQEcBAABAgAGBQJXc+GeAAoJEL/70l94x66DtIAH/3+eUBqSxVJ3SMUxJep2Op07 lIWqw1GHAdw1gWQDG4HzokKWrVVp/+NFYQjRFcNMfF8L+/Xm6hHAYc7Y4DMkDxSw zHX2BT93gPcaFJRz3Md8n2anzFHaWePx7LucPjaoas2OzrbVKXC8JT6n3GGnKQzZ 0CxDoyW4keI4ZVAOy9SOKsLPxdSvG8uLvaZU98l/YS/TuiGzpv8IWcdHR+k1hua+ FIenzj7jD9+JFoLEUWkU0pYs33J6yYKPiZn7HgGL9RNWKPFR88+CtMdYXgfOPo7z i05L9RTmL4SpahmStPN2r72MC0T0ub0czk/+qxBNms4r/2gBwaSyldmcTfAXM9o= =DA8v -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging * serial port fixes (Paolo) * Q35 modeling improvements (Paolo, Vasily) * chardev cleanup improvements (Marc-André) * iscsi bugfix (Peter L.) * cpu_exec patch from multi-arch patches (Peter C.) * pci-assign tweak (Lin Ma) # gpg: Signature made Wed 29 Jun 2016 15:56:30 BST # gpg: using RSA key 0xBFFBD25F78C7AE83 # gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" # gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" # Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1 # Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83 * remotes/bonzini/tags/for-upstream: (35 commits) socket: unlink unix socket on remove socket: add listen feature char: clean up remaining chardevs when leaving vhost-user: disable chardev handlers on close vhost-user-test: fix g_cond_wait_until compat implementation vl: smp_parse: fix regression ich9: implement SCI_IRQ_SEL register ich9: implement ACPI_EN register serial: reinstate watch after migration serial: remove watch on reset char: change qemu_chr_fe_add_watch to return unsigned serial: separate serial_xmit and serial_watch_cb serial: simplify tsr_retry reset serial: make tsr_retry unsigned iscsi: fix assertion in is_sector_request_lun_aligned target-*: Don't redefine cpu_exec() pci-assign: Move "Invalid ROM" error message to pci-assign-load-rom.c vnc: generalize "VNC server running on ..." message scsi: esp: fix migration MC146818 RTC: add GPIO access to output IRQ ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
1ec20c2a3a
63 changed files with 350 additions and 214 deletions
|
@ -295,9 +295,12 @@ static gboolean cadence_uart_xmit(GIOChannel *chan, GIOCondition cond,
|
|||
}
|
||||
|
||||
if (s->tx_count) {
|
||||
int r = qemu_chr_fe_add_watch(s->chr, G_IO_OUT|G_IO_HUP,
|
||||
cadence_uart_xmit, s);
|
||||
assert(r);
|
||||
guint r = qemu_chr_fe_add_watch(s->chr, G_IO_OUT|G_IO_HUP,
|
||||
cadence_uart_xmit, s);
|
||||
if (!r) {
|
||||
s->tx_count = 0;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
uart_update_status(s);
|
||||
|
|
|
@ -106,6 +106,7 @@ do {} while (0)
|
|||
#endif
|
||||
|
||||
static void serial_receive1(void *opaque, const uint8_t *buf, int size);
|
||||
static void serial_xmit(SerialState *s);
|
||||
|
||||
static inline void recv_fifo_put(SerialState *s, uint8_t chr)
|
||||
{
|
||||
|
@ -223,13 +224,20 @@ static void serial_update_msl(SerialState *s)
|
|||
}
|
||||
}
|
||||
|
||||
static gboolean serial_xmit(GIOChannel *chan, GIOCondition cond, void *opaque)
|
||||
static gboolean serial_watch_cb(GIOChannel *chan, GIOCondition cond,
|
||||
void *opaque)
|
||||
{
|
||||
SerialState *s = opaque;
|
||||
s->watch_tag = 0;
|
||||
serial_xmit(s);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void serial_xmit(SerialState *s)
|
||||
{
|
||||
do {
|
||||
assert(!(s->lsr & UART_LSR_TEMT));
|
||||
if (s->tsr_retry <= 0) {
|
||||
if (s->tsr_retry == 0) {
|
||||
assert(!(s->lsr & UART_LSR_THRE));
|
||||
|
||||
if (s->fcr & UART_FCR_FE) {
|
||||
|
@ -251,17 +259,17 @@ static gboolean serial_xmit(GIOChannel *chan, GIOCondition cond, void *opaque)
|
|||
if (s->mcr & UART_MCR_LOOP) {
|
||||
/* in loopback mode, say that we just received a char */
|
||||
serial_receive1(s, &s->tsr, 1);
|
||||
} else if (qemu_chr_fe_write(s->chr, &s->tsr, 1) != 1) {
|
||||
if (s->tsr_retry >= 0 && s->tsr_retry < MAX_XMIT_RETRY &&
|
||||
qemu_chr_fe_add_watch(s->chr, G_IO_OUT|G_IO_HUP,
|
||||
serial_xmit, s) > 0) {
|
||||
} else if (qemu_chr_fe_write(s->chr, &s->tsr, 1) != 1 &&
|
||||
s->tsr_retry < MAX_XMIT_RETRY) {
|
||||
assert(s->watch_tag == 0);
|
||||
s->watch_tag = qemu_chr_fe_add_watch(s->chr, G_IO_OUT|G_IO_HUP,
|
||||
serial_watch_cb, s);
|
||||
if (s->watch_tag > 0) {
|
||||
s->tsr_retry++;
|
||||
return FALSE;
|
||||
return;
|
||||
}
|
||||
s->tsr_retry = 0;
|
||||
} else {
|
||||
s->tsr_retry = 0;
|
||||
}
|
||||
s->tsr_retry = 0;
|
||||
|
||||
/* Transmit another byte if it is already available. It is only
|
||||
possible when FIFO is enabled and not empty. */
|
||||
|
@ -269,11 +277,8 @@ static gboolean serial_xmit(GIOChannel *chan, GIOCondition cond, void *opaque)
|
|||
|
||||
s->last_xmit_ts = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
|
||||
s->lsr |= UART_LSR_TEMT;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/* Setter for FCR.
|
||||
is_load flag means, that value is set while loading VM state
|
||||
and interrupt should not be invoked */
|
||||
|
@ -330,8 +335,8 @@ static void serial_ioport_write(void *opaque, hwaddr addr, uint64_t val,
|
|||
s->lsr &= ~UART_LSR_THRE;
|
||||
s->lsr &= ~UART_LSR_TEMT;
|
||||
serial_update_irq(s);
|
||||
if (s->tsr_retry <= 0) {
|
||||
serial_xmit(NULL, G_IO_OUT, s);
|
||||
if (s->tsr_retry == 0) {
|
||||
serial_xmit(s);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -639,6 +644,31 @@ static int serial_post_load(void *opaque, int version_id)
|
|||
if (s->thr_ipending == -1) {
|
||||
s->thr_ipending = ((s->iir & UART_IIR_ID) == UART_IIR_THRI);
|
||||
}
|
||||
|
||||
if (s->tsr_retry > 0) {
|
||||
/* tsr_retry > 0 implies LSR.TEMT = 0 (transmitter not empty). */
|
||||
if (s->lsr & UART_LSR_TEMT) {
|
||||
error_report("inconsistent state in serial device "
|
||||
"(tsr empty, tsr_retry=%d", s->tsr_retry);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (s->tsr_retry > MAX_XMIT_RETRY) {
|
||||
s->tsr_retry = MAX_XMIT_RETRY;
|
||||
}
|
||||
|
||||
assert(s->watch_tag == 0);
|
||||
s->watch_tag = qemu_chr_fe_add_watch(s->chr, G_IO_OUT|G_IO_HUP,
|
||||
serial_watch_cb, s);
|
||||
} else {
|
||||
/* tsr_retry == 0 implies LSR.TEMT = 1 (transmitter empty). */
|
||||
if (!(s->lsr & UART_LSR_TEMT)) {
|
||||
error_report("inconsistent state in serial device "
|
||||
"(tsr not empty, tsr_retry=0");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
s->last_break_enable = (s->lcr >> 6) & 1;
|
||||
/* Initialize fcr via setter to perform essential side-effects */
|
||||
serial_write_fcr(s, s->fcr_vmstate);
|
||||
|
@ -685,7 +715,7 @@ static const VMStateDescription vmstate_serial_tsr = {
|
|||
.minimum_version_id = 1,
|
||||
.needed = serial_tsr_needed,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_INT32(tsr_retry, SerialState),
|
||||
VMSTATE_UINT32(tsr_retry, SerialState),
|
||||
VMSTATE_UINT8(thr, SerialState),
|
||||
VMSTATE_UINT8(tsr, SerialState),
|
||||
VMSTATE_END_OF_LIST()
|
||||
|
@ -815,6 +845,11 @@ static void serial_reset(void *opaque)
|
|||
{
|
||||
SerialState *s = opaque;
|
||||
|
||||
if (s->watch_tag > 0) {
|
||||
g_source_remove(s->watch_tag);
|
||||
s->watch_tag = 0;
|
||||
}
|
||||
|
||||
s->rbr = 0;
|
||||
s->ier = 0;
|
||||
s->iir = UART_IIR_NO_INT;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue