diff options
author | David Hildenbrand <david@redhat.com> | 2018-12-12 10:16:22 +0100 |
---|---|---|
committer | Michael S. Tsirkin <mst@redhat.com> | 2018-12-20 11:19:12 -0500 |
commit | 8f560cdce42562a3c41d61c896667cf77c76d51f (patch) | |
tree | 38b27134228c8264e5b9cd11efe939ebce0faf30 /hw/pci | |
parent | 62b765639691de36476c471117e96184a2a3c7a6 (diff) |
pci/shpc: perform unplug via the hotplug handler
Introduce and use the "unplug" callback.
This is a preparation for multi-stage hotplug handlers, whereby the bus
hotplug handler is overwritten by the machine hotplug handler. This handler
will then pass control to the bus hotplug handler. So to get this running
cleanly, we also have to make sure to go via the hotplug handler chain when
actually unplugging a device after an unplug request. Lookup the hotplug
handler and call "unplug".
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: David Hildenbrand <david@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'hw/pci')
-rw-r--r-- | hw/pci/shpc.c | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/hw/pci/shpc.c b/hw/pci/shpc.c index 7851bfa8ad..45053b39b9 100644 --- a/hw/pci/shpc.c +++ b/hw/pci/shpc.c @@ -238,6 +238,7 @@ static void shpc_invalid_command(SHPCDevice *shpc) static void shpc_free_devices_in_slot(SHPCDevice *shpc, int slot) { + HotplugHandler *hotplug_ctrl; int devfn; int pci_slot = SHPC_IDX_TO_PCI(slot); for (devfn = PCI_DEVFN(pci_slot, 0); @@ -245,7 +246,9 @@ static void shpc_free_devices_in_slot(SHPCDevice *shpc, int slot) ++devfn) { PCIDevice *affected_dev = shpc->sec_bus->devices[devfn]; if (affected_dev) { - object_unparent(OBJECT(affected_dev)); + hotplug_ctrl = qdev_get_hotplug_handler(DEVICE(affected_dev)); + hotplug_handler_unplug(hotplug_ctrl, DEVICE(affected_dev), + &error_abort); } } } @@ -540,6 +543,12 @@ void shpc_device_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, shpc_interrupt_update(pci_hotplug_dev); } +void shpc_device_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, + Error **errp) +{ + object_unparent(OBJECT(dev)); +} + void shpc_device_unplug_request_cb(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { |