aboutsummaryrefslogtreecommitdiff
path: root/hw/pci/pcie_port.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/pci/pcie_port.c')
-rw-r--r--hw/pci/pcie_port.c74
1 files changed, 73 insertions, 1 deletions
diff --git a/hw/pci/pcie_port.c b/hw/pci/pcie_port.c
index da850e8dde..20ff2b39e8 100644
--- a/hw/pci/pcie_port.c
+++ b/hw/pci/pcie_port.c
@@ -136,6 +136,76 @@ static void pcie_port_class_init(ObjectClass *oc, void *data)
device_class_set_props(dc, pcie_port_props);
}
+PCIDevice *pcie_find_port_by_pn(PCIBus *bus, uint8_t pn)
+{
+ int devfn;
+
+ for (devfn = 0; devfn < ARRAY_SIZE(bus->devices); devfn++) {
+ PCIDevice *d = bus->devices[devfn];
+ PCIEPort *port;
+
+ if (!d || !pci_is_express(d) || !d->exp.exp_cap) {
+ continue;
+ }
+
+ if (!object_dynamic_cast(OBJECT(d), TYPE_PCIE_PORT)) {
+ continue;
+ }
+
+ port = PCIE_PORT(d);
+ if (port->port == pn) {
+ return d;
+ }
+ }
+
+ return NULL;
+}
+
+/* Find first port in devfn number order */
+PCIDevice *pcie_find_port_first(PCIBus *bus)
+{
+ int devfn;
+
+ for (devfn = 0; devfn < ARRAY_SIZE(bus->devices); devfn++) {
+ PCIDevice *d = bus->devices[devfn];
+
+ if (!d || !pci_is_express(d) || !d->exp.exp_cap) {
+ continue;
+ }
+
+ if (object_dynamic_cast(OBJECT(d), TYPE_PCIE_PORT)) {
+ return d;
+ }
+ }
+
+ return NULL;
+}
+
+int pcie_count_ds_ports(PCIBus *bus)
+{
+ int dsp_count = 0;
+ int devfn;
+
+ for (devfn = 0; devfn < ARRAY_SIZE(bus->devices); devfn++) {
+ PCIDevice *d = bus->devices[devfn];
+
+ if (!d || !pci_is_express(d) || !d->exp.exp_cap) {
+ continue;
+ }
+ if (object_dynamic_cast(OBJECT(d), TYPE_PCIE_PORT)) {
+ dsp_count++;
+ }
+ }
+ return dsp_count;
+}
+
+static bool pcie_slot_is_hotpluggbale_bus(HotplugHandler *plug_handler,
+ BusState *bus)
+{
+ PCIESlot *s = PCIE_SLOT(bus->parent);
+ return s->hotplug;
+}
+
static const TypeInfo pcie_port_type_info = {
.name = TYPE_PCIE_PORT,
.parent = TYPE_PCI_BRIDGE,
@@ -148,7 +218,8 @@ static Property pcie_slot_props[] = {
DEFINE_PROP_UINT8("chassis", PCIESlot, chassis, 0),
DEFINE_PROP_UINT16("slot", PCIESlot, slot, 0),
DEFINE_PROP_BOOL("hotplug", PCIESlot, hotplug, true),
- DEFINE_PROP_BOOL("native-hotplug", PCIESlot, native_hotplug, true),
+ DEFINE_PROP_BOOL("x-do-not-expose-native-hotplug-cap", PCIESlot,
+ hide_native_hotplug_cap, false),
DEFINE_PROP_END_OF_LIST()
};
@@ -162,6 +233,7 @@ static void pcie_slot_class_init(ObjectClass *oc, void *data)
hc->plug = pcie_cap_slot_plug_cb;
hc->unplug = pcie_cap_slot_unplug_cb;
hc->unplug_request = pcie_cap_slot_unplug_request_cb;
+ hc->is_hotpluggable_bus = pcie_slot_is_hotpluggbale_bus;
}
static const TypeInfo pcie_slot_type_info = {