pcihp: add ACPI PCI hotplug specific is_hotpluggable_bus() callback
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>
This commit is contained in:
parent
6536e427ce
commit
f18e29fc90
@ -40,3 +40,7 @@ void acpi_pcihp_reset(AcpiPciHpState *s)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool acpi_pcihp_is_hotpluggbale_bus(AcpiPciHpState *s, BusState *bus)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@ -578,6 +578,12 @@ void ich9_pm_device_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
void ich9_pm_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list)
|
||||||
{
|
{
|
||||||
ICH9LPCState *s = ICH9_LPC_DEVICE(adev);
|
ICH9LPCState *s = ICH9_LPC_DEVICE(adev);
|
||||||
|
@ -121,20 +121,6 @@ static void acpi_set_pci_info(bool has_bridge_hotplug)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
static void acpi_pcihp_test_hotplug_bus(PCIBus *bus, void *opaque)
|
||||||
{
|
{
|
||||||
AcpiPciHpFind *find = opaque;
|
AcpiPciHpFind *find = opaque;
|
||||||
@ -278,9 +264,6 @@ static void acpi_pcihp_update(AcpiPciHpState *s)
|
|||||||
|
|
||||||
void acpi_pcihp_reset(AcpiPciHpState *s)
|
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_set_pci_info(s->use_acpi_hotplug_bridge);
|
||||||
acpi_pcihp_update(s);
|
acpi_pcihp_update(s);
|
||||||
}
|
}
|
||||||
@ -320,13 +303,6 @@ void acpi_pcihp_device_plug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s,
|
|||||||
object_dynamic_cast(OBJECT(dev), TYPE_PCI_BRIDGE)) {
|
object_dynamic_cast(OBJECT(dev), TYPE_PCI_BRIDGE)) {
|
||||||
PCIBus *sec = pci_bridge_get_sec_bus(PCI_BRIDGE(pdev));
|
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));
|
qbus_set_hotplug_handler(BUS(sec), OBJECT(hotplug_dev));
|
||||||
/* We don't have to overwrite any other hotplug handler yet */
|
/* We don't have to overwrite any other hotplug handler yet */
|
||||||
assert(QLIST_EMPTY(&sec->child));
|
assert(QLIST_EMPTY(&sec->child));
|
||||||
@ -385,6 +361,24 @@ void acpi_pcihp_device_unplug_request_cb(HotplugHandler *hotplug_dev,
|
|||||||
acpi_send_event(DEVICE(hotplug_dev), ACPI_PCI_HOTPLUG_STATUS);
|
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)
|
static uint64_t pci_read(void *opaque, hwaddr addr, unsigned int size)
|
||||||
{
|
{
|
||||||
AcpiPciHpState *s = opaque;
|
AcpiPciHpState *s = opaque;
|
||||||
|
@ -404,6 +404,13 @@ static void piix4_device_unplug_cb(HotplugHandler *hotplug_dev,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
static void piix4_pm_machine_ready(Notifier *n, void *opaque)
|
||||||
{
|
{
|
||||||
PIIX4PMState *s = container_of(n, PIIX4PMState, machine_ready);
|
PIIX4PMState *s = container_of(n, PIIX4PMState, machine_ready);
|
||||||
@ -644,6 +651,7 @@ static void piix4_pm_class_init(ObjectClass *klass, void *data)
|
|||||||
hc->plug = piix4_device_plug_cb;
|
hc->plug = piix4_device_plug_cb;
|
||||||
hc->unplug_request = piix4_device_unplug_request_cb;
|
hc->unplug_request = piix4_device_unplug_request_cb;
|
||||||
hc->unplug = piix4_device_unplug_cb;
|
hc->unplug = piix4_device_unplug_cb;
|
||||||
|
hc->is_hotpluggable_bus = piix4_is_hotpluggable_bus;
|
||||||
adevc->ospm_status = piix4_ospm_status;
|
adevc->ospm_status = piix4_ospm_status;
|
||||||
adevc->send_event = piix4_send_gpe;
|
adevc->send_event = piix4_send_gpe;
|
||||||
adevc->madt_cpu = pc_madt_cpu_entry;
|
adevc->madt_cpu = pc_madt_cpu_entry;
|
||||||
|
@ -865,6 +865,7 @@ static void ich9_lpc_class_init(ObjectClass *klass, void *data)
|
|||||||
hc->plug = ich9_pm_device_plug_cb;
|
hc->plug = ich9_pm_device_plug_cb;
|
||||||
hc->unplug_request = ich9_pm_device_unplug_request_cb;
|
hc->unplug_request = ich9_pm_device_unplug_request_cb;
|
||||||
hc->unplug = ich9_pm_device_unplug_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->ospm_status = ich9_pm_ospm_status;
|
||||||
adevc->send_event = ich9_send_gpe;
|
adevc->send_event = ich9_send_gpe;
|
||||||
adevc->madt_cpu = pc_madt_cpu_entry;
|
adevc->madt_cpu = pc_madt_cpu_entry;
|
||||||
|
@ -87,6 +87,7 @@ void ich9_pm_device_unplug_request_cb(HotplugHandler *hotplug_dev,
|
|||||||
DeviceState *dev, Error **errp);
|
DeviceState *dev, Error **errp);
|
||||||
void ich9_pm_device_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
|
void ich9_pm_device_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
|
||||||
Error **errp);
|
Error **errp);
|
||||||
|
bool ich9_pm_is_hotpluggable_bus(HotplugHandler *hotplug_dev, BusState *bus);
|
||||||
|
|
||||||
void ich9_pm_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list);
|
void ich9_pm_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list);
|
||||||
#endif /* HW_ACPI_ICH9_H */
|
#endif /* HW_ACPI_ICH9_H */
|
||||||
|
@ -58,6 +58,7 @@ typedef struct AcpiPciHpState {
|
|||||||
void acpi_pcihp_init(Object *owner, AcpiPciHpState *, PCIBus *root,
|
void acpi_pcihp_init(Object *owner, AcpiPciHpState *, PCIBus *root,
|
||||||
MemoryRegion *address_space_io, uint16_t io_base);
|
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,
|
void acpi_pcihp_device_pre_plug_cb(HotplugHandler *hotplug_dev,
|
||||||
DeviceState *dev, Error **errp);
|
DeviceState *dev, Error **errp);
|
||||||
void acpi_pcihp_device_plug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s,
|
void acpi_pcihp_device_plug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s,
|
||||||
|
Loading…
Reference in New Issue
Block a user