Skip to contentSkip to conversation

PCI: Separate host_bridge code out from probe.c

PATCH In review Yinghai Lu 2 participants 4 messages Feb 25, 2012 – Feb 26, 2012

Subsystems (2)
lore
Share & tools
lore

Yinghai Lu

author
#0 lore raw

PATCH 1/2 PCI: Separate host_bridge code out from probe.c

---
 drivers/pci/Makefile      |    2 
 drivers/pci/host-bridge.c |   93 ++++++++++++++++++++++++++++++++++++++++++++++
 drivers/pci/pci.h         |    2 
 drivers/pci/probe.c       |   81 ----------------------------------------
 4 files changed, 97 insertions(+), 81 deletions(-)
drivers/pci/host-bridge.c new file +93 -0
Index: linux-2.6/drivers/pci/host-bridge.c
===================================================================
@@ -0,0 +1,93 @@
+/*
+ * host_bridge.c - host bridge related code
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/module.h>
+
+#include "pci.h"
+
+static LIST_HEAD(pci_host_bridges);
+
+void add_to_pci_host_bridges(struct list_head *list)
+{
+	list_add_tail(list, &pci_host_bridges);
+}
+
+static struct pci_host_bridge *pci_host_bridge(struct pci_dev *dev)
+{
+	struct pci_bus *bus;
+	struct pci_host_bridge *bridge;
+
+	bus = dev->bus;
+	while (bus->parent)
+		bus = bus->parent;
+
+	list_for_each_entry(bridge, &pci_host_bridges, list) {
+		if (bridge->bus == bus)
+			return bridge;
+	}
+
+	return NULL;
+}
+
+static bool resource_contains(struct resource *res1, struct resource *res2)
+{
+	return res1->start <= res2->start && res1->end >= res2->end;
+}
+
+void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
+			     struct resource *res)
+{
+	struct pci_host_bridge *bridge = pci_host_bridge(dev);
+	struct pci_host_bridge_window *window;
+	resource_size_t offset = 0;
+
+	list_for_each_entry(window, &bridge->windows, list) {
+		if (resource_type(res) != resource_type(window->res))
+			continue;
+
+		if (resource_contains(window->res, res)) {
+			offset = window->offset;
+			break;
+		}
+	}
+
+	region->start = res->start - offset;
+	region->end = res->end - offset;
+}
+EXPORT_SYMBOL(pcibios_resource_to_bus);
+
+static bool region_contains(struct pci_bus_region *region1,
+			    struct pci_bus_region *region2)
+{
+	return region1->start <= region2->start && region1->end >= region2->end;
+}
+
+void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
+			     struct pci_bus_region *region)
+{
+	struct pci_host_bridge *bridge = pci_host_bridge(dev);
+	struct pci_host_bridge_window *window;
+	struct pci_bus_region bus_region;
+	resource_size_t offset = 0;
+
+	list_for_each_entry(window, &bridge->windows, list) {
+		if (resource_type(res) != resource_type(window->res))
+			continue;
+
+		bus_region.start = window->res->start - window->offset;
+		bus_region.end = window->res->end - window->offset;
+
+		if (region_contains(&bus_region, region)) {
+			offset = window->offset;
+			break;
+		}
+	}
+
+	res->start = region->start + offset;
+	res->end = region->end + offset;
+}
+EXPORT_SYMBOL(pcibios_bus_to_resource);
drivers/pci/pci.h +2 -0
Index: linux-2.6/drivers/pci/pci.h
===================================================================
@@ -231,6 +231,8 @@ static inline int pci_ari_enabled(struct
 void pci_reassigndev_resource_alignment(struct pci_dev *dev);
 extern void pci_disable_bridge_window(struct pci_dev *dev);
 
+void add_to_pci_host_bridges(struct list_head *list);
+
 /* Single Root I/O Virtualization */
 struct pci_sriov {
 	int pos;		/* capability position */
drivers/pci/probe.c +1 -80

103 lines not on this page · raw message

drivers/pci/Makefile +1 -1
Index: linux-2.6/drivers/pci/Makefile
===================================================================
@@ -2,7 +2,7 @@
 # Makefile for the PCI bus specific drivers.
 #
 
-obj-y		+= access.o bus.o probe.o remove.o pci.o \
+obj-y		+= access.o bus.o probe.o host-bridge.o remove.o pci.o \
 			pci-driver.o search.o pci-sysfs.o rom.o setup-res.o \
 			irq.o vpd.o
 obj-$(CONFIG_PROC_FS) += proc.o
author
#1 lore raw

PATCH 2/2 x86, PCI: have own version for pcibios_bus_to_resource

x86 does not need to offset the address. So we can skip that costing offset searching.

---
 arch/x86/pci/i386.c       |   14 ++++++++++++++
 drivers/pci/host-bridge.c |    9 +++++----
 2 files changed, 19 insertions(+), 4 deletions(-)
arch/x86/pci/i386.c +14 -0
Index: linux-2.6/arch/x86/pci/i386.c
===================================================================
@@ -335,6 +335,20 @@ void __init pcibios_resource_survey(void
  */
 fs_initcall(pcibios_assign_resources);
 
+void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
+			     struct resource *res)
+{
+	region->start = res->start;
+	region->end = res->end;
+}
+
+void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
+			     struct pci_bus_region *region)
+{
+	res->start = region->start;
+	res->end = region->end;
+}
+
 static const struct vm_operations_struct pci_mmap_ops = {
 	.access = generic_access_phys,
 };
drivers/pci/host-bridge.c +5 -4
Index: linux-2.6/drivers/pci/host-bridge.c
===================================================================
@@ -38,8 +38,9 @@ static bool resource_contains(struct res
 	return res1->start <= res2->start && res1->end >= res2->end;
 }
 
-void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
-			     struct resource *res)
+void __weak pcibios_resource_to_bus(struct pci_dev *dev,
+				    struct pci_bus_region *region,
+				    struct resource *res)
 {
 	struct pci_host_bridge *bridge = pci_host_bridge(dev);
 	struct pci_host_bridge_window *window;
@@ -66,8 +67,8 @@ static bool region_contains(struct pci_b
 	return region1->start <= region2->start && region1->end >= region2->end;
 }
 
-void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
-			     struct pci_bus_region *region)
+void __weak pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
+				    struct pci_bus_region *region)
 {
 	struct pci_host_bridge *bridge = pci_host_bridge(dev);
 	struct pci_host_bridge_window *window;
maintainer
#2 lore raw
In reply to Yinghai Lu
Quoted 18 lines · Yinghai Lu

---
 drivers/pci/Makefile      |    2
 drivers/pci/host-bridge.c |   93 ++++++++++++++++++++++++++++++++++++++++++++++ drivers/pci/pci.h         |    2
 drivers/pci/probe.c       |   81 ----------------------------------------

 4 files changed, 97 insertions(+), 81 deletions(-)

Index: linux-2.6/drivers/pci/host-bridge.c
===================================================================

drivers/pci/host-bridge.c new file +4 -0
@@ -0,0 +1,93 @@
+/*
+ * host_bridge.c - host bridge related code
+ */
+

drivers/pci/host-bridge.c line 14

Quoted 10 lines
drivers/pci/host-bridge.c new file +10 -0
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/module.h>
+
+#include "pci.h"
+
+static LIST_HEAD(pci_host_bridges);
+
+void add_to_pci_host_bridges(struct list_head *list)

I'd prefer to pass a "struct pci_host_bridge *" here instead of a "struct list_head *". That way the compiler can check a little more.

Quoted 219 lines
drivers/pci/host-bridge.c new file +79 -0
+{
+       list_add_tail(list, &pci_host_bridges);
+}
+
+static struct pci_host_bridge *pci_host_bridge(struct pci_dev *dev)
+{
+       struct pci_bus *bus;
+       struct pci_host_bridge *bridge;
+
+       bus = dev->bus;
+       while (bus->parent)
+               bus = bus->parent;
+
+       list_for_each_entry(bridge, &pci_host_bridges, list) {
+               if (bridge->bus == bus)
+                       return bridge;
+       }
+
+       return NULL;
+}
+
+static bool resource_contains(struct resource *res1, struct resource *res2)
+{
+       return res1->start <= res2->start && res1->end >= res2->end;
+}
+
+void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
+                            struct resource *res)
+{
+       struct pci_host_bridge *bridge = pci_host_bridge(dev);
+       struct pci_host_bridge_window *window;
+       resource_size_t offset = 0;
+
+       list_for_each_entry(window, &bridge->windows, list) {
+               if (resource_type(res) != resource_type(window->res))
+                       continue;
+
+               if (resource_contains(window->res, res)) {
+                       offset = window->offset;
+                       break;
+               }
+       }
+
+       region->start = res->start - offset;
+       region->end = res->end - offset;
+}
+EXPORT_SYMBOL(pcibios_resource_to_bus);
+
+static bool region_contains(struct pci_bus_region *region1,
+                           struct pci_bus_region *region2)
+{
+       return region1->start <= region2->start && region1->end >= region2->end;
+}
+
+void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
+                            struct pci_bus_region *region)
+{
+       struct pci_host_bridge *bridge = pci_host_bridge(dev);
+       struct pci_host_bridge_window *window;
+       struct pci_bus_region bus_region;
+       resource_size_t offset = 0;
+
+       list_for_each_entry(window, &bridge->windows, list) {
+               if (resource_type(res) != resource_type(window->res))
+                       continue;
+
+               bus_region.start = window->res->start - window->offset;
+               bus_region.end = window->res->end - window->offset;
+
+               if (region_contains(&bus_region, region)) {
+                       offset = window->offset;
+                       break;
+               }
+       }
+
+       res->start = region->start + offset;
+       res->end = region->end + offset;
+}
+EXPORT_SYMBOL(pcibios_bus_to_resource);

Index: linux-2.6/drivers/pci/pci.h
===================================================================

drivers/pci/pci.h +2 -0
@@ -231,6 +231,8 @@ static inline int pci_ari_enabled(struct
  void pci_reassigndev_resource_alignment(struct pci_dev *dev);
  extern void pci_disable_bridge_window(struct pci_dev *dev);
 
+void add_to_pci_host_bridges(struct list_head *list);
+
  /* Single Root I/O Virtualization */
  struct pci_sriov {

       int pos;                /* capability position */
Index: linux-2.6/drivers/pci/probe.c
===================================================================

drivers/pci/probe.c +1 -80
@@ -15,13 +15,10 @@
  #define CARDBUS_LATENCY_TIMER  176     /* secondary latency timer */
  #define CARDBUS_RESERVE_BUSNR  3
 
-static LIST_HEAD(pci_host_bridges);
-
  /* Ugh.  Need to stop exporting this to modules. */
  LIST_HEAD(pci_root_buses);
  EXPORT_SYMBOL(pci_root_buses);
 
-
  static int find_anything(struct device *dev, void *data)
  {
        return 1;
@@ -44,82 +41,6 @@ int no_pci_devices(void)
  }
  EXPORT_SYMBOL(no_pci_devices);
 
-static struct pci_host_bridge *pci_host_bridge(struct pci_dev *dev)
-{
-       struct pci_bus *bus;
-       struct pci_host_bridge *bridge;
-
-       bus = dev->bus;
-       while (bus->parent)
-               bus = bus->parent;
-
-       list_for_each_entry(bridge, &pci_host_bridges, list) {
-               if (bridge->bus == bus)
-                       return bridge;
-       }
-
-       return NULL;
-}
-
-static bool resource_contains(struct resource *res1, struct resource *res2)
-{
-       return res1->start <= res2->start && res1->end >= res2->end;
-}
-
-void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
-                            struct resource *res)
-{
-       struct pci_host_bridge *bridge = pci_host_bridge(dev);
-       struct pci_host_bridge_window *window;
-       resource_size_t offset = 0;
-
-       list_for_each_entry(window, &bridge->windows, list) {
-               if (resource_type(res) != resource_type(window->res))
-                       continue;
-
-               if (resource_contains(window->res, res)) {
-                       offset = window->offset;
-                       break;
-               }
-       }
-
-       region->start = res->start - offset;
-       region->end = res->end - offset;
-}
-EXPORT_SYMBOL(pcibios_resource_to_bus);
-
-static bool region_contains(struct pci_bus_region *region1,
-                           struct pci_bus_region *region2)
-{
-       return region1->start <= region2->start && region1->end >= region2->end;
-}
-
-void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
-                            struct pci_bus_region *region)
-{
-       struct pci_host_bridge *bridge = pci_host_bridge(dev);
-       struct pci_host_bridge_window *window;
-       struct pci_bus_region bus_region;
-       resource_size_t offset = 0;
-
-       list_for_each_entry(window, &bridge->windows, list) {
-               if (resource_type(res) != resource_type(window->res))
-                       continue;
-
-               bus_region.start = window->res->start - window->offset;
-               bus_region.end = window->res->end - window->offset;
-
-               if (region_contains(&bus_region, region)) {
-                       offset = window->offset;
-                       break;
-               }
-       }
-
-       res->start = region->start + offset;
-       res->end = region->end + offset;
-}
-EXPORT_SYMBOL(pcibios_bus_to_resource);
-
  /*
  * PCI Bus Class
  */
@@ -1731,7 +1652,7 @@ struct pci_bus *pci_create_root_bus(stru
        }
 
        down_write(&pci_bus_sem);
-       list_add_tail(&bridge->list, &pci_host_bridges);
+       add_to_pci_host_bridges(&bridge->list);
        list_add_tail(&b->node, &pci_root_buses);
        up_write(&pci_bus_sem);
 

Index: linux-2.6/drivers/pci/Makefile
===================================================================

drivers/pci/Makefile +1 -1
@@ -2,7 +2,7 @@
  # Makefile for the PCI bus specific drivers.
  #
 
-obj-y          += access.o bus.o probe.o remove.o pci.o \
+obj-y          += access.o bus.o probe.o host-bridge.o remove.o pci.o \
                        pci-driver.o search.o pci-sysfs.o rom.o setup-res.o \

                       irq.o vpd.o
 obj-$(CONFIG_PROC_FS) += proc.o
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

author
#3 lore raw
Quoted 5 lines · Bjorn Helgaas
Quoted 1 line · Yinghai Lu

+void add_to_pci_host_bridges(struct list_head *list)

I'd prefer to pass a "struct pci_host_bridge *" here instead of a "struct list_head *".  That way the compiler can check a little more.

ok, let me check it.

Yinghai