Provide pcihp specific callback to check if bus is hotpluggable
and consolidate its scattered hotplug criteria there.
While at it clean up no longer needed
qbus_set_hotplug_handler(BUS(bus), NULL)
workarounds since callback makes qbus_is_hotpluggable() return
correct answer even if hotplug_handler is set on bus.
PS:
see ("pci: fix 'hotplugglable' property behavior") for details
why callback was introduced.
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Message-Id: <
20230302161543.286002-35-imammedo@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
return;
}
+bool acpi_pcihp_is_hotpluggbale_bus(AcpiPciHpState *s, BusState *bus)
+{
+ return true;
+}
}
}
+bool ich9_pm_is_hotpluggable_bus(HotplugHandler *hotplug_dev, BusState *bus)
+{
+ ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev);
+ return acpi_pcihp_is_hotpluggbale_bus(&lpc->pm.acpi_pci_hotplug, bus);
+}
+
void ich9_pm_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list)
{
ICH9LPCState *s = ICH9_LPC_DEVICE(adev);
}
}
-static void acpi_pcihp_disable_root_bus(void)
-{
- Object *host = acpi_get_i386_pci_host();
- PCIBus *bus;
-
- bus = PCI_HOST_BRIDGE(host)->bus;
- if (bus && qbus_is_hotpluggable(BUS(bus))) {
- /* setting the hotplug handler to NULL makes the bus non-hotpluggable */
- qbus_set_hotplug_handler(BUS(bus), NULL);
- }
-
- return;
-}
-
static void acpi_pcihp_test_hotplug_bus(PCIBus *bus, void *opaque)
{
AcpiPciHpFind *find = opaque;
void acpi_pcihp_reset(AcpiPciHpState *s)
{
- if (!s->use_acpi_root_pci_hotplug) {
- acpi_pcihp_disable_root_bus();
- }
acpi_set_pci_info(s->use_acpi_hotplug_bridge);
acpi_pcihp_update(s);
}
object_dynamic_cast(OBJECT(dev), TYPE_PCI_BRIDGE)) {
PCIBus *sec = pci_bridge_get_sec_bus(PCI_BRIDGE(pdev));
- /* Remove all hot-plug handlers if hot-plug is disabled on slot */
- if (object_dynamic_cast(OBJECT(dev), TYPE_PCIE_SLOT) &&
- !PCIE_SLOT(pdev)->hotplug) {
- qbus_set_hotplug_handler(BUS(sec), NULL);
- return;
- }
-
qbus_set_hotplug_handler(BUS(sec), OBJECT(hotplug_dev));
/* We don't have to overwrite any other hotplug handler yet */
assert(QLIST_EMPTY(&sec->child));
acpi_send_event(DEVICE(hotplug_dev), ACPI_PCI_HOTPLUG_STATUS);
}
+bool acpi_pcihp_is_hotpluggbale_bus(AcpiPciHpState *s, BusState *bus)
+{
+ Object *o = OBJECT(bus->parent);
+
+ if (s->use_acpi_hotplug_bridge &&
+ object_dynamic_cast(o, TYPE_PCI_BRIDGE)) {
+ if (object_dynamic_cast(o, TYPE_PCIE_SLOT) && !PCIE_SLOT(o)->hotplug) {
+ return false;
+ }
+ return true;
+ }
+
+ if (s->use_acpi_root_pci_hotplug) {
+ return true;
+ }
+ return false;
+}
+
static uint64_t pci_read(void *opaque, hwaddr addr, unsigned int size)
{
AcpiPciHpState *s = opaque;
}
}
+static bool piix4_is_hotpluggable_bus(HotplugHandler *hotplug_dev,
+ BusState *bus)
+{
+ PIIX4PMState *s = PIIX4_PM(hotplug_dev);
+ return acpi_pcihp_is_hotpluggbale_bus(&s->acpi_pci_hotplug, bus);
+}
+
static void piix4_pm_machine_ready(Notifier *n, void *opaque)
{
PIIX4PMState *s = container_of(n, PIIX4PMState, machine_ready);
hc->plug = piix4_device_plug_cb;
hc->unplug_request = piix4_device_unplug_request_cb;
hc->unplug = piix4_device_unplug_cb;
+ hc->is_hotpluggable_bus = piix4_is_hotpluggable_bus;
adevc->ospm_status = piix4_ospm_status;
adevc->send_event = piix4_send_gpe;
adevc->madt_cpu = pc_madt_cpu_entry;
hc->plug = ich9_pm_device_plug_cb;
hc->unplug_request = ich9_pm_device_unplug_request_cb;
hc->unplug = ich9_pm_device_unplug_cb;
+ hc->is_hotpluggable_bus = ich9_pm_is_hotpluggable_bus;
adevc->ospm_status = ich9_pm_ospm_status;
adevc->send_event = ich9_send_gpe;
adevc->madt_cpu = pc_madt_cpu_entry;
DeviceState *dev, Error **errp);
void ich9_pm_device_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
Error **errp);
+bool ich9_pm_is_hotpluggable_bus(HotplugHandler *hotplug_dev, BusState *bus);
void ich9_pm_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list);
#endif /* HW_ACPI_ICH9_H */
void acpi_pcihp_init(Object *owner, AcpiPciHpState *, PCIBus *root,
MemoryRegion *address_space_io, uint16_t io_base);
+bool acpi_pcihp_is_hotpluggbale_bus(AcpiPciHpState *s, BusState *bus);
void acpi_pcihp_device_pre_plug_cb(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp);
void acpi_pcihp_device_plug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s,