#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qemu/iov.h"
+#include "qemu/main-loop.h"
+#include "qemu/module.h"
+#include "migration/qemu-file-types.h"
#include "monitor/monitor.h"
#include "qemu/error-report.h"
#include "qemu/queue.h"
port->elem->out_sg[i].iov_base
+ port->iov_offset,
buf_size);
+ if (!port->elem) { /* bail if we got disconnected */
+ return;
+ }
if (port->throttled) {
port->iov_idx = i;
if (ret > 0) {
VirtIOSerial *vser = VIRTIO_SERIAL(vdev);
struct virtio_console_config *config =
(struct virtio_console_config *)config_data;
- uint8_t emerg_wr_lo = le32_to_cpu(config->emerg_wr);
VirtIOSerialPort *port = find_first_connected_console(vser);
VirtIOSerialPortClass *vsc;
+ uint8_t emerg_wr_lo;
- if (!config->emerg_wr) {
+ if (!virtio_has_feature(vser->host_features,
+ VIRTIO_CONSOLE_F_EMERG_WRITE) || !config->emerg_wr) {
return;
}
+
+ emerg_wr_lo = le32_to_cpu(config->emerg_wr);
/* Make sure we don't misdetect an emergency write when the guest
* does a short config write after an emergency write. */
config->emerg_wr = 0;
if (!(status & VIRTIO_CONFIG_S_DRIVER_OK)) {
guest_reset(vser);
}
+
+ QTAILQ_FOREACH(port, &vser->ports, next) {
+ VirtIOSerialPortClass *vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port);
+ if (vsc->enable_backend) {
+ vsc->enable_backend(port, vdev->vm_running);
+ }
+ }
}
static void vser_reset(VirtIODevice *vdev)
/* The config space (ignored on the far end in current versions) */
get_config(vdev, (uint8_t *)&config);
- qemu_put_be16s(f, &config.cols);
- qemu_put_be16s(f, &config.rows);
- qemu_put_be32s(f, &config.max_nr_ports);
+ qemu_put_be16(f, config.cols);
+ qemu_put_be16(f, config.rows);
+ qemu_put_be32(f, config.max_nr_ports);
/* The ports map */
max_nr_ports = s->serial.max_virtserial_ports;
- for (i = 0; i < (max_nr_ports + 31) / 32; i++) {
+ for (i = 0; i < DIV_ROUND_UP(max_nr_ports, 32); i++) {
qemu_put_be32s(f, &s->ports_map[i]);
}
qemu_put_byte(f, port->guest_connected);
qemu_put_byte(f, port->host_connected);
- elem_popped = 0;
+ elem_popped = 0;
if (port->elem) {
elem_popped = 1;
}
}
}
g_free(s->post_load->connected);
+ timer_del(s->post_load->timer);
timer_free(s->post_load->timer);
g_free(s->post_load);
s->post_load = NULL;
qemu_get_be32s(f, &tmp);
max_nr_ports = s->serial.max_virtserial_ports;
- for (i = 0; i < (max_nr_ports + 31) / 32; i++) {
+ for (i = 0; i < DIV_ROUND_UP(max_nr_ports, 32); i++) {
qemu_get_be32s(f, &ports_map);
if (ports_map != s->ports_map[i]) {
unsigned int i, max_nr_ports;
max_nr_ports = vser->serial.max_virtserial_ports;
- for (i = 0; i < (max_nr_ports + 31) / 32; i++) {
+ for (i = 0; i < DIV_ROUND_UP(max_nr_ports, 32); i++) {
uint32_t map, zeroes;
map = vser->ports_map[i];
/* Spawn a new virtio-serial bus on which the ports will ride as devices */
qbus_create_inplace(&vser->bus, sizeof(vser->bus), TYPE_VIRTIO_SERIAL_BUS,
dev, vdev->bus_name);
- qbus_set_hotplug_handler(BUS(&vser->bus), DEVICE(vser), errp);
+ qbus_set_hotplug_handler(BUS(&vser->bus), OBJECT(vser), errp);
vser->bus.vser = vser;
QTAILQ_INIT(&vser->ports);
vser->ovqs[i] = virtio_add_queue(vdev, 128, handle_output);
}
- vser->ports_map = g_malloc0(((vser->serial.max_virtserial_ports + 31) / 32)
+ vser->ports_map = g_malloc0((DIV_ROUND_UP(vser->serial.max_virtserial_ports, 32))
* sizeof(vser->ports_map[0]));
/*
* Reserve location 0 for a console port for backward compat
timer_free(vser->post_load->timer);
g_free(vser->post_load);
}
+
+ qbus_set_hotplug_handler(BUS(&vser->bus), NULL, errp);
+
virtio_cleanup(vdev);
}