PCI: Separate host_bridge code out from probe.c
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
@@ -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
@@ -231,6 +231,8 @@ static inline int pci_ari_enabled(structvoid 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
@@ -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
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
@@ -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
@@ -38,8 +38,9 @@ static bool resource_contains(struct resreturn 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_breturn 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;
Bjorn Helgaas
maintainerQuoted 18 lines · Yinghai Lu
Signed-off-by Yinghai Lu <[email protected]>---
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
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 "structlist_head*". That way the compiler can check a little more.
ok, let me check it.
Yinghai