pcie: factor out pcie_cap_slot_unplug()
No functional change. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> Message-Id: <20211111130859.1171890-5-kraxel@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
81124b3c7a
commit
44242d4d3d
@ -497,6 +497,25 @@ static void pcie_unplug_device(PCIBus *bus, PCIDevice *dev, void *opaque)
|
|||||||
object_unparent(OBJECT(dev));
|
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,
|
void pcie_cap_slot_unplug_request_cb(HotplugHandler *hotplug_dev,
|
||||||
DeviceState *dev, Error **errp)
|
DeviceState *dev, Error **errp)
|
||||||
{
|
{
|
||||||
@ -676,7 +695,6 @@ void pcie_cap_slot_write_config(PCIDevice *dev,
|
|||||||
uint32_t pos = dev->exp.exp_cap;
|
uint32_t pos = dev->exp.exp_cap;
|
||||||
uint8_t *exp_cap = dev->config + pos;
|
uint8_t *exp_cap = dev->config + pos;
|
||||||
uint16_t sltsta = pci_get_word(exp_cap + PCI_EXP_SLTSTA);
|
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)) {
|
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 &&
|
(val & PCI_EXP_SLTCTL_PIC_OFF) == PCI_EXP_SLTCTL_PIC_OFF &&
|
||||||
(!(old_slt_ctl & PCI_EXP_SLTCTL_PCC) ||
|
(!(old_slt_ctl & PCI_EXP_SLTCTL_PCC) ||
|
||||||
(old_slt_ctl & PCI_EXP_SLTCTL_PIC_OFF) != PCI_EXP_SLTCTL_PIC_OFF)) {
|
(old_slt_ctl & PCI_EXP_SLTCTL_PIC_OFF) != PCI_EXP_SLTCTL_PIC_OFF)) {
|
||||||
PCIBus *sec_bus = pci_bridge_get_sec_bus(PCI_BRIDGE(dev));
|
pcie_cap_slot_do_unplug(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_update_power(dev);
|
pcie_cap_update_power(dev);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user