@@ -145,6 +145,8 @@ static Property gen_rp_props[] = {
speed, PCIE_LINK_SPEED_16),
DEFINE_PROP_PCIE_LINK_WIDTH("x-width", PCIESlot,
width, PCIE_LINK_WIDTH_32),
+ DEFINE_PROP_BOOL("x-atomic-completion", PCIESlot,
+ atomic_completion, false),
DEFINE_PROP_END_OF_LIST()
};
@@ -663,6 +663,12 @@ void pcie_cap_slot_init(PCIDevice *dev, PCIESlot *s)
qbus_set_hotplug_handler(BUS(pci_bridge_get_sec_bus(PCI_BRIDGE(dev))),
OBJECT(dev));
+
+ if (s->atomic_completion) {
+ /* PCIe requires setting both comp32 and comp64 if either is supported */
+ pci_set_long(dev->config + dev->exp.exp_cap + PCI_EXP_DEVCAP2,
+ PCI_EXP_DEVCAP2_ATOMIC_COMP32 | PCI_EXP_DEVCAP2_ATOMIC_COMP64);
+ }
}
void pcie_cap_slot_reset(PCIDevice *dev)
@@ -68,6 +68,9 @@ struct PCIESlot {
/* broken ACPI hotplug compat knob to preserve 6.1 ABI intact */
bool hide_native_hotplug_cap;
+ /* Enables PCIE Atomic completion on pcie_root_port */
+ bool atomic_completion;
+
QLIST_ENTRY(PCIESlot) next;
};