Message ID | c7ce40597d537fd052af00b13f29a985dd305c9a.1312536046.git.yamahata@valinux.co.jp |
---|---|
State | New |
Headers | show |
On Fri, Aug 05, 2011 at 06:22:03PM +0900, Isaku Yamahata wrote: > 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> Thanks, applied. > --- > hw/pcie.c | 12 ++++++++++++ > 1 files changed, 12 insertions(+), 0 deletions(-) > > diff --git a/hw/pcie.c b/hw/pcie.c > index 39607bf..5c9eb2f 100644 > --- a/hw/pcie.c > +++ b/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; > } > -- > 1.7.1.1
diff --git a/hw/pcie.c b/hw/pcie.c index 39607bf..5c9eb2f 100644 --- a/hw/pcie.c +++ b/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; }
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> --- hw/pcie.c | 12 ++++++++++++ 1 files changed, 12 insertions(+), 0 deletions(-)