From 568f0690fd9aa4d39d84b04c1a5dbb53a915c3fe Mon Sep 17 00:00:00 2001 From: David Gibson Date: Thu, 6 Jun 2013 18:48:49 +1000 Subject: pci: Replace pci_find_domain() with more general pci_root_bus_path() pci_find_domain() is used in a number of places where we want an id for a whole PCI domain (i.e. the subtree under a PCI root bus). The trouble is that many platforms may support multiple independent host bridges with no hardware supplied notion of domain number. This patch, therefore, replaces calls to pci_find_domain() with calls to a new pci_root_bus_path() returning a string. The new call is implemented in terms of a new callback in the host bridge class, so it can be defined in some way that's well defined for the platform. When no callback is available we fall back on the qbus name. Most current uses of pci_find_domain() are for error or informational messages, so the change in identifiers should be harmless. The exception is pci_get_dev_path(), whose results form part of migration streams. To maintain compatibility with old migration streams, the PIIX PCI host is altered to always supply "0000" for this path, which matches the old domain number (since the code didn't actually support domains other than 0). For the pseries (spapr) PCI bridge we use a different platform-unique identifier (pseries machines can routinely have dozens of PCI host bridges). Theoretically that breaks migration streams, but given that we don't yet have migration support for pseries, it doesn't matter. Any other machines that have working migration support including PCI devices will need to be updated to maintain migration stream compatibility. Signed-off-by: David Gibson Signed-off-by: Michael S. Tsirkin --- include/hw/pci/pci.h | 2 +- include/hw/pci/pci_host.h | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h index f2bf1ed..e0597b7 100644 --- a/include/hw/pci/pci.h +++ b/include/hw/pci/pci.h @@ -391,7 +391,7 @@ void pci_for_each_device(PCIBus *bus, int bus_num, void *opaque); PCIBus *pci_find_primary_bus(void); PCIBus *pci_device_root_bus(const PCIDevice *d); -int pci_find_domain(const PCIDevice *dev); +const char *pci_root_bus_path(PCIDevice *dev); PCIDevice *pci_find_device(PCIBus *bus, int bus_num, uint8_t devfn); int pci_qdev_find_device(const char *id, PCIDevice **pdev); PCIBus *pci_get_bus_devfn(int *devfnp, const char *devaddr); diff --git a/include/hw/pci/pci_host.h b/include/hw/pci/pci_host.h index 236cd0f..44052f2 100644 --- a/include/hw/pci/pci_host.h +++ b/include/hw/pci/pci_host.h @@ -33,6 +33,10 @@ #define TYPE_PCI_HOST_BRIDGE "pci-host-bridge" #define PCI_HOST_BRIDGE(obj) \ OBJECT_CHECK(PCIHostState, (obj), TYPE_PCI_HOST_BRIDGE) +#define PCI_HOST_BRIDGE_CLASS(klass) \ + OBJECT_CLASS_CHECK(PCIHostBridgeClass, (klass), TYPE_PCI_HOST_BRIDGE) +#define PCI_HOST_BRIDGE_GET_CLASS(obj) \ + OBJECT_GET_CLASS(PCIHostBridgeClass, (obj), TYPE_PCI_HOST_BRIDGE) struct PCIHostState { SysBusDevice busdev; @@ -44,6 +48,12 @@ struct PCIHostState { PCIBus *bus; }; +typedef struct PCIHostBridgeClass { + SysBusDeviceClass parent_class; + + const char *(*root_bus_path)(PCIHostState *, PCIBus *); +} PCIHostBridgeClass; + /* common internal helpers for PCI/PCIe hosts, cut off overflows */ void pci_host_config_write_common(PCIDevice *pci_dev, uint32_t addr, uint32_t limit, uint32_t val, uint32_t len); -- cgit v1.1