qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [RFC v5 10/23] isa: Provide enable and disable callbacks


From: Andreas Färber
Subject: [Qemu-devel] [RFC v5 10/23] isa: Provide enable and disable callbacks
Date: Tue, 14 Jun 2011 04:37:44 +0200

To allow enabling/disabling present ISA devices without hotplug,
keep track of state and add a helper to avoid enabling twice.
Since the properties to be configured are defined at device level,
delegate the actual work to callback functions. Use separate ones
for enable and disable, otherwise the functions ended up as a big
"if" statement.

If no callback is supplied, the device can't be disabled.

Prepare VMSTATE_ISA_DEVICE for devices that support disabling.
Legacy devices never change their state and won't need this yet.
For those that do, supply a "needed" callback.

Cc: Gerd Hoffmann <address@hidden>
Cc: Markus Armbruster <address@hidden>
Cc: Juan Quintela <address@hidden>
Signed-off-by: Andreas Färber <address@hidden>
---
 hw/hw.h      |   15 +++++++++++++++
 hw/isa-bus.c |   39 +++++++++++++++++++++++++++++++++++++++
 hw/isa.h     |    6 ++++++
 3 files changed, 60 insertions(+), 0 deletions(-)

diff --git a/hw/hw.h b/hw/hw.h
index 56447a7..32226b1 100644
--- a/hw/hw.h
+++ b/hw/hw.h
@@ -628,6 +628,21 @@ extern const VMStateInfo vmstate_info_unused_buffer;
     .info         = &vmstate_info_unused_buffer,                     \
     .flags        = VMS_BUFFER,                                      \
 }
+
+extern const VMStateDescription vmstate_isa_device;
+
+#define VMSTATE_ISA_DEVICE_V(_field, _state, _version) {             \
+    .name       = (stringify(_field)),                               \
+    .version_id   = (_version),                                      \
+    .size       = sizeof(ISADevice),                                 \
+    .vmsd       = &vmstate_isa_device,                               \
+    .flags      = VMS_STRUCT,                                        \
+    .offset     = vmstate_offset_value(_state, _field, ISADevice),   \
+}
+
+#define VMSTATE_ISA_DEVICE(_field, _state)                           \
+    VMSTATE_ISA_DEVICE_V(_field, _state, 0)
+
 extern const VMStateDescription vmstate_pci_device;
 
 #define VMSTATE_PCI_DEVICE(_field, _state) {                         \
diff --git a/hw/isa-bus.c b/hw/isa-bus.c
index 2765543..bbafb75 100644
--- a/hw/isa-bus.c
+++ b/hw/isa-bus.c
@@ -112,6 +112,9 @@ static int isa_qdev_init(DeviceState *qdev, DeviceInfo 
*base)
 
     dev->isairq[0] = -1;
     dev->isairq[1] = -1;
+    dev->enabled = true; /* XXX for legacy devices without qdev property */
+
+    dev->initially_enabled = dev->enabled;
 
     return info->init(dev);
 }
@@ -156,6 +159,42 @@ ISADevice *isa_create_simple(const char *name)
     return dev;
 }
 
+const VMStateDescription vmstate_isa_device = {
+    .name = "ISADevice",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField []) {
+        VMSTATE_BOOL(enabled, ISADevice),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+int isa_set_state(ISADevice *dev, bool enabled)
+{
+    ISADeviceInfo *info = DO_UPCAST(ISADeviceInfo, qdev, dev->qdev.info);
+    isa_qdev_initfn statefn = enabled ? info->enable : info->disable;
+    int err;
+
+    if (dev->enabled == enabled) {
+        return 0;
+    } else if (statefn == NULL) {
+        return -1;
+    }
+    err = statefn(dev);
+    if (err < 0) {
+        return err;
+    }
+    dev->enabled = enabled;
+    return err;
+}
+
+bool isa_vmstate_needed(void *opaque)
+{
+    ISADevice *s = opaque;
+
+    return s->initially_enabled != s->enabled;
+}
+
 static void isabus_dev_print(Monitor *mon, DeviceState *dev, int indent)
 {
     ISADevice *d = DO_UPCAST(ISADevice, qdev, dev);
diff --git a/hw/isa.h b/hw/isa.h
index d2b6126..1eefd17 100644
--- a/hw/isa.h
+++ b/hw/isa.h
@@ -16,12 +16,16 @@ struct ISADevice {
     int nirqs;
     uint16_t ioports[32];
     int nioports;
+    bool enabled;
+    bool initially_enabled;
 };
 
 typedef int (*isa_qdev_initfn)(ISADevice *dev);
 struct ISADeviceInfo {
     DeviceInfo qdev;
     isa_qdev_initfn init;
+    isa_qdev_initfn enable;
+    isa_qdev_initfn disable;
 };
 
 ISABus *isa_bus_new(DeviceState *dev);
@@ -34,6 +38,8 @@ void isa_qdev_register(ISADeviceInfo *info);
 ISADevice *isa_create(const char *name);
 ISADevice *isa_try_create(const char *name);
 ISADevice *isa_create_simple(const char *name);
+int isa_set_state(ISADevice *dev, bool enabled);
+bool isa_vmstate_needed(void *opaque);
 
 extern target_phys_addr_t isa_mem_base;
 
-- 
1.7.5.3




reply via email to

[Prev in Thread] Current Thread [Next in Thread]