Skip to content
Snippets Groups Projects
Commit 44242d4d authored by Gerd Hoffmann's avatar Gerd Hoffmann Committed by Michael S. Tsirkin
Browse files

pcie: factor out pcie_cap_slot_unplug()


No functional change.

Signed-off-by: default avatarGerd Hoffmann <kraxel@redhat.com>
Message-Id: <20211111130859.1171890-5-kraxel@redhat.com>
Reviewed-by: default avatarMichael S. Tsirkin <mst@redhat.com>
Signed-off-by: default avatarMichael S. Tsirkin <mst@redhat.com>
parent 81124b3c
No related branches found
No related tags found
No related merge requests found
......@@ -497,6 +497,25 @@ static void pcie_unplug_device(PCIBus *bus, PCIDevice *dev, void *opaque)
object_unparent(OBJECT(dev));
}
static void pcie_cap_slot_do_unplug(PCIDevice *dev)
{
PCIBus *sec_bus = pci_bridge_get_sec_bus(PCI_BRIDGE(dev));
uint8_t *exp_cap = dev->config + dev->exp.exp_cap;
uint32_t lnkcap = pci_get_long(exp_cap + PCI_EXP_LNKCAP);
pci_for_each_device_under_bus(sec_bus, pcie_unplug_device, NULL);
pci_word_test_and_clear_mask(exp_cap + PCI_EXP_SLTSTA,
PCI_EXP_SLTSTA_PDS);
if (dev->cap_present & QEMU_PCIE_LNKSTA_DLLLA ||
(lnkcap & PCI_EXP_LNKCAP_DLLLARC)) {
pci_word_test_and_clear_mask(exp_cap + PCI_EXP_LNKSTA,
PCI_EXP_LNKSTA_DLLLA);
}
pci_word_test_and_set_mask(exp_cap + PCI_EXP_SLTSTA,
PCI_EXP_SLTSTA_PDC);
}
void pcie_cap_slot_unplug_request_cb(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp)
{
......@@ -676,7 +695,6 @@ void pcie_cap_slot_write_config(PCIDevice *dev,
uint32_t pos = dev->exp.exp_cap;
uint8_t *exp_cap = dev->config + pos;
uint16_t sltsta = pci_get_word(exp_cap + PCI_EXP_SLTSTA);
uint32_t lnkcap = pci_get_long(exp_cap + PCI_EXP_LNKCAP);
if (ranges_overlap(addr, len, pos + PCI_EXP_SLTSTA, 2)) {
/*
......@@ -726,17 +744,7 @@ void pcie_cap_slot_write_config(PCIDevice *dev,
(val & PCI_EXP_SLTCTL_PIC_OFF) == PCI_EXP_SLTCTL_PIC_OFF &&
(!(old_slt_ctl & PCI_EXP_SLTCTL_PCC) ||
(old_slt_ctl & PCI_EXP_SLTCTL_PIC_OFF) != PCI_EXP_SLTCTL_PIC_OFF)) {
PCIBus *sec_bus = pci_bridge_get_sec_bus(PCI_BRIDGE(dev));
pci_for_each_device_under_bus(sec_bus, pcie_unplug_device, NULL);
pci_word_test_and_clear_mask(exp_cap + PCI_EXP_SLTSTA,
PCI_EXP_SLTSTA_PDS);
if (dev->cap_present & QEMU_PCIE_LNKSTA_DLLLA ||
(lnkcap & PCI_EXP_LNKCAP_DLLLARC)) {
pci_word_test_and_clear_mask(exp_cap + PCI_EXP_LNKSTA,
PCI_EXP_LNKSTA_DLLLA);
}
pci_word_test_and_set_mask(exp_cap + PCI_EXP_SLTSTA,
PCI_EXP_SLTSTA_PDC);
pcie_cap_slot_do_unplug(dev);
}
pcie_cap_update_power(dev);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment