mirror of
https://github.com/xemu-project/xemu.git
synced 2025-01-22 11:54:47 +00:00
pci/pcihp: 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: Igor Mammedov <imammedo@redhat.com> 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>
This commit is contained in:
parent
3e52092657
commit
c97adf3ccf
@ -154,6 +154,7 @@ static bool acpi_pcihp_pc_no_hotplug(AcpiPciHpState *s, PCIDevice *dev)
|
||||
|
||||
static void acpi_pcihp_eject_slot(AcpiPciHpState *s, unsigned bsel, unsigned slots)
|
||||
{
|
||||
HotplugHandler *hotplug_ctrl;
|
||||
BusChild *kid, *next;
|
||||
int slot = ctz32(slots);
|
||||
PCIBus *bus = acpi_pcihp_find_hotplug_bus(s, bsel);
|
||||
@ -171,7 +172,8 @@ static void acpi_pcihp_eject_slot(AcpiPciHpState *s, unsigned bsel, unsigned slo
|
||||
PCIDevice *dev = PCI_DEVICE(qdev);
|
||||
if (PCI_SLOT(dev->devfn) == slot) {
|
||||
if (!acpi_pcihp_pc_no_hotplug(s, dev)) {
|
||||
object_unparent(OBJECT(qdev));
|
||||
hotplug_ctrl = qdev_get_hotplug_handler(qdev);
|
||||
hotplug_handler_unplug(hotplug_ctrl, qdev, &error_abort);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -266,6 +268,13 @@ void acpi_pcihp_device_plug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s,
|
||||
|
||||
void acpi_pcihp_device_unplug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s,
|
||||
DeviceState *dev, Error **errp)
|
||||
{
|
||||
object_unparent(OBJECT(dev));
|
||||
}
|
||||
|
||||
void acpi_pcihp_device_unplug_request_cb(HotplugHandler *hotplug_dev,
|
||||
AcpiPciHpState *s, DeviceState *dev,
|
||||
Error **errp)
|
||||
{
|
||||
PCIDevice *pdev = PCI_DEVICE(dev);
|
||||
int slot = PCI_SLOT(pdev->devfn);
|
||||
|
@ -419,8 +419,8 @@ static void piix4_device_unplug_request_cb(HotplugHandler *hotplug_dev,
|
||||
acpi_memory_unplug_request_cb(hotplug_dev, &s->acpi_memory_hotplug,
|
||||
dev, errp);
|
||||
} else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
|
||||
acpi_pcihp_device_unplug_cb(hotplug_dev, &s->acpi_pci_hotplug, dev,
|
||||
errp);
|
||||
acpi_pcihp_device_unplug_request_cb(hotplug_dev, &s->acpi_pci_hotplug,
|
||||
dev, errp);
|
||||
} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU) &&
|
||||
!s->cpu_hotplug_legacy) {
|
||||
acpi_cpu_unplug_request_cb(hotplug_dev, &s->cpuhp_state, dev, errp);
|
||||
@ -438,6 +438,9 @@ static void piix4_device_unplug_cb(HotplugHandler *hotplug_dev,
|
||||
if (s->acpi_memory_hotplug.is_enabled &&
|
||||
object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
|
||||
acpi_memory_unplug_cb(&s->acpi_memory_hotplug, dev, errp);
|
||||
} else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
|
||||
acpi_pcihp_device_unplug_cb(hotplug_dev, &s->acpi_pci_hotplug, dev,
|
||||
errp);
|
||||
} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU) &&
|
||||
!s->cpu_hotplug_legacy) {
|
||||
acpi_cpu_unplug_cb(&s->cpuhp_state, dev, errp);
|
||||
|
@ -62,6 +62,9 @@ void acpi_pcihp_device_plug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s,
|
||||
DeviceState *dev, Error **errp);
|
||||
void acpi_pcihp_device_unplug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s,
|
||||
DeviceState *dev, Error **errp);
|
||||
void acpi_pcihp_device_unplug_request_cb(HotplugHandler *hotplug_dev,
|
||||
AcpiPciHpState *s, DeviceState *dev,
|
||||
Error **errp);
|
||||
|
||||
/* Called on reset */
|
||||
void acpi_pcihp_reset(AcpiPciHpState *s);
|
||||
|
Loading…
x
Reference in New Issue
Block a user