aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/acpi/pcihp.c4
-rw-r--r--hw/acpi/piix4.c7
-rw-r--r--hw/acpi/vmgenid.c30
-rw-r--r--hw/alpha/typhoon.c8
-rw-r--r--hw/core/qdev-properties.c61
-rw-r--r--hw/i2c/pm_smbus.c16
-rw-r--r--hw/i386/intel_iommu.c12
-rw-r--r--hw/i386/pc_piix.c8
-rw-r--r--hw/i386/xen/xen_platform.c12
-rw-r--r--hw/isa/lpc_ich9.c10
-rw-r--r--hw/mips/gt64xxx_pci.c12
-rw-r--r--hw/net/vmxnet3.c2
-rw-r--r--hw/pci-bridge/pci_expander_bridge.c21
-rw-r--r--hw/pci-host/apb.c10
-rw-r--r--hw/pci-host/bonito.c8
-rw-r--r--hw/pci-host/gpex.c6
-rw-r--r--hw/pci-host/grackle.c14
-rw-r--r--hw/pci-host/piix.c59
-rw-r--r--hw/pci-host/ppce500.c6
-rw-r--r--hw/pci-host/prep.c4
-rw-r--r--hw/pci-host/q35.c7
-rw-r--r--hw/pci-host/uninorth.c24
-rw-r--r--hw/pci-host/versatile.c8
-rw-r--r--hw/pci-host/xilinx-pcie.c27
-rw-r--r--hw/pci/pci.c141
-rw-r--r--hw/pci/pci_bridge.c6
-rw-r--r--hw/pci/pcie.c5
-rw-r--r--hw/pci/pcie_aer.c4
-rw-r--r--hw/ppc/ppc4xx_pci.c6
-rw-r--r--hw/ppc/spapr_pci.c10
-rw-r--r--hw/s390x/s390-pci-bus.c18
-rw-r--r--hw/scsi/megasas.c2
-rw-r--r--hw/scsi/mptsas.c2
-rw-r--r--hw/scsi/vmw_pvscsi.c2
-rw-r--r--hw/sh4/sh_pci.c12
-rw-r--r--hw/smbios/smbios.c72
-rw-r--r--hw/smbios/smbios_build.h12
-rw-r--r--hw/usb/hcd-xhci.c2
-rw-r--r--hw/vfio/pci.c10
-rw-r--r--hw/virtio/virtio-pci.c12
-rw-r--r--hw/virtio/virtio.c2
-rw-r--r--hw/xen/xen_pt.c10
42 files changed, 418 insertions, 286 deletions
diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
index 7da51c0569..91c82fdc7a 100644
--- a/hw/acpi/pcihp.c
+++ b/hw/acpi/pcihp.c
@@ -223,7 +223,7 @@ void acpi_pcihp_device_plug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s,
{
PCIDevice *pdev = PCI_DEVICE(dev);
int slot = PCI_SLOT(pdev->devfn);
- int bsel = acpi_pcihp_get_bsel(pdev->bus);
+ int bsel = acpi_pcihp_get_bsel(pci_get_bus(pdev));
if (bsel < 0) {
error_setg(errp, "Unsupported bus. Bus doesn't have property '"
ACPI_PCIHP_PROP_BSEL "' set");
@@ -246,7 +246,7 @@ void acpi_pcihp_device_unplug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s,
{
PCIDevice *pdev = PCI_DEVICE(dev);
int slot = PCI_SLOT(pdev->devfn);
- int bsel = acpi_pcihp_get_bsel(pdev->bus);
+ int bsel = acpi_pcihp_get_bsel(pci_get_bus(pdev));
if (bsel < 0) {
error_setg(errp, "Unsupported bus. Bus doesn't have property '"
ACPI_PCIHP_PROP_BSEL "' set");
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index a0fb1ce037..8b703455b7 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -460,9 +460,9 @@ static void piix4_pm_machine_ready(Notifier *n, void *opaque)
(memory_region_present(io_as, 0x2f8) ? 0x90 : 0);
if (s->use_acpi_pci_hotplug) {
- pci_for_each_bus(d->bus, piix4_update_bus_hotplug, s);
+ pci_for_each_bus(pci_get_bus(d), piix4_update_bus_hotplug, s);
} else {
- piix4_update_bus_hotplug(d->bus, s);
+ piix4_update_bus_hotplug(pci_get_bus(d), s);
}
}
@@ -535,7 +535,8 @@ static void piix4_pm_realize(PCIDevice *dev, Error **errp)
qemu_add_machine_init_done_notifier(&s->machine_ready);
qemu_register_reset(piix4_reset, s);
- piix4_acpi_system_hot_add_init(pci_address_space_io(dev), dev->bus, s);
+ piix4_acpi_system_hot_add_init(pci_address_space_io(dev),
+ pci_get_bus(dev), s);
piix4_pm_add_propeties(s);
}
diff --git a/hw/acpi/vmgenid.c b/hw/acpi/vmgenid.c
index 105044f666..ba6f47b67b 100644
--- a/hw/acpi/vmgenid.c
+++ b/hw/acpi/vmgenid.c
@@ -162,21 +162,6 @@ static void vmgenid_update_guest(VmGenIdState *vms)
}
}
-static void vmgenid_set_guid(Object *obj, const char *value, Error **errp)
-{
- VmGenIdState *vms = VMGENID(obj);
-
- if (!strcmp(value, "auto")) {
- qemu_uuid_generate(&vms->guid);
- } else if (qemu_uuid_parse(value, &vms->guid) < 0) {
- error_setg(errp, "'%s. %s': Failed to parse GUID string: %s",
- object_get_typename(OBJECT(vms)), VMGENID_GUID, value);
- return;
- }
-
- vmgenid_update_guest(vms);
-}
-
/* After restoring an image, we need to update the guest memory and notify
* it of a potential change to VM Generation ID
*/
@@ -224,23 +209,24 @@ static void vmgenid_realize(DeviceState *dev, Error **errp)
}
qemu_register_reset(vmgenid_handle_reset, vms);
+
+ vmgenid_update_guest(vms);
}
+static Property vmgenid_device_properties[] = {
+ DEFINE_PROP_UUID(VMGENID_GUID, VmGenIdState, guid),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
static void vmgenid_device_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
dc->vmsd = &vmstate_vmgenid;
dc->realize = vmgenid_realize;
+ dc->props = vmgenid_device_properties;
dc->hotpluggable = false;
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
-
- object_class_property_add_str(klass, VMGENID_GUID, NULL,
- vmgenid_set_guid, NULL);
- object_class_property_set_description(klass, VMGENID_GUID,
- "Set Global Unique Identifier "
- "(big-endian) or auto for random value",
- NULL);
}
static const TypeInfo vmgenid_device_info = {
diff --git a/hw/alpha/typhoon.c b/hw/alpha/typhoon.c
index ae11e012c7..6a40869488 100644
--- a/hw/alpha/typhoon.c
+++ b/hw/alpha/typhoon.c
@@ -881,10 +881,10 @@ PCIBus *typhoon_init(ram_addr_t ram_size, ISABus **isa_bus,
memory_region_add_subregion(addr_space, 0x801fc000000ULL,
&s->pchip.reg_io);
- b = pci_register_bus(dev, "pci",
- typhoon_set_irq, sys_map_irq, s,
- &s->pchip.reg_mem, &s->pchip.reg_io,
- 0, 64, TYPE_PCI_BUS);
+ b = pci_register_root_bus(dev, "pci",
+ typhoon_set_irq, sys_map_irq, s,
+ &s->pchip.reg_mem, &s->pchip.reg_io,
+ 0, 64, TYPE_PCI_BUS);
phb->bus = b;
qdev_init_nofail(dev);
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 1dc80fcea2..24c17800e3 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -10,6 +10,7 @@
#include "net/hub.h"
#include "qapi/visitor.h"
#include "chardev/char.h"
+#include "qemu/uuid.h"
void qdev_prop_set_after_realize(DeviceState *dev, const char *name,
Error **errp)
@@ -883,6 +884,66 @@ const PropertyInfo qdev_prop_pci_host_devaddr = {
.set = set_pci_host_devaddr,
};
+/* --- UUID --- */
+
+static void get_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
+ Error **errp)
+{
+ DeviceState *dev = DEVICE(obj);
+ Property *prop = opaque;
+ QemuUUID *uuid = qdev_get_prop_ptr(dev, prop);
+ char buffer[UUID_FMT_LEN + 1];
+ char *p = buffer;
+
+ qemu_uuid_unparse(uuid, buffer);
+
+ visit_type_str(v, name, &p, errp);
+}
+
+#define UUID_VALUE_AUTO "auto"
+
+static void set_uuid(Object *obj, Visitor *v, const char *name, void *opaque,
+ Error **errp)
+{
+ DeviceState *dev = DEVICE(obj);
+ Property *prop = opaque;
+ QemuUUID *uuid = qdev_get_prop_ptr(dev, prop);
+ Error *local_err = NULL;
+ char *str;
+
+ if (dev->realized) {
+ qdev_prop_set_after_realize(dev, name, errp);
+ return;
+ }
+
+ visit_type_str(v, name, &str, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+
+ if (!strcmp(str, UUID_VALUE_AUTO)) {
+ qemu_uuid_generate(uuid);
+ } else if (qemu_uuid_parse(str, uuid) < 0) {
+ error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str);
+ }
+ g_free(str);
+}
+
+static void set_default_uuid_auto(Object *obj, const Property *prop)
+{
+ object_property_set_str(obj, UUID_VALUE_AUTO, prop->name, &error_abort);
+}
+
+const PropertyInfo qdev_prop_uuid = {
+ .name = "str",
+ .description = "UUID (aka GUID) or \"" UUID_VALUE_AUTO
+ "\" for random value (default)",
+ .get = get_uuid,
+ .set = set_uuid,
+ .set_default_value = set_default_uuid_auto,
+};
+
/* --- support for array properties --- */
/* Used as an opaque for the object properties we add for each
diff --git a/hw/i2c/pm_smbus.c b/hw/i2c/pm_smbus.c
index a044dd1b27..0d26e0f6b5 100644
--- a/hw/i2c/pm_smbus.c
+++ b/hw/i2c/pm_smbus.c
@@ -62,6 +62,9 @@ static void smb_transaction(PMSMBus *s)
I2CBus *bus = s->smbus;
int ret;
+ assert(s->smb_stat & STS_HOST_BUSY);
+ s->smb_stat &= ~STS_HOST_BUSY;
+
SMBUS_DPRINTF("SMBus trans addr=0x%02x prot=0x%02x\n", addr, prot);
/* Transaction isn't exec if STS_DEV_ERR bit set */
if ((s->smb_stat & STS_DEV_ERR) != 0) {
@@ -134,6 +137,13 @@ error:
}
+static void smb_transaction_start(PMSMBus *s)
+{
+ /* Do not execute immediately the command ; it will be
+ * executed when guest will read SMB_STAT register */
+ s->smb_stat |= STS_HOST_BUSY;
+}
+
static void smb_ioport_writeb(void *opaque, hwaddr addr, uint64_t val,
unsigned width)
{
@@ -149,7 +159,7 @@ static void smb_ioport_writeb(void *opaque, hwaddr addr, uint64_t val,
case SMBHSTCNT:
s->smb_ctl = val;
if (val & 0x40)
- smb_transaction(s);
+ smb_transaction_start(s);
break;
case SMBHSTCMD:
s->smb_cmd = val;
@@ -181,6 +191,10 @@ static uint64_t smb_ioport_readb(void *opaque, hwaddr addr, unsigned width)
switch(addr) {
case SMBHSTSTS:
val = s->smb_stat;
+ if (s->smb_stat & STS_HOST_BUSY) {
+ /* execute command now */
+ smb_transaction(s);
+ }
break;
case SMBHSTCNT:
s->smb_index = 0;
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 3a5bb0bc2e..fe15d3ba84 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -186,7 +186,7 @@ static void vtd_reset_context_cache(IntelIOMMUState *s)
g_hash_table_iter_init(&bus_it, s->vtd_as_by_busptr);
while (g_hash_table_iter_next (&bus_it, NULL, (void**)&vtd_bus)) {
- for (devfn_it = 0; devfn_it < X86_IOMMU_PCI_DEVFN_MAX; ++devfn_it) {
+ for (devfn_it = 0; devfn_it < PCI_DEVFN_MAX; ++devfn_it) {
vtd_as = vtd_bus->dev_as[devfn_it];
if (!vtd_as) {
continue;
@@ -1002,7 +1002,7 @@ static void vtd_switch_address_space_all(IntelIOMMUState *s)
g_hash_table_iter_init(&iter, s->vtd_as_by_busptr);
while (g_hash_table_iter_next(&iter, NULL, (void **)&vtd_bus)) {
- for (i = 0; i < X86_IOMMU_PCI_DEVFN_MAX; i++) {
+ for (i = 0; i < PCI_DEVFN_MAX; i++) {
if (!vtd_bus->dev_as[i]) {
continue;
}
@@ -1294,7 +1294,7 @@ static void vtd_context_device_invalidate(IntelIOMMUState *s,
vtd_bus = vtd_find_as_from_bus_num(s, bus_n);
if (vtd_bus) {
devfn = VTD_SID_TO_DEVFN(source_id);
- for (devfn_it = 0; devfn_it < X86_IOMMU_PCI_DEVFN_MAX; ++devfn_it) {
+ for (devfn_it = 0; devfn_it < PCI_DEVFN_MAX; ++devfn_it) {
vtd_as = vtd_bus->dev_as[devfn_it];
if (vtd_as && ((devfn_it & mask) == (devfn & mask))) {
trace_vtd_inv_desc_cc_device(bus_n, VTD_PCI_SLOT(devfn_it),
@@ -2327,7 +2327,7 @@ static void vtd_iommu_notify_flag_changed(IOMMUMemoryRegion *iommu,
IntelIOMMUNotifierNode *next_node = NULL;
if (!s->caching_mode && new & IOMMU_NOTIFIER_MAP) {
- error_report("We need to set cache_mode=1 for intel-iommu to enable "
+ error_report("We need to set caching-mode=1 for intel-iommu to enable "
"device assignment with IOMMU protection.");
exit(1);
}
@@ -2699,7 +2699,7 @@ VTDAddressSpace *vtd_find_add_as(IntelIOMMUState *s, PCIBus *bus, int devfn)
*new_key = (uintptr_t)bus;
/* No corresponding free() */
vtd_bus = g_malloc0(sizeof(VTDBus) + sizeof(VTDAddressSpace *) * \
- X86_IOMMU_PCI_DEVFN_MAX);
+ PCI_DEVFN_MAX);
vtd_bus->bus = bus;
g_hash_table_insert(s->vtd_as_by_busptr, new_key, vtd_bus);
}
@@ -2982,7 +2982,7 @@ static AddressSpace *vtd_host_dma_iommu(PCIBus *bus, void *opaque, int devfn)
IntelIOMMUState *s = opaque;
VTDAddressSpace *vtd_as;
- assert(0 <= devfn && devfn < X86_IOMMU_PCI_DEVFN_MAX);
+ assert(0 <= devfn && devfn < PCI_DEVFN_MAX);
vtd_as = vtd_find_add_as(s, bus, devfn);
return &vtd_as->as;
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 5e47528993..2febd0e136 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -394,7 +394,7 @@ static void pc_xen_hvm_init_pci(MachineState *machine)
static void pc_xen_hvm_init(MachineState *machine)
{
- PCIBus *bus;
+ PCMachineState *pcms = PC_MACHINE(machine);
if (!xen_enabled()) {
error_report("xenfv machine requires the xen accelerator");
@@ -402,11 +402,7 @@ static void pc_xen_hvm_init(MachineState *machine)
}
pc_xen_hvm_init_pci(machine);
-
- bus = pci_find_primary_bus();
- if (bus != NULL) {
- pci_create_simple(bus, -1, "xen-platform");
- }
+ pci_create_simple(pcms->bus, -1, "xen-platform");
}
#endif
diff --git a/hw/i386/xen/xen_platform.c b/hw/i386/xen/xen_platform.c
index fc8623c90b..deb7a0c374 100644
--- a/hw/i386/xen/xen_platform.c
+++ b/hw/i386/xen/xen_platform.c
@@ -185,11 +185,11 @@ static void platform_fixed_ioport_writew(void *opaque, uint32_t addr, uint32_t v
if (val & (UNPLUG_IDE_SCSI_DISKS | UNPLUG_AUX_IDE_DISKS |
UNPLUG_NVME_DISKS)) {
DPRINTF("unplug disks\n");
- pci_unplug_disks(pci_dev->bus, val);
+ pci_unplug_disks(pci_get_bus(pci_dev), val);
}
if (val & UNPLUG_ALL_NICS) {
DPRINTF("unplug nics\n");
- pci_unplug_nics(pci_dev->bus);
+ pci_unplug_nics(pci_get_bus(pci_dev));
}
break;
}
@@ -371,17 +371,17 @@ static void xen_platform_ioport_writeb(void *opaque, hwaddr addr,
* If VMDP was to control both disk and LAN it would use 4.
* If it controlled just disk or just LAN, it would use 8 below.
*/
- pci_unplug_disks(pci_dev->bus, UNPLUG_IDE_SCSI_DISKS);
- pci_unplug_nics(pci_dev->bus);
+ pci_unplug_disks(pci_get_bus(pci_dev), UNPLUG_IDE_SCSI_DISKS);
+ pci_unplug_nics(pci_get_bus(pci_dev));
}
break;
case 8:
switch (val) {
case 1:
- pci_unplug_disks(pci_dev->bus, UNPLUG_IDE_SCSI_DISKS);
+ pci_unplug_disks(pci_get_bus(pci_dev), UNPLUG_IDE_SCSI_DISKS);
break;
case 2:
- pci_unplug_nics(pci_dev->bus);
+ pci_unplug_nics(pci_get_bus(pci_dev));
break;
default:
log_writeb(s, (uint32_t)val);
diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c
index ec3c9f7d0b..adcf077fa5 100644
--- a/hw/isa/lpc_ich9.c
+++ b/hw/isa/lpc_ich9.c
@@ -162,7 +162,7 @@ static void ich9_cc_write(void *opaque, hwaddr addr,
ich9_cc_addr_len(&addr, &len);
memcpy(lpc->chip_config + addr, &val, len);
- pci_bus_fire_intx_routing_notifier(lpc->d.bus);
+ pci_bus_fire_intx_routing_notifier(pci_get_bus(&lpc->d));
ich9_cc_update(lpc);
}
@@ -218,7 +218,7 @@ static void ich9_lpc_update_pic(ICH9LPCState *lpc, int gsi)
int tmp_dis;
ich9_lpc_pic_irq(lpc, i, &tmp_irq, &tmp_dis);
if (!tmp_dis && tmp_irq == gsi) {
- pic_level |= pci_bus_get_irq_level(lpc->d.bus, i);
+ pic_level |= pci_bus_get_irq_level(pci_get_bus(&lpc->d), i);
}
}
if (gsi == lpc->sci_gsi) {
@@ -246,7 +246,7 @@ static void ich9_lpc_update_apic(ICH9LPCState *lpc, int gsi)
assert(gsi >= ICH9_LPC_PIC_NUM_PINS);
- level |= pci_bus_get_irq_level(lpc->d.bus, ich9_gsi_to_pirq(gsi));
+ level |= pci_bus_get_irq_level(pci_get_bus(&lpc->d), ich9_gsi_to_pirq(gsi));
if (gsi == lpc->sci_gsi) {
level |= lpc->sci_level;
}
@@ -524,10 +524,10 @@ static void ich9_lpc_config_write(PCIDevice *d,
ich9_lpc_rcba_update(lpc, rcba_old);
}
if (ranges_overlap(addr, len, ICH9_LPC_PIRQA_ROUT, 4)) {
- pci_bus_fire_intx_routing_notifier(lpc->d.bus);
+ pci_bus_fire_intx_routing_notifier(pci_get_bus(&lpc->d));
}
if (ranges_overlap(addr, len, ICH9_LPC_PIRQE_ROUT, 4)) {
- pci_bus_fire_intx_routing_notifier(lpc->d.bus);
+ pci_bus_fire_intx_routing_notifier(pci_get_bus(&lpc->d));
}
if (ranges_overlap(addr, len, ICH9_LPC_GEN_PMCON_1, 8)) {
ich9_lpc_pmcon_update(lpc);
diff --git a/hw/mips/gt64xxx_pci.c b/hw/mips/gt64xxx_pci.c
index 5a9dad9aae..a9c222a967 100644
--- a/hw/mips/gt64xxx_pci.c
+++ b/hw/mips/gt64xxx_pci.c
@@ -1171,12 +1171,12 @@ PCIBus *gt64120_register(qemu_irq *pic)
phb = PCI_HOST_BRIDGE(dev);
memory_region_init(&d->pci0_mem, OBJECT(dev), "pci0-mem", UINT32_MAX);
address_space_init(&d->pci0_mem_as, &d->pci0_mem, "pci0-mem");
- phb->bus = pci_register_bus(dev, "pci",
- gt64120_pci_set_irq, gt64120_pci_map_irq,
- pic,
- &d->pci0_mem,
- get_system_io(),
- PCI_DEVFN(18, 0), 4, TYPE_PCI_BUS);
+ phb->bus = pci_register_root_bus(dev, "pci",
+ gt64120_pci_set_irq, gt64120_pci_map_irq,
+ pic,
+ &d->pci0_mem,
+ get_system_io(),
+ PCI_DEVFN(18, 0), 4, TYPE_PCI_BUS);
qdev_init_nofail(dev);
memory_region_init_io(&d->ISD_mem, OBJECT(dev), &isd_mem_ops, d, "isd-mem", 0x1000);
diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c
index b8404cb2e2..0654d594c1 100644
--- a/hw/net/vmxnet3.c
+++ b/hw/net/vmxnet3.c
@@ -2356,7 +2356,7 @@ static void vmxnet3_pci_realize(PCIDevice *pci_dev, Error **errp)
vmxnet3_net_init(s);
if (pci_is_express(pci_dev)) {
- if (pci_bus_is_express(pci_dev->bus)) {
+ if (pci_bus_is_express(pci_get_bus(pci_dev))) {
pcie_endpoint_cap_init(pci_dev, VMXNET3_EXP_EP_OFFSET);
}
diff --git a/hw/pci-bridge/pci_expander_bridge.c b/hw/pci-bridge/pci_expander_bridge.c
index 9e799dc10f..e62de4218f 100644
--- a/hw/pci-bridge/pci_expander_bridge.c
+++ b/hw/pci-bridge/pci_expander_bridge.c
@@ -51,7 +51,8 @@ typedef struct PXBDev {
static PXBDev *convert_to_pxb(PCIDevice *dev)
{
- return pci_bus_is_express(dev->bus) ? PXB_PCIE_DEV(dev) : PXB_DEV(dev);
+ return pci_bus_is_express(pci_get_bus(dev))
+ ? PXB_PCIE_DEV(dev) : PXB_DEV(dev);
}
static GList *pxb_dev_list;
@@ -165,7 +166,7 @@ static const TypeInfo pxb_host_info = {
*/
static void pxb_register_bus(PCIDevice *dev, PCIBus *pxb_bus, Error **errp)
{
- PCIBus *bus = dev->bus;
+ PCIBus *bus = pci_get_bus(dev);
int pxb_bus_num = pci_bus_num(pxb_bus);
if (bus->parent_dev) {
@@ -179,12 +180,12 @@ static void pxb_register_bus(PCIDevice *dev, PCIBus *pxb_bus, Error **errp)
return;
}
}
- QLIST_INSERT_HEAD(&dev->bus->child, pxb_bus, sibling);
+ QLIST_INSERT_HEAD(&pci_get_bus(dev)->child, pxb_bus, sibling);
}
static int pxb_map_irq_fn(PCIDevice *pci_dev, int pin)
{
- PCIDevice *pxb = pci_dev->bus->parent_dev;
+ PCIDevice *pxb = pci_get_bus(pci_dev)->parent_dev;
/*
* The bios does not index the pxb slot number when
@@ -229,9 +230,9 @@ static void pxb_dev_realize_common(PCIDevice *dev, bool pcie, Error **errp)
ds = qdev_create(NULL, TYPE_PXB_HOST);
if (pcie) {
- bus = pci_bus_new(ds, dev_name, NULL, NULL, 0, TYPE_PXB_PCIE_BUS);
+ bus = pci_root_bus_new(ds, dev_name, NULL, NULL, 0, TYPE_PXB_PCIE_BUS);
} else {
- bus = pci_bus_new(ds, "pxb-internal", NULL, NULL, 0, TYPE_PXB_BUS);
+ bus = pci_root_bus_new(ds, "pxb-internal", NULL, NULL, 0, TYPE_PXB_BUS);
bds = qdev_create(BUS(bus), "pci-bridge");
bds->id = dev_name;
qdev_prop_set_uint8(bds, PCI_BRIDGE_DEV_PROP_CHASSIS_NR, pxb->bus_nr);
@@ -239,8 +240,8 @@ static void pxb_dev_realize_common(PCIDevice *dev, bool pcie, Error **errp)
}
bus->parent_dev = dev;
- bus->address_space_mem = dev->bus->address_space_mem;
- bus->address_space_io = dev->bus->address_space_io;
+ bus->address_space_mem = pci_get_bus(dev)->address_space_mem;
+ bus->address_space_io = pci_get_bus(dev)->address_space_io;
bus->map_irq = pxb_map_irq_fn;
PCI_HOST_BRIDGE(ds)->bus = bus;
@@ -271,7 +272,7 @@ err_register_bus:
static void pxb_dev_realize(PCIDevice *dev, Error **errp)
{
- if (pci_bus_is_express(dev->bus)) {
+ if (pci_bus_is_express(pci_get_bus(dev))) {
error_setg(errp, "pxb devices cannot reside on a PCIe bus");
return;
}
@@ -323,7 +324,7 @@ static const TypeInfo pxb_dev_info = {
static void pxb_pcie_dev_realize(PCIDevice *dev, Error **errp)
{
- if (!pci_bus_is_express(dev->bus)) {
+ if (!pci_bus_is_express(pci_get_bus(dev))) {
error_setg(errp, "pxb-pcie devices cannot reside on a PCI bus");
return;
}
diff --git a/hw/pci-host/apb.c b/hw/pci-host/apb.c
index 3e796fb6fc..ec676f94b6 100644
--- a/hw/pci-host/apb.c
+++ b/hw/pci-host/apb.c
@@ -433,11 +433,11 @@ static void pci_pbm_realize(DeviceState *dev, Error **errp)
memory_region_add_subregion(get_system_memory(), s->mem_base,
&s->pci_mmio);
- phb->bus = pci_register_bus(dev, "pci",
- pci_apb_set_irq, pci_apb_map_irq, s,
- &s->pci_mmio,
- &s->pci_ioport,
- 0, 32, TYPE_PCI_BUS);
+ phb->bus = pci_register_root_bus(dev, "pci",
+ pci_apb_set_irq, pci_apb_map_irq, s,
+ &s->pci_mmio,
+ &s->pci_ioport,
+ 0, 32, TYPE_PCI_BUS);
pci_create_simple(phb->bus, 0, "pbm-pci");
diff --git a/hw/pci-host/bonito.c b/hw/pci-host/bonito.c
index 9f61e27edc..f08593feab 100644
--- a/hw/pci-host/bonito.c
+++ b/hw/pci-host/bonito.c
@@ -714,10 +714,10 @@ static int bonito_pcihost_initfn(SysBusDevice *dev)
{
PCIHostState *phb = PCI_HOST_BRIDGE(dev);
- phb->bus = pci_register_bus(DEVICE(dev), "pci",
- pci_bonito_set_irq, pci_bonito_map_irq, dev,
- get_system_memory(), get_system_io(),
- 0x28, 32, TYPE_PCI_BUS);
+ phb->bus = pci_register_root_bus(DEVICE(dev), "pci",
+ pci_bonito_set_irq, pci_bonito_map_irq,
+ dev, get_system_memory(), get_system_io(),
+ 0x28, 32, TYPE_PCI_BUS);
return 0;
}
diff --git a/hw/pci-host/gpex.c b/hw/pci-host/gpex.c
index edf305b1fd..2583b151a4 100644
--- a/hw/pci-host/gpex.c
+++ b/hw/pci-host/gpex.c
@@ -89,9 +89,9 @@ static void gpex_host_realize(DeviceState *dev, Error **errp)
s->irq_num[i] = -1;
}
- pci->bus = pci_register_bus(dev, "pcie.0", gpex_set_irq,
- pci_swizzle_map_irq_fn, s, &s->io_mmio,
- &s->io_ioport, 0, 4, TYPE_PCIE_BUS);
+ pci->bus = pci_register_root_bus(dev, "pcie.0", gpex_set_irq,
+ pci_swizzle_map_irq_fn, s, &s->io_mmio,
+ &s->io_ioport, 0, 4, TYPE_PCIE_BUS);
qdev_set_parent_bus(DEVICE(&s->gpex_root), BUS(pci->bus));
pci_bus_set_route_irq_fn(pci->bus, gpex_route_intx_pin_to_irq);
diff --git a/hw/pci-host/grackle.c b/hw/pci-host/grackle.c
index 38cd279b6b..3caf1ccb37 100644
--- a/hw/pci-host/grackle.c
+++ b/hw/pci-host/grackle.c
@@ -82,13 +82,13 @@ PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic,
memory_region_add_subregion(address_space_mem, 0x80000000ULL,
&d->pci_hole);
- phb->bus = pci_register_bus(dev, NULL,
- pci_grackle_set_irq,
- pci_grackle_map_irq,
- pic,
- &d->pci_mmio,
- address_space_io,
- 0, 4, TYPE_PCI_BUS);
+ phb->bus = pci_register_root_bus(dev, NULL,
+ pci_grackle_set_irq,
+ pci_grackle_map_irq,
+ pic,
+ &d->pci_mmio,
+ address_space_io,
+ 0, 4, TYPE_PCI_BUS);
pci_create_simple(phb->bus, 0, "grackle");
qdev_init_nofail(dev);
diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
index a684a7cca9..0e608347c1 100644
--- a/hw/pci-host/piix.c
+++ b/hw/pci-host/piix.c
@@ -361,8 +361,8 @@ PCIBus *i440fx_init(const char *host_type, const char *pci_type,
dev = qdev_create(NULL, host_type);
s = PCI_HOST_BRIDGE(dev);
- b = pci_bus_new(dev, NULL, pci_address_space,
- address_space_io, 0, TYPE_PCI_BUS);
+ b = pci_root_bus_new(dev, NULL, pci_address_space,
+ address_space_io, 0, TYPE_PCI_BUS);
s->bus = b;
object_property_add_child(qdev_get_machine(), "i440fx", OBJECT(dev), NULL);
qdev_init_nofail(dev);
@@ -512,12 +512,12 @@ static PCIINTxRoute piix3_route_intx_pin_to_irq(void *opaque, int pin)
/* irq routing is changed. so rebuild bitmap */
static void piix3_update_irq_levels(PIIX3State *piix3)
{
+ PCIBus *bus = pci_get_bus(&piix3->dev);
int pirq;
piix3->pic_levels = 0;
for (pirq = 0; pirq < PIIX_NUM_PIRQS; pirq++) {
- piix3_set_irq_level(piix3, pirq,
- pci_bus_get_irq_level(piix3->dev.bus, pirq));
+ piix3_set_irq_level(piix3, pirq, pci_bus_get_irq_level(bus, pirq));
}
}
@@ -529,7 +529,7 @@ static void piix3_write_config(PCIDevice *dev,
PIIX3State *piix3 = PIIX3_PCI_DEVICE(dev);
int pic_irq;
- pci_bus_fire_intx_routing_notifier(piix3->dev.bus);
+ pci_bus_fire_intx_routing_notifier(pci_get_bus(&piix3->dev));
piix3_update_irq_levels(piix3);
for (pic_irq = 0; pic_irq < PIIX_NUM_PIC_IRQS; pic_irq++) {
piix3_set_irq_pic(piix3, pic_irq);
@@ -601,7 +601,7 @@ static int piix3_post_load(void *opaque, int version_id)
piix3->pic_levels = 0;
for (pirq = 0; pirq < PIIX_NUM_PIRQS; pirq++) {
piix3_set_irq_level_internal(piix3, pirq,
- pci_bus_get_irq_level(piix3->dev.bus, pirq));
+ pci_bus_get_irq_level(pci_get_bus(&piix3->dev), pirq));
}
return 0;
}
@@ -613,7 +613,7 @@ static int piix3_pre_save(void *opaque)
for (i = 0; i < ARRAY_SIZE(piix3->pci_irq_levels_vmstate); i++) {
piix3->pci_irq_levels_vmstate[i] =
- pci_bus_get_irq_level(piix3->dev.bus, i);
+ pci_bus_get_irq_level(pci_get_bus(&piix3->dev), i);
}
return 0;
@@ -804,60 +804,55 @@ static const IGDHostInfo igd_host_bridge_infos[] = {
{0xa8, 4}, /* SNB: base of GTT stolen memory */
};
-static int host_pci_config_read(int pos, int len, uint32_t *val)
+static void host_pci_config_read(int pos, int len, uint32_t *val, Error **errp)
{
- char path[PATH_MAX];
- int config_fd;
- ssize_t size = sizeof(path);
+ int rc, config_fd;
/* Access real host bridge. */
- int rc = snprintf(path, size, "/sys/bus/pci/devices/%04x:%02x:%02x.%d/%s",
- 0, 0, 0, 0, "config");
- int ret = 0;
-
- if (rc >= size || rc < 0) {
- return -ENODEV;
- }
+ char *path = g_strdup_printf("/sys/bus/pci/devices/%04x:%02x:%02x.%d/%s",
+ 0, 0, 0, 0, "config");
config_fd = open(path, O_RDWR);
if (config_fd < 0) {
- return -ENODEV;
+ error_setg_errno(errp, errno, "Failed to open: %s", path);
+ goto out;
}
if (lseek(config_fd, pos, SEEK_SET) != pos) {
- ret = -errno;
- goto out;
+ error_setg_errno(errp, errno, "Failed to seek: %s", path);
+ goto out_close_fd;
}
do {
rc = read(config_fd, (uint8_t *)val, len);
} while (rc < 0 && (errno == EINTR || errno == EAGAIN));
if (rc != len) {
- ret = -errno;
+ error_setg_errno(errp, errno, "Failed to read: %s", path);
}
-out:
+out_close_fd:
close(config_fd);
- return ret;
+out:
+ g_free(path);
}
-static int igd_pt_i440fx_initfn(struct PCIDevice *pci_dev)
+static void igd_pt_i440fx_realize(PCIDevice *pci_dev, Error **errp)
{
uint32_t val = 0;
- int rc, i, num;
+ int i, num;
int pos, len;
+ Error *local_err = NULL;
num = ARRAY_SIZE(igd_host_bridge_infos);
for (i = 0; i < num; i++) {
pos = igd_host_bridge_infos[i].offset;
len = igd_host_bridge_infos[i].len;
- rc = host_pci_config_read(pos, len, &val);
- if (rc) {
- return -ENODEV;
+ host_pci_config_read(pos, len, &val, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
}
pci_default_write_config(pci_dev, pos, val, len);
}
-
- return 0;
}
static void igd_passthrough_i440fx_class_init(ObjectClass *klass, void *data)
@@ -865,7 +860,7 @@ static void igd_passthrough_i440fx_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
- k->init = igd_pt_i440fx_initfn;
+ k->realize = igd_pt_i440fx_realize;
dc->desc = "IGD Passthrough Host bridge";
}
diff --git a/hw/pci-host/ppce500.c b/hw/pci-host/ppce500.c
index 279badc894..eb75e080fc 100644
--- a/hw/pci-host/ppce500.c
+++ b/hw/pci-host/ppce500.c
@@ -460,9 +460,9 @@ static int e500_pcihost_initfn(SysBusDevice *dev)
/* PIO lives at the bottom of our bus space */
memory_region_add_subregion_overlap(&s->busmem, 0, &s->pio, -2);
- b = pci_register_bus(DEVICE(dev), NULL, mpc85xx_pci_set_irq,
- mpc85xx_pci_map_irq, s, &s->busmem, &s->pio,
- PCI_DEVFN(s->first_slot, 0), 4, TYPE_PCI_BUS);
+ b = pci_register_root_bus(DEVICE(dev), NULL, mpc85xx_pci_set_irq,
+ mpc85xx_pci_map_irq, s, &s->busmem, &s->pio,
+ PCI_DEVFN(s->first_slot, 0), 4, TYPE_PCI_BUS);
h->bus = b;
/* Set up PCI view of memory */
diff --git a/hw/pci-host/prep.c b/hw/pci-host/prep.c
index 92eed0f3e1..01f67f9db1 100644
--- a/hw/pci-host/prep.c
+++ b/hw/pci-host/prep.c
@@ -269,8 +269,8 @@ static void raven_pcihost_initfn(Object *obj)
memory_region_add_subregion_overlap(address_space_mem, 0x80000000,
&s->pci_io_non_contiguous, 1);
memory_region_add_subregion(address_space_mem, 0xc0000000, &s->pci_memory);
- pci_bus_new_inplace(&s->pci_bus, sizeof(s->pci_bus), DEVICE(obj), NULL,
- &s->pci_memory, &s->pci_io, 0, TYPE_PCI_BUS);
+ pci_root_bus_new_inplace(&s->pci_bus, sizeof(s->pci_bus), DEVICE(obj), NULL,
+ &s->pci_memory, &s->pci_io, 0, TYPE_PCI_BUS);
/* Bus master address space */
memory_region_init(&s->bm, obj, "bm-raven", UINT32_MAX);
diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
index 6cb9a8d121..a36a1195e4 100644
--- a/hw/pci-host/q35.c
+++ b/hw/pci-host/q35.c
@@ -51,9 +51,10 @@ static void q35_host_realize(DeviceState *dev, Error **errp)
sysbus_add_io(sbd, MCH_HOST_BRIDGE_CONFIG_DATA, &pci->data_mem);
sysbus_init_ioports(sbd, MCH_HOST_BRIDGE_CONFIG_DATA, 4);
- pci->bus = pci_bus_new(DEVICE(s), "pcie.0",
- s->mch.pci_address_space, s->mch.address_space_io,
- 0, TYPE_PCIE_BUS);
+ pci->bus = pci_root_bus_new(DEVICE(s), "pcie.0",
+ s->mch.pci_address_space,
+ s->mch.address_space_io,
+ 0, TYPE_PCIE_BUS);
PC_MACHINE(qdev_get_machine())->bus = pci->bus;
qdev_set_parent_bus(DEVICE(&s->mch), BUS(pci->bus));
qdev_init_nofail(DEVICE(&s->mch));
diff --git a/hw/pci-host/uninorth.c b/hw/pci-host/uninorth.c
index ea5c265718..5d8ccaa711 100644
--- a/hw/pci-host/uninorth.c
+++ b/hw/pci-host/uninorth.c
@@ -233,12 +233,12 @@ PCIBus *pci_pmac_init(qemu_irq *pic,
memory_region_add_subregion(address_space_mem, 0x80000000ULL,
&d->pci_hole);
- h->bus = pci_register_bus(dev, NULL,
- pci_unin_set_irq, pci_unin_map_irq,
- pic,
- &d->pci_mmio,
- address_space_io,
- PCI_DEVFN(11, 0), 4, TYPE_PCI_BUS);
+ h->bus = pci_register_root_bus(dev, NULL,
+ pci_unin_set_irq, pci_unin_map_irq,
+ pic,
+ &d->pci_mmio,
+ address_space_io,
+ PCI_DEVFN(11, 0), 4, TYPE_PCI_BUS);
#if 0
pci_create_simple(h->bus, PCI_DEVFN(11, 0), "uni-north");
@@ -299,12 +299,12 @@ PCIBus *pci_pmac_u3_init(qemu_irq *pic,
memory_region_add_subregion(address_space_mem, 0x80000000ULL,
&d->pci_hole);
- h->bus = pci_register_bus(dev, NULL,
- pci_unin_set_irq, pci_unin_map_irq,
- pic,
- &d->pci_mmio,
- address_space_io,
- PCI_DEVFN(11, 0), 4, TYPE_PCI_BUS);
+ h->bus = pci_register_root_bus(dev, NULL,
+ pci_unin_set_irq, pci_unin_map_irq,
+ pic,
+ &d->pci_mmio,
+ address_space_io,
+ PCI_DEVFN(11, 0), 4, TYPE_PCI_BUS);
sysbus_mmio_map(s, 0, 0xf0800000);
sysbus_mmio_map(s, 1, 0xf0c00000);
diff --git a/hw/pci-host/versatile.c b/hw/pci-host/versatile.c
index 6394a520fc..d0b02bdc47 100644
--- a/hw/pci-host/versatile.c
+++ b/hw/pci-host/versatile.c
@@ -311,7 +311,7 @@ static const MemoryRegionOps pci_vpb_config_ops = {
static int pci_vpb_map_irq(PCIDevice *d, int irq_num)
{
- PCIVPBState *s = container_of(d->bus, PCIVPBState, pci_bus);
+ PCIVPBState *s = container_of(pci_get_bus(d), PCIVPBState, pci_bus);
if (s->irq_mapping == PCI_VPB_IRQMAP_BROKEN) {
/* Legacy broken IRQ mapping for compatibility with old and
@@ -399,9 +399,9 @@ static void pci_vpb_realize(DeviceState *dev, Error **errp)
memory_region_init(&s->pci_io_space, OBJECT(s), "pci_io", 1ULL << 32);
memory_region_init(&s->pci_mem_space, OBJECT(s), "pci_mem", 1ULL << 32);
- pci_bus_new_inplace(&s->pci_bus, sizeof(s->pci_bus), dev, "pci",
- &s->pci_mem_space, &s->pci_io_space,
- PCI_DEVFN(11, 0), TYPE_PCI_BUS);
+ pci_root_bus_new_inplace(&s->pci_bus, sizeof(s->pci_bus), dev, "pci",
+ &s->pci_mem_space, &s->pci_io_space,
+ PCI_DEVFN(11, 0), TYPE_PCI_BUS);
h->bus = &s->pci_bus;
object_initialize(&s->pci_dev, sizeof(s->pci_dev), TYPE_VERSATILE_PCI_HOST);
diff --git a/hw/pci-host/xilinx-pcie.c b/hw/pci-host/xilinx-pcie.c
index 7659253090..53b561f81f 100644
--- a/hw/pci-host/xilinx-pcie.c
+++ b/hw/pci-host/xilinx-pcie.c
@@ -18,6 +18,7 @@
*/
#include "qemu/osdep.h"
+#include "qapi/error.h"
#include "hw/pci/pci_bridge.h"
#include "hw/pci-host/xilinx-pcie.h"
@@ -129,9 +130,9 @@ static void xilinx_pcie_host_realize(DeviceState *dev, Error **errp)
sysbus_init_mmio(sbd, &pex->mmio);
sysbus_init_mmio(sbd, &s->mmio);
- pci->bus = pci_register_bus(dev, s->name, xilinx_pcie_set_irq,
- pci_swizzle_map_irq_fn, s, &s->mmio,
- &s->io, 0, 4, TYPE_PCIE_BUS);
+ pci->bus = pci_register_root_bus(dev, s->name, xilinx_pcie_set_irq,
+ pci_swizzle_map_irq_fn, s, &s->mmio,
+ &s->io, 0, 4, TYPE_PCIE_BUS);
qdev_set_parent_bus(DEVICE(&s->root), BUS(pci->bus));
qdev_init_nofail(DEVICE(&s->root));
@@ -267,24 +268,22 @@ static void xilinx_pcie_root_config_write(PCIDevice *d, uint32_t address,
}
}
-static int xilinx_pcie_root_init(PCIDevice *dev)
+static void xilinx_pcie_root_realize(PCIDevice *pci_dev, Error **errp)
{
- BusState *bus = qdev_get_parent_bus(DEVICE(dev));
+ BusState *bus = qdev_get_parent_bus(DEVICE(pci_dev));
XilinxPCIEHost *s = XILINX_PCIE_HOST(bus->parent);
- pci_set_word(dev->config + PCI_COMMAND,
+ pci_set_word(pci_dev->config + PCI_COMMAND,
PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
- pci_set_word(dev->config + PCI_MEMORY_BASE, s->mmio_base >> 16);
- pci_set_word(dev->config + PCI_MEMORY_LIMIT,
+ pci_set_word(pci_dev->config + PCI_MEMORY_BASE, s->mmio_base >> 16);
+ pci_set_word(pci_dev->config + PCI_MEMORY_LIMIT,
((s->mmio_base + s->mmio_size - 1) >> 16) & 0xfff0);
- pci_bridge_initfn(dev, TYPE_PCI_BUS);
+ pci_bridge_initfn(pci_dev, TYPE_PCI_BUS);
- if (pcie_endpoint_cap_v1_init(dev, 0x80) < 0) {
- hw_error("Failed to initialize PCIe capability");
+ if (pcie_endpoint_cap_v1_init(pci_dev, 0x80) < 0) {
+ error_setg(errp, "Failed to initialize PCIe capability");
}
-
- return 0;
}
static void xilinx_pcie_root_class_init(ObjectClass *klass, void *data)
@@ -300,7 +299,7 @@ static void xilinx_pcie_root_class_init(ObjectClass *klass, void *data)
k->class_id = PCI_CLASS_BRIDGE_HOST;
k->is_express = true;
k->is_bridge = true;
- k->init = xilinx_pcie_root_init;
+ k->realize = xilinx_pcie_root_realize;
k->exit = pci_bridge_exitfn;
dc->reset = pci_bridge_reset;
k->config_read = xilinx_pcie_root_config_read;
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index b2d139bd9a..e8f9fc1c27 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -222,7 +222,7 @@ static void pci_change_irq_level(PCIDevice *pci_dev, int irq_num, int change)
{
PCIBus *bus;
for (;;) {
- bus = pci_dev->bus;
+ bus = pci_get_bus(pci_dev);
irq_num = bus->map_irq(pci_dev, irq_num);
if (bus->set_irq)
break;
@@ -331,31 +331,15 @@ static void pci_host_bus_register(DeviceState *host)
QLIST_INSERT_HEAD(&pci_host_bridges, host_bridge, next);
}
-PCIBus *pci_find_primary_bus(void)
-{
- PCIBus *primary_bus = NULL;
- PCIHostState *host;
-
- QLIST_FOREACH(host, &pci_host_bridges, next) {
- if (primary_bus) {
- /* We have multiple root buses, refuse to select a primary */
- return NULL;
- }
- primary_bus = host->bus;
- }
-
- return primary_bus;
-}
-
PCIBus *pci_device_root_bus(const PCIDevice *d)
{
- PCIBus *bus = d->bus;
+ PCIBus *bus = pci_get_bus(d);
while (!pci_bus_is_root(bus)) {
d = bus->parent_dev;
assert(d != NULL);
- bus = d->bus;
+ bus = pci_get_bus(d);
}
return bus;
@@ -376,10 +360,10 @@ const char *pci_root_bus_path(PCIDevice *dev)
return rootbus->qbus.name;
}
-static void pci_bus_init(PCIBus *bus, DeviceState *parent,
- MemoryRegion *address_space_mem,
- MemoryRegion *address_space_io,
- uint8_t devfn_min)
+static void pci_root_bus_init(PCIBus *bus, DeviceState *parent,
+ MemoryRegion *address_space_mem,
+ MemoryRegion *address_space_io,
+ uint8_t devfn_min)
{
assert(PCI_FUNC(devfn_min) == 0);
bus->devfn_min = devfn_min;
@@ -403,25 +387,27 @@ bool pci_bus_is_root(PCIBus *bus)
return PCI_BUS_GET_CLASS(bus)->is_root(bus);
}
-void pci_bus_new_inplace(PCIBus *bus, size_t bus_size, DeviceState *parent,
- const char *name,
- MemoryRegion *address_space_mem,
- MemoryRegion *address_space_io,
- uint8_t devfn_min, const char *typename)
+void pci_root_bus_new_inplace(PCIBus *bus, size_t bus_size, DeviceState *parent,
+ const char *name,
+ MemoryRegion *address_space_mem,
+ MemoryRegion *address_space_io,
+ uint8_t devfn_min, const char *typename)
{
qbus_create_inplace(bus, bus_size, typename, parent, name);
- pci_bus_init(bus, parent, address_space_mem, address_space_io, devfn_min);
+ pci_root_bus_init(bus, parent, address_space_mem, address_space_io,
+ devfn_min);
}
-PCIBus *pci_bus_new(DeviceState *parent, const char *name,
- MemoryRegion *address_space_mem,
- MemoryRegion *address_space_io,
- uint8_t devfn_min, const char *typename)
+PCIBus *pci_root_bus_new(DeviceState *parent, const char *name,
+ MemoryRegion *address_space_mem,
+ MemoryRegion *address_space_io,
+ uint8_t devfn_min, const char *typename)
{
PCIBus *bus;
bus = PCI_BUS(qbus_create(typename, parent, name));
- pci_bus_init(bus, parent, address_space_mem, address_space_io, devfn_min);
+ pci_root_bus_init(bus, parent, address_space_mem, address_space_io,
+ devfn_min);
return bus;
}
@@ -435,17 +421,18 @@ void pci_bus_irqs(PCIBus *bus, pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
bus->irq_count = g_malloc0(nirq * sizeof(bus->irq_count[0]));
}
-PCIBus *pci_register_bus(DeviceState *parent, const char *name,
- pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
- void *irq_opaque,
- MemoryRegion *address_space_mem,
- MemoryRegion *address_space_io,
- uint8_t devfn_min, int nirq, const char *typename)
+PCIBus *pci_register_root_bus(DeviceState *parent, const char *name,
+ pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
+ void *irq_opaque,
+ MemoryRegion *address_space_mem,
+ MemoryRegion *address_space_io,
+ uint8_t devfn_min, int nirq,
+ const char *typename)
{
PCIBus *bus;
- bus = pci_bus_new(parent, name, address_space_mem,
- address_space_io, devfn_min, typename);
+ bus = pci_root_bus_new(parent, name, address_space_mem,
+ address_space_io, devfn_min, typename);
pci_bus_irqs(bus, set_irq, map_irq, irq_opaque, nirq);
return bus;
}
@@ -879,7 +866,7 @@ static void pci_config_free(PCIDevice *pci_dev)
static void do_pci_unregister_device(PCIDevice *pci_dev)
{
- pci_dev->bus->devices[pci_dev->devfn] = NULL;
+ pci_get_bus(pci_dev)->devices[pci_dev->devfn] = NULL;
pci_config_free(pci_dev);
if (memory_region_is_mapped(&pci_dev->bus_master_enable_region)) {
@@ -900,7 +887,7 @@ static uint16_t pci_req_id_cache_extract(PCIReqIDCache *cache)
result = pci_get_bdf(cache->dev);
break;
case PCI_REQ_ID_SECONDARY_BUS:
- bus_n = pci_bus_num(cache->dev->bus);
+ bus_n = pci_dev_bus_num(cache->dev);
result = PCI_BUILD_BDF(bus_n, 0);
break;
default:
@@ -930,9 +917,9 @@ static PCIReqIDCache pci_req_id_cache_get(PCIDevice *dev)
.type = PCI_REQ_ID_BDF,
};
- while (!pci_bus_is_root(dev->bus)) {
+ while (!pci_bus_is_root(pci_get_bus(dev))) {
/* We are under PCI/PCIe bridges */
- parent = dev->bus->parent_dev;
+ parent = pci_get_bus(dev)->parent_dev;
if (pci_is_express(parent)) {
if (pcie_cap_get_type(parent) == PCI_EXP_TYPE_PCI_BRIDGE) {
/* When we pass through PCIe-to-PCI/PCIX bridges, we
@@ -975,7 +962,7 @@ static bool pci_bus_devfn_reserved(PCIBus *bus, int devfn)
}
/* -1 for devfn means auto assign */
-static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
+static PCIDevice *do_pci_register_device(PCIDevice *pci_dev,
const char *name, int devfn,
Error **errp)
{
@@ -984,8 +971,8 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
PCIConfigWriteFunc *config_write = pc->config_write;
Error *local_err = NULL;
DeviceState *dev = DEVICE(pci_dev);
+ PCIBus *bus = pci_get_bus(pci_dev);
- pci_dev->bus = bus;
/* Only pci bridges can be attached to extra PCI root buses */
if (pci_bus_is_root(bus) && bus->parent_dev && !pc->is_bridge) {
error_setg(errp,
@@ -1139,8 +1126,8 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num,
r->type = type;
r->memory = memory;
r->address_space = type & PCI_BASE_ADDRESS_SPACE_IO
- ? pci_dev->bus->address_space_io
- : pci_dev->bus->address_space_mem;
+ ? pci_get_bus(pci_dev)->address_space_io
+ : pci_get_bus(pci_dev)->address_space_mem;
wmask = ~(size - 1);
if (region_num == PCI_ROM_SLOT) {
@@ -1182,21 +1169,23 @@ static void pci_update_vga(PCIDevice *pci_dev)
void pci_register_vga(PCIDevice *pci_dev, MemoryRegion *mem,
MemoryRegion *io_lo, MemoryRegion *io_hi)
{
+ PCIBus *bus = pci_get_bus(pci_dev);
+
assert(!pci_dev->has_vga);
assert(memory_region_size(mem) == QEMU_PCI_VGA_MEM_SIZE);
pci_dev->vga_regions[QEMU_PCI_VGA_MEM] = mem;
- memory_region_add_subregion_overlap(pci_dev->bus->address_space_mem,
+ memory_region_add_subregion_overlap(bus->address_space_mem,
QEMU_PCI_VGA_MEM_BASE, mem, 1);
assert(memory_region_size(io_lo) == QEMU_PCI_VGA_IO_LO_SIZE);
pci_dev->vga_regions[QEMU_PCI_VGA_IO_LO] = io_lo;
- memory_region_add_subregion_overlap(pci_dev->bus->address_space_io,
+ memory_region_add_subregion_overlap(bus->address_space_io,
QEMU_PCI_VGA_IO_LO_BASE, io_lo, 1);
assert(memory_region_size(io_hi) == QEMU_PCI_VGA_IO_HI_SIZE);
pci_dev->vga_regions[QEMU_PCI_VGA_IO_HI] = io_hi;
- memory_region_add_subregion_overlap(pci_dev->bus->address_space_io,
+ memory_region_add_subregion_overlap(bus->address_space_io,
QEMU_PCI_VGA_IO_HI_BASE, io_hi, 1);
pci_dev->has_vga = true;
@@ -1205,15 +1194,17 @@ void pci_register_vga(PCIDevice *pci_dev, MemoryRegion *mem,
void pci_unregister_vga(PCIDevice *pci_dev)
{
+ PCIBus *bus = pci_get_bus(pci_dev);
+
if (!pci_dev->has_vga) {
return;
}
- memory_region_del_subregion(pci_dev->bus->address_space_mem,
+ memory_region_del_subregion(bus->address_space_mem,
pci_dev->vga_regions[QEMU_PCI_VGA_MEM]);
- memory_region_del_subregion(pci_dev->bus->address_space_io,
+ memory_region_del_subregion(bus->address_space_io,
pci_dev->vga_regions[QEMU_PCI_VGA_IO_LO]);
- memory_region_del_subregion(pci_dev->bus->address_space_io,
+ memory_region_del_subregion(bus->address_space_io,
pci_dev->vga_regions[QEMU_PCI_VGA_IO_HI]);
pci_dev->has_vga = false;
}
@@ -1316,7 +1307,7 @@ static void pci_update_mappings(PCIDevice *d)
/* now do the real mapping */
if (r->addr != PCI_BAR_UNMAPPED) {
- trace_pci_update_mappings_del(d, pci_bus_num(d->bus),
+ trace_pci_update_mappings_del(d, pci_dev_bus_num(d),
PCI_SLOT(d->devfn),
PCI_FUNC(d->devfn),
i, r->addr, r->size);
@@ -1324,7 +1315,7 @@ static void pci_update_mappings(PCIDevice *d)
}
r->addr = new_addr;
if (r->addr != PCI_BAR_UNMAPPED) {
- trace_pci_update_mappings_add(d, pci_bus_num(d->bus),
+ trace_pci_update_mappings_add(d, pci_dev_bus_num(d),
PCI_SLOT(d->devfn),
PCI_FUNC(d->devfn),
i, r->addr, r->size);
@@ -1443,9 +1434,9 @@ PCIINTxRoute pci_device_route_intx_to_irq(PCIDevice *dev, int pin)
PCIBus *bus;
do {
- bus = dev->bus;
- pin = bus->map_irq(dev, pin);
- dev = bus->parent_dev;
+ bus = pci_get_bus(dev);
+ pin = bus->map_irq(dev, pin);
+ dev = bus->parent_dev;
} while (dev);
if (!bus->route_intx_to_irq) {
@@ -2015,7 +2006,6 @@ static void pci_qdev_realize(DeviceState *qdev, Error **errp)
PCIDevice *pci_dev = (PCIDevice *)qdev;
PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(pci_dev);
Error *local_err = NULL;
- PCIBus *bus;
bool is_default_rom;
/* initialize cap_present for pci_is_express() and pci_config_size() */
@@ -2023,8 +2013,7 @@ static void pci_qdev_realize(DeviceState *qdev, Error **errp)
pci_dev->cap_present |= QEMU_PCI_CAP_EXPRESS;
}
- bus = PCI_BUS(qdev_get_parent_bus(qdev));
- pci_dev = do_pci_register_device(pci_dev, bus,
+ pci_dev = do_pci_register_device(pci_dev,
object_get_typename(OBJECT(qdev)),
pci_dev->devfn, errp);
if (pci_dev == NULL)
@@ -2317,7 +2306,7 @@ int pci_add_capability(PCIDevice *pdev, uint8_t cap_id,
error_setg(errp, "%s:%02x:%02x.%x "
"Attempt to add PCI capability %x at offset "
"%x overlaps existing capability %x at offset %x",
- pci_root_bus_path(pdev), pci_bus_num(pdev->bus),
+ pci_root_bus_path(pdev), pci_dev_bus_num(pdev),
PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
cap_id, offset, overlapping_cap, i);
return -EINVAL;
@@ -2381,7 +2370,7 @@ static void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent)
monitor_printf(mon, "%*sclass %s, addr %02x:%02x.%x, "
"pci id %04x:%04x (sub %04x:%04x)\n",
- indent, "", ctxt, pci_bus_num(d->bus),
+ indent, "", ctxt, pci_dev_bus_num(d),
PCI_SLOT(d->devfn), PCI_FUNC(d->devfn),
pci_get_word(d->config + PCI_VENDOR_ID),
pci_get_word(d->config + PCI_DEVICE_ID),
@@ -2464,7 +2453,7 @@ static char *pcibus_get_dev_path(DeviceState *dev)
/* Calculate # of slots on path between device and root. */;
slot_depth = 0;
- for (t = d; t; t = t->bus->parent_dev) {
+ for (t = d; t; t = pci_get_bus(t)->parent_dev) {
++slot_depth;
}
@@ -2479,7 +2468,7 @@ static char *pcibus_get_dev_path(DeviceState *dev)
/* Fill in slot numbers. We walk up from device to root, so need to print
* them in the reverse order, last to first. */
p = path + path_len;
- for (t = d; t; t = t->bus->parent_dev) {
+ for (t = d; t; t = pci_get_bus(t)->parent_dev) {
p -= slot_len;
s = snprintf(slot, sizeof slot, ":%02x.%x",
PCI_SLOT(t->devfn), PCI_FUNC(t->devfn));
@@ -2527,12 +2516,12 @@ int pci_qdev_find_device(const char *id, PCIDevice **pdev)
MemoryRegion *pci_address_space(PCIDevice *dev)
{
- return dev->bus->address_space_mem;
+ return pci_get_bus(dev)->address_space_mem;
}
MemoryRegion *pci_address_space_io(PCIDevice *dev)
{
- return dev->bus->address_space_io;
+ return pci_get_bus(dev)->address_space_io;
}
static void pci_device_class_init(ObjectClass *klass, void *data)
@@ -2560,11 +2549,11 @@ static void pci_device_class_base_init(ObjectClass *klass, void *data)
AddressSpace *pci_device_iommu_address_space(PCIDevice *dev)
{
- PCIBus *bus = PCI_BUS(dev->bus);
+ PCIBus *bus = pci_get_bus(dev);
PCIBus *iommu_bus = bus;
while(iommu_bus && !iommu_bus->iommu_fn && iommu_bus->parent_dev) {
- iommu_bus = PCI_BUS(iommu_bus->parent_dev->bus);
+ iommu_bus = pci_get_bus(iommu_bus->parent_dev);
}
if (iommu_bus && iommu_bus->iommu_fn) {
return iommu_bus->iommu_fn(bus, iommu_bus->iommu_opaque, dev->devfn);
@@ -2635,7 +2624,7 @@ void pci_bus_get_w64_range(PCIBus *bus, Range *range)
static bool pcie_has_upstream_port(PCIDevice *dev)
{
- PCIDevice *parent_dev = pci_bridge_get_device(dev->bus);
+ PCIDevice *parent_dev = pci_bridge_get_device(pci_get_bus(dev));
/* Device associated with an upstream port.
* As there are several types of these, it's easier to check the
@@ -2651,12 +2640,14 @@ static bool pcie_has_upstream_port(PCIDevice *dev)
PCIDevice *pci_get_function_0(PCIDevice *pci_dev)
{
+ PCIBus *bus = pci_get_bus(pci_dev);
+
if(pcie_has_upstream_port(pci_dev)) {
/* With an upstream PCIe port, we only support 1 device at slot 0 */
- return pci_dev->bus->devices[0];
+ return bus->devices[0];
} else {
/* Other bus types might support multiple devices at slots 0-31 */
- return pci_dev->bus->devices[PCI_DEVFN(PCI_SLOT(pci_dev->devfn), 0)];
+ return bus->devices[PCI_DEVFN(PCI_SLOT(pci_dev->devfn), 0)];
}
}
diff --git a/hw/pci/pci_bridge.c b/hw/pci/pci_bridge.c
index a47d257149..b2e50c36a0 100644
--- a/hw/pci/pci_bridge.c
+++ b/hw/pci/pci_bridge.c
@@ -183,7 +183,7 @@ static void pci_bridge_init_vga_aliases(PCIBridge *br, PCIBus *parent,
static PCIBridgeWindows *pci_bridge_region_init(PCIBridge *br)
{
PCIDevice *pd = PCI_DEVICE(br);
- PCIBus *parent = pd->bus;
+ PCIBus *parent = pci_get_bus(pd);
PCIBridgeWindows *w = g_new(PCIBridgeWindows, 1);
uint16_t cmd = pci_get_word(pd->config + PCI_COMMAND);
@@ -214,7 +214,7 @@ static PCIBridgeWindows *pci_bridge_region_init(PCIBridge *br)
static void pci_bridge_region_del(PCIBridge *br, PCIBridgeWindows *w)
{
PCIDevice *pd = PCI_DEVICE(br);
- PCIBus *parent = pd->bus;
+ PCIBus *parent = pci_get_bus(pd);
memory_region_del_subregion(parent->address_space_io, &w->alias_io);
memory_region_del_subregion(parent->address_space_mem, &w->alias_mem);
@@ -339,7 +339,7 @@ void pci_bridge_reset(DeviceState *qdev)
/* default qdev initialization function for PCI-to-PCI bridge */
void pci_bridge_initfn(PCIDevice *dev, const char *typename)
{
- PCIBus *parent = dev->bus;
+ PCIBus *parent = pci_get_bus(dev);
PCIBridge *br = PCI_BRIDGE(dev);
PCIBus *sec_bus = &br->sec_bus;
diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
index 32191f2a55..6c91bd44a0 100644
--- a/hw/pci/pcie.c
+++ b/hw/pci/pcie.c
@@ -155,7 +155,8 @@ pcie_endpoint_cap_common_init(PCIDevice *dev, uint8_t offset, uint8_t cap_size)
* 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)) {
+ if (pci_bus_is_express(pci_get_bus(dev))
+ && pci_bus_is_root(pci_get_bus(dev))) {
type = PCI_EXP_TYPE_RC_END;
}
@@ -369,7 +370,7 @@ void pcie_cap_slot_hot_unplug_request_cb(HotplugHandler *hotplug_dev,
{
uint8_t *exp_cap;
PCIDevice *pci_dev = PCI_DEVICE(dev);
- PCIBus *bus = pci_dev->bus;
+ PCIBus *bus = pci_get_bus(pci_dev);
pcie_cap_slot_hotplug_common(PCI_DEVICE(hotplug_dev), dev, &exp_cap, errp);
diff --git a/hw/pci/pcie_aer.c b/hw/pci/pcie_aer.c
index 97200742b4..b009be7f17 100644
--- a/hw/pci/pcie_aer.c
+++ b/hw/pci/pcie_aer.c
@@ -409,7 +409,7 @@ static void pcie_aer_msg(PCIDevice *dev, const PCIEAERMsg *msg)
*/
return;
}
- dev = pci_bridge_get_device(dev->bus);
+ dev = pci_bridge_get_device(pci_get_bus(dev));
}
}
@@ -1025,7 +1025,7 @@ static int do_pcie_aer_inject_error(Monitor *mon,
}
details->id = id;
details->root_bus = pci_root_bus_path(dev);
- details->bus = pci_bus_num(dev->bus);
+ details->bus = pci_dev_bus_num(dev);
details->devfn = dev->devfn;
return 0;
diff --git a/hw/ppc/ppc4xx_pci.c b/hw/ppc/ppc4xx_pci.c
index 4765dcecca..b7642bac01 100644
--- a/hw/ppc/ppc4xx_pci.c
+++ b/hw/ppc/ppc4xx_pci.c
@@ -314,9 +314,9 @@ static int ppc4xx_pcihost_initfn(SysBusDevice *dev)
sysbus_init_irq(dev, &s->irq[i]);
}
- b = pci_register_bus(DEVICE(dev), NULL, ppc4xx_pci_set_irq,
- ppc4xx_pci_map_irq, s->irq, get_system_memory(),
- get_system_io(), 0, 4, TYPE_PCI_BUS);
+ b = pci_register_root_bus(DEVICE(dev), NULL, ppc4xx_pci_set_irq,
+ ppc4xx_pci_map_irq, s->irq, get_system_memory(),
+ get_system_io(), 0, 4, TYPE_PCI_BUS);
h->bus = b;
pci_create_simple(b, 0, "ppc4xx-host-bridge");
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 695c820911..37f18b3d32 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -505,7 +505,7 @@ static void rtas_ibm_get_config_addr_info2(PowerPCCPU *cpu,
goto param_error_exit;
}
- rtas_st(rets, 1, (pci_bus_num(pdev->bus) << 16) + 1);
+ rtas_st(rets, 1, (pci_bus_num(pci_get_bus(pdev)) << 16) + 1);
break;
case RTAS_GET_PE_MODE:
rtas_st(rets, 1, RTAS_PE_MODE_SHARED);
@@ -1621,10 +1621,10 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp)
memory_region_add_subregion(get_system_memory(), sphb->io_win_addr,
&sphb->iowindow);
- bus = pci_register_bus(dev, NULL,
- pci_spapr_set_irq, pci_spapr_map_irq, sphb,
- &sphb->memspace, &sphb->iospace,
- PCI_DEVFN(0, 0), PCI_NUM_PINS, TYPE_PCI_BUS);
+ bus = pci_register_root_bus(dev, NULL,
+ pci_spapr_set_irq, pci_spapr_map_irq, sphb,
+ &sphb->memspace, &sphb->iospace,
+ PCI_DEVFN(0, 0), PCI_NUM_PINS, TYPE_PCI_BUS);
phb->bus = bus;
qbus_set_hotplug_handler(BUS(phb->bus), DEVICE(sphb), NULL);
diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
index 2b1e1409bf..7d9c65e719 100644
--- a/hw/s390x/s390-pci-bus.c
+++ b/hw/s390x/s390-pci-bus.c
@@ -554,10 +554,10 @@ static int s390_pcihost_init(SysBusDevice *dev)
DPRINTF("host_init\n");
- b = pci_register_bus(DEVICE(dev), NULL,
- s390_pci_set_irq, s390_pci_map_irq, NULL,
- get_system_memory(), get_system_io(), 0, 64,
- TYPE_PCI_BUS);
+ b = pci_register_root_bus(DEVICE(dev), NULL,
+ s390_pci_set_irq, s390_pci_map_irq, NULL,
+ get_system_memory(), get_system_io(), 0, 64,
+ TYPE_PCI_BUS);
pci_setup_iommu(b, s390_pci_dma_iommu, s);
bus = BUS(b);
@@ -680,10 +680,10 @@ static void s390_pcihost_hot_plug(HotplugHandler *hotplug_dev,
s->bus_no += 1;
pci_default_write_config(pdev, PCI_SECONDARY_BUS, s->bus_no, 1);
do {
- pdev = pdev->bus->parent_dev;
+ pdev = pci_get_bus(pdev)->parent_dev;
pci_default_write_config(pdev, PCI_SUBORDINATE_BUS,
s->bus_no, 1);
- } while (pdev->bus && pci_bus_num(pdev->bus));
+ } while (pci_get_bus(pdev) && pci_dev_bus_num(pdev));
}
} else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
pdev = PCI_DEVICE(dev);
@@ -692,7 +692,7 @@ static void s390_pcihost_hot_plug(HotplugHandler *hotplug_dev,
/* In the case the PCI device does not define an id */
/* we generate one based on the PCI address */
dev->id = g_strdup_printf("auto_%02x:%02x.%01x",
- pci_bus_num(pdev->bus),
+ pci_dev_bus_num(pdev),
PCI_SLOT(pdev->devfn),
PCI_FUNC(pdev->devfn));
}
@@ -713,7 +713,7 @@ static void s390_pcihost_hot_plug(HotplugHandler *hotplug_dev,
}
pbdev->pdev = pdev;
- pbdev->iommu = s390_pci_get_iommu(s, pdev->bus, pdev->devfn);
+ pbdev->iommu = s390_pci_get_iommu(s, pci_get_bus(pdev), pdev->devfn);
pbdev->iommu->pbdev = pbdev;
pbdev->state = ZPCI_FS_DISABLED;
@@ -807,7 +807,7 @@ static void s390_pcihost_hot_unplug(HotplugHandler *hotplug_dev,
s390_pci_generate_plug_event(HP_EVENT_STANDBY_TO_RESERVED,
pbdev->fh, pbdev->fid);
- bus = pci_dev->bus;
+ bus = pci_get_bus(pci_dev);
devfn = pci_dev->devfn;
object_unparent(OBJECT(pci_dev));
s390_pci_msix_free(pbdev);
diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c
index d5eae6239a..3e38e9e8aa 100644
--- a/hw/scsi/megasas.c
+++ b/hw/scsi/megasas.c
@@ -2372,7 +2372,7 @@ static void megasas_scsi_realize(PCIDevice *dev, Error **errp)
if (!s->sas_addr) {
s->sas_addr = ((NAA_LOCALLY_ASSIGNED_ID << 24) |
IEEE_COMPANY_LOCALLY_ASSIGNED) << 36;
- s->sas_addr |= (pci_bus_num(dev->bus) << 16);
+ s->sas_addr |= (pci_dev_bus_num(dev) << 16);
s->sas_addr |= (PCI_SLOT(dev->devfn) << 8);
s->sas_addr |= PCI_FUNC(dev->devfn);
}
diff --git a/hw/scsi/mptsas.c b/hw/scsi/mptsas.c
index f6db1b0103..3f061f3f68 100644
--- a/hw/scsi/mptsas.c
+++ b/hw/scsi/mptsas.c
@@ -1312,7 +1312,7 @@ static void mptsas_scsi_realize(PCIDevice *dev, Error **errp)
if (!s->sas_addr) {
s->sas_addr = ((NAA_LOCALLY_ASSIGNED_ID << 24) |
IEEE_COMPANY_LOCALLY_ASSIGNED) << 36;
- s->sas_addr |= (pci_bus_num(dev->bus) << 16);
+ s->sas_addr |= (pci_dev_bus_num(dev) << 16);
s->sas_addr |= (PCI_SLOT(dev->devfn) << 8);
s->sas_addr |= PCI_FUNC(dev->devfn);
}
diff --git a/hw/scsi/vmw_pvscsi.c b/hw/scsi/vmw_pvscsi.c
index d564e5caff..27749c0e42 100644
--- a/hw/scsi/vmw_pvscsi.c
+++ b/hw/scsi/vmw_pvscsi.c
@@ -1133,7 +1133,7 @@ pvscsi_realizefn(PCIDevice *pci_dev, Error **errp)
pvscsi_init_msi(s);
- if (pci_is_express(pci_dev) && pci_bus_is_express(pci_dev->bus)) {
+ if (pci_is_express(pci_dev) && pci_bus_is_express(pci_get_bus(pci_dev))) {
pcie_endpoint_cap_init(pci_dev, PVSCSI_EXP_EP_OFFSET);
}
diff --git a/hw/sh4/sh_pci.c b/hw/sh4/sh_pci.c
index cbb01af57f..4ec2e35500 100644
--- a/hw/sh4/sh_pci.c
+++ b/hw/sh4/sh_pci.c
@@ -131,12 +131,12 @@ static int sh_pci_device_init(SysBusDevice *dev)
for (i = 0; i < 4; i++) {
sysbus_init_irq(dev, &s->irq[i]);
}
- phb->bus = pci_register_bus(DEVICE(dev), "pci",
- sh_pci_set_irq, sh_pci_map_irq,
- s->irq,
- get_system_memory(),
- get_system_io(),
- PCI_DEVFN(0, 0), 4, TYPE_PCI_BUS);
+ phb->bus = pci_register_root_bus(DEVICE(dev), "pci",
+ sh_pci_set_irq, sh_pci_map_irq,
+ s->irq,
+ get_system_memory(),
+ get_system_io(),
+ PCI_DEVFN(0, 0), 4, TYPE_PCI_BUS);
memory_region_init_io(&s->memconfig_p4, OBJECT(s), &sh_pci_reg_ops, s,
"sh_pci", 0x224);
memory_region_init_alias(&s->memconfig_a7, OBJECT(s), "sh_pci.2",
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
index 1a5437a07d..5d11f01874 100644
--- a/hw/smbios/smbios.c
+++ b/hw/smbios/smbios.c
@@ -96,6 +96,11 @@ static struct {
} type4;
static struct {
+ size_t nvalues;
+ const char **values;
+} type11;
+
+static struct {
const char *loc_pfx, *bank, *manufacturer, *serial, *asset, *part;
uint16_t speed;
} type17;
@@ -282,6 +287,14 @@ static const QemuOptDesc qemu_smbios_type4_opts[] = {
{ /* end of list */ }
};
+static const QemuOptDesc qemu_smbios_type11_opts[] = {
+ {
+ .name = "value",
+ .type = QEMU_OPT_STRING,
+ .help = "OEM string data",
+ },
+};
+
static const QemuOptDesc qemu_smbios_type17_opts[] = {
{
.name = "type",
@@ -590,6 +603,27 @@ static void smbios_build_type_4_table(unsigned instance)
smbios_type4_count++;
}
+static void smbios_build_type_11_table(void)
+{
+ char count_str[128];
+ size_t i;
+
+ if (type11.nvalues == 0) {
+ return;
+ }
+
+ SMBIOS_BUILD_TABLE_PRE(11, 0xe00, true); /* required */
+
+ snprintf(count_str, sizeof(count_str), "%zu", type11.nvalues);
+ t->count = type11.nvalues;
+
+ for (i = 0; i < type11.nvalues; i++) {
+ SMBIOS_TABLE_SET_STR_LIST(11, type11.values[i]);
+ }
+
+ SMBIOS_BUILD_TABLE_POST;
+}
+
#define ONE_KB ((ram_addr_t)1 << 10)
#define ONE_MB ((ram_addr_t)1 << 20)
#define ONE_GB ((ram_addr_t)1 << 30)
@@ -832,6 +866,8 @@ void smbios_get_tables(const struct smbios_phys_mem_area *mem_array,
smbios_build_type_4_table(i);
}
+ smbios_build_type_11_table();
+
#define MAX_DIMM_SZ (16ll * ONE_GB)
#define GET_DIMM_SZ ((i < dimm_cnt - 1) ? MAX_DIMM_SZ \
: ((ram_size - 1) % MAX_DIMM_SZ) + 1)
@@ -882,6 +918,38 @@ static void save_opt(const char **dest, QemuOpts *opts, const char *name)
}
}
+
+struct opt_list {
+ const char *name;
+ size_t *ndest;
+ const char ***dest;
+};
+
+static int save_opt_one(void *opaque,
+ const char *name, const char *value,
+ Error **errp)
+{
+ struct opt_list *opt = opaque;
+
+ if (!g_str_equal(name, opt->name)) {
+ return 0;
+ }
+
+ *opt->dest = g_renew(const char *, *opt->dest, (*opt->ndest) + 1);
+ (*opt->dest)[*opt->ndest] = value;
+ (*opt->ndest)++;
+ return 0;
+}
+
+static void save_opt_list(size_t *ndest, const char ***dest,
+ QemuOpts *opts, const char *name)
+{
+ struct opt_list opt = {
+ name, ndest, dest,
+ };
+ qemu_opt_foreach(opts, save_opt_one, &opt, NULL);
+}
+
void smbios_entry_add(QemuOpts *opts, Error **errp)
{
const char *val;
@@ -1035,6 +1103,10 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
save_opt(&type4.asset, opts, "asset");
save_opt(&type4.part, opts, "part");
return;
+ case 11:
+ qemu_opts_validate(opts, qemu_smbios_type11_opts, &error_fatal);
+ save_opt_list(&type11.nvalues, &type11.values, opts, "value");
+ return;
case 17:
qemu_opts_validate(opts, qemu_smbios_type17_opts, &error_fatal);
save_opt(&type17.loc_pfx, opts, "loc_pfx");
diff --git a/hw/smbios/smbios_build.h b/hw/smbios/smbios_build.h
index 68b8b72e09..93b360d520 100644
--- a/hw/smbios/smbios_build.h
+++ b/hw/smbios/smbios_build.h
@@ -63,6 +63,18 @@ extern unsigned smbios_table_cnt;
} \
} while (0)
+#define SMBIOS_TABLE_SET_STR_LIST(tbl_type, value) \
+ do { \
+ int len = (value != NULL) ? strlen(value) + 1 : 0; \
+ if (len > 1) { \
+ smbios_tables = g_realloc(smbios_tables, \
+ smbios_tables_len + len); \
+ memcpy(smbios_tables + smbios_tables_len, value, len); \
+ smbios_tables_len += len; \
+ ++str_index; \
+ } \
+ } while (0)
+
#define SMBIOS_BUILD_TABLE_POST \
do { \
size_t term_cnt, t_size; \
diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index af3a9d88de..228e82b3fb 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -3416,7 +3416,7 @@ static void usb_xhci_realize(struct PCIDevice *dev, Error **errp)
PCI_BASE_ADDRESS_SPACE_MEMORY|PCI_BASE_ADDRESS_MEM_TYPE_64,
&xhci->mem);
- if (pci_bus_is_express(dev->bus) ||
+ if (pci_bus_is_express(pci_get_bus(dev)) ||
xhci_get_flag(xhci, XHCI_FLAG_FORCE_PCIE_ENDCAP)) {
ret = pcie_endpoint_cap_init(dev, 0xa0);
assert(ret > 0);
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index c977ee327f..2c71295125 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -1654,8 +1654,8 @@ static int vfio_setup_pcie_cap(VFIOPCIDevice *vdev, int pos, uint8_t size,
return -EINVAL;
}
- if (!pci_bus_is_express(vdev->pdev.bus)) {
- PCIBus *bus = vdev->pdev.bus;
+ if (!pci_bus_is_express(pci_get_bus(&vdev->pdev))) {
+ PCIBus *bus = pci_get_bus(&vdev->pdev);
PCIDevice *bridge;
/*
@@ -1680,14 +1680,14 @@ static int vfio_setup_pcie_cap(VFIOPCIDevice *vdev, int pos, uint8_t size,
*/
while (!pci_bus_is_root(bus)) {
bridge = pci_bridge_get_device(bus);
- bus = bridge->bus;
+ bus = pci_get_bus(bridge);
}
if (pci_bus_is_express(bus)) {
return 0;
}
- } else if (pci_bus_is_root(vdev->pdev.bus)) {
+ } else if (pci_bus_is_root(pci_get_bus(&vdev->pdev))) {
/*
* On a Root Complex bus Endpoints become Root Complex Integrated
* Endpoints, which changes the type and clears the LNK & LNK2 fields.
@@ -1890,7 +1890,7 @@ static void vfio_add_ext_cap(VFIOPCIDevice *vdev)
uint8_t *config;
/* Only add extended caps if we have them and the guest can see them */
- if (!pci_is_express(pdev) || !pci_bus_is_express(pdev->bus) ||
+ if (!pci_is_express(pdev) || !pci_bus_is_express(pci_get_bus(pdev)) ||
!pci_get_long(pdev->config + PCI_CONFIG_SPACE_SIZE)) {
return;
}
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index e92837c42b..6c75cca88a 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -1588,9 +1588,11 @@ static void virtio_pci_device_plugged(DeviceState *d, Error **errp)
"neither legacy nor transitional device.");
return ;
}
- /* legacy and transitional */
- pci_set_word(config + PCI_SUBSYSTEM_VENDOR_ID,
- pci_get_word(config + PCI_VENDOR_ID));
+ /*
+ * Legacy and transitional devices use specific subsystem IDs.
+ * Note that the subsystem vendor ID (config + PCI_SUBSYSTEM_VENDOR_ID)
+ * is set to PCI_SUBVENDOR_ID_REDHAT_QUMRANET by default.
+ */
pci_set_word(config + PCI_SUBSYSTEM_ID, virtio_bus_get_vdev_id(bus));
} else {
/* pure virtio-1.0 */
@@ -1708,8 +1710,8 @@ static void virtio_pci_realize(PCIDevice *pci_dev, Error **errp)
{
VirtIOPCIProxy *proxy = VIRTIO_PCI(pci_dev);
VirtioPCIClass *k = VIRTIO_PCI_GET_CLASS(pci_dev);
- bool pcie_port = pci_bus_is_express(pci_dev->bus) &&
- !pci_bus_is_root(pci_dev->bus);
+ bool pcie_port = pci_bus_is_express(pci_get_bus(pci_dev)) &&
+ !pci_bus_is_root(pci_get_bus(pci_dev));
if (kvm_enabled() && !kvm_has_many_ioeventfds()) {
proxy->flags &= ~VIRTIO_PCI_FLAG_USE_IOEVENTFD;
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index ad564b0132..d6002ee550 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -2469,7 +2469,7 @@ void GCC_FMT_ATTR(2, 3) virtio_error(VirtIODevice *vdev, const char *fmt, ...)
va_end(ap);
if (virtio_vdev_has_feature(vdev, VIRTIO_F_VERSION_1)) {
- virtio_set_status(vdev, vdev->status | VIRTIO_CONFIG_S_NEEDS_RESET);
+ vdev->status = vdev->status | VIRTIO_CONFIG_S_NEEDS_RESET;
virtio_notify_config(vdev);
}
diff --git a/hw/xen/xen_pt.c b/hw/xen/xen_pt.c
index d57c6d3485..f662f30370 100644
--- a/hw/xen/xen_pt.c
+++ b/hw/xen/xen_pt.c
@@ -73,7 +73,7 @@ void xen_pt_log(const PCIDevice *d, const char *f, ...)
va_start(ap, f);
if (d) {
- fprintf(stderr, "[%02x:%02x.%d] ", pci_bus_num(d->bus),
+ fprintf(stderr, "[%02x:%02x.%d] ", pci_dev_bus_num(d),
PCI_SLOT(d->devfn), PCI_FUNC(d->devfn));
}
vfprintf(stderr, f, ap);
@@ -602,7 +602,7 @@ static void xen_pt_region_update(XenPCIPassthroughState *s,
}
args.type = d->io_regions[bar].type;
- pci_for_each_device(d->bus, pci_bus_num(d->bus),
+ pci_for_each_device(pci_get_bus(d), pci_dev_bus_num(d),
xen_pt_check_bar_overlap, &args);
if (args.rc) {
XEN_PT_WARN(d, "Region: %d (addr: %#"FMT_PCIBUS
@@ -695,7 +695,7 @@ xen_igd_passthrough_isa_bridge_create(XenPCIPassthroughState *s,
PCIDevice *d = &s->dev;
gpu_dev_id = dev->device_id;
- igd_passthrough_isa_bridge_create(d->bus, gpu_dev_id);
+ igd_passthrough_isa_bridge_create(pci_get_bus(d), gpu_dev_id);
}
/* destroy. */
@@ -711,7 +711,7 @@ static void xen_pt_destroy(PCIDevice *d) {
intx = xen_pt_pci_intx(s);
rc = xc_domain_unbind_pt_irq(xen_xc, xen_domid, machine_irq,
PT_IRQ_TYPE_PCI,
- pci_bus_num(d->bus),
+ pci_dev_bus_num(d),
PCI_SLOT(s->dev.devfn),
intx,
0 /* isa_irq */);
@@ -867,7 +867,7 @@ static void xen_pt_realize(PCIDevice *d, Error **errp)
uint8_t e_intx = xen_pt_pci_intx(s);
rc = xc_domain_bind_pt_pci_irq(xen_xc, xen_domid, machine_irq,
- pci_bus_num(d->bus),
+ pci_dev_bus_num(d),
PCI_SLOT(d->devfn),
e_intx);
if (rc < 0) {