pcie/slot: fix hotplug event
When slot status register is cleared, PCIDevice::exp.hpev_notify needs to be cleared. Otherwise, PCIDevice::exp.hpev_notify is never set to false resulting in no more hot plug event once it's raised. Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
parent
e8906f3529
commit
1553d4f1fc
12
hw/pcie.c
12
hw/pcie.c
@ -175,6 +175,14 @@ static void hotplug_event_notify(PCIDevice *dev)
|
||||
}
|
||||
}
|
||||
|
||||
static void hotplug_event_clear(PCIDevice *dev)
|
||||
{
|
||||
hotplug_event_update_event_status(dev);
|
||||
if (!msix_enabled(dev) && !msi_enabled(dev) && !dev->exp.hpev_notified) {
|
||||
qemu_set_irq(dev->irq[dev->exp.hpev_intx], 0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* A PCI Express Hot-Plug Event has occurred, so update slot status register
|
||||
* and notify OS of the event if necessary.
|
||||
@ -320,6 +328,10 @@ void pcie_cap_slot_write_config(PCIDevice *dev,
|
||||
uint8_t *exp_cap = dev->config + pos;
|
||||
uint16_t sltsta = pci_get_word(exp_cap + PCI_EXP_SLTSTA);
|
||||
|
||||
if (ranges_overlap(addr, len, pos + PCI_EXP_SLTSTA, 2)) {
|
||||
hotplug_event_clear(dev);
|
||||
}
|
||||
|
||||
if (!ranges_overlap(addr, len, pos + PCI_EXP_SLTCTL, 2)) {
|
||||
return;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user