aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/baum.c9
-rw-r--r--hw/baum.h30
-rw-r--r--hw/msmouse.c10
-rw-r--r--hw/msmouse.h7
-rw-r--r--hw/serial.c28
-rw-r--r--hw/serial.h2
-rw-r--r--hw/virtio-console.c28
-rw-r--r--hw/virtio-serial-bus.c19
8 files changed, 49 insertions, 84 deletions
diff --git a/hw/baum.c b/hw/baum.c
index 09dcb9c..d75b150 100644
--- a/hw/baum.c
+++ b/hw/baum.c
@@ -562,7 +562,7 @@ static void baum_close(struct CharDriverState *chr)
g_free(baum);
}
-CharDriverState *chr_baum_init(QemuOpts *opts)
+static CharDriverState *chr_baum_init(QemuOpts *opts)
{
BaumDriverState *baum;
CharDriverState *chr;
@@ -625,3 +625,10 @@ fail_handle:
g_free(baum);
return NULL;
}
+
+static void register_types(void)
+{
+ register_char_driver("braille", chr_baum_init);
+}
+
+type_init(register_types);
diff --git a/hw/baum.h b/hw/baum.h
deleted file mode 100644
index 7635884..0000000
--- a/hw/baum.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * QEMU Baum
- *
- * Copyright (c) 2008 Samuel Thibault
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#ifndef HW_BAUM_H
-#define HW_BAUM_H 1
-
-/* char device */
-CharDriverState *chr_baum_init(QemuOpts *opts);
-
-#endif
diff --git a/hw/msmouse.c b/hw/msmouse.c
index ef47aed..407ec87 100644
--- a/hw/msmouse.c
+++ b/hw/msmouse.c
@@ -25,7 +25,6 @@
#include "qemu-common.h"
#include "char/char.h"
#include "ui/console.h"
-#include "msmouse.h"
#define MSMOUSE_LO6(n) ((n) & 0x3f)
#define MSMOUSE_HI2(n) (((n) & 0xc0) >> 6)
@@ -64,7 +63,7 @@ static void msmouse_chr_close (struct CharDriverState *chr)
g_free (chr);
}
-CharDriverState *qemu_chr_open_msmouse(QemuOpts *opts)
+static CharDriverState *qemu_chr_open_msmouse(QemuOpts *opts)
{
CharDriverState *chr;
@@ -76,3 +75,10 @@ CharDriverState *qemu_chr_open_msmouse(QemuOpts *opts)
return chr;
}
+
+static void register_types(void)
+{
+ register_char_driver("msmouse", qemu_chr_open_msmouse);
+}
+
+type_init(register_types);
diff --git a/hw/msmouse.h b/hw/msmouse.h
deleted file mode 100644
index 8cff3a7..0000000
--- a/hw/msmouse.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef HW_MSMOUSE_H
-#define HW_MSMOUSE_H 1
-
-/* msmouse.c */
-CharDriverState *qemu_chr_open_msmouse(QemuOpts *opts);
-
-#endif
diff --git a/hw/serial.c b/hw/serial.c
index f0ce9b0..eb38f22 100644
--- a/hw/serial.c
+++ b/hw/serial.c
@@ -256,16 +256,17 @@ static void serial_update_msl(SerialState *s)
qemu_mod_timer(s->modem_status_poll, qemu_get_clock_ns(vm_clock) + get_ticks_per_sec() / 100);
}
-static void serial_xmit(void *opaque)
+static gboolean serial_xmit(GIOChannel *chan, GIOCondition cond, void *opaque)
{
SerialState *s = opaque;
- uint64_t new_xmit_ts = qemu_get_clock_ns(vm_clock);
if (s->tsr_retry <= 0) {
if (s->fcr & UART_FCR_FE) {
s->tsr = fifo_get(s,XMIT_FIFO);
if (!s->xmit_fifo.count)
s->lsr |= UART_LSR_THRE;
+ } else if ((s->lsr & UART_LSR_THRE)) {
+ return FALSE;
} else {
s->tsr = s->thr;
s->lsr |= UART_LSR_THRE;
@@ -277,30 +278,25 @@ static void serial_xmit(void *opaque)
/* 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)) {
+ if (s->tsr_retry >= 0 && s->tsr_retry < MAX_XMIT_RETRY &&
+ qemu_chr_fe_add_watch(s->chr, G_IO_OUT, serial_xmit, s) > 0) {
s->tsr_retry++;
- qemu_mod_timer(s->transmit_timer, new_xmit_ts + s->char_transmit_time);
- return;
- } else if (s->poll_msl < 0) {
- /* If we exceed MAX_XMIT_RETRY and the backend is not a real serial port, then
- drop any further failed writes instantly, until we get one that goes through.
- This is to prevent guests that log to unconnected pipes or pty's from stalling. */
- s->tsr_retry = -1;
+ return FALSE;
}
- }
- else {
+ s->tsr_retry = 0;
+ } else {
s->tsr_retry = 0;
}
s->last_xmit_ts = qemu_get_clock_ns(vm_clock);
- if (!(s->lsr & UART_LSR_THRE))
- qemu_mod_timer(s->transmit_timer, s->last_xmit_ts + s->char_transmit_time);
if (s->lsr & UART_LSR_THRE) {
s->lsr |= UART_LSR_TEMT;
s->thr_ipending = 1;
serial_update_irq(s);
}
+
+ return FALSE;
}
@@ -330,7 +326,7 @@ static void serial_ioport_write(void *opaque, hwaddr addr, uint64_t val,
s->lsr &= ~UART_LSR_THRE;
serial_update_irq(s);
}
- serial_xmit(s);
+ serial_xmit(NULL, G_IO_OUT, s);
}
break;
case 1:
@@ -684,8 +680,6 @@ void serial_init_core(SerialState *s)
s->modem_status_poll = qemu_new_timer_ns(vm_clock, (QEMUTimerCB *) serial_update_msl, s);
s->fifo_timeout_timer = qemu_new_timer_ns(vm_clock, (QEMUTimerCB *) fifo_timeout_int, s);
- s->transmit_timer = qemu_new_timer_ns(vm_clock, (QEMUTimerCB *) serial_xmit, s);
-
qemu_register_reset(serial_reset, s);
qemu_chr_add_handlers(s->chr, serial_can_receive1, serial_receive1,
diff --git a/hw/serial.h b/hw/serial.h
index 98ee424..e57375d 100644
--- a/hw/serial.h
+++ b/hw/serial.h
@@ -72,8 +72,6 @@ struct SerialState {
struct QEMUTimer *fifo_timeout_timer;
int timeout_ipending; /* timeout interrupt pending state */
- struct QEMUTimer *transmit_timer;
-
uint64_t char_transmit_time; /* time to transmit a char in ticks */
int poll_msl;
diff --git a/hw/virtio-console.c b/hw/virtio-console.c
index 46072a0..194de64 100644
--- a/hw/virtio-console.c
+++ b/hw/virtio-console.c
@@ -20,6 +20,18 @@ typedef struct VirtConsole {
CharDriverState *chr;
} VirtConsole;
+/*
+ * Callback function that's called from chardevs when backend becomes
+ * writable.
+ */
+static gboolean chr_write_unblocked(GIOChannel *chan, GIOCondition cond,
+ void *opaque)
+{
+ VirtConsole *vcon = opaque;
+
+ virtio_serial_throttle_port(&vcon->port, false);
+ return FALSE;
+}
/* Callback function that's called when the guest sends us data */
static ssize_t flush_buf(VirtIOSerialPort *port, const uint8_t *buf, size_t len)
@@ -35,19 +47,21 @@ static ssize_t flush_buf(VirtIOSerialPort *port, const uint8_t *buf, size_t len)
ret = qemu_chr_fe_write(vcon->chr, buf, len);
trace_virtio_console_flush_buf(port->id, len, ret);
- if (ret < 0) {
+ if (ret <= 0) {
+ VirtIOSerialPortClass *k = VIRTIO_SERIAL_PORT_GET_CLASS(port);
+
/*
* Ideally we'd get a better error code than just -1, but
* that's what the chardev interface gives us right now. If
* we had a finer-grained message, like -EPIPE, we could close
- * this connection. Absent such error messages, the most we
- * can do is to return 0 here.
- *
- * This will prevent stray -1 values to go to
- * virtio-serial-bus.c and cause abort()s in
- * do_flush_queued_data().
+ * this connection.
*/
ret = 0;
+ if (!k->is_console) {
+ virtio_serial_throttle_port(port, true);
+ qemu_chr_fe_add_watch(vcon->chr, G_IO_OUT, chr_write_unblocked,
+ vcon);
+ }
}
return ret;
}
diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
index aa7d0d7..f76c505 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -172,24 +172,7 @@ static void do_flush_queued_data(VirtIOSerialPort *port, VirtQueue *vq,
port->elem.out_sg[i].iov_base
+ port->iov_offset,
buf_size);
- if (ret < 0 && ret != -EAGAIN) {
- /* We don't handle any other type of errors here */
- abort();
- }
- if (ret == -EAGAIN || (ret >= 0 && ret < buf_size)) {
- /*
- * this is a temporary check until chardevs can signal to
- * frontends that they are writable again. This prevents
- * the console from going into throttled mode (forever)
- * if virtio-console is connected to a pty without a
- * listener. Otherwise the guest spins forever.
- * We can revert this if
- * 1: chardevs can notify frondends
- * 2: the guest driver does not spin in these cases
- */
- if (!vsc->is_console) {
- virtio_serial_throttle_port(port, true);
- }
+ if (port->throttled) {
port->iov_idx = i;
if (ret > 0) {
port->iov_offset += ret;