From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38322) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZwJJW-0003II-GP for qemu-devel@nongnu.org; Tue, 10 Nov 2015 19:31:03 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZwJJV-0004jb-4k for qemu-devel@nongnu.org; Tue, 10 Nov 2015 19:31:02 -0500 From: Benjamin Herrenschmidt Date: Wed, 11 Nov 2015 11:27:59 +1100 Message-Id: <1447201710-10229-47-git-send-email-benh@kernel.crashing.org> In-Reply-To: <1447201710-10229-1-git-send-email-benh@kernel.crashing.org> References: <1447201710-10229-1-git-send-email-benh@kernel.crashing.org> Subject: [Qemu-devel] [PATCH 46/77] pci: Use the new pci_can_add_device() to enforce devfn_min/max List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-ppc@nongnu.org Cc: qemu-devel@nongnu.org This adds a devfn_max field to PCIBus and adds a pci_can_add_device() function which, if no "addr" (aka devfn) is specified, will tell whether there is any slot free between devfn_min and devfn_max. This will be used by some PCI root complex implementations that support only one direct child to avoid having qemu put dumb devices at different slot numbers. Signed-off-by: Benjamin Herrenschmidt --- hw/pci/pci.c | 22 ++++++++++++++++++++++ include/hw/pci/pci_bus.h | 1 + 2 files changed, 23 insertions(+) diff --git a/hw/pci/pci.c b/hw/pci/pci.c index 168b9cc..7003f7c 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -108,6 +108,27 @@ static uint16_t pcibus_numa_node(PCIBus *bus) return NUMA_NODE_UNASSIGNED; } +static bool pci_can_add_device(BusState *bus, QemuOpts *opts) +{ + unsigned int devfn, max; + PCIBus *pbus = PCI_BUS(bus); + + /* If address is specified, say yes and let it fail if that doesn't work */ + if (qemu_opt_get(opts, "addr") != NULL) { + return true; + } + max = ARRAY_SIZE(pbus->devices); + if (pbus->devfn_max && pbus->devfn_max < max) { + max = pbus->devfn_max; + } + for (devfn = pbus->devfn_min ; devfn < max; devfn += PCI_FUNC_MAX) { + if (!pbus->devices[devfn]) { + break; + } + } + return devfn < max; +} + static void pci_bus_class_init(ObjectClass *klass, void *data) { BusClass *k = BUS_CLASS(klass); @@ -119,6 +140,7 @@ static void pci_bus_class_init(ObjectClass *klass, void *data) k->realize = pci_bus_realize; k->unrealize = pci_bus_unrealize; k->reset = pcibus_reset; + k->can_add_device = pci_can_add_device; pbc->is_root = pcibus_is_root; pbc->bus_num = pcibus_num; diff --git a/include/hw/pci/pci_bus.h b/include/hw/pci/pci_bus.h index 403fec6..02055d4 100644 --- a/include/hw/pci/pci_bus.h +++ b/include/hw/pci/pci_bus.h @@ -23,6 +23,7 @@ struct PCIBus { PCIIOMMUFunc iommu_fn; void *iommu_opaque; uint8_t devfn_min; + uint8_t devfn_max; pci_set_irq_fn set_irq; pci_map_irq_fn map_irq; pci_route_irq_fn route_intx_to_irq; -- 2.5.0