[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 13/15] hotplug: introduce qdev_unplug_complete() to
From: |
Liu Ping Fan |
Subject: |
[Qemu-devel] [PATCH 13/15] hotplug: introduce qdev_unplug_complete() to remove device from views |
Date: |
Wed, 8 Aug 2012 14:25:54 +0800 |
From: Liu Ping Fan <address@hidden>
When guest confirm the removal of device, we should
--unmap from MemoryRegion view
--isolated from device tree view
Signed-off-by: Liu Ping Fan <address@hidden>
---
hw/acpi_piix4.c | 4 ++--
hw/pci.c | 13 ++++++++++++-
hw/pci.h | 2 ++
hw/qdev.c | 28 ++++++++++++++++++++++++++++
hw/qdev.h | 3 ++-
5 files changed, 46 insertions(+), 4 deletions(-)
diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index 0aace60..c209ff7 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -305,8 +305,8 @@ static void acpi_piix_eject_slot(PIIX4PMState *s, unsigned
slots)
if (pc->no_hotplug) {
slot_free = false;
} else {
- object_unparent(OBJECT(dev));
- qdev_free(qdev);
+ /* refcnt will be decreased */
+ qdev_unplug_complete(qdev, NULL);
}
}
}
diff --git a/hw/pci.c b/hw/pci.c
index 99a4304..2095abf 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -856,12 +856,22 @@ static int pci_unregister_device(DeviceState *dev)
if (ret)
return ret;
- pci_unregister_io_regions(pci_dev);
pci_del_option_rom(pci_dev);
do_pci_unregister_device(pci_dev);
return 0;
}
+static void pci_unmap_device(DeviceState *dev)
+{
+ PCIDevice *pci_dev = PCI_DEVICE(dev);
+ PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(pci_dev);
+
+ pci_unregister_io_regions(pci_dev);
+ if (pc->unmap) {
+ pc->unmap(pci_dev);
+ }
+}
+
void pci_register_bar(PCIDevice *pci_dev, int region_num,
uint8_t type, MemoryRegion *memory)
{
@@ -2022,6 +2032,7 @@ static void pci_device_class_init(ObjectClass *klass,
void *data)
DeviceClass *k = DEVICE_CLASS(klass);
k->init = pci_qdev_init;
k->unplug = pci_unplug_device;
+ k->unmap = pci_unmap_device;
k->exit = pci_unregister_device;
k->bus_type = TYPE_PCI_BUS;
k->props = pci_props;
diff --git a/hw/pci.h b/hw/pci.h
index 79d38fd..1c5b909 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -145,6 +145,8 @@ typedef struct PCIDeviceClass {
DeviceClass parent_class;
int (*init)(PCIDevice *dev);
+ void (*unmap)(PCIDevice *dev);
+
PCIUnregisterFunc *exit;
PCIConfigReadFunc *config_read;
PCIConfigWriteFunc *config_write;
diff --git a/hw/qdev.c b/hw/qdev.c
index 17525fe..530eabe 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -104,6 +104,14 @@ void qdev_set_parent_bus(DeviceState *dev, BusState *bus)
bus_add_child(bus, dev);
}
+static void qdev_unset_parent(DeviceState *dev)
+{
+ BusState *b = dev->parent_bus;
+
+ object_unparent(OBJECT(dev));
+ bus_remove_child(b, dev);
+}
+
/* Create a new device. This only initializes the device state structure
and allows properties to be set. qdev_init should be called to
initialize the actual device emulation. */
@@ -194,6 +202,26 @@ void qdev_set_legacy_instance_id(DeviceState *dev, int
alias_id,
dev->alias_required_for_version = required_for_version;
}
+static int qdev_unmap(DeviceState *dev)
+{
+ DeviceClass *dc = DEVICE_GET_CLASS(dev);
+ if (dc->unmap) {
+ dc->unmap(dev);
+ }
+ return 0;
+}
+
+void qdev_unplug_complete(DeviceState *dev, Error **errp)
+{
+ /* isolate from mem view */
+ qdev_unmap(dev);
+ qemu_lock_devtree();
+ /* isolate from device tree */
+ qdev_unset_parent(dev);
+ qemu_unlock_devtree();
+ object_unref(OBJECT(dev));
+}
+
void qdev_unplug(DeviceState *dev, Error **errp)
{
DeviceClass *dc = DEVICE_GET_CLASS(dev);
diff --git a/hw/qdev.h b/hw/qdev.h
index f4683dc..705635a 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -47,7 +47,7 @@ typedef struct DeviceClass {
/* callbacks */
void (*reset)(DeviceState *dev);
-
+ void (*unmap)(DeviceState *dev);
/* device state */
const VMStateDescription *vmsd;
@@ -162,6 +162,7 @@ void qdev_init_nofail(DeviceState *dev);
void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
int required_for_version);
void qdev_unplug(DeviceState *dev, Error **errp);
+void qdev_unplug_complete(DeviceState *dev, Error **errp);
void qdev_free(DeviceState *dev);
int qdev_simple_unplug_cb(DeviceState *dev);
void qdev_machine_creation_done(void);
--
1.7.4.4
- Re: [Qemu-devel] [PATCH 06/15] memory: use refcnt to manage MemoryRegion, (continued)
[Qemu-devel] [PATCH 10/15] memory: change tcg related code to using PhysMap, Liu Ping Fan, 2012/08/08
[Qemu-devel] [PATCH 09/15] memory: prepare flatview and radix-tree for rcu style access, Liu Ping Fan, 2012/08/08
Re: [Qemu-devel] [PATCH 09/15] memory: prepare flatview and radix-tree for rcu style access, Blue Swirl, 2012/08/08
[Qemu-devel] [PATCH 13/15] hotplug: introduce qdev_unplug_complete() to remove device from views,
Liu Ping Fan <=
- Re: [Qemu-devel] [PATCH 13/15] hotplug: introduce qdev_unplug_complete() to remove device from views, Paolo Bonzini, 2012/08/08
- Re: [Qemu-devel] [PATCH 13/15] hotplug: introduce qdev_unplug_complete() to remove device from views, Avi Kivity, 2012/08/08
- Re: [Qemu-devel] [PATCH 13/15] hotplug: introduce qdev_unplug_complete() to remove device from views, liu ping fan, 2012/08/09
- Re: [Qemu-devel] [PATCH 13/15] hotplug: introduce qdev_unplug_complete() to remove device from views, Paolo Bonzini, 2012/08/09
- Re: [Qemu-devel] [PATCH 13/15] hotplug: introduce qdev_unplug_complete() to remove device from views, liu ping fan, 2012/08/10
- Re: [Qemu-devel] [PATCH 13/15] hotplug: introduce qdev_unplug_complete() to remove device from views, Marcelo Tosatti, 2012/08/13
- Re: [Qemu-devel] [PATCH 13/15] hotplug: introduce qdev_unplug_complete() to remove device from views, Marcelo Tosatti, 2012/08/13
[Qemu-devel] [PATCH 15/15] e1000: using new interface--unmap to unplug, Liu Ping Fan, 2012/08/08