]> git.proxmox.com Git - qemu.git/blobdiff - hw/pci/pcie.c
hw/pcie: AER and hot-plug events must use device's interrupt
[qemu.git] / hw / pci / pcie.c
index 485c94c1b25894818135f61b4e25ef882629778e..268a69664654b8816f835c708c105ba4c9ce2421 100644 (file)
@@ -87,6 +87,22 @@ int pcie_cap_init(PCIDevice *dev, uint8_t offset, uint8_t type, uint8_t port)
     return pos;
 }
 
+int pcie_endpoint_cap_init(PCIDevice *dev, uint8_t offset)
+{
+    uint8_t type = PCI_EXP_TYPE_ENDPOINT;
+
+    /*
+     * Windows guests will report Code 10, device cannot start, if
+     * a regular Endpoint type is exposed on a root complex.  These
+     * should instead be Root Complex Integrated Endpoints.
+     */
+    if (pci_bus_is_express(dev->bus) && pci_bus_is_root(dev->bus)) {
+        type = PCI_EXP_TYPE_RC_END;
+    }
+
+    return pcie_cap_init(dev, offset, type, 0);
+}
+
 void pcie_cap_exit(PCIDevice *dev)
 {
     pci_del_capability(dev, PCI_CAP_ID_EXP, PCI_EXP_VER2_SIZEOF);
@@ -171,7 +187,7 @@ static void hotplug_event_notify(PCIDevice *dev)
     } else if (msi_enabled(dev)) {
         msi_notify(dev, pcie_cap_flags_get_vector(dev));
     } else {
-        qemu_set_irq(dev->irq[dev->exp.hpev_intx], dev->exp.hpev_notified);
+        pci_set_irq(dev, dev->exp.hpev_notified);
     }
 }
 
@@ -179,7 +195,7 @@ 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);
+        pci_irq_deassert(dev);
     }
 }
 
@@ -289,7 +305,7 @@ void pcie_cap_slot_init(PCIDevice *dev, uint16_t slot)
 
     dev->exp.hpev_notified = false;
 
-    pci_bus_hotplug(pci_bridge_get_sec_bus(DO_UPCAST(PCIBridge, dev, dev)),
+    pci_bus_hotplug(pci_bridge_get_sec_bus(PCI_BRIDGE(dev)),
                     pcie_cap_slot_hotplug, &dev->qdev);
 }