diff options
Diffstat (limited to 'hw')
-rw-r--r-- | hw/net/vmxnet3.c | 2 | ||||
-rw-r--r-- | hw/pci-bridge/ioh3420.c | 7 | ||||
-rw-r--r-- | hw/pci-bridge/pci_bridge_dev.c | 4 | ||||
-rw-r--r-- | hw/pci-bridge/xio3130_downstream.c | 6 | ||||
-rw-r--r-- | hw/pci-bridge/xio3130_upstream.c | 3 | ||||
-rw-r--r-- | hw/pci/msi.c | 16 |
6 files changed, 35 insertions, 3 deletions
diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c index 16645e6c23..d97897670d 100644 --- a/hw/net/vmxnet3.c +++ b/hw/net/vmxnet3.c @@ -348,7 +348,7 @@ typedef struct { /* Interrupt management */ /* - *This function returns sign whether interrupt line is in asserted state + * This function returns sign whether interrupt line is in asserted state * This depends on the type of interrupt used. For INTX interrupt line will * be asserted until explicit deassertion, for MSI(X) interrupt line will * be deasserted automatically due to notification semantics of the MSI(X) diff --git a/hw/pci-bridge/ioh3420.c b/hw/pci-bridge/ioh3420.c index 0937fa34be..b4a7806e2e 100644 --- a/hw/pci-bridge/ioh3420.c +++ b/hw/pci-bridge/ioh3420.c @@ -106,12 +106,14 @@ static int ioh3420_initfn(PCIDevice *d) if (rc < 0) { goto err_bridge; } + rc = msi_init(d, IOH_EP_MSI_OFFSET, IOH_EP_MSI_NR_VECTOR, IOH_EP_MSI_SUPPORTED_FLAGS & PCI_MSI_FLAGS_64BIT, IOH_EP_MSI_SUPPORTED_FLAGS & PCI_MSI_FLAGS_MASKBIT); if (rc < 0) { goto err_bridge; } + rc = pcie_cap_init(d, IOH_EP_EXP_OFFSET, PCI_EXP_TYPE_ROOT_PORT, p->port); if (rc < 0) { goto err_msi; @@ -120,18 +122,21 @@ static int ioh3420_initfn(PCIDevice *d) pcie_cap_arifwd_init(d); pcie_cap_deverr_init(d); pcie_cap_slot_init(d, s->slot); + pcie_cap_root_init(d); + pcie_chassis_create(s->chassis); rc = pcie_chassis_add_slot(s); if (rc < 0) { goto err_pcie_cap; } - pcie_cap_root_init(d); + rc = pcie_aer_init(d, IOH_EP_AER_OFFSET, PCI_ERR_SIZEOF); if (rc < 0) { goto err; } pcie_aer_root_init(d); ioh3420_aer_vector_update(d); + return 0; err: diff --git a/hw/pci-bridge/pci_bridge_dev.c b/hw/pci-bridge/pci_bridge_dev.c index 7b582e96ac..41ca47b15a 100644 --- a/hw/pci-bridge/pci_bridge_dev.c +++ b/hw/pci-bridge/pci_bridge_dev.c @@ -68,10 +68,12 @@ static int pci_bridge_dev_initfn(PCIDevice *dev) /* MSI is not applicable without SHPC */ bridge_dev->flags &= ~(1 << PCI_BRIDGE_DEV_F_MSI_REQ); } + err = slotid_cap_init(dev, 0, bridge_dev->chassis_nr, 0); if (err) { goto slotid_error; } + if ((bridge_dev->flags & (1 << PCI_BRIDGE_DEV_F_MSI_REQ)) && msi_nonbroken) { err = msi_init(dev, 0, 1, true, true); @@ -79,6 +81,7 @@ static int pci_bridge_dev_initfn(PCIDevice *dev) goto msi_error; } } + if (shpc_present(dev)) { /* TODO: spec recommends using 64 bit prefetcheable BAR. * Check whether that works well. */ @@ -86,6 +89,7 @@ static int pci_bridge_dev_initfn(PCIDevice *dev) PCI_BASE_ADDRESS_MEM_TYPE_64, &bridge_dev->bar); } return 0; + msi_error: slotid_cap_cleanup(dev); slotid_error: diff --git a/hw/pci-bridge/xio3130_downstream.c b/hw/pci-bridge/xio3130_downstream.c index cf1ee63aba..e6d653de4f 100644 --- a/hw/pci-bridge/xio3130_downstream.c +++ b/hw/pci-bridge/xio3130_downstream.c @@ -70,11 +70,13 @@ static int xio3130_downstream_initfn(PCIDevice *d) if (rc < 0) { goto err_bridge; } + rc = pci_bridge_ssvid_init(d, XIO3130_SSVID_OFFSET, XIO3130_SSVID_SVID, XIO3130_SSVID_SSID); if (rc < 0) { goto err_bridge; } + rc = pcie_cap_init(d, XIO3130_EXP_OFFSET, PCI_EXP_TYPE_DOWNSTREAM, p->port); if (rc < 0) { @@ -83,12 +85,14 @@ static int xio3130_downstream_initfn(PCIDevice *d) pcie_cap_flr_init(d); pcie_cap_deverr_init(d); pcie_cap_slot_init(d, s->slot); + pcie_cap_arifwd_init(d); + pcie_chassis_create(s->chassis); rc = pcie_chassis_add_slot(s); if (rc < 0) { goto err_pcie_cap; } - pcie_cap_arifwd_init(d); + rc = pcie_aer_init(d, XIO3130_AER_OFFSET, PCI_ERR_SIZEOF); if (rc < 0) { goto err; diff --git a/hw/pci-bridge/xio3130_upstream.c b/hw/pci-bridge/xio3130_upstream.c index 164ef58c46..d97684474f 100644 --- a/hw/pci-bridge/xio3130_upstream.c +++ b/hw/pci-bridge/xio3130_upstream.c @@ -66,11 +66,13 @@ static int xio3130_upstream_initfn(PCIDevice *d) if (rc < 0) { goto err_bridge; } + rc = pci_bridge_ssvid_init(d, XIO3130_SSVID_OFFSET, XIO3130_SSVID_SVID, XIO3130_SSVID_SSID); if (rc < 0) { goto err_bridge; } + rc = pcie_cap_init(d, XIO3130_EXP_OFFSET, PCI_EXP_TYPE_UPSTREAM, p->port); if (rc < 0) { @@ -78,6 +80,7 @@ static int xio3130_upstream_initfn(PCIDevice *d) } pcie_cap_flr_init(d); pcie_cap_deverr_init(d); + rc = pcie_aer_init(d, XIO3130_AER_OFFSET, PCI_ERR_SIZEOF); if (rc < 0) { goto err; diff --git a/hw/pci/msi.c b/hw/pci/msi.c index a87ef4d752..359058e12c 100644 --- a/hw/pci/msi.c +++ b/hw/pci/msi.c @@ -165,6 +165,22 @@ bool msi_enabled(const PCIDevice *dev) PCI_MSI_FLAGS_ENABLE); } +/* + * Make PCI device @dev MSI-capable. + * Non-zero @offset puts capability MSI at that offset in PCI config + * space. + * @nr_vectors is the number of MSI vectors (1, 2, 4, 8, 16 or 32). + * If @msi64bit, make the device capable of sending a 64-bit message + * address. + * If @msi_per_vector_mask, make the device support per-vector masking. + * Return the offset of capability MSI in config space on success, + * return -errno on error. + * + * -ENOTSUP means lacking msi support for a msi-capable platform. + * -EINVAL means capability overlap, happens when @offset is non-zero, + * also means a programming error, except device assignment, which can check + * if a real HW is broken. + */ int msi_init(struct PCIDevice *dev, uint8_t offset, unsigned int nr_vectors, bool msi64bit, bool msi_per_vector_mask) { |