diff mbox

[5/11,v3,FIXED] qdev: add "hotplugable" property to Device

Message ID 1386783785-24456-1-git-send-email-imammedo@redhat.com
State New
Headers show

Commit Message

Igor Mammedov Dec. 11, 2013, 5:43 p.m. UTC
Currently it's possible to make PCIDevice not hotplugable by using
no_hotplug field of PCIDeviceClass. However it limits this
only to PCI devices and prevents from generalizing hotplug code.

So add similar field to DeviceClass so it could be reused with other
Devices and would allow to replace PCI specific hotplug callbacks
with generic implementation.

In addition expose field as "hotplugable" readonly property, to make
it possible to get it via QOM interface.

v3:
make DeviceClass hotlugable by default. Since PCIDevice still uses
internal checks it shouldn't reggress. And follow up patch that
converts PCIDevices to use "hotplugable" property will take care
about not hotplugable PCI devices explicitly setting "hotplugable"
to false in their class_init().

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
v3:
 move generic hotplug checks from
 "7/11 qdev:pci: refactor PCIDevice to use generic "hotplugable" property"
 to this patch
---
 hw/core/qdev.c         | 29 +++++++++++++++++++++++++++++
 include/hw/qdev-core.h |  3 +++
 2 files changed, 32 insertions(+)

Comments

Markus Armbruster Dec. 11, 2013, 7:57 p.m. UTC | #1
Please spell it "pluggable", both in C identifiers and strings.
Igor Mammedov Dec. 12, 2013, 3:45 p.m. UTC | #2
On Wed, 11 Dec 2013 20:57:43 +0100
Markus Armbruster <armbru@redhat.com> wrote:

> Please spell it "pluggable", both in C identifiers and strings.

Sure,
I'll respin series since it will touch several patches.
diff mbox

Patch

diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 25c2d2c..21c4522 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -215,6 +215,12 @@  void qdev_unplug(DeviceState *dev, Error **errp)
     }
     assert(dc->unplug != NULL);
 
+    if (!dc->hotplugable) {
+        error_set(errp, QERR_DEVICE_NO_HOTPLUG,
+                  object_get_typename(OBJECT(dev)));
+        return;
+    }
+
     qdev_hot_removed = true;
 
     if (dc->unplug(dev) < 0) {
@@ -679,6 +685,11 @@  static void device_set_realized(Object *obj, bool value, Error **err)
     DeviceClass *dc = DEVICE_GET_CLASS(dev);
     Error *local_err = NULL;
 
+    if (dev->hotplugged && !dc->hotplugable) {
+        error_set(err, QERR_DEVICE_NO_HOTPLUG, object_get_typename(obj));
+        return;
+    }
+
     if (value && !dev->realized) {
         if (!obj->parent && local_err == NULL) {
             static int unattached_count;
@@ -719,6 +730,14 @@  static void device_set_realized(Object *obj, bool value, Error **err)
     dev->realized = value;
 }
 
+static bool device_get_hotplugable(Object *obj, Error **err)
+{
+    DeviceClass *dc = DEVICE_GET_CLASS(obj);
+    DeviceState *dev = DEVICE(obj);
+
+    return dc->hotplugable && dev->parent_bus->allow_hotplug;
+}
+
 static void device_initfn(Object *obj)
 {
     DeviceState *dev = DEVICE(obj);
@@ -736,6 +755,8 @@  static void device_initfn(Object *obj)
 
     object_property_add_bool(obj, "realized",
                              device_get_realized, device_set_realized, NULL);
+    object_property_add_bool(obj, "hotplugable",
+                             device_get_hotplugable, NULL, NULL);
 
     class = object_get_class(OBJECT(dev));
     do {
@@ -784,6 +805,14 @@  static void device_class_base_init(ObjectClass *class, void *data)
      * so do not propagate them to the subclasses.
      */
     klass->props = NULL;
+
+    /* by default all devices were considered as hotplugable,
+     * so with intent to check it in generic qdev_unplug() /
+     * device_set_realized() functions make every device
+     * hotplugable. Devices that shouldn't be hoplugable,
+     * should override it in their class_init()
+     */
+    klass->hotplugable = true;
 }
 
 static void device_unparent(Object *obj)
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index 684a5da..5d4a9c8 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -50,6 +50,8 @@  struct VMStateDescription;
  * is changed to %true. Deprecated, new types inheriting directly from
  * TYPE_DEVICE should use @realize instead, new leaf types should consult
  * their respective parent type.
+ * @hotplugable: booleean indicating if #DeviceClass is hotplugable, available
+ * as readonly "hotplugable" property of #DeviceState instance
  *
  * # Realization #
  * Devices are constructed in two stages,
@@ -99,6 +101,7 @@  typedef struct DeviceClass {
     const char *desc;
     Property *props;
     int no_user;
+    bool hotplugable;
 
     /* callbacks */
     void (*reset)(DeviceState *dev);