[PATCH v2 03/29] PCI: add pci_scan_root_bus(), deprecate pci_scan_bus() and pci_scan_bus_parented()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



"Early" and "header" quirks use incorrect bus resources because they see
the default resources assigned by pci_create_bus(), before the architecture
fixes them up (typically in pcibios_fixup_bus()).  Regions reserved by
these quirks end up with the wrong parents.

Here's the standard path for scanning a PCI root bus:

  pci_scan_bus or pci_scan_bus_parented
    pci_create_bus                     <-- A create with default resources
    pci_scan_child_bus
      pci_scan_slot
        pci_scan_single_device
          pci_scan_device
            pci_setup_device
              pci_fixup_device(early)  <-- B
          pci_device_add
            pci_fixup_device(header)   <-- C
      pcibios_fixup_bus                <-- D fill in correct resources

Early and header quirks at B and C use the default (incorrect) root bus
resources rather than those filled in at D.

This patch adds a new pci_scan_root_bus() function that sets the bus
resources correctly from a supplied list of resources.  It also marks
pci_scan_bus() and pci_scan_bus_parented() as deprecated.

Callers of pci_scan_bus() should switch to pci_scan_root_bus().  Callers of
pci_scan_bus_parented() should use pci_create_root_bus() followed by
pci_scan_child_bus().  In both cases, root bus resource fixups, e.g.,
in pcibios_fixup_bus(), should be removed.

Signed-off-by: Bjorn Helgaas <bhelgaas@xxxxxxxxxx>
---
 drivers/pci/probe.c |   39 +++++++++++++++++++++++++++++++++++++--
 include/linux/pci.h |   19 ++++++++-----------
 2 files changed, 45 insertions(+), 13 deletions(-)

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 20d2d40..9cb7158 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1624,18 +1624,53 @@ struct pci_bus *pci_create_bus(struct device *parent,
 	return pci_create_root_bus(parent, bus, ops, sysdata, NULL);
 }
 
+/*
+ * Deprecated; use pci_create_root_bus() with non-NULL resources and
+ * pci_scan_child_bus() instead
+ */
 struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent,
 		int bus, struct pci_ops *ops, void *sysdata)
 {
 	struct pci_bus *b;
 
 	b = pci_create_root_bus(parent, bus, ops, sysdata, NULL);
-	if (b)
-		b->subordinate = pci_scan_child_bus(b);
+	if (!b)
+		return NULL;
+
+	b->subordinate = pci_scan_child_bus(b);
 	return b;
 }
 EXPORT_SYMBOL(pci_scan_bus_parented);
 
+/* Deprecated; use pci_scan_root_bus() with non-NULL resources instead */
+struct pci_bus * __devinit pci_scan_bus(int bus, struct pci_ops *ops,
+		void *sysdata)
+{
+	struct pci_bus *b;
+
+	b = pci_create_root_bus(NULL, bus, ops, sysdata, NULL);
+	if (!b)
+		return NULL;
+
+	b->subordinate = pci_scan_child_bus(b);
+	pci_bus_add_devices(b);
+	return b;
+}
+
+struct pci_bus * __devinit pci_scan_root_bus(struct device *parent, int bus_num,
+		struct pci_ops *ops, void *sysdata, struct list_head *resources)
+{
+	struct pci_bus *bus;
+
+	bus = pci_create_root_bus(parent, bus_num, ops, sysdata, resources);
+	if (!bus)
+		return NULL;
+
+	bus->subordinate = pci_scan_child_bus(bus);
+	pci_bus_add_devices(bus);
+	return bus;
+}
+
 #ifdef CONFIG_HOTPLUG
 /**
  * pci_rescan_bus - scan a PCI bus for devices.
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 6bdf854..03c6089 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -655,20 +655,17 @@ void pci_fixup_cardbus(struct pci_bus *);
 void pcibios_scan_specific_bus(int busn);
 extern struct pci_bus *pci_find_bus(int domain, int busnr);
 void pci_bus_add_devices(const struct pci_bus *bus);
-struct pci_bus *pci_scan_bus_parented(struct device *parent, int bus,
-				      struct pci_ops *ops, void *sysdata);
-static inline struct pci_bus * __devinit pci_scan_bus(int bus, struct pci_ops *ops,
-					   void *sysdata)
-{
-	struct pci_bus *root_bus;
-	root_bus = pci_scan_bus_parented(NULL, bus, ops, sysdata);
-	if (root_bus)
-		pci_bus_add_devices(root_bus);
-	return root_bus;
-}
+struct pci_bus * __devinit pci_scan_root_bus(struct device *parent, int bus,
+					     struct pci_ops *ops, void *sysdata,
+					     struct list_head *resources);
 struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
 				    struct pci_ops *ops, void *sysdata,
 				    struct list_head *resources);
+struct pci_bus *pci_scan_bus_parented(struct device *parent, int bus,
+				      struct pci_ops *ops, void *sysdata)
+				      __deprecated;
+struct pci_bus * __devinit pci_scan_bus(int bus, struct pci_ops *ops,
+					void *sysdata) __deprecated;
 struct pci_bus *pci_create_bus(struct device *parent, int bus,
 			       struct pci_ops *ops, void *sysdata) __deprecated;
 struct pci_bus *pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev,

--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [DMA Engine]     [Linux Coverity]     [Linux USB]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Greybus]

  Powered by Linux