@@ -234,9 +234,15 @@ DeviceState *qdev_device_add(QemuOpts *opts)
return NULL;
}
}
- if (qdev_hotplug && !bus->allow_hotplug) {
- qerror_report(QERR_BUS_NO_HOTPLUG, bus->name);
- return NULL;
+ if (qdev_hotplug) {
+ if (!bus->allow_hotplug) {
+ qerror_report(QERR_BUS_NO_HOTPLUG, bus->name);
+ return NULL;
+ }
+ if (info->no_hotplug) {
+ qerror_report(QERR_DEVICE_NO_HOTPLUG, info->name);
+ return NULL;
+ }
}
/* create device, set properties */
@@ -303,6 +309,10 @@ int qdev_unplug(DeviceState *dev)
qerror_report(QERR_BUS_NO_HOTPLUG, dev->parent_bus->name);
return -1;
}
+ if (dev->info->no_hotplug) {
+ qerror_report(QERR_DEVICE_NO_HOTPLUG, dev->info->name);
+ return -1;
+ }
assert(dev->info->unplug != NULL);
return dev->info->unplug(dev);
@@ -144,6 +144,7 @@ struct DeviceInfo {
size_t size;
Property *props;
int no_user;
+ int no_hotplug;
/* callbacks */
qdev_resetfn reset;
@@ -101,6 +101,10 @@ static const QErrorStringTable qerror_table[] = {
.desc = "Device '%(device)' has no child bus",
},
{
+ .error_fmt = QERR_DEVICE_NO_HOTPLUG,
+ .desc = "Device '%(device)' does not support hotplugging",
+ },
+ {
.error_fmt = QERR_DUPLICATE_ID,
.desc = "Duplicate ID '%(id)' for %(object)",
},
@@ -90,6 +90,9 @@ QError *qobject_to_qerror(const QObject *obj);
#define QERR_DEVICE_NO_BUS \
"{ 'class': 'DeviceNoBus', 'data': { 'device': %s } }"
+#define QERR_DEVICE_NO_HOTPLUG \
+ "{ 'class': 'DeviceNoHotplug', 'data': { 'device': %s } }"
+
#define QERR_DUPLICATE_ID \
"{ 'class': 'DuplicateId', 'data': { 'id': %s, 'object': %s } }"
This patch adds a field to DeviceInfo to tag devices as being not hotpluggable. Any attempt to plug-in or -out such a device will throw an error. This check is done in addition to the check whenever the bus supports hotplug, i.e. there is no need to tag devices which sit on busses without hotplug support (ISA for example). Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> --- hw/qdev.c | 16 +++++++++++++--- hw/qdev.h | 1 + qerror.c | 4 ++++ qerror.h | 3 +++ 4 files changed, 21 insertions(+), 3 deletions(-)