summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2014-08-18 18:24:38 +0100
committerPeter Maydell <peter.maydell@linaro.org>2014-08-18 18:24:38 +0100
commit073fd73e566c711f5c0cdaa300fdd1a3c8e7faa0 (patch)
treeed221783760dc3733384087a4ae9fc4c5dbe3525
parent08ab59770da57648bfb8fc9be37f0ef7fb50b0f9 (diff)
parentd0a0bfe6729ef6044d76ea49fafa07e29fa598bd (diff)
downloadqemu-073fd73e566c711f5c0cdaa300fdd1a3c8e7faa0.tar.gz
Merge remote-tracking branch 'remotes/amit/for-2.2' into staging
* remotes/amit/for-2.2: virtio-serial: search for duplicate port names before adding new ports virtio-serial: create a linked list of all active devices Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--hw/char/virtio-serial-bus.c32
-rw-r--r--include/hw/virtio/virtio-serial.h2
2 files changed, 34 insertions, 0 deletions
diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
index 23123b730e..3931085983 100644
--- a/hw/char/virtio-serial-bus.c
+++ b/hw/char/virtio-serial-bus.c
@@ -26,6 +26,10 @@
#include "hw/virtio/virtio-serial.h"
#include "hw/virtio/virtio-access.h"
+struct VirtIOSerialDevices {
+ QLIST_HEAD(, VirtIOSerial) devices;
+} vserdevices;
+
static VirtIOSerialPort *find_port_by_id(VirtIOSerial *vser, uint32_t id)
{
VirtIOSerialPort *port;
@@ -52,6 +56,22 @@ static VirtIOSerialPort *find_port_by_vq(VirtIOSerial *vser, VirtQueue *vq)
return NULL;
}
+static VirtIOSerialPort *find_port_by_name(char *name)
+{
+ VirtIOSerial *vser;
+
+ QLIST_FOREACH(vser, &vserdevices.devices, next) {
+ VirtIOSerialPort *port;
+
+ QTAILQ_FOREACH(port, &vser->ports, next) {
+ if (!strcmp(port->name, name)) {
+ return port;
+ }
+ }
+ }
+ return NULL;
+}
+
static bool use_multiport(VirtIOSerial *vser)
{
VirtIODevice *vdev = VIRTIO_DEVICE(vser);
@@ -851,6 +871,12 @@ static void virtser_port_device_realize(DeviceState *dev, Error **errp)
return;
}
+ if (find_port_by_name(port->name)) {
+ error_setg(errp, "virtio-serial-bus: A port already exists by name %s",
+ port->name);
+ return;
+ }
+
if (port->id == VIRTIO_CONSOLE_BAD_ID) {
if (plugging_port0) {
port->id = 0;
@@ -983,6 +1009,8 @@ static void virtio_serial_device_realize(DeviceState *dev, Error **errp)
*/
register_savevm(dev, "virtio-console", -1, 3, virtio_serial_save,
virtio_serial_load, vser);
+
+ QLIST_INSERT_HEAD(&vserdevices.devices, vser, next);
}
static void virtio_serial_port_class_init(ObjectClass *klass, void *data)
@@ -1011,6 +1039,8 @@ static void virtio_serial_device_unrealize(DeviceState *dev, Error **errp)
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
VirtIOSerial *vser = VIRTIO_SERIAL(dev);
+ QLIST_REMOVE(vser, next);
+
unregister_savevm(dev, "virtio-console", vser);
g_free(vser->ivqs);
@@ -1035,6 +1065,8 @@ static void virtio_serial_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
+ QLIST_INIT(&vserdevices.devices);
+
dc->props = virtio_serial_properties;
set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
vdc->realize = virtio_serial_device_realize;
diff --git a/include/hw/virtio/virtio-serial.h b/include/hw/virtio/virtio-serial.h
index 4746312a83..a679e54aab 100644
--- a/include/hw/virtio/virtio-serial.h
+++ b/include/hw/virtio/virtio-serial.h
@@ -202,6 +202,8 @@ struct VirtIOSerial {
QTAILQ_HEAD(, VirtIOSerialPort) ports;
+ QLIST_ENTRY(VirtIOSerial) next;
+
/* bitmap for identifying active ports */
uint32_t *ports_map;