All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/18] add PCI bus-to-resource offset support in core
@ 2012-02-10  2:36 Bjorn Helgaas
  2012-02-10  2:36 ` [PATCH v2 01/18] PCI: don't publish new root bus until it's fully initialized Bjorn Helgaas
                   ` (18 more replies)
  0 siblings, 19 replies; 34+ messages in thread
From: Bjorn Helgaas @ 2012-02-10  2:36 UTC (permalink / raw)
  To: linux-pci; +Cc: linux-arch

There's a lot of PCI-related code under arch/, but much of it is not actually
architecture-specific.  This series removes some of that code by moving most
of the bus-to-resource conversions into the core.

We currently read PCI bus addresses from BARs in the core (pci_setup_device()).
Then every arch is responsible for converting those bus addresses to CPU
resources, usually in pcibios_fixup_bus().

We already have a way for architectures to tell the core what the windows
through a host bridge are:

    LIST_HEAD(resources);
    pci_add_resource(&resources, io_space);
    pci_add_resource(&resources, mem_space);
    pci_scan_root_bus(parent, bus, ops, sysdata, &resources);

This series extends that so the arch can also tell the core about address
translation performed by the host bridge:

    LIST_HEAD(resources);
    pci_add_resource_offset(&resources, io_space, io_offset);
    pci_add_resource_offset(&resources, mem_space, mem_offset);
    pci_scan_root_bus(parent, bus, ops, sysdata, &resources);

Given that offset (the difference between bus address and CPU address for
each aperture), the core can do the bus-to-resource conversion immediately
when it reads the BARs.

This removes an opportunity for bugs (some PCI fixups currently see bus
addresses in struct pci_dev resources when they're expecting CPU addresses),
but the main reason to do this is to make our PCI resource handling simpler
and more uniform.

These patches are also available in this git repo:
    git://github.com/bjorn-helgaas/linux.git pci-offset-v2-d15af52258dd

Or you can browse them here:
    https://github.com/bjorn-helgaas/linux/compare/master...pci-offset-v2-d15af52258dd

I'd like to get these into linux-next soon to be ready for the 3.4 merge
window, so please let me know if you see any issues.

Changes since v1:
  - mips: remove Cobalt legacy IDE fixup
  - show bus address range, not offset, e.g., this:
	pci_bus 0000:00: root bus resource [mem 0xf0000000000-0xf007edfffff] (bus address [0x80000000-0xfedfffff])
    instead of this:
	pci_bus 0000:00: root bus resource [mem 0xf0000000000-0xf007edfffff] (bus offset 0xeff80000000)

---

Bjorn Helgaas (18):
      PCI: don't publish new root bus until it's fully initialized
      PCI: add struct pci_host_bridge and a list of all bridges found
      PCI: add struct pci_host_bridge_window with CPU/bus address offset
      PCI: convert bus addresses to resource when reading BARs
      PCI: add generic pcibios_resource_to_bus()
      alpha/PCI: get rid of device resource fixups
      arm/PCI: get rid of device resource fixups
      ia64/PCI: SN: convert to pci_scan_root_bus() for correct root bus resources
      ia64/PCI: get rid of device resource fixups
      microblaze/PCI: get rid of device resource fixups
      mips/PCI: get rid of device resource fixups
      mn10300/PCI: get rid of device resource fixups
      parisc/PCI: get rid of device resource fixups
      powerpc/PCI: get rid of device resource fixups
      sh/PCI: get rid of device resource fixups
      sparc/PCI: get rid of device resource fixups
      xtensa/PCI: get rid of device resource fixups
      PCI: collapse pcibios_resource_to_bus


 arch/alpha/include/asm/pci.h          |    6 -
 arch/alpha/kernel/pci.c               |   71 +----------
 arch/arm/common/it8152.c              |    4 -
 arch/arm/include/asm/pci.h            |    8 -
 arch/arm/kernel/bios32.c              |   69 +----------
 arch/arm/mach-cns3xxx/pcie.c          |    4 -
 arch/arm/mach-dove/pcie.c             |    4 -
 arch/arm/mach-footbridge/dc21285.c    |    8 +
 arch/arm/mach-integrator/pci_v3.c     |    7 +
 arch/arm/mach-iop13xx/pci.c           |    4 -
 arch/arm/mach-ixp2000/pci.c           |    6 +
 arch/arm/mach-ixp23xx/pci.c           |    6 +
 arch/arm/mach-ixp4xx/common-pci.c     |    4 -
 arch/arm/mach-kirkwood/pcie.c         |    4 -
 arch/arm/mach-ks8695/pci.c            |    4 -
 arch/arm/mach-mv78xx0/pcie.c          |    4 -
 arch/arm/mach-orion5x/pci.c           |   14 +-
 arch/arm/mach-sa1100/pci-nanoengine.c |    8 +
 arch/arm/mach-tegra/pcie.c            |    6 -
 arch/arm/mach-versatile/pci.c         |    6 -
 arch/arm/plat-iop/pci.c               |    4 -
 arch/ia64/include/asm/pci.h           |    6 -
 arch/ia64/pci/pci.c                   |   55 ---------
 arch/ia64/sn/kernel/io_init.c         |   16 ++-
 arch/microblaze/include/asm/pci.h     |    8 -
 arch/microblaze/pci/pci-common.c      |   69 -----------
 arch/mips/include/asm/pci.h           |    6 -
 arch/mips/pci/fixup-cobalt.c          |   61 ----------
 arch/mips/pci/pci.c                   |   70 -----------
 arch/mn10300/include/asm/pci.h        |   16 ---
 arch/mn10300/unit-asb2305/pci.c       |   62 +---------
 arch/parisc/include/asm/pci.h         |   38 ------
 arch/parisc/kernel/pci.c              |   52 --------
 arch/powerpc/include/asm/pci.h        |    8 -
 arch/powerpc/kernel/pci-common.c      |   79 +------------
 arch/sh/drivers/pci/pci.c             |   75 ++----------
 arch/sh/include/asm/pci.h             |    6 -
 arch/sparc/include/asm/pci_32.h       |    8 -
 arch/sparc/include/asm/pci_64.h       |    8 -
 arch/sparc/kernel/leon_pci.c          |   47 +------
 arch/sparc/kernel/pci.c               |   46 +------
 arch/xtensa/kernel/pci.c              |   17 ---
 drivers/parisc/dino.c                 |   27 +---
 drivers/parisc/lba_pci.c              |   31 +----
 drivers/pci/bus.c                     |   30 +++--
 drivers/pci/probe.c                   |  208 ++++++++++++++++++++++++++-------
 include/asm-generic/pci.h             |   24 ----
 include/linux/pci.h                   |   18 +++
 48 files changed, 331 insertions(+), 1011 deletions(-)

-- 
Signature

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [PATCH v2 01/18] PCI: don't publish new root bus until it's fully initialized
  2012-02-10  2:36 [PATCH v2 00/18] add PCI bus-to-resource offset support in core Bjorn Helgaas
@ 2012-02-10  2:36 ` Bjorn Helgaas
  2012-02-10  2:36 ` [PATCH v2 02/18] PCI: add struct pci_host_bridge and a list of all bridges found Bjorn Helgaas
                   ` (17 subsequent siblings)
  18 siblings, 0 replies; 34+ messages in thread
From: Bjorn Helgaas @ 2012-02-10  2:36 UTC (permalink / raw)
  To: linux-pci; +Cc: linux-arch

When pci_create_root_bus() adds the new struct pci_bus to the global
pci_root_buses list, the bus becomes visible to other parts of the
kernel, so it should be fully initialized.

This patch delays adding the bus to the pci_root_buses list until after
all the struct pci_bus initialization is finished.

Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
---
 drivers/pci/probe.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 7cc9e2f..da0d655 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1551,10 +1551,6 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
 		goto err_out;
 	}
 
-	down_write(&pci_bus_sem);
-	list_add_tail(&b->node, &pci_root_buses);
-	up_write(&pci_bus_sem);
-
 	dev->parent = parent;
 	dev->release = pci_release_bus_bridge_dev;
 	dev_set_name(dev, "pci%04x:%02x", pci_domain_nr(b), bus);
@@ -1594,6 +1590,10 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
 			dev_info(&b->dev, "root bus resource %pR\n", res);
 	}
 
+	down_write(&pci_bus_sem);
+	list_add_tail(&b->node, &pci_root_buses);
+	up_write(&pci_bus_sem);
+
 	return b;
 
 class_dev_reg_err:


^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v2 02/18] PCI: add struct pci_host_bridge and a list of all bridges found
  2012-02-10  2:36 [PATCH v2 00/18] add PCI bus-to-resource offset support in core Bjorn Helgaas
  2012-02-10  2:36 ` [PATCH v2 01/18] PCI: don't publish new root bus until it's fully initialized Bjorn Helgaas
@ 2012-02-10  2:36 ` Bjorn Helgaas
  2012-02-10  3:47   ` Yinghai Lu
  2012-02-10  2:36 ` [PATCH v2 03/18] PCI: add struct pci_host_bridge_window with CPU/bus address offset Bjorn Helgaas
                   ` (16 subsequent siblings)
  18 siblings, 1 reply; 34+ messages in thread
From: Bjorn Helgaas @ 2012-02-10  2:36 UTC (permalink / raw)
  To: linux-pci; +Cc: linux-arch

This adds a list of all PCI host bridges we find and a way to look up
the host bridge from a pci_dev.

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

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index da0d655..2ffe8a3 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -15,6 +15,8 @@
 #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);
@@ -42,6 +44,23 @@ 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;
+}
+
 /*
  * PCI Bus Class
  */
@@ -1526,20 +1545,23 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
 		struct pci_ops *ops, void *sysdata, struct list_head *resources)
 {
 	int error, i;
+	struct pci_host_bridge *bridge;
 	struct pci_bus *b, *b2;
 	struct device *dev;
 	struct pci_bus_resource *bus_res, *n;
 	struct resource *res;
 
+	bridge = kzalloc(sizeof(*bridge), GFP_KERNEL);
+	if (!bridge)
+		return NULL;
+
 	b = pci_alloc_bus();
 	if (!b)
-		return NULL;
+		goto err_bus;
 
 	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
-	if (!dev) {
-		kfree(b);
-		return NULL;
-	}
+	if (!dev)
+		goto err_dev;
 
 	b->sysdata = sysdata;
 	b->ops = ops;
@@ -1576,6 +1598,8 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
 
 	b->number = b->secondary = bus;
 
+	bridge->bus = b;
+
 	/* Add initial resources to the bus */
 	list_for_each_entry_safe(bus_res, n, resources, list)
 		list_move_tail(&bus_res->list, &b->resources);
@@ -1591,6 +1615,7 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
 	}
 
 	down_write(&pci_bus_sem);
+	list_add_tail(&bridge->list, &pci_host_bridges);
 	list_add_tail(&b->node, &pci_root_buses);
 	up_write(&pci_bus_sem);
 
@@ -1600,11 +1625,15 @@ class_dev_reg_err:
 	device_unregister(dev);
 dev_reg_err:
 	down_write(&pci_bus_sem);
+	list_del(&bridge->list);
 	list_del(&b->node);
 	up_write(&pci_bus_sem);
 err_out:
 	kfree(dev);
+err_dev:
 	kfree(b);
+err_bus:
+	kfree(bridge);
 	return NULL;
 }
 
diff --git a/include/linux/pci.h b/include/linux/pci.h
index a16b1df..dfb2b64 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -388,6 +388,11 @@ static inline void pci_add_saved_cap(struct pci_dev *pci_dev,
 	hlist_add_head(&new_cap->next, &pci_dev->saved_cap_space);
 }
 
+struct pci_host_bridge {
+	struct list_head list;
+	struct pci_bus *bus;		/* root bus */
+};
+
 /*
  * The first PCI_BRIDGE_RESOURCE_NUM PCI bus resources (those that correspond
  * to P2P or CardBus bridge windows) go in a table.  Additional ones (for


^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v2 03/18] PCI: add struct pci_host_bridge_window with CPU/bus address offset
  2012-02-10  2:36 [PATCH v2 00/18] add PCI bus-to-resource offset support in core Bjorn Helgaas
  2012-02-10  2:36 ` [PATCH v2 01/18] PCI: don't publish new root bus until it's fully initialized Bjorn Helgaas
  2012-02-10  2:36 ` [PATCH v2 02/18] PCI: add struct pci_host_bridge and a list of all bridges found Bjorn Helgaas
@ 2012-02-10  2:36 ` Bjorn Helgaas
  2012-02-10  3:49   ` Yinghai Lu
  2012-02-10  2:36 ` [PATCH v2 04/18] PCI: convert bus addresses to resource when reading BARs Bjorn Helgaas
                   ` (15 subsequent siblings)
  18 siblings, 1 reply; 34+ messages in thread
From: Bjorn Helgaas @ 2012-02-10  2:36 UTC (permalink / raw)
  To: linux-pci; +Cc: linux-arch

Some PCI host bridges apply an address offset, so bus addresses on PCI are
different from CPU addresses.  This patch adds a way for architectures to
tell the PCI core about this offset.  For example:

    LIST_HEAD(resources);
    pci_add_resource_offset(&resources, host->io_space, host->io_offset);
    pci_add_resource_offset(&resources, host->mem_space, host->mem_offset);
    pci_scan_root_bus(parent, bus, ops, sysdata, &resources);

Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
---
 drivers/pci/bus.c   |   30 +++++++++++++++++++-----------
 drivers/pci/probe.c |   32 +++++++++++++++++++++++---------
 include/linux/pci.h |    9 +++++++++
 3 files changed, 51 insertions(+), 20 deletions(-)

diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index 398f5d8..4ce5ef2 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -18,28 +18,36 @@
 
 #include "pci.h"
 
-void pci_add_resource(struct list_head *resources, struct resource *res)
+void pci_add_resource_offset(struct list_head *resources, struct resource *res,
+			     resource_size_t offset)
 {
-	struct pci_bus_resource *bus_res;
+	struct pci_host_bridge_window *window;
 
-	bus_res = kzalloc(sizeof(struct pci_bus_resource), GFP_KERNEL);
-	if (!bus_res) {
-		printk(KERN_ERR "PCI: can't add bus resource %pR\n", res);
+	window = kzalloc(sizeof(struct pci_host_bridge_window), GFP_KERNEL);
+	if (!window) {
+		printk(KERN_ERR "PCI: can't add host bridge window %pR\n", res);
 		return;
 	}
 
-	bus_res->res = res;
-	list_add_tail(&bus_res->list, resources);
+	window->res = res;
+	window->offset = offset;
+	list_add_tail(&window->list, resources);
+}
+EXPORT_SYMBOL(pci_add_resource_offset);
+
+void pci_add_resource(struct list_head *resources, struct resource *res)
+{
+	pci_add_resource_offset(resources, res, 0);
 }
 EXPORT_SYMBOL(pci_add_resource);
 
 void pci_free_resource_list(struct list_head *resources)
 {
-	struct pci_bus_resource *bus_res, *tmp;
+	struct pci_host_bridge_window *window, *tmp;
 
-	list_for_each_entry_safe(bus_res, tmp, resources, list) {
-		list_del(&bus_res->list);
-		kfree(bus_res);
+	list_for_each_entry_safe(window, tmp, resources, list) {
+		list_del(&window->list);
+		kfree(window);
 	}
 }
 EXPORT_SYMBOL(pci_free_resource_list);
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 2ffe8a3..69c1b11 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1544,12 +1544,15 @@ unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus)
 struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
 		struct pci_ops *ops, void *sysdata, struct list_head *resources)
 {
-	int error, i;
+	int error;
 	struct pci_host_bridge *bridge;
 	struct pci_bus *b, *b2;
 	struct device *dev;
-	struct pci_bus_resource *bus_res, *n;
+	struct pci_host_bridge_window *window, *n;
 	struct resource *res;
+	resource_size_t offset;
+	char bus_addr[64];
+	char *fmt;
 
 	bridge = kzalloc(sizeof(*bridge), GFP_KERNEL);
 	if (!bridge)
@@ -1599,19 +1602,30 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
 	b->number = b->secondary = bus;
 
 	bridge->bus = b;
-
-	/* Add initial resources to the bus */
-	list_for_each_entry_safe(bus_res, n, resources, list)
-		list_move_tail(&bus_res->list, &b->resources);
+	INIT_LIST_HEAD(&bridge->windows);
 
 	if (parent)
 		dev_info(parent, "PCI host bridge to bus %s\n", dev_name(&b->dev));
 	else
 		printk(KERN_INFO "PCI host bridge to bus %s\n", dev_name(&b->dev));
 
-	pci_bus_for_each_resource(b, res, i) {
-		if (res)
-			dev_info(&b->dev, "root bus resource %pR\n", res);
+	/* Add initial resources to the bus */
+	list_for_each_entry_safe(window, n, resources, list) {
+		list_move_tail(&window->list, &bridge->windows);
+		res = window->res;
+		offset = window->offset;
+		pci_bus_add_resource(b, res, 0);
+		if (offset) {
+			if (resource_type(res) == IORESOURCE_IO)
+				fmt = " (bus address [%#06llx-%#06llx])";
+			else
+				fmt = " (bus address [%#010llx-%#010llx])";
+			snprintf(bus_addr, sizeof(bus_addr), fmt,
+				 (unsigned long long) (res->start - offset),
+				 (unsigned long long) (res->end - offset));
+		} else
+			bus_addr[0] = '\0';
+		dev_info(&b->dev, "root bus resource %pR%s\n", res, bus_addr);
 	}
 
 	down_write(&pci_bus_sem);
diff --git a/include/linux/pci.h b/include/linux/pci.h
index dfb2b64..35ef2d1 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -388,9 +388,16 @@ static inline void pci_add_saved_cap(struct pci_dev *pci_dev,
 	hlist_add_head(&new_cap->next, &pci_dev->saved_cap_space);
 }
 
+struct pci_host_bridge_window {
+	struct list_head list;
+	struct resource *res;		/* host bridge aperture (CPU address) */
+	resource_size_t offset;		/* bus address + offset = CPU address */
+};
+
 struct pci_host_bridge {
 	struct list_head list;
 	struct pci_bus *bus;		/* root bus */
+	struct list_head windows;	/* pci_host_bridge_windows */
 };
 
 /*
@@ -919,6 +926,8 @@ void pci_release_selected_regions(struct pci_dev *, int);
 
 /* drivers/pci/bus.c */
 void pci_add_resource(struct list_head *resources, struct resource *res);
+void pci_add_resource_offset(struct list_head *resources, struct resource *res,
+			     resource_size_t offset);
 void pci_free_resource_list(struct list_head *resources);
 void pci_bus_add_resource(struct pci_bus *bus, struct resource *res, unsigned int flags);
 struct resource *pci_bus_resource_n(const struct pci_bus *bus, int n);


^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v2 04/18] PCI: convert bus addresses to resource when reading BARs
  2012-02-10  2:36 [PATCH v2 00/18] add PCI bus-to-resource offset support in core Bjorn Helgaas
                   ` (2 preceding siblings ...)
  2012-02-10  2:36 ` [PATCH v2 03/18] PCI: add struct pci_host_bridge_window with CPU/bus address offset Bjorn Helgaas
@ 2012-02-10  2:36 ` Bjorn Helgaas
  2012-02-10  2:36 ` [PATCH v2 05/18] PCI: add generic pcibios_resource_to_bus() Bjorn Helgaas
                   ` (14 subsequent siblings)
  18 siblings, 0 replies; 34+ messages in thread
From: Bjorn Helgaas @ 2012-02-10  2:36 UTC (permalink / raw)
  To: linux-pci; +Cc: linux-arch

Some PCI host bridges translate CPU addresses to PCI bus addresses.
Previously, we initialized pci_dev resources with PCI bus addresses,
then converted them to CPU addresses later in arch-specific code
(pcibios_fixup_resources()), which leaves a window of time where the
pci_dev resources are incorrect.

This patch adds support in the core for this address translation.
When the arch creates the root bus, it can supply the host bridge
address translation information, and the core can use it to set the
pci_dev resources correctly from the beginning.

This gives us a way to fix the problem that quirks that run between device
discovery and pcibios_fixup_resources() fail because they use pci_dev
resources that haven't been converted.  The reference below is to one
such problem that affected ARM and ia64.

Note that this patch has no effect until an arch starts using
pci_add_resource_offset() with a non-zero offset: before that, all
all host bridge windows have a zero offset and pci_bus_to_resource()
copies the pci_bus_region directly to the struct resource.

Reference: https://lkml.org/lkml/2009/10/12/405
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
---
 drivers/pci/probe.c |  129 +++++++++++++++++++++++++++++++++++++++++----------
 1 files changed, 104 insertions(+), 25 deletions(-)

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 69c1b11..3ae6304 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -61,6 +61,63 @@ static struct pci_host_bridge *pci_host_bridge(struct pci_dev *dev)
 	return NULL;
 }
 
+static bool resource_contains(struct resource *res1, struct resource *res2)
+{
+	return res1->start <= res2->start && res1->end >= res2->end;
+}
+
+void pci_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;
+}
+
+static bool region_contains(struct pci_bus_region *region1,
+			    struct pci_bus_region *region2)
+{
+	return region1->start <= region2->start && region1->end >= region2->end;
+}
+
+void pci_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;
+}
+
 /*
  * PCI Bus Class
  */
@@ -154,6 +211,7 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
 {
 	u32 l, sz, mask;
 	u16 orig_cmd;
+	struct pci_bus_region region;
 
 	mask = type ? PCI_ROM_ADDRESS_MASK : ~0;
 
@@ -233,11 +291,13 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
 			/* Address above 32-bit boundary; disable the BAR */
 			pci_write_config_dword(dev, pos, 0);
 			pci_write_config_dword(dev, pos + 4, 0);
-			res->start = 0;
-			res->end = sz64;
+			region.start = 0;
+			region.end = sz64;
+			pci_bus_to_resource(dev, res, &region);
 		} else {
-			res->start = l64;
-			res->end = l64 + sz64;
+			region.start = l64;
+			region.end = l64 + sz64;
+			pci_bus_to_resource(dev, res, &region);
 			dev_printk(KERN_DEBUG, &dev->dev, "reg %x: %pR\n",
 				   pos, res);
 		}
@@ -247,8 +307,9 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
 		if (!sz)
 			goto fail;
 
-		res->start = l;
-		res->end = l + sz;
+		region.start = l;
+		region.end = l + sz;
+		pci_bus_to_resource(dev, res, &region);
 
 		dev_printk(KERN_DEBUG, &dev->dev, "reg %x: %pR\n", pos, res);
 	}
@@ -285,7 +346,8 @@ static void __devinit pci_read_bridge_io(struct pci_bus *child)
 	struct pci_dev *dev = child->self;
 	u8 io_base_lo, io_limit_lo;
 	unsigned long base, limit;
-	struct resource *res;
+	struct pci_bus_region region;
+	struct resource *res, res2;
 
 	res = child->resource[0];
 	pci_read_config_byte(dev, PCI_IO_BASE, &io_base_lo);
@@ -303,10 +365,13 @@ static void __devinit pci_read_bridge_io(struct pci_bus *child)
 
 	if (base && base <= limit) {
 		res->flags = (io_base_lo & PCI_IO_RANGE_TYPE_MASK) | IORESOURCE_IO;
+		region.start = base;
+		region.end = limit + 0xfff;
+		pci_bus_to_resource(dev, &res2, &region);
 		if (!res->start)
-			res->start = base;
+			res->start = res2.start;
 		if (!res->end)
-			res->end = limit + 0xfff;
+			res->end = res2.end;
 		dev_printk(KERN_DEBUG, &dev->dev, "  bridge window %pR\n", res);
 	}
 }
@@ -316,6 +381,7 @@ static void __devinit pci_read_bridge_mmio(struct pci_bus *child)
 	struct pci_dev *dev = child->self;
 	u16 mem_base_lo, mem_limit_lo;
 	unsigned long base, limit;
+	struct pci_bus_region region;
 	struct resource *res;
 
 	res = child->resource[1];
@@ -325,8 +391,9 @@ static void __devinit pci_read_bridge_mmio(struct pci_bus *child)
 	limit = (mem_limit_lo & PCI_MEMORY_RANGE_MASK) << 16;
 	if (base && base <= limit) {
 		res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM;
-		res->start = base;
-		res->end = limit + 0xfffff;
+		region.start = base;
+		region.end = limit + 0xfffff;
+		pci_bus_to_resource(dev, res, &region);
 		dev_printk(KERN_DEBUG, &dev->dev, "  bridge window %pR\n", res);
 	}
 }
@@ -336,6 +403,7 @@ static void __devinit pci_read_bridge_mmio_pref(struct pci_bus *child)
 	struct pci_dev *dev = child->self;
 	u16 mem_base_lo, mem_limit_lo;
 	unsigned long base, limit;
+	struct pci_bus_region region;
 	struct resource *res;
 
 	res = child->resource[2];
@@ -372,8 +440,9 @@ static void __devinit pci_read_bridge_mmio_pref(struct pci_bus *child)
 					 IORESOURCE_MEM | IORESOURCE_PREFETCH;
 		if (res->flags & PCI_PREF_RANGE_TYPE_64)
 			res->flags |= IORESOURCE_MEM_64;
-		res->start = base;
-		res->end = limit + 0xfffff;
+		region.start = base;
+		region.end = limit + 0xfffff;
+		pci_bus_to_resource(dev, res, &region);
 		dev_printk(KERN_DEBUG, &dev->dev, "  bridge window %pR\n", res);
 	}
 }
@@ -914,6 +983,8 @@ int pci_setup_device(struct pci_dev *dev)
 	u8 hdr_type;
 	struct pci_slot *slot;
 	int pos = 0;
+	struct pci_bus_region region;
+	struct resource *res;
 
 	if (pci_read_config_byte(dev, PCI_HEADER_TYPE, &hdr_type))
 		return -EIO;
@@ -977,20 +1048,28 @@ int pci_setup_device(struct pci_dev *dev)
 			u8 progif;
 			pci_read_config_byte(dev, PCI_CLASS_PROG, &progif);
 			if ((progif & 1) == 0) {
-				dev->resource[0].start = 0x1F0;
-				dev->resource[0].end = 0x1F7;
-				dev->resource[0].flags = LEGACY_IO_RESOURCE;
-				dev->resource[1].start = 0x3F6;
-				dev->resource[1].end = 0x3F6;
-				dev->resource[1].flags = LEGACY_IO_RESOURCE;
+				region.start = 0x1F0;
+				region.end = 0x1F7;
+				res = &dev->resource[0];
+				res->flags = LEGACY_IO_RESOURCE;
+				pci_bus_to_resource(dev, res, &region);
+				region.start = 0x3F6;
+				region.end = 0x3F6;
+				res = &dev->resource[1];
+				res->flags = LEGACY_IO_RESOURCE;
+				pci_bus_to_resource(dev, res, &region);
 			}
 			if ((progif & 4) == 0) {
-				dev->resource[2].start = 0x170;
-				dev->resource[2].end = 0x177;
-				dev->resource[2].flags = LEGACY_IO_RESOURCE;
-				dev->resource[3].start = 0x376;
-				dev->resource[3].end = 0x376;
-				dev->resource[3].flags = LEGACY_IO_RESOURCE;
+				region.start = 0x170;
+				region.end = 0x177;
+				res = &dev->resource[2];
+				res->flags = LEGACY_IO_RESOURCE;
+				pci_bus_to_resource(dev, res, &region);
+				region.start = 0x376;
+				region.end = 0x376;
+				res = &dev->resource[3];
+				res->flags = LEGACY_IO_RESOURCE;
+				pci_bus_to_resource(dev, res, &region);
 			}
 		}
 		break;


^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v2 05/18] PCI: add generic pcibios_resource_to_bus()
  2012-02-10  2:36 [PATCH v2 00/18] add PCI bus-to-resource offset support in core Bjorn Helgaas
                   ` (3 preceding siblings ...)
  2012-02-10  2:36 ` [PATCH v2 04/18] PCI: convert bus addresses to resource when reading BARs Bjorn Helgaas
@ 2012-02-10  2:36 ` Bjorn Helgaas
  2012-02-10  2:36 ` [PATCH v2 06/18] alpha/PCI: get rid of device resource fixups Bjorn Helgaas
                   ` (13 subsequent siblings)
  18 siblings, 0 replies; 34+ messages in thread
From: Bjorn Helgaas @ 2012-02-10  2:36 UTC (permalink / raw)
  To: linux-pci; +Cc: linux-arch

This replaces the generic versions of pcibios_resource_to_bus() and
pcibios_bus_to_resource() in asm-generic/pci.h with versions that use
pci_resource_to_bus() and pci_bus_to_resource().

The replacements are equivalent except that they can apply host
bridge window offsets when the arch has supplied them by using
pci_add_resource_offset().

Each arch can convert to using pci_add_resource_offset() individually by
removing its device resource fixups from pcibios_fixup_bus() and supplying
ARCH_HAS_GENERIC_PCI_OFFSETS.  ARCH_HAS_GENERIC_PCI_OFFSETS can be removed
after all have converted.

Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
---
 drivers/pci/probe.c       |   16 ++++++++++++++++
 include/asm-generic/pci.h |   24 +-----------------------
 include/linux/pci.h       |    4 ++++
 3 files changed, 21 insertions(+), 23 deletions(-)

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 3ae6304..f3c503a 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -118,6 +118,22 @@ void pci_bus_to_resource(struct pci_dev *dev, struct resource *res,
 	res->end = region->end + offset;
 }
 
+#ifdef ARCH_HAS_GENERIC_PCI_OFFSETS
+void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
+			     struct resource *res)
+{
+	pci_resource_to_bus(dev, region, res);
+}
+EXPORT_SYMBOL(pcibios_resource_to_bus);
+
+void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
+			     struct pci_bus_region *region)
+{
+	pci_bus_to_resource(dev, res, region);
+}
+EXPORT_SYMBOL(pcibios_bus_to_resource);
+#endif
+
 /*
  * PCI Bus Class
  */
diff --git a/include/asm-generic/pci.h b/include/asm-generic/pci.h
index 26373cf..0410346 100644
--- a/include/asm-generic/pci.h
+++ b/include/asm-generic/pci.h
@@ -6,29 +6,7 @@
 #ifndef _ASM_GENERIC_PCI_H
 #define _ASM_GENERIC_PCI_H
 
-/**
- * pcibios_resource_to_bus - convert resource to PCI bus address
- * @dev: device which owns this resource
- * @region: converted bus-centric region (start,end)
- * @res: resource to convert
- *
- * Convert a resource to a PCI device bus address or bus window.
- */
-static inline 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;
-}
-
-static inline 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;
-}
+#define ARCH_HAS_GENERIC_PCI_OFFSETS
 
 static inline struct resource *
 pcibios_select_root(struct pci_dev *pdev, struct resource *res)
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 35ef2d1..a422217 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -668,6 +668,10 @@ void pci_fixup_cardbus(struct pci_bus *);
 
 /* Generic PCI functions used internally */
 
+void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
+			     struct resource *res);
+void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
+			     struct pci_bus_region *region);
 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);


^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v2 06/18] alpha/PCI: get rid of device resource fixups
  2012-02-10  2:36 [PATCH v2 00/18] add PCI bus-to-resource offset support in core Bjorn Helgaas
                   ` (4 preceding siblings ...)
  2012-02-10  2:36 ` [PATCH v2 05/18] PCI: add generic pcibios_resource_to_bus() Bjorn Helgaas
@ 2012-02-10  2:36 ` Bjorn Helgaas
  2012-02-10  2:36 ` [PATCH v2 07/18] arm/PCI: " Bjorn Helgaas
                   ` (12 subsequent siblings)
  18 siblings, 0 replies; 34+ messages in thread
From: Bjorn Helgaas @ 2012-02-10  2:36 UTC (permalink / raw)
  To: linux-pci; +Cc: linux-arch, linux-alpha

Tell the PCI core about host bridge address translation so it can take
care of bus-to-resource conversion for us.

CC: linux-alpha@vger.kernel.org
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
---
 arch/alpha/include/asm/pci.h |    6 +---
 arch/alpha/kernel/pci.c      |   71 ++----------------------------------------
 2 files changed, 5 insertions(+), 72 deletions(-)

diff --git a/arch/alpha/include/asm/pci.h b/arch/alpha/include/asm/pci.h
index 28d0497..dace435 100644
--- a/arch/alpha/include/asm/pci.h
+++ b/arch/alpha/include/asm/pci.h
@@ -99,11 +99,7 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
 	return channel ? 15 : 14;
 }
 
-extern void pcibios_resource_to_bus(struct pci_dev *, struct pci_bus_region *,
-				    struct resource *);
-
-extern void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
-				    struct pci_bus_region *region);
+#define ARCH_HAS_GENERIC_PCI_OFFSETS
 
 #define pci_domain_nr(bus) ((struct pci_controller *)(bus)->sysdata)->index
 
diff --git a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c
index 8c723c1..ee74503 100644
--- a/arch/alpha/kernel/pci.c
+++ b/arch/alpha/kernel/pci.c
@@ -253,32 +253,6 @@ pci_restore_srm_config(void)
 #endif
 
 void __devinit
-pcibios_fixup_resource(struct resource *res, struct resource *root)
-{
-	res->start += root->start;
-	res->end += root->start;
-}
-
-void __devinit
-pcibios_fixup_device_resources(struct pci_dev *dev, struct pci_bus *bus)
-{
-	/* Update device resources.  */
-	struct pci_controller *hose = (struct pci_controller *)bus->sysdata;
-	int i;
-
-	for (i = 0; i < PCI_NUM_RESOURCES; i++) {
-		if (!dev->resource[i].start)
-			continue;
-		if (dev->resource[i].flags & IORESOURCE_IO)
-			pcibios_fixup_resource(&dev->resource[i],
-					       hose->io_space);
-		else if (dev->resource[i].flags & IORESOURCE_MEM)
-			pcibios_fixup_resource(&dev->resource[i],
-					       hose->mem_space);
-	}
-}
-
-void __devinit
 pcibios_fixup_bus(struct pci_bus *bus)
 {
 	struct pci_dev *dev = bus->self;
@@ -286,13 +260,10 @@ pcibios_fixup_bus(struct pci_bus *bus)
 	if (pci_probe_only && dev &&
  		   (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
  		pci_read_bridge_bases(bus);
- 		pcibios_fixup_device_resources(dev, bus);
 	} 
 
 	list_for_each_entry(dev, &bus->devices, bus_list) {
 		pdev_save_srm_config(dev);
-		if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
-			pcibios_fixup_device_resources(dev, bus);
 	}
 }
 
@@ -302,42 +273,6 @@ pcibios_update_irq(struct pci_dev *dev, int irq)
 	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
 }
 
-void
-pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
-			 struct resource *res)
-{
-	struct pci_controller *hose = (struct pci_controller *)dev->sysdata;
-	unsigned long offset = 0;
-
-	if (res->flags & IORESOURCE_IO)
-		offset = hose->io_space->start;
-	else if (res->flags & IORESOURCE_MEM)
-		offset = hose->mem_space->start;
-
-	region->start = res->start - offset;
-	region->end = res->end - offset;
-}
-
-void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
-			     struct pci_bus_region *region)
-{
-	struct pci_controller *hose = (struct pci_controller *)dev->sysdata;
-	unsigned long offset = 0;
-
-	if (res->flags & IORESOURCE_IO)
-		offset = hose->io_space->start;
-	else if (res->flags & IORESOURCE_MEM)
-		offset = hose->mem_space->start;
-
-	res->start = region->start + offset;
-	res->end = region->end + offset;
-}
-
-#ifdef CONFIG_HOTPLUG
-EXPORT_SYMBOL(pcibios_resource_to_bus);
-EXPORT_SYMBOL(pcibios_bus_to_resource);
-#endif
-
 int
 pcibios_enable_device(struct pci_dev *dev, int mask)
 {
@@ -416,8 +351,10 @@ common_init_pci(void)
 			hose->mem_space->end = end;
 
 		INIT_LIST_HEAD(&resources);
-		pci_add_resource(&resources, hose->io_space);
-		pci_add_resource(&resources, hose->mem_space);
+		pci_add_resource_offset(&resources, hose->io_space,
+					hose->io_space->start);
+		pci_add_resource_offset(&resources, hose->mem_space,
+					hose->mem_space->start);
 
 		bus = pci_scan_root_bus(NULL, next_busno, alpha_mv.pci_ops,
 					hose, &resources);


^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v2 07/18] arm/PCI: get rid of device resource fixups
  2012-02-10  2:36 [PATCH v2 00/18] add PCI bus-to-resource offset support in core Bjorn Helgaas
                   ` (5 preceding siblings ...)
  2012-02-10  2:36 ` [PATCH v2 06/18] alpha/PCI: get rid of device resource fixups Bjorn Helgaas
@ 2012-02-10  2:36 ` Bjorn Helgaas
  2012-02-10  2:37 ` [PATCH v2 08/18] ia64/PCI: SN: convert to pci_scan_root_bus() for correct root bus resources Bjorn Helgaas
                   ` (11 subsequent siblings)
  18 siblings, 0 replies; 34+ messages in thread
From: Bjorn Helgaas @ 2012-02-10  2:36 UTC (permalink / raw)
  To: linux-pci; +Cc: linux-arch, Russell King

Tell the PCI core about host bridge address translation so it can take
care of bus-to-resource conversion for us.

CC: Russell King <linux@arm.linux.org.uk>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
---
 arch/arm/common/it8152.c              |    4 +-
 arch/arm/include/asm/pci.h            |    8 ----
 arch/arm/kernel/bios32.c              |   69 ++-------------------------------
 arch/arm/mach-cns3xxx/pcie.c          |    4 +-
 arch/arm/mach-dove/pcie.c             |    4 +-
 arch/arm/mach-footbridge/dc21285.c    |    8 ++--
 arch/arm/mach-integrator/pci_v3.c     |    7 ++-
 arch/arm/mach-iop13xx/pci.c           |    4 +-
 arch/arm/mach-ixp2000/pci.c           |    6 ++-
 arch/arm/mach-ixp23xx/pci.c           |    6 ++-
 arch/arm/mach-ixp4xx/common-pci.c     |    4 +-
 arch/arm/mach-kirkwood/pcie.c         |    4 +-
 arch/arm/mach-ks8695/pci.c            |    4 +-
 arch/arm/mach-mv78xx0/pcie.c          |    4 +-
 arch/arm/mach-orion5x/pci.c           |   14 +++----
 arch/arm/mach-sa1100/pci-nanoengine.c |    8 ++--
 arch/arm/mach-tegra/pcie.c            |    6 +--
 arch/arm/mach-versatile/pci.c         |    6 +--
 arch/arm/plat-iop/pci.c               |    4 +-
 19 files changed, 57 insertions(+), 117 deletions(-)

diff --git a/arch/arm/common/it8152.c b/arch/arm/common/it8152.c
index d1bcd7b..9384c2d 100644
--- a/arch/arm/common/it8152.c
+++ b/arch/arm/common/it8152.c
@@ -299,8 +299,8 @@ int __init it8152_pci_setup(int nr, struct pci_sys_data *sys)
 		goto err1;
 	}
 
-	pci_add_resource(&sys->resources, &it8152_io);
-	pci_add_resource(&sys->resources, &it8152_mem);
+	pci_add_resource_offset(&sys->resources, &it8152_io, sys->io_offset);
+	pci_add_resource_offset(&sys->resources, &it8152_mem, sys->mem_offset);
 
 	if (platform_notify || platform_notify_remove) {
 		printk(KERN_ERR "PCI: Can't use platform_notify\n");
diff --git a/arch/arm/include/asm/pci.h b/arch/arm/include/asm/pci.h
index da337ba..4748a75 100644
--- a/arch/arm/include/asm/pci.h
+++ b/arch/arm/include/asm/pci.h
@@ -57,13 +57,7 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev,
 extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
                                enum pci_mmap_state mmap_state, int write_combine);
 
-extern void
-pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
-			 struct resource *res);
-
-extern void
-pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
-			struct pci_bus_region *region);
+#define ARCH_HAS_GENERIC_PCI_OFFSETS
 
 /*
  * Dummy implementation; always return 0.
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index f58ba35..b2f1ecf 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -295,28 +295,6 @@ static inline int pdev_bad_for_parity(struct pci_dev *dev)
 }
 
 /*
- * Adjust the device resources from bus-centric to Linux-centric.
- */
-static void __devinit
-pdev_fixup_device_resources(struct pci_sys_data *root, struct pci_dev *dev)
-{
-	resource_size_t offset;
-	int i;
-
-	for (i = 0; i < PCI_NUM_RESOURCES; i++) {
-		if (dev->resource[i].start == 0)
-			continue;
-		if (dev->resource[i].flags & IORESOURCE_MEM)
-			offset = root->mem_offset;
-		else
-			offset = root->io_offset;
-
-		dev->resource[i].start += offset;
-		dev->resource[i].end   += offset;
-	}
-}
-
-/*
  * pcibios_fixup_bus - Called after each bus is probed,
  * but before its children are examined.
  */
@@ -333,8 +311,6 @@ void pcibios_fixup_bus(struct pci_bus *bus)
 	list_for_each_entry(dev, &bus->devices, bus_list) {
 		u16 status;
 
-		pdev_fixup_device_resources(root, dev);
-
 		pci_read_config_word(dev, PCI_STATUS, &status);
 
 		/*
@@ -400,43 +376,6 @@ EXPORT_SYMBOL(pcibios_fixup_bus);
 #endif
 
 /*
- * Convert from Linux-centric to bus-centric addresses for bridge devices.
- */
-void
-pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
-			 struct resource *res)
-{
-	struct pci_sys_data *root = dev->sysdata;
-	unsigned long offset = 0;
-
-	if (res->flags & IORESOURCE_IO)
-		offset = root->io_offset;
-	if (res->flags & IORESOURCE_MEM)
-		offset = root->mem_offset;
-
-	region->start = res->start - offset;
-	region->end   = res->end - offset;
-}
-EXPORT_SYMBOL(pcibios_resource_to_bus);
-
-void __devinit
-pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
-			struct pci_bus_region *region)
-{
-	struct pci_sys_data *root = dev->sysdata;
-	unsigned long offset = 0;
-
-	if (res->flags & IORESOURCE_IO)
-		offset = root->io_offset;
-	if (res->flags & IORESOURCE_MEM)
-		offset = root->mem_offset;
-
-	res->start = region->start + offset;
-	res->end   = region->end + offset;
-}
-EXPORT_SYMBOL(pcibios_bus_to_resource);
-
-/*
  * Swizzle the device pin each time we cross a bridge.
  * This might update pin and returns the slot number.
  */
@@ -497,10 +436,10 @@ static void __init pcibios_init_hw(struct hw_pci *hw)
 
 		if (ret > 0) {
 			if (list_empty(&sys->resources)) {
-				pci_add_resource(&sys->resources,
-						 &ioport_resource);
-				pci_add_resource(&sys->resources,
-						 &iomem_resource);
+				pci_add_resource_offset(&sys->resources,
+					 &ioport_resource, sys->io_offset);
+				pci_add_resource_offset(&sys->resources,
+					 &iomem_resource, sys->mem_offset);
 			}
 
 			sys->bus = hw->scan(nr, sys);
diff --git a/arch/arm/mach-cns3xxx/pcie.c b/arch/arm/mach-cns3xxx/pcie.c
index e159d69..79d001f 100644
--- a/arch/arm/mach-cns3xxx/pcie.c
+++ b/arch/arm/mach-cns3xxx/pcie.c
@@ -155,8 +155,8 @@ static int cns3xxx_pci_setup(int nr, struct pci_sys_data *sys)
 	BUG_ON(request_resource(&iomem_resource, res_io) ||
 	       request_resource(&iomem_resource, res_mem));
 
-	pci_add_resource(&sys->resources, res_io);
-	pci_add_resource(&sys->resources, res_mem);
+	pci_add_resource_offset(&sys->resources, res_io, sys->io_offset);
+	pci_add_resource_offset(&sys->resources, res_mem, sys->mem_offset);
 
 	return 1;
 }
diff --git a/arch/arm/mach-dove/pcie.c b/arch/arm/mach-dove/pcie.c
index 52e96d3..48a0320 100644
--- a/arch/arm/mach-dove/pcie.c
+++ b/arch/arm/mach-dove/pcie.c
@@ -69,7 +69,7 @@ static int __init dove_pcie_setup(int nr, struct pci_sys_data *sys)
 	pp->res[0].flags = IORESOURCE_IO;
 	if (request_resource(&ioport_resource, &pp->res[0]))
 		panic("Request PCIe IO resource failed\n");
-	pci_add_resource(&sys->resources, &pp->res[0]);
+	pci_add_resource_offset(&sys->resources, &pp->res[0], sys->io_offset);
 
 	/*
 	 * IORESOURCE_MEM
@@ -88,7 +88,7 @@ static int __init dove_pcie_setup(int nr, struct pci_sys_data *sys)
 	pp->res[1].flags = IORESOURCE_MEM;
 	if (request_resource(&iomem_resource, &pp->res[1]))
 		panic("Request PCIe Memory resource failed\n");
-	pci_add_resource(&sys->resources, &pp->res[1]);
+	pci_add_resource_offset(&sys->resources, &pp->res[1], sys->mem_offset);
 
 	return 1;
 }
diff --git a/arch/arm/mach-footbridge/dc21285.c b/arch/arm/mach-footbridge/dc21285.c
index f685650..3194d3f 100644
--- a/arch/arm/mach-footbridge/dc21285.c
+++ b/arch/arm/mach-footbridge/dc21285.c
@@ -275,11 +275,13 @@ int __init dc21285_setup(int nr, struct pci_sys_data *sys)
 	allocate_resource(&iomem_resource, &res[0], 0x40000000,
 			  0x80000000, 0xffffffff, 0x40000000, NULL, NULL);
 
-	pci_add_resource(&sys->resources, &ioport_resource);
-	pci_add_resource(&sys->resources, &res[0]);
-	pci_add_resource(&sys->resources, &res[1]);
 	sys->mem_offset  = DC21285_PCI_MEM;
 
+	pci_add_resource_offset(&sys->resources,
+				&ioport_resource, sys->io_offset);
+	pci_add_resource_offset(&sys->resources, &res[0], sys->mem_offset);
+	pci_add_resource_offset(&sys->resources, &res[1], sys->mem_offset);
+
 	return 1;
 }
 
diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c
index 3c82566..015be77 100644
--- a/arch/arm/mach-integrator/pci_v3.c
+++ b/arch/arm/mach-integrator/pci_v3.c
@@ -378,9 +378,10 @@ static int __init pci_v3_setup_resources(struct pci_sys_data *sys)
 	 * the mem resource for this bus
 	 * the prefetch mem resource for this bus
 	 */
-	pci_add_resource(&sys->resources, &ioport_resource);
-	pci_add_resource(&sys->resources, &non_mem);
-	pci_add_resource(&sys->resources, &pre_mem);
+	pci_add_resource_offset(&sys->resources,
+				&ioport_resource, sys->io_offset);
+	pci_add_resource_offset(&sys->resources, &non_mem, sys->mem_offset);
+	pci_add_resource_offset(&sys->resources, &pre_mem, sys->mem_offset);
 
 	return 1;
 }
diff --git a/arch/arm/mach-iop13xx/pci.c b/arch/arm/mach-iop13xx/pci.c
index b8f5a87..861cb12 100644
--- a/arch/arm/mach-iop13xx/pci.c
+++ b/arch/arm/mach-iop13xx/pci.c
@@ -1084,8 +1084,8 @@ int iop13xx_pci_setup(int nr, struct pci_sys_data *sys)
 	request_resource(&ioport_resource, &res[0]);
 	request_resource(&iomem_resource, &res[1]);
 
-	pci_add_resource(&sys->resources, &res[0]);
-	pci_add_resource(&sys->resources, &res[1]);
+	pci_add_resource_offset(&sys->resources, &res[0], sys->io_offset);
+	pci_add_resource_offset(&sys->resources, &res[1], sys->mem_offset);
 
 	return 1;
 }
diff --git a/arch/arm/mach-ixp2000/pci.c b/arch/arm/mach-ixp2000/pci.c
index 626fda4..49c36f3 100644
--- a/arch/arm/mach-ixp2000/pci.c
+++ b/arch/arm/mach-ixp2000/pci.c
@@ -243,8 +243,10 @@ int ixp2000_pci_setup(int nr, struct pci_sys_data *sys)
 	if (nr >= 1)
 		return 0;
 
-	pci_add_resource(&sys->resources, &ixp2000_pci_io_space);
-	pci_add_resource(&sys->resources, &ixp2000_pci_mem_space);
+	pci_add_resource_offset(&sys->resources,
+				&ixp2000_pci_io_space, sys->io_offset);
+	pci_add_resource_offset(&sys->resources,
+				&ixp2000_pci_mem_space, sys->mem_offset);
 
 	return 1;
 }
diff --git a/arch/arm/mach-ixp23xx/pci.c b/arch/arm/mach-ixp23xx/pci.c
index 25b5c46..3cbbd32 100644
--- a/arch/arm/mach-ixp23xx/pci.c
+++ b/arch/arm/mach-ixp23xx/pci.c
@@ -281,8 +281,10 @@ int ixp23xx_pci_setup(int nr, struct pci_sys_data *sys)
 	if (nr >= 1)
 		return 0;
 
-	pci_add_resource(&sys->resources, &ixp23xx_pci_io_space);
-	pci_add_resource(&sys->resources, &ixp23xx_pci_mem_space);
+	pci_add_resource_offset(&sys->resources,
+				&ixp23xx_pci_io_space, sys->io_offset);
+	pci_add_resource_offset(&sys->resources,
+				&ixp23xx_pci_mem_space, sys->mem_offset);
 
 	return 1;
 }
diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c
index 5eff15f..8508882 100644
--- a/arch/arm/mach-ixp4xx/common-pci.c
+++ b/arch/arm/mach-ixp4xx/common-pci.c
@@ -472,8 +472,8 @@ int ixp4xx_setup(int nr, struct pci_sys_data *sys)
 	request_resource(&ioport_resource, &res[0]);
 	request_resource(&iomem_resource, &res[1]);
 
-	pci_add_resource(&sys->resources, &res[0]);
-	pci_add_resource(&sys->resources, &res[1]);
+	pci_add_resource_offset(&sys->resources, &res[0], sys->io_offset);
+	pci_add_resource_offset(&sys->resources, &res[1], sys->mem_offset);
 
 	platform_notify = ixp4xx_pci_platform_notify;
 	platform_notify_remove = ixp4xx_pci_platform_notify_remove;
diff --git a/arch/arm/mach-kirkwood/pcie.c b/arch/arm/mach-kirkwood/pcie.c
index a066a6d..f56a011 100644
--- a/arch/arm/mach-kirkwood/pcie.c
+++ b/arch/arm/mach-kirkwood/pcie.c
@@ -198,9 +198,9 @@ static int __init kirkwood_pcie_setup(int nr, struct pci_sys_data *sys)
 	if (request_resource(&iomem_resource, &pp->res[1]))
 		panic("Request PCIe%d Memory resource failed\n", index);
 
-	pci_add_resource(&sys->resources, &pp->res[0]);
-	pci_add_resource(&sys->resources, &pp->res[1]);
 	sys->io_offset = 0;
+	pci_add_resource_offset(&sys->resources, &pp->res[0], sys->io_offset);
+	pci_add_resource_offset(&sys->resources, &pp->res[1], sys->mem_offset);
 
 	/*
 	 * Generic PCIe unit setup.
diff --git a/arch/arm/mach-ks8695/pci.c b/arch/arm/mach-ks8695/pci.c
index b26f992..acc7014 100644
--- a/arch/arm/mach-ks8695/pci.c
+++ b/arch/arm/mach-ks8695/pci.c
@@ -169,8 +169,8 @@ static int __init ks8695_pci_setup(int nr, struct pci_sys_data *sys)
 	request_resource(&iomem_resource, &pci_mem);
 	request_resource(&ioport_resource, &pci_io);
 
-	pci_add_resource(&sys->resources, &pci_io);
-	pci_add_resource(&sys->resources, &pci_mem);
+	pci_add_resource_offset(&sys->resources, &pci_io, sys->io_offset);
+	pci_add_resource_offset(&sys->resources, &pci_mem, sys->mem_offset);
 
 	/* Assign and enable processor bridge */
 	ks8695_local_writeconfig(PCI_BASE_ADDRESS_0, KS8695_PCIMEM_PA);
diff --git a/arch/arm/mach-mv78xx0/pcie.c b/arch/arm/mach-mv78xx0/pcie.c
index 8459f6d..df3e380 100644
--- a/arch/arm/mach-mv78xx0/pcie.c
+++ b/arch/arm/mach-mv78xx0/pcie.c
@@ -155,8 +155,8 @@ static int __init mv78xx0_pcie_setup(int nr, struct pci_sys_data *sys)
 	orion_pcie_set_local_bus_nr(pp->base, sys->busnr);
 	orion_pcie_setup(pp->base);
 
-	pci_add_resource(&sys->resources, &pp->res[0]);
-	pci_add_resource(&sys->resources, &pp->res[1]);
+	pci_add_resource_offset(&sys->resources, &pp->res[0], sys->io_offset);
+	pci_add_resource_offset(&sys->resources, &pp->res[1], sys->mem_offset);
 
 	return 1;
 }
diff --git a/arch/arm/mach-orion5x/pci.c b/arch/arm/mach-orion5x/pci.c
index 09a045f..d6a9194 100644
--- a/arch/arm/mach-orion5x/pci.c
+++ b/arch/arm/mach-orion5x/pci.c
@@ -171,13 +171,14 @@ static int __init pcie_setup(struct pci_sys_data *sys)
 	/*
 	 * IORESOURCE_IO
 	 */
+	sys->io_offset = 0;
 	res[0].name = "PCIe I/O Space";
 	res[0].flags = IORESOURCE_IO;
 	res[0].start = ORION5X_PCIE_IO_BUS_BASE;
 	res[0].end = res[0].start + ORION5X_PCIE_IO_SIZE - 1;
 	if (request_resource(&ioport_resource, &res[0]))
 		panic("Request PCIe IO resource failed\n");
-	pci_add_resource(&sys->resources, &res[0]);
+	pci_add_resource_offset(&sys->resources, &res[0], sys->io_offset);
 
 	/*
 	 * IORESOURCE_MEM
@@ -188,9 +189,7 @@ static int __init pcie_setup(struct pci_sys_data *sys)
 	res[1].end = res[1].start + ORION5X_PCIE_MEM_SIZE - 1;
 	if (request_resource(&iomem_resource, &res[1]))
 		panic("Request PCIe Memory resource failed\n");
-	pci_add_resource(&sys->resources, &res[1]);
-
-	sys->io_offset = 0;
+	pci_add_resource_offset(&sys->resources, &res[1], sys->mem_offset);
 
 	return 1;
 }
@@ -499,13 +498,14 @@ static int __init pci_setup(struct pci_sys_data *sys)
 	/*
 	 * IORESOURCE_IO
 	 */
+	sys->io_offset = 0;
 	res[0].name = "PCI I/O Space";
 	res[0].flags = IORESOURCE_IO;
 	res[0].start = ORION5X_PCI_IO_BUS_BASE;
 	res[0].end = res[0].start + ORION5X_PCI_IO_SIZE - 1;
 	if (request_resource(&ioport_resource, &res[0]))
 		panic("Request PCI IO resource failed\n");
-	pci_add_resource(&sys->resources, &res[0]);
+	pci_add_resource_offset(&sys->resources, &res[0], sys->io_offset);
 
 	/*
 	 * IORESOURCE_MEM
@@ -516,9 +516,7 @@ static int __init pci_setup(struct pci_sys_data *sys)
 	res[1].end = res[1].start + ORION5X_PCI_MEM_SIZE - 1;
 	if (request_resource(&iomem_resource, &res[1]))
 		panic("Request PCI Memory resource failed\n");
-	pci_add_resource(&sys->resources, &res[1]);
-
-	sys->io_offset = 0;
+	pci_add_resource_offset(&sys->resources, &res[1], sys->mem_offset);
 
 	return 1;
 }
diff --git a/arch/arm/mach-sa1100/pci-nanoengine.c b/arch/arm/mach-sa1100/pci-nanoengine.c
index 0d01ca7..b466bca 100644
--- a/arch/arm/mach-sa1100/pci-nanoengine.c
+++ b/arch/arm/mach-sa1100/pci-nanoengine.c
@@ -244,9 +244,11 @@ static int __init pci_nanoengine_setup_resources(struct pci_sys_data *sys)
 		printk(KERN_ERR "PCI: unable to allocate prefetchable\n");
 		return -EBUSY;
 	}
-	pci_add_resource(&sys->resources, &pci_io_ports);
-	pci_add_resource(&sys->resources, &pci_non_prefetchable_memory);
-	pci_add_resource(&sys->resources, &pci_prefetchable_memory);
+	pci_add_resource_offset(&sys->resources, &pci_io_ports, sys->io_offset);
+	pci_add_resource_offset(&sys->resources,
+				&pci_non_prefetchable_memory, sys->mem_offset);
+	pci_add_resource_offset(&sys->resources,
+				&pci_prefetchable_memory, sys->mem_offset);
 
 	return 1;
 }
diff --git a/arch/arm/mach-tegra/pcie.c b/arch/arm/mach-tegra/pcie.c
index af8b634..14b29ab 100644
--- a/arch/arm/mach-tegra/pcie.c
+++ b/arch/arm/mach-tegra/pcie.c
@@ -408,7 +408,7 @@ static int tegra_pcie_setup(int nr, struct pci_sys_data *sys)
 	pp->res[0].flags = IORESOURCE_IO;
 	if (request_resource(&ioport_resource, &pp->res[0]))
 		panic("Request PCIe IO resource failed\n");
-	pci_add_resource(&sys->resources, &pp->res[0]);
+	pci_add_resource_offset(&sys->resources, &pp->res[0], sys->io_offset);
 
 	/*
 	 * IORESOURCE_MEM
@@ -427,7 +427,7 @@ static int tegra_pcie_setup(int nr, struct pci_sys_data *sys)
 	pp->res[1].flags = IORESOURCE_MEM;
 	if (request_resource(&iomem_resource, &pp->res[1]))
 		panic("Request PCIe Memory resource failed\n");
-	pci_add_resource(&sys->resources, &pp->res[1]);
+	pci_add_resource_offset(&sys->resources, &pp->res[1], sys->mem_offset);
 
 	/*
 	 * IORESOURCE_MEM | IORESOURCE_PREFETCH
@@ -446,7 +446,7 @@ static int tegra_pcie_setup(int nr, struct pci_sys_data *sys)
 	pp->res[2].flags = IORESOURCE_MEM | IORESOURCE_PREFETCH;
 	if (request_resource(&iomem_resource, &pp->res[2]))
 		panic("Request PCIe Prefetch Memory resource failed\n");
-	pci_add_resource(&sys->resources, &pp->res[2]);
+	pci_add_resource_offset(&sys->resources, &pp->res[2], sys->mem_offset);
 
 	return 1;
 }
diff --git a/arch/arm/mach-versatile/pci.c b/arch/arm/mach-versatile/pci.c
index 90069bc..51733b0 100644
--- a/arch/arm/mach-versatile/pci.c
+++ b/arch/arm/mach-versatile/pci.c
@@ -219,9 +219,9 @@ static int __init pci_versatile_setup_resources(struct list_head *resources)
 	 * the mem resource for this bus
 	 * the prefetch mem resource for this bus
 	 */
-	pci_add_resource(resources, &io_mem);
-	pci_add_resource(resources, &non_mem);
-	pci_add_resource(resources, &pre_mem);
+	pci_add_resource_offset(resources, &io_mem, sys->io_offset);
+	pci_add_resource_offset(resources, &non_mem, sys->mem_offset);
+	pci_add_resource_offset(resources, &pre_mem, sys->mem_offset);
 
 	goto out;
 
diff --git a/arch/arm/plat-iop/pci.c b/arch/arm/plat-iop/pci.c
index f4d40a2..7276835 100644
--- a/arch/arm/plat-iop/pci.c
+++ b/arch/arm/plat-iop/pci.c
@@ -215,8 +215,8 @@ int iop3xx_pci_setup(int nr, struct pci_sys_data *sys)
 	sys->mem_offset = IOP3XX_PCI_LOWER_MEM_PA - *IOP3XX_OMWTVR0;
 	sys->io_offset  = IOP3XX_PCI_LOWER_IO_PA - *IOP3XX_OIOWTVR;
 
-	pci_add_resource(&sys->resources, &res[0]);
-	pci_add_resource(&sys->resources, &res[1]);
+	pci_add_resource_offset(&sys->resources, &res[0], sys->io_offset);
+	pci_add_resource_offset(&sys->resources, &res[1], sys->mem_offset);
 
 	return 1;
 }


^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v2 08/18] ia64/PCI: SN: convert to pci_scan_root_bus() for correct root bus resources
  2012-02-10  2:36 [PATCH v2 00/18] add PCI bus-to-resource offset support in core Bjorn Helgaas
                   ` (6 preceding siblings ...)
  2012-02-10  2:36 ` [PATCH v2 07/18] arm/PCI: " Bjorn Helgaas
@ 2012-02-10  2:37 ` Bjorn Helgaas
  2012-02-10  2:46   ` Bjorn Helgaas
  2012-02-10  2:37 ` [PATCH v2 09/18] ia64/PCI: get rid of device resource fixups Bjorn Helgaas
                   ` (10 subsequent siblings)
  18 siblings, 1 reply; 34+ messages in thread
From: Bjorn Helgaas @ 2012-02-10  2:37 UTC (permalink / raw)
  To: linux-pci; +Cc: linux-arch, Tony Luck, Jack Steiner

Convert from pci_scan_bus() to pci_scan_root_bus().  Supply the root
bus resources from bussoft.  When we move the resource adjustment from
pcibios_fixup_resources() to the PCI core, it will be important to have
the root bus resources correct from the beginning.

CC: Tony Luck <tony.luck@intel.com>
CC: Jack Steiner <steiner@sgi.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
---
 arch/ia64/sn/kernel/io_init.c |   14 +++++++++-----
 1 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c
index 0a36f08..c99c2ca 100644
--- a/arch/ia64/sn/kernel/io_init.c
+++ b/arch/ia64/sn/kernel/io_init.c
@@ -297,7 +297,8 @@ sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus)
 	s64 status = 0;
 	struct pci_controller *controller;
 	struct pcibus_bussoft *prom_bussoft_ptr;
-
+	LIST_HEAD(resources);
+	int i;
 
  	status = sal_get_pcibus_info((u64) segment, (u64) busnum,
  				     (u64) ia64_tpa(&prom_bussoft_ptr));
@@ -315,7 +316,13 @@ sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus)
 	 */
 	controller->platform_data = prom_bussoft_ptr;
 
-	bus = pci_scan_bus(busnum, &pci_root_ops, controller);
+	sn_legacy_pci_window_fixup(controller,
+				   prom_bussoft_ptr->bs_legacy_io,
+				   prom_bussoft_ptr->bs_legacy_mem);
+	for (i = 0; i < controller->windows; i++)
+		pci_add_resource(&resources, &controller->window[i].resource);
+	bus = pci_scan_root_bus(NULL, busnum, &pci_root_ops, controller,
+				&resources);
  	if (bus == NULL)
  		goto error_return; /* error, or bus already scanned */
 
@@ -348,9 +355,6 @@ sn_bus_fixup(struct pci_bus *bus)
 			return;
 		}
 		sn_common_bus_fixup(bus, prom_bussoft_ptr);
-		sn_legacy_pci_window_fixup(PCI_CONTROLLER(bus),
-					   prom_bussoft_ptr->bs_legacy_io,
-					   prom_bussoft_ptr->bs_legacy_mem);
         }
         list_for_each_entry(pci_dev, &bus->devices, bus_list) {
                 sn_io_slot_fixup(pci_dev);


^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v2 09/18] ia64/PCI: get rid of device resource fixups
  2012-02-10  2:36 [PATCH v2 00/18] add PCI bus-to-resource offset support in core Bjorn Helgaas
                   ` (7 preceding siblings ...)
  2012-02-10  2:37 ` [PATCH v2 08/18] ia64/PCI: SN: convert to pci_scan_root_bus() for correct root bus resources Bjorn Helgaas
@ 2012-02-10  2:37 ` Bjorn Helgaas
  2012-02-10  2:37 ` [PATCH v2 10/18] microblaze/PCI: " Bjorn Helgaas
                   ` (9 subsequent siblings)
  18 siblings, 0 replies; 34+ messages in thread
From: Bjorn Helgaas @ 2012-02-10  2:37 UTC (permalink / raw)
  To: linux-pci; +Cc: linux-arch, Tony Luck, Jack Steiner

Tell the PCI core about host bridge address translation so it can take
care of bus-to-resource conversion for us.

CC: Tony Luck <tony.luck@intel.com>
CC: Jack Steiner <steiner@sgi.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
---
 arch/ia64/include/asm/pci.h   |    6 +---
 arch/ia64/pci/pci.c           |   55 +----------------------------------------
 arch/ia64/sn/kernel/io_init.c |    4 ++-
 3 files changed, 6 insertions(+), 59 deletions(-)

diff --git a/arch/ia64/include/asm/pci.h b/arch/ia64/include/asm/pci.h
index 279b38a..519bb5c 100644
--- a/arch/ia64/include/asm/pci.h
+++ b/arch/ia64/include/asm/pci.h
@@ -108,11 +108,7 @@ static inline int pci_proc_domain(struct pci_bus *bus)
 	return (pci_domain_nr(bus) != 0);
 }
 
-extern void pcibios_resource_to_bus(struct pci_dev *dev,
-		struct pci_bus_region *region, struct resource *res);
-
-extern void pcibios_bus_to_resource(struct pci_dev *dev,
-		struct resource *res, struct pci_bus_region *region);
+#define ARCH_HAS_GENERIC_PCI_OFFSETS
 
 static inline struct resource *
 pcibios_select_root(struct pci_dev *pdev, struct resource *res)
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index f82f5d4..d1ce320 100644
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -320,7 +320,8 @@ static __devinit acpi_status add_window(struct acpi_resource *res, void *data)
 	 * Ignore these tiny memory ranges */
 	if (!((window->resource.flags & IORESOURCE_MEM) &&
 	      (window->resource.end - window->resource.start < 16)))
-		pci_add_resource(&info->resources, &window->resource);
+		pci_add_resource_offset(&info->resources, &window->resource,
+					window->offset);
 
 	return AE_OK;
 }
@@ -395,54 +396,6 @@ out1:
 	return NULL;
 }
 
-void pcibios_resource_to_bus(struct pci_dev *dev,
-		struct pci_bus_region *region, struct resource *res)
-{
-	struct pci_controller *controller = PCI_CONTROLLER(dev);
-	unsigned long offset = 0;
-	int i;
-
-	for (i = 0; i < controller->windows; i++) {
-		struct pci_window *window = &controller->window[i];
-		if (!(window->resource.flags & res->flags))
-			continue;
-		if (window->resource.start > res->start)
-			continue;
-		if (window->resource.end < res->end)
-			continue;
-		offset = window->offset;
-		break;
-	}
-
-	region->start = res->start - offset;
-	region->end = res->end - offset;
-}
-EXPORT_SYMBOL(pcibios_resource_to_bus);
-
-void pcibios_bus_to_resource(struct pci_dev *dev,
-		struct resource *res, struct pci_bus_region *region)
-{
-	struct pci_controller *controller = PCI_CONTROLLER(dev);
-	unsigned long offset = 0;
-	int i;
-
-	for (i = 0; i < controller->windows; i++) {
-		struct pci_window *window = &controller->window[i];
-		if (!(window->resource.flags & res->flags))
-			continue;
-		if (window->resource.start - window->offset > region->start)
-			continue;
-		if (window->resource.end - window->offset < region->end)
-			continue;
-		offset = window->offset;
-		break;
-	}
-
-	res->start = region->start + offset;
-	res->end = region->end + offset;
-}
-EXPORT_SYMBOL(pcibios_bus_to_resource);
-
 static int __devinit is_valid_resource(struct pci_dev *dev, int idx)
 {
 	unsigned int i, type_mask = IORESOURCE_IO | IORESOURCE_MEM;
@@ -464,15 +417,11 @@ static int __devinit is_valid_resource(struct pci_dev *dev, int idx)
 static void __devinit
 pcibios_fixup_resources(struct pci_dev *dev, int start, int limit)
 {
-	struct pci_bus_region region;
 	int i;
 
 	for (i = start; i < limit; i++) {
 		if (!dev->resource[i].flags)
 			continue;
-		region.start = dev->resource[i].start;
-		region.end = dev->resource[i].end;
-		pcibios_bus_to_resource(dev, &dev->resource[i], &region);
 		if ((is_valid_resource(dev, i)))
 			pci_claim_resource(dev, i);
 	}
diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c
index c99c2ca..238e2c5 100644
--- a/arch/ia64/sn/kernel/io_init.c
+++ b/arch/ia64/sn/kernel/io_init.c
@@ -320,7 +320,9 @@ sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus)
 				   prom_bussoft_ptr->bs_legacy_io,
 				   prom_bussoft_ptr->bs_legacy_mem);
 	for (i = 0; i < controller->windows; i++)
-		pci_add_resource(&resources, &controller->window[i].resource);
+		pci_add_resource_offset(&resources,
+					&controller->window[i].resource,
+					controller->window[i].offset);
 	bus = pci_scan_root_bus(NULL, busnum, &pci_root_ops, controller,
 				&resources);
  	if (bus == NULL)


^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v2 10/18] microblaze/PCI: get rid of device resource fixups
  2012-02-10  2:36 [PATCH v2 00/18] add PCI bus-to-resource offset support in core Bjorn Helgaas
                   ` (8 preceding siblings ...)
  2012-02-10  2:37 ` [PATCH v2 09/18] ia64/PCI: get rid of device resource fixups Bjorn Helgaas
@ 2012-02-10  2:37 ` Bjorn Helgaas
  2012-02-10  2:37 ` [PATCH v2 11/18] mips/PCI: " Bjorn Helgaas
                   ` (8 subsequent siblings)
  18 siblings, 0 replies; 34+ messages in thread
From: Bjorn Helgaas @ 2012-02-10  2:37 UTC (permalink / raw)
  To: linux-pci; +Cc: linux-arch, Michal Simek

Tell the PCI core about host bridge address translation so it can take
care of bus-to-resource conversion for us.

CC: Michal Simek <monstr@monstr.eu>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
---
 arch/microblaze/include/asm/pci.h |    8 +---
 arch/microblaze/pci/pci-common.c  |   69 ++-----------------------------------
 2 files changed, 4 insertions(+), 73 deletions(-)

diff --git a/arch/microblaze/include/asm/pci.h b/arch/microblaze/include/asm/pci.h
index 0331376..8db01f7 100644
--- a/arch/microblaze/include/asm/pci.h
+++ b/arch/microblaze/include/asm/pci.h
@@ -94,13 +94,7 @@ extern int pci_mmap_legacy_page_range(struct pci_bus *bus,
  */
 #define PCI_DMA_BUS_IS_PHYS     (1)
 
-extern void pcibios_resource_to_bus(struct pci_dev *dev,
-			struct pci_bus_region *region,
-			struct resource *res);
-
-extern void pcibios_bus_to_resource(struct pci_dev *dev,
-			struct resource *res,
-			struct pci_bus_region *region);
+#define ARCH_HAS_GENERIC_PCI_OFFSETS
 
 static inline struct resource *pcibios_select_root(struct pci_dev *pdev,
 			struct resource *res)
diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c
index 85f2ac1..a9fa875 100644
--- a/arch/microblaze/pci/pci-common.c
+++ b/arch/microblaze/pci/pci-common.c
@@ -840,59 +840,6 @@ int pci_proc_domain(struct pci_bus *bus)
 	return 1;
 }
 
-void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
-			     struct resource *res)
-{
-	resource_size_t offset = 0, mask = (resource_size_t)-1;
-	struct pci_controller *hose = pci_bus_to_host(dev->bus);
-
-	if (!hose)
-		return;
-	if (res->flags & IORESOURCE_IO) {
-		offset = (unsigned long)hose->io_base_virt - _IO_BASE;
-		mask = 0xffffffffu;
-	} else if (res->flags & IORESOURCE_MEM)
-		offset = hose->pci_mem_offset;
-
-	region->start = (res->start - offset) & mask;
-	region->end = (res->end - offset) & mask;
-}
-EXPORT_SYMBOL(pcibios_resource_to_bus);
-
-void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
-			     struct pci_bus_region *region)
-{
-	resource_size_t offset = 0, mask = (resource_size_t)-1;
-	struct pci_controller *hose = pci_bus_to_host(dev->bus);
-
-	if (!hose)
-		return;
-	if (res->flags & IORESOURCE_IO) {
-		offset = (unsigned long)hose->io_base_virt - _IO_BASE;
-		mask = 0xffffffffu;
-	} else if (res->flags & IORESOURCE_MEM)
-		offset = hose->pci_mem_offset;
-	res->start = (region->start + offset) & mask;
-	res->end = (region->end + offset) & mask;
-}
-EXPORT_SYMBOL(pcibios_bus_to_resource);
-
-/* Fixup a bus resource into a linux resource */
-static void __devinit fixup_resource(struct resource *res, struct pci_dev *dev)
-{
-	struct pci_controller *hose = pci_bus_to_host(dev->bus);
-	resource_size_t offset = 0, mask = (resource_size_t)-1;
-
-	if (res->flags & IORESOURCE_IO) {
-		offset = (unsigned long)hose->io_base_virt - _IO_BASE;
-		mask = 0xffffffffu;
-	} else if (res->flags & IORESOURCE_MEM)
-		offset = hose->pci_mem_offset;
-
-	res->start = (res->start + offset) & mask;
-	res->end = (res->end + offset) & mask;
-}
-
 /* This header fixup will do the resource fixup for all devices as they are
  * probed, but not for bridge ranges
  */
@@ -929,18 +876,11 @@ static void __devinit pcibios_fixup_resources(struct pci_dev *dev)
 			continue;
 		}
 
-		pr_debug("PCI:%s Resource %d %016llx-%016llx [%x] fixup...\n",
+		pr_debug("PCI:%s Resource %d %016llx-%016llx [%x]\n",
 			 pci_name(dev), i,
 			 (unsigned long long)res->start,\
 			 (unsigned long long)res->end,
 			 (unsigned int)res->flags);
-
-		fixup_resource(res, dev);
-
-		pr_debug("PCI:%s            %016llx-%016llx\n",
-			 pci_name(dev),
-			 (unsigned long long)res->start,
-			 (unsigned long long)res->end);
 	}
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_resources);
@@ -1037,9 +977,6 @@ static void __devinit pcibios_fixup_bridge(struct pci_bus *bus)
 			 (unsigned long long)res->end,
 			 (unsigned int)res->flags);
 
-		/* Perform fixup */
-		fixup_resource(res, dev);
-
 		/* Try to detect uninitialized P2P bridge resources,
 		 * and clear them out so they get re-assigned later
 		 */
@@ -1535,7 +1472,7 @@ static void __devinit pcibios_setup_phb_resources(struct pci_controller *hose, s
 		res->end = res->start + IO_SPACE_LIMIT;
 		res->flags = IORESOURCE_IO;
 	}
-	pci_add_resource(resources, res);
+	pci_add_resource_offset(resources, res, hose->io_base_virt - _IO_BASE);
 
 	pr_debug("PCI: PHB IO resource    = %016llx-%016llx [%lx]\n",
 		 (unsigned long long)res->start,
@@ -1558,7 +1495,7 @@ static void __devinit pcibios_setup_phb_resources(struct pci_controller *hose, s
 			res->flags = IORESOURCE_MEM;
 
 		}
-		pci_add_resource(resources, res);
+		pci_add_resource_offset(resources, res, hose->pci_mem_offset);
 
 		pr_debug("PCI: PHB MEM resource %d = %016llx-%016llx [%lx]\n",
 			i, (unsigned long long)res->start,


^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v2 11/18] mips/PCI: get rid of device resource fixups
  2012-02-10  2:36 [PATCH v2 00/18] add PCI bus-to-resource offset support in core Bjorn Helgaas
                   ` (9 preceding siblings ...)
  2012-02-10  2:37 ` [PATCH v2 10/18] microblaze/PCI: " Bjorn Helgaas
@ 2012-02-10  2:37 ` Bjorn Helgaas
  2012-02-10  2:43   ` Bjorn Helgaas
  2012-02-10  2:37 ` [PATCH v2 12/18] mn10300/PCI: " Bjorn Helgaas
                   ` (7 subsequent siblings)
  18 siblings, 1 reply; 34+ messages in thread
From: Bjorn Helgaas @ 2012-02-10  2:37 UTC (permalink / raw)
  To: linux-pci; +Cc: linux-arch, Ralf Baechle, Yoichi Yuasa

Tell the PCI core about host bridge address translation so it can take
care of bus-to-resource conversion for us.

Here's the wrinkle on Cobalt: we can't generate normal I/O port addresses
on PCI because the GT-64111 doesn't do any address translation, so we have
this:

  CPU I/O port addresses		[io 0x0000-0xffffff]
  PCI bus I/O port addresses	[io 0x10000000-0x10ffffff]

Legacy-mode IDE controllers start out with the legacy bus addresses, e.g.,
0x1f0, assigned by pci_setup_device().  These are outside the range of
addresses GT-64111 can generate on PCI, but pcibios_fixup_device_resources()
converted them to CPU addresses anyway by adding io_offset.  Therefore, we
had to pre-adjust them in cobalt_legacy_ide_fixup().

With io_offset = 0xf0000000, we had this:

  res->start = 0x1f0	initialized in pci_setup_device()
  res->start = 0x100001f0	-= io_offset in cobalt_legacy_ide_fixup()
  res->start = 0x1f0	+= io_offset in pcibios_fixup_device_resources()

The difference after this patch is that the generic pci_bus_to_resource()
only adds the offset if the bus address is inside a host bridge window.
Since 0x1f0 is not a valid bus address and is not inside any windows, it is
unaffected, so we now have this:

  region->start = 0x1f0	initialized in pci_setup_device()
  res->start = 0x1f0	no offset by pci_bus_to_resource()

That means we can remove both pcibios_fixup_device_resources() and
cobalt_legacy_ide_fixup().

I would *rather* set the host bridge offset to zero (which corresponds
to what the GT-64111 actually does), and have both CPU and PCI addresses
of [io 0x10000000-0x10ffffff].  However, that would require changes to
generic code that assumes legacy I/O addresses, such as pic1_io_resource
([io 0x0020-0x00021]), and we'd have to keep a Cobalt IDE fixup.

Of course, none of this changes the fact that references to I/O port
0x1f0 actually go to port 0x100001f0, not 0x1f0, on the Cobalt PCI bus.
Fortunately the VT82C586 IDE controller only decodes the low 24 address
bits, so it does work.

CC: Ralf Baechle <ralf@linux-mips.org>
CC: Yoichi Yuasa <yuasa@linux-mips.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
---
 arch/mips/include/asm/pci.h  |    6 +---
 arch/mips/pci/fixup-cobalt.c |   61 -------------------------------------
 arch/mips/pci/pci.c          |   70 ++----------------------------------------
 3 files changed, 4 insertions(+), 133 deletions(-)

diff --git a/arch/mips/include/asm/pci.h b/arch/mips/include/asm/pci.h
index 576397c..2be0c69 100644
--- a/arch/mips/include/asm/pci.h
+++ b/arch/mips/include/asm/pci.h
@@ -112,11 +112,7 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev,
 }
 #endif
 
-extern void pcibios_resource_to_bus(struct pci_dev *dev,
-	struct pci_bus_region *region, struct resource *res);
-
-extern void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
-				    struct pci_bus_region *region);
+#define ARCH_HAS_GENERIC_PCI_OFFSETS
 
 #define pci_domain_nr(bus) ((struct pci_controller *)(bus)->sysdata)->index
 
diff --git a/arch/mips/pci/fixup-cobalt.c b/arch/mips/pci/fixup-cobalt.c
index acacd14..9553b14 100644
--- a/arch/mips/pci/fixup-cobalt.c
+++ b/arch/mips/pci/fixup-cobalt.c
@@ -51,67 +51,6 @@ static void qube_raq_galileo_early_fixup(struct pci_dev *dev)
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_GT64111,
 	 qube_raq_galileo_early_fixup);
 
-static void __devinit cobalt_legacy_ide_resource_fixup(struct pci_dev *dev,
-						       struct resource *res)
-{
-	struct pci_controller *hose = (struct pci_controller *)dev->sysdata;
-	unsigned long offset = hose->io_offset;
-	struct resource orig = *res;
-
-	if (!(res->flags & IORESOURCE_IO) ||
-	    !(res->flags & IORESOURCE_PCI_FIXED))
-		return;
-
-	res->start -= offset;
-	res->end -= offset;
-	dev_printk(KERN_DEBUG, &dev->dev, "converted legacy %pR to bus %pR\n",
-		   &orig, res);
-}
-
-static void __devinit cobalt_legacy_ide_fixup(struct pci_dev *dev)
-{
-	u32 class;
-	u8 progif;
-
-	/*
-	 * If the IDE controller is in legacy mode, pci_setup_device() fills in
-	 * the resources with the legacy addresses that normally appear on the
-	 * PCI bus, just as if we had read them from a BAR.
-	 *
-	 * However, with the GT-64111, those legacy addresses, e.g., 0x1f0,
-	 * will never appear on the PCI bus because it converts memory accesses
-	 * in the PCI I/O region (which is never at address zero) into I/O port
-	 * accesses with no address translation.
-	 *
-	 * For example, if GT_DEF_PCI0_IO_BASE is 0x10000000, a load or store
-	 * to physical address 0x100001f0 will become a PCI access to I/O port
-	 * 0x100001f0.  There's no way to generate an access to I/O port 0x1f0,
-	 * but the VT82C586 IDE controller does respond at 0x100001f0 because
-	 * it only decodes the low 24 bits of the address.
-	 *
-	 * When this quirk runs, the pci_dev resources should contain bus
-	 * addresses, not Linux I/O port numbers, so convert legacy addresses
-	 * like 0x1f0 to bus addresses like 0x100001f0.  Later, we'll convert
-	 * them back with pcibios_fixup_bus() or pcibios_bus_to_resource().
-	 */
-	class = dev->class >> 8;
-	if (class != PCI_CLASS_STORAGE_IDE)
-		return;
-
-	pci_read_config_byte(dev, PCI_CLASS_PROG, &progif);
-	if ((progif & 1) == 0) {
-		cobalt_legacy_ide_resource_fixup(dev, &dev->resource[0]);
-		cobalt_legacy_ide_resource_fixup(dev, &dev->resource[1]);
-	}
-	if ((progif & 4) == 0) {
-		cobalt_legacy_ide_resource_fixup(dev, &dev->resource[2]);
-		cobalt_legacy_ide_resource_fixup(dev, &dev->resource[3]);
-	}
-}
-
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1,
-	  cobalt_legacy_ide_fixup);
-
 static void qube_raq_via_bmIDE_fixup(struct pci_dev *dev)
 {
 	unsigned short cfgword;
diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c
index aec2b11..cab58e6 100644
--- a/arch/mips/pci/pci.c
+++ b/arch/mips/pci/pci.c
@@ -95,8 +95,9 @@ static void __devinit pcibios_scanbus(struct pci_controller *hose)
 	if (hose->get_busno && pci_probe_only)
 		next_busno = (*hose->get_busno)();
 
-	pci_add_resource(&resources, hose->mem_resource);
-	pci_add_resource(&resources, hose->io_resource);
+	pci_add_resource_offset(&resources,
+				hose->mem_resource, hose->mem_offset);
+	pci_add_resource_offset(&resources, hose->io_resource, hose->io_offset);
 	bus = pci_scan_root_bus(NULL, next_busno, hose->pci_ops, hose,
 				&resources);
 	if (!bus)
@@ -254,45 +255,13 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
 	return pcibios_plat_dev_init(dev);
 }
 
-static void pcibios_fixup_device_resources(struct pci_dev *dev,
-	struct pci_bus *bus)
-{
-	/* Update device resources.  */
-	struct pci_controller *hose = (struct pci_controller *)bus->sysdata;
-	unsigned long offset = 0;
-	int i;
-
-	for (i = 0; i < PCI_NUM_RESOURCES; i++) {
-		if (!dev->resource[i].start)
-			continue;
-		if (dev->resource[i].flags & IORESOURCE_IO)
-			offset = hose->io_offset;
-		else if (dev->resource[i].flags & IORESOURCE_MEM)
-			offset = hose->mem_offset;
-
-		dev->resource[i].start += offset;
-		dev->resource[i].end += offset;
-	}
-}
-
 void __devinit pcibios_fixup_bus(struct pci_bus *bus)
 {
-	/* Propagate hose info into the subordinate devices.  */
-
-	struct list_head *ln;
 	struct pci_dev *dev = bus->self;
 
 	if (pci_probe_only && dev &&
 	    (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
 		pci_read_bridge_bases(bus);
-		pcibios_fixup_device_resources(dev, bus);
-	}
-
-	for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) {
-		dev = pci_dev_b(ln);
-
-		if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
-			pcibios_fixup_device_resources(dev, bus);
 	}
 }
 
@@ -302,40 +271,7 @@ pcibios_update_irq(struct pci_dev *dev, int irq)
 	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
 }
 
-void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
-			 struct resource *res)
-{
-	struct pci_controller *hose = (struct pci_controller *)dev->sysdata;
-	unsigned long offset = 0;
-
-	if (res->flags & IORESOURCE_IO)
-		offset = hose->io_offset;
-	else if (res->flags & IORESOURCE_MEM)
-		offset = hose->mem_offset;
-
-	region->start = res->start - offset;
-	region->end = res->end - offset;
-}
-
-void __devinit
-pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
-			struct pci_bus_region *region)
-{
-	struct pci_controller *hose = (struct pci_controller *)dev->sysdata;
-	unsigned long offset = 0;
-
-	if (res->flags & IORESOURCE_IO)
-		offset = hose->io_offset;
-	else if (res->flags & IORESOURCE_MEM)
-		offset = hose->mem_offset;
-
-	res->start = region->start + offset;
-	res->end = region->end + offset;
-}
-
 #ifdef CONFIG_HOTPLUG
-EXPORT_SYMBOL(pcibios_resource_to_bus);
-EXPORT_SYMBOL(pcibios_bus_to_resource);
 EXPORT_SYMBOL(PCIBIOS_MIN_IO);
 EXPORT_SYMBOL(PCIBIOS_MIN_MEM);
 #endif


^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v2 12/18] mn10300/PCI: get rid of device resource fixups
  2012-02-10  2:36 [PATCH v2 00/18] add PCI bus-to-resource offset support in core Bjorn Helgaas
                   ` (10 preceding siblings ...)
  2012-02-10  2:37 ` [PATCH v2 11/18] mips/PCI: " Bjorn Helgaas
@ 2012-02-10  2:37 ` Bjorn Helgaas
  2012-02-10  2:37 ` [PATCH v2 13/18] parisc/PCI: " Bjorn Helgaas
                   ` (6 subsequent siblings)
  18 siblings, 0 replies; 34+ messages in thread
From: Bjorn Helgaas @ 2012-02-10  2:37 UTC (permalink / raw)
  To: linux-pci; +Cc: linux-arch, David Howells

Tell the PCI core about host bridge address translation so it can take
care of bus-to-resource conversion for us.

CC: David Howells <dhowells@redhat.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
---
 arch/mn10300/include/asm/pci.h  |   16 +---------
 arch/mn10300/unit-asb2305/pci.c |   62 ++++++---------------------------------
 2 files changed, 10 insertions(+), 68 deletions(-)

diff --git a/arch/mn10300/include/asm/pci.h b/arch/mn10300/include/asm/pci.h
index 6095a28..dfe1581 100644
--- a/arch/mn10300/include/asm/pci.h
+++ b/arch/mn10300/include/asm/pci.h
@@ -85,21 +85,7 @@ extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
 /* implement the pci_ DMA API in terms of the generic device dma_ one */
 #include <asm-generic/pci-dma-compat.h>
 
-/**
- * pcibios_resource_to_bus - convert resource to PCI bus address
- * @dev: device which owns this resource
- * @region: converted bus-centric region (start,end)
- * @res: resource to convert
- *
- * Convert a resource to a PCI device bus address or bus window.
- */
-extern void pcibios_resource_to_bus(struct pci_dev *dev,
-				    struct pci_bus_region *region,
-				    struct resource *res);
-
-extern void pcibios_bus_to_resource(struct pci_dev *dev,
-				    struct resource *res,
-				    struct pci_bus_region *region);
+#define ARCH_HAS_GENERIC_PCI_OFFSETS
 
 static inline struct resource *
 pcibios_select_root(struct pci_dev *pdev, struct resource *res)
diff --git a/arch/mn10300/unit-asb2305/pci.c b/arch/mn10300/unit-asb2305/pci.c
index a7c5f08..6dce9fc 100644
--- a/arch/mn10300/unit-asb2305/pci.c
+++ b/arch/mn10300/unit-asb2305/pci.c
@@ -32,8 +32,7 @@ struct pci_ops *pci_root_ops;
  * insert specific PCI bus resources instead of using the platform-level bus
  * resources directly for the PCI root bus.
  *
- * These are configured and inserted by pcibios_init() and are attached to the
- * root bus by pcibios_fixup_bus().
+ * These are configured and inserted by pcibios_init().
  */
 static struct resource pci_ioport_resource = {
 	.name	= "PCI IO",
@@ -78,52 +77,6 @@ static inline int __query(const struct pci_bus *bus, unsigned int devfn)
 }
 
 /*
- * translate Linuxcentric addresses to PCI bus addresses
- */
-void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
-			     struct resource *res)
-{
-	if (res->flags & IORESOURCE_IO) {
-		region->start = (res->start & 0x00ffffff);
-		region->end   = (res->end   & 0x00ffffff);
-	}
-
-	if (res->flags & IORESOURCE_MEM) {
-		region->start = (res->start & 0x03ffffff) | MEM_PAGING_REG;
-		region->end   = (res->end   & 0x03ffffff) | MEM_PAGING_REG;
-	}
-
-#if 0
-	printk(KERN_DEBUG "RES->BUS: %lx-%lx => %lx-%lx\n",
-	       res->start, res->end, region->start, region->end);
-#endif
-}
-EXPORT_SYMBOL(pcibios_resource_to_bus);
-
-/*
- * translate PCI bus addresses to Linuxcentric addresses
- */
-void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
-			     struct pci_bus_region *region)
-{
-	if (res->flags & IORESOURCE_IO) {
-		res->start = (region->start & 0x00ffffff) | 0xbe000000;
-		res->end   = (region->end   & 0x00ffffff) | 0xbe000000;
-	}
-
-	if (res->flags & IORESOURCE_MEM) {
-		res->start = (region->start & 0x03ffffff) | 0xb8000000;
-		res->end   = (region->end   & 0x03ffffff) | 0xb8000000;
-	}
-
-#if 0
-	printk(KERN_INFO "BUS->RES: %lx-%lx => %lx-%lx\n",
-	       region->start, region->end, res->start, res->end);
-#endif
-}
-EXPORT_SYMBOL(pcibios_bus_to_resource);
-
-/*
  *
  */
 static int pci_ampci_read_config_byte(struct pci_bus *bus, unsigned int devfn,
@@ -364,9 +317,6 @@ static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev)
 		if (!dev->resource[i].flags)
 			continue;
 
-		region.start = dev->resource[i].start;
-		region.end = dev->resource[i].end;
-		pcibios_bus_to_resource(dev, &dev->resource[i], &region);
 		if (is_valid_resource(dev, i))
 			pci_claim_resource(dev, i);
 	}
@@ -397,6 +347,7 @@ void __devinit pcibios_fixup_bus(struct pci_bus *bus)
  */
 static int __init pcibios_init(void)
 {
+	resource_size_t io_offset, mem_offset;
 	LIST_HEAD(resources);
 
 	ioport_resource.start	= 0xA0000000;
@@ -420,8 +371,13 @@ static int __init pcibios_init(void)
 	printk(KERN_INFO "PCI: Probing PCI hardware [mempage %08x]\n",
 	       MEM_PAGING_REG);
 
-	pci_add_resource(&resources, &pci_ioport_resource);
-	pci_add_resource(&resources, &pci_iomem_resource);
+	io_offset = pci_ioport_resource.start -
+	    (pci_ioport_resource.start & 0x00ffffff);
+	mem_offset = pci_iomem_resource.start -
+	    ((pci_iomem_resource.start & 0x03ffffff) | MEM_PAGING_REG);
+
+	pci_add_resource_offset(&resources, &pci_ioport_resource, io_offset);
+	pci_add_resource_offset(&resources, &pci_iomem_resource, mem_offset);
 	pci_root_bus = pci_scan_root_bus(NULL, 0, &pci_direct_ampci, NULL,
 					 &resources);
 


^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v2 13/18] parisc/PCI: get rid of device resource fixups
  2012-02-10  2:36 [PATCH v2 00/18] add PCI bus-to-resource offset support in core Bjorn Helgaas
                   ` (11 preceding siblings ...)
  2012-02-10  2:37 ` [PATCH v2 12/18] mn10300/PCI: " Bjorn Helgaas
@ 2012-02-10  2:37 ` Bjorn Helgaas
  2012-02-10  2:37 ` [PATCH v2 14/18] powerpc/PCI: " Bjorn Helgaas
                   ` (5 subsequent siblings)
  18 siblings, 0 replies; 34+ messages in thread
From: Bjorn Helgaas @ 2012-02-10  2:37 UTC (permalink / raw)
  To: linux-pci; +Cc: linux-arch, linux-parisc

Tell the PCI core about host bridge address translation so it can take
care of bus-to-resource conversion for us.

CC: linux-parisc@vger.kernel.org
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
---
 arch/parisc/include/asm/pci.h |   38 +-----------------------------
 arch/parisc/kernel/pci.c      |   52 -----------------------------------------
 drivers/parisc/dino.c         |   27 +++++----------------
 drivers/parisc/lba_pci.c      |   31 +++++-------------------
 4 files changed, 13 insertions(+), 135 deletions(-)

diff --git a/arch/parisc/include/asm/pci.h b/arch/parisc/include/asm/pci.h
index 2242a5c..a8b591f 100644
--- a/arch/parisc/include/asm/pci.h
+++ b/arch/parisc/include/asm/pci.h
@@ -82,38 +82,8 @@ struct pci_hba_data {
 
 #ifdef CONFIG_64BIT
 #define PCI_F_EXTEND		0xffffffff00000000UL
-#define PCI_IS_LMMIO(hba,a)	pci_is_lmmio(hba,a)
-
-/* We need to know if an address is LMMMIO or GMMIO.
- * LMMIO requires mangling and GMMIO we must use as-is.
- */
-static __inline__  int pci_is_lmmio(struct pci_hba_data *hba, unsigned long a)
-{
-	return(((a) & PCI_F_EXTEND) == PCI_F_EXTEND);
-}
-
-/*
-** Convert between PCI (IO_VIEW) addresses and processor (PA_VIEW) addresses.
-** See pci.c for more conversions used by Generic PCI code.
-**
-** Platform characteristics/firmware guarantee that
-**	(1) PA_VIEW - IO_VIEW = lmmio_offset for both LMMIO and ELMMIO
-**	(2) PA_VIEW == IO_VIEW for GMMIO
-*/
-#define PCI_BUS_ADDR(hba,a)	(PCI_IS_LMMIO(hba,a)	\
-		?  ((a) - hba->lmmio_space_offset)	/* mangle LMMIO */ \
-		: (a))					/* GMMIO */
-#define PCI_HOST_ADDR(hba,a)	(((a) & PCI_F_EXTEND) == 0 \
-		? (a) + hba->lmmio_space_offset \
-		: (a))
-
 #else	/* !CONFIG_64BIT */
-
-#define PCI_BUS_ADDR(hba,a)	(a)
-#define PCI_HOST_ADDR(hba,a)	(a)
 #define PCI_F_EXTEND		0UL
-#define PCI_IS_LMMIO(hba,a)	(1)	/* 32-bit doesn't support GMMIO */
-
 #endif /* !CONFIG_64BIT */
 
 /*
@@ -245,13 +215,7 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev,
 }
 #endif
 
-extern void
-pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
-			 struct resource *res);
-
-extern void
-pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
-			struct pci_bus_region *region);
+#define ARCH_HAS_GENERIC_PCI_OFFSETS
 
 static inline void pcibios_penalize_isa_irq(int irq, int active)
 {
diff --git a/arch/parisc/kernel/pci.c b/arch/parisc/kernel/pci.c
index 9efd974..74d544b 100644
--- a/arch/parisc/kernel/pci.c
+++ b/arch/parisc/kernel/pci.c
@@ -195,58 +195,6 @@ void __init pcibios_init_bus(struct pci_bus *bus)
 	pci_write_config_word(dev, PCI_BRIDGE_CONTROL, bridge_ctl);
 }
 
-/* called by drivers/pci/setup-bus.c:pci_setup_bridge().  */
-void __devinit pcibios_resource_to_bus(struct pci_dev *dev,
-		struct pci_bus_region *region, struct resource *res)
-{
-#ifdef CONFIG_64BIT
-	struct pci_hba_data *hba = HBA_DATA(dev->bus->bridge->platform_data);
-#endif
-
-	if (res->flags & IORESOURCE_IO) {
-		/*
-		** I/O space may see busnumbers here. Something
-		** in the form of 0xbbxxxx where bb is the bus num
-		** and xxxx is the I/O port space address.
-		** Remaining address translation are done in the
-		** PCI Host adapter specific code - ie dino_out8.
-		*/
-		region->start = PCI_PORT_ADDR(res->start);
-		region->end   = PCI_PORT_ADDR(res->end);
-	} else if (res->flags & IORESOURCE_MEM) {
-		/* Convert MMIO addr to PCI addr (undo global virtualization) */
-		region->start = PCI_BUS_ADDR(hba, res->start);
-		region->end   = PCI_BUS_ADDR(hba, res->end);
-	}
-
-	DBG_RES("pcibios_resource_to_bus(%02x %s [%lx,%lx])\n",
-		dev->bus->number, res->flags & IORESOURCE_IO ? "IO" : "MEM",
-		region->start, region->end);
-}
-
-void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
-			      struct pci_bus_region *region)
-{
-#ifdef CONFIG_64BIT
-	struct pci_hba_data *hba = HBA_DATA(dev->bus->bridge->platform_data);
-#endif
-
-	if (res->flags & IORESOURCE_MEM) {
-		res->start = PCI_HOST_ADDR(hba, region->start);
-		res->end = PCI_HOST_ADDR(hba, region->end);
-	}
-
-	if (res->flags & IORESOURCE_IO) {
-		res->start = region->start;
-		res->end = region->end;
-	}
-}
-
-#ifdef CONFIG_HOTPLUG
-EXPORT_SYMBOL(pcibios_resource_to_bus);
-EXPORT_SYMBOL(pcibios_bus_to_resource);
-#endif
-
 /*
  * pcibios align resources() is called every time generic PCI code
  * wants to generate a new address. The process of looking for
diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c
index 7ff10c1..0610e91 100644
--- a/drivers/parisc/dino.c
+++ b/drivers/parisc/dino.c
@@ -553,7 +553,6 @@ dino_fixup_bus(struct pci_bus *bus)
 	struct list_head *ln;
         struct pci_dev *dev;
         struct dino_device *dino_dev = DINO_DEV(parisc_walk_tree(bus->bridge));
-	int port_base = HBA_PORT_BASE(dino_dev->hba.hba_num);
 
 	DBG(KERN_WARNING "%s(0x%p) bus %d platform_data 0x%p\n",
 	    __func__, bus, bus->secondary,
@@ -599,8 +598,6 @@ dino_fixup_bus(struct pci_bus *bus)
 
 
 	list_for_each(ln, &bus->devices) {
-		int i;
-
 		dev = pci_dev_b(ln);
 		if (is_card_dino(&dino_dev->hba.dev->id))
 			dino_card_fixup(dev);
@@ -612,21 +609,6 @@ dino_fixup_bus(struct pci_bus *bus)
 		if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)
 			continue;
 
-		/* Adjust the I/O Port space addresses */
-		for (i = 0; i < PCI_NUM_RESOURCES; i++) {
-			struct resource *res = &dev->resource[i];
-			if (res->flags & IORESOURCE_IO) {
-				res->start |= port_base;
-				res->end |= port_base;
-			}
-#ifdef __LP64__
-			/* Sign Extend MMIO addresses */
-			else if (res->flags & IORESOURCE_MEM) {
-				res->start |= F_EXTEND(0UL);
-				res->end   |= F_EXTEND(0UL);
-			}
-#endif
-		}
 		/* null out the ROM resource if there is one (we don't
 		 * care about an expansion rom on parisc, since it
 		 * usually contains (x86) bios code) */
@@ -991,11 +973,14 @@ static int __init dino_probe(struct parisc_device *dev)
 
 	dev->dev.platform_data = dino_dev;
 
-	pci_add_resource(&resources, &dino_dev->hba.io_space);
+	pci_add_resource_offset(&resources, &dino_dev->hba.io_space,
+				HBA_PORT_BASE(dino_dev->hba.hba_num));
 	if (dino_dev->hba.lmmio_space.flags)
-		pci_add_resource(&resources, &dino_dev->hba.lmmio_space);
+		pci_add_resource_offset(&resources, &dino_dev->hba.lmmio_space,
+					dino_dev->hba.lmmio_space_offset);
 	if (dino_dev->hba.elmmio_space.flags)
-		pci_add_resource(&resources, &dino_dev->hba.elmmio_space);
+		pci_add_resource_offset(&resources, &dino_dev->hba.elmmio_space,
+					dino_dev->hba.lmmio_space_offset);
 	if (dino_dev->hba.gmmio_space.flags)
 		pci_add_resource(&resources, &dino_dev->hba.gmmio_space);
 
diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c
index d5f3d75..e885764 100644
--- a/drivers/parisc/lba_pci.c
+++ b/drivers/parisc/lba_pci.c
@@ -635,7 +635,6 @@ lba_fixup_bus(struct pci_bus *bus)
 	u16 status;
 #endif
 	struct lba_device *ldev = LBA_DEV(parisc_walk_tree(bus->bridge));
-	int lba_portbase = HBA_PORT_BASE(ldev->hba.hba_num);
 
 	DBG("lba_fixup_bus(0x%p) bus %d platform_data 0x%p\n",
 		bus, bus->secondary, bus->bridge->platform_data);
@@ -726,27 +725,6 @@ lba_fixup_bus(struct pci_bus *bus)
 			if (!res->start)
 				continue;
 
-			if (res->flags & IORESOURCE_IO) {
-				DBG("lba_fixup_bus() I/O Ports [%lx/%lx] -> ",
-					res->start, res->end);
-				res->start |= lba_portbase;
-				res->end   |= lba_portbase;
-				DBG("[%lx/%lx]\n", res->start, res->end);
-			} else if (res->flags & IORESOURCE_MEM) {
-				/*
-				** Convert PCI (IO_VIEW) addresses to
-				** processor (PA_VIEW) addresses
-				 */
-				DBG("lba_fixup_bus() MMIO [%lx/%lx] -> ",
-					res->start, res->end);
-				res->start = PCI_HOST_ADDR(HBA_DATA(ldev), res->start);
-				res->end   = PCI_HOST_ADDR(HBA_DATA(ldev), res->end);
-				DBG("[%lx/%lx]\n", res->start, res->end);
-			} else {
-				DBG("lba_fixup_bus() WTF? 0x%lx [%lx/%lx] XXX",
-					res->flags, res->start, res->end);
-			}
-
 			/*
 			** FIXME: this will result in whinging for devices
 			** that share expansion ROMs (think quad tulip), but
@@ -1514,11 +1492,14 @@ lba_driver_probe(struct parisc_device *dev)
 		lba_dev->hba.lmmio_space.flags = 0;
 	}
 
-	pci_add_resource(&resources, &lba_dev->hba.io_space);
+	pci_add_resource_offset(&resources, &lba_dev->hba.io_space,
+				HBA_PORT_BASE(lba_dev->hba.hba_num));
 	if (lba_dev->hba.elmmio_space.start)
-		pci_add_resource(&resources, &lba_dev->hba.elmmio_space);
+		pci_add_resource_offset(&resources, &lba_dev->hba.elmmio_space,
+					lba_dev->hba.lmmio_space_offset);
 	if (lba_dev->hba.lmmio_space.flags)
-		pci_add_resource(&resources, &lba_dev->hba.lmmio_space);
+		pci_add_resource_offset(&resources, &lba_dev->hba.lmmio_space,
+					lba_dev->hba.lmmio_space_offset);
 	if (lba_dev->hba.gmmio_space.flags)
 		pci_add_resource(&resources, &lba_dev->hba.gmmio_space);
 

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v2 14/18] powerpc/PCI: get rid of device resource fixups
  2012-02-10  2:36 [PATCH v2 00/18] add PCI bus-to-resource offset support in core Bjorn Helgaas
                   ` (12 preceding siblings ...)
  2012-02-10  2:37 ` [PATCH v2 13/18] parisc/PCI: " Bjorn Helgaas
@ 2012-02-10  2:37 ` Bjorn Helgaas
  2012-02-10  2:37 ` [PATCH v2 15/18] sh/PCI: " Bjorn Helgaas
                   ` (4 subsequent siblings)
  18 siblings, 0 replies; 34+ messages in thread
From: Bjorn Helgaas @ 2012-02-10  2:37 UTC (permalink / raw)
  To: linux-pci; +Cc: linux-arch, Benjamin Herrenschmidt

Tell the PCI core about host bridge address translation so it can take
care of bus-to-resource conversion for us.

CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
---
 arch/powerpc/include/asm/pci.h   |    8 ----
 arch/powerpc/kernel/pci-common.c |   79 ++------------------------------------
 2 files changed, 6 insertions(+), 81 deletions(-)

diff --git a/arch/powerpc/include/asm/pci.h b/arch/powerpc/include/asm/pci.h
index f54b3d2..839178b 100644
--- a/arch/powerpc/include/asm/pci.h
+++ b/arch/powerpc/include/asm/pci.h
@@ -154,13 +154,7 @@ extern int pci_mmap_legacy_page_range(struct pci_bus *bus,
 
 #endif /* CONFIG_PPC64 */
 
-extern void pcibios_resource_to_bus(struct pci_dev *dev,
-			struct pci_bus_region *region,
-			struct resource *res);
-
-extern void pcibios_bus_to_resource(struct pci_dev *dev,
-			struct resource *res,
-			struct pci_bus_region *region);
+#define ARCH_HAS_GENERIC_PCI_OFFSETS
 
 extern void pcibios_claim_one_bus(struct pci_bus *b);
 
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index cce98d7..f0084c9 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -849,60 +849,6 @@ int pci_proc_domain(struct pci_bus *bus)
 	return 1;
 }
 
-void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
-			     struct resource *res)
-{
-	resource_size_t offset = 0, mask = (resource_size_t)-1;
-	struct pci_controller *hose = pci_bus_to_host(dev->bus);
-
-	if (!hose)
-		return;
-	if (res->flags & IORESOURCE_IO) {
-		offset = (unsigned long)hose->io_base_virt - _IO_BASE;
-		mask = 0xffffffffu;
-	} else if (res->flags & IORESOURCE_MEM)
-		offset = hose->pci_mem_offset;
-
-	region->start = (res->start - offset) & mask;
-	region->end = (res->end - offset) & mask;
-}
-EXPORT_SYMBOL(pcibios_resource_to_bus);
-
-void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
-			     struct pci_bus_region *region)
-{
-	resource_size_t offset = 0, mask = (resource_size_t)-1;
-	struct pci_controller *hose = pci_bus_to_host(dev->bus);
-
-	if (!hose)
-		return;
-	if (res->flags & IORESOURCE_IO) {
-		offset = (unsigned long)hose->io_base_virt - _IO_BASE;
-		mask = 0xffffffffu;
-	} else if (res->flags & IORESOURCE_MEM)
-		offset = hose->pci_mem_offset;
-	res->start = (region->start + offset) & mask;
-	res->end = (region->end + offset) & mask;
-}
-EXPORT_SYMBOL(pcibios_bus_to_resource);
-
-/* Fixup a bus resource into a linux resource */
-static void __devinit fixup_resource(struct resource *res, struct pci_dev *dev)
-{
-	struct pci_controller *hose = pci_bus_to_host(dev->bus);
-	resource_size_t offset = 0, mask = (resource_size_t)-1;
-
-	if (res->flags & IORESOURCE_IO) {
-		offset = (unsigned long)hose->io_base_virt - _IO_BASE;
-		mask = 0xffffffffu;
-	} else if (res->flags & IORESOURCE_MEM)
-		offset = hose->pci_mem_offset;
-
-	res->start = (res->start + offset) & mask;
-	res->end = (res->end + offset) & mask;
-}
-
-
 /* This header fixup will do the resource fixup for all devices as they are
  * probed, but not for bridge ranges
  */
@@ -942,18 +888,11 @@ static void __devinit pcibios_fixup_resources(struct pci_dev *dev)
 			continue;
 		}
 
-		pr_debug("PCI:%s Resource %d %016llx-%016llx [%x] fixup...\n",
+		pr_debug("PCI:%s Resource %d %016llx-%016llx [%x]\n",
 			 pci_name(dev), i,
 			 (unsigned long long)res->start,\
 			 (unsigned long long)res->end,
 			 (unsigned int)res->flags);
-
-		fixup_resource(res, dev);
-
-		pr_debug("PCI:%s            %016llx-%016llx\n",
-			 pci_name(dev),
-			 (unsigned long long)res->start,
-			 (unsigned long long)res->end);
 	}
 
 	/* Call machine specific resource fixup */
@@ -1055,27 +994,18 @@ static void __devinit pcibios_fixup_bridge(struct pci_bus *bus)
 			continue;
 		}
 
-		pr_debug("PCI:%s Bus rsrc %d %016llx-%016llx [%x] fixup...\n",
+		pr_debug("PCI:%s Bus rsrc %d %016llx-%016llx [%x]\n",
 			 pci_name(dev), i,
 			 (unsigned long long)res->start,\
 			 (unsigned long long)res->end,
 			 (unsigned int)res->flags);
 
-		/* Perform fixup */
-		fixup_resource(res, dev);
-
 		/* Try to detect uninitialized P2P bridge resources,
 		 * and clear them out so they get re-assigned later
 		 */
 		if (pcibios_uninitialized_bridge_resource(bus, res)) {
 			res->flags = 0;
 			pr_debug("PCI:%s            (unassigned)\n", pci_name(dev));
-		} else {
-
-			pr_debug("PCI:%s            %016llx-%016llx\n",
-				 pci_name(dev),
-				 (unsigned long long)res->start,
-				 (unsigned long long)res->end);
 		}
 	}
 }
@@ -1589,7 +1519,8 @@ static void __devinit pcibios_setup_phb_resources(struct pci_controller *hose, s
 		 (unsigned long long)res->start,
 		 (unsigned long long)res->end,
 		 (unsigned long)res->flags);
-	pci_add_resource(resources, res);
+	pci_add_resource_offset(resources, res,
+			(resource_size_t) hose->io_base_virt - _IO_BASE);
 
 	/* Hookup PHB Memory resources */
 	for (i = 0; i < 3; ++i) {
@@ -1612,7 +1543,7 @@ static void __devinit pcibios_setup_phb_resources(struct pci_controller *hose, s
 			 (unsigned long long)res->start,
 			 (unsigned long long)res->end,
 			 (unsigned long)res->flags);
-		pci_add_resource(resources, res);
+		pci_add_resource_offset(resources, res, hose->pci_mem_offset);
 	}
 
 	pr_debug("PCI: PHB MEM offset     = %016llx\n",


^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v2 15/18] sh/PCI: get rid of device resource fixups
  2012-02-10  2:36 [PATCH v2 00/18] add PCI bus-to-resource offset support in core Bjorn Helgaas
                   ` (13 preceding siblings ...)
  2012-02-10  2:37 ` [PATCH v2 14/18] powerpc/PCI: " Bjorn Helgaas
@ 2012-02-10  2:37 ` Bjorn Helgaas
  2012-02-10  2:37   ` Bjorn Helgaas
                   ` (3 subsequent siblings)
  18 siblings, 0 replies; 34+ messages in thread
From: Bjorn Helgaas @ 2012-02-10  2:37 UTC (permalink / raw)
  To: linux-pci; +Cc: linux-arch, Paul Mundt

Tell the PCI core about host bridge address translation so it can take
care of bus-to-resource conversion for us.

CC: Paul Mundt <lethal@linux-sh.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
---
 arch/sh/drivers/pci/pci.c |   75 +++++++--------------------------------------
 arch/sh/include/asm/pci.h |    6 +---
 2 files changed, 12 insertions(+), 69 deletions(-)

diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c
index 1e7b0e2..9d10a3c 100644
--- a/arch/sh/drivers/pci/pci.c
+++ b/arch/sh/drivers/pci/pci.c
@@ -37,11 +37,20 @@ static void __devinit pcibios_scanbus(struct pci_channel *hose)
 	static int next_busno;
 	static int need_domain_info;
 	LIST_HEAD(resources);
+	struct resource *res;
+	resource_size_t offset;
 	int i;
 	struct pci_bus *bus;
 
-	for (i = 0; i < hose->nr_resources; i++)
-		pci_add_resource(&resources, hose->resources + i);
+	for (i = 0; i < hose->nr_resources; i++) {
+		res = hose->resources + i;
+		offset = 0;
+		if (res->flags & IORESOURCE_IO)
+			offset = hose->io_offset;
+		else if (res->flags & IORESOURCE_MEM)
+			offset = hose->mem_offset;
+		pci_add_resource_offset(&resources, res, offset);
+	}
 
 	bus = pci_scan_root_bus(NULL, next_busno, hose->pci_ops, hose,
 				&resources);
@@ -143,42 +152,12 @@ static int __init pcibios_init(void)
 }
 subsys_initcall(pcibios_init);
 
-static void pcibios_fixup_device_resources(struct pci_dev *dev,
-	struct pci_bus *bus)
-{
-	/* Update device resources.  */
-	struct pci_channel *hose = bus->sysdata;
-	unsigned long offset = 0;
-	int i;
-
-	for (i = 0; i < PCI_NUM_RESOURCES; i++) {
-		if (!dev->resource[i].start)
-			continue;
-		if (dev->resource[i].flags & IORESOURCE_IO)
-			offset = hose->io_offset;
-		else if (dev->resource[i].flags & IORESOURCE_MEM)
-			offset = hose->mem_offset;
-
-		dev->resource[i].start += offset;
-		dev->resource[i].end += offset;
-	}
-}
-
 /*
  *  Called after each bus is probed, but before its children
  *  are examined.
  */
 void __devinit pcibios_fixup_bus(struct pci_bus *bus)
 {
-	struct pci_dev *dev;
-	struct list_head *ln;
-
-	for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) {
-		dev = pci_dev_b(ln);
-
-		if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
-			pcibios_fixup_device_resources(dev, bus);
-	}
 }
 
 /*
@@ -208,36 +187,6 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,
 	return start;
 }
 
-void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
-			     struct resource *res)
-{
-	struct pci_channel *hose = dev->sysdata;
-	unsigned long offset = 0;
-
-	if (res->flags & IORESOURCE_IO)
-		offset = hose->io_offset;
-	else if (res->flags & IORESOURCE_MEM)
-		offset = hose->mem_offset;
-
-	region->start = res->start - offset;
-	region->end = res->end - offset;
-}
-
-void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
-			     struct pci_bus_region *region)
-{
-	struct pci_channel *hose = dev->sysdata;
-	unsigned long offset = 0;
-
-	if (res->flags & IORESOURCE_IO)
-		offset = hose->io_offset;
-	else if (res->flags & IORESOURCE_MEM)
-		offset = hose->mem_offset;
-
-	res->start = region->start + offset;
-	res->end = region->end + offset;
-}
-
 int pcibios_enable_device(struct pci_dev *dev, int mask)
 {
 	return pci_enable_resources(dev, mask);
@@ -381,8 +330,6 @@ EXPORT_SYMBOL(pci_iounmap);
 #endif /* CONFIG_GENERIC_IOMAP */
 
 #ifdef CONFIG_HOTPLUG
-EXPORT_SYMBOL(pcibios_resource_to_bus);
-EXPORT_SYMBOL(pcibios_bus_to_resource);
 EXPORT_SYMBOL(PCIBIOS_MIN_IO);
 EXPORT_SYMBOL(PCIBIOS_MIN_MEM);
 #endif
diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h
index cb21e23..3b5b6ab 100644
--- a/arch/sh/include/asm/pci.h
+++ b/arch/sh/include/asm/pci.h
@@ -114,11 +114,7 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev,
 /* Board-specific fixup routines. */
 int pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin);
 
-extern void pcibios_resource_to_bus(struct pci_dev *dev,
-	struct pci_bus_region *region, struct resource *res);
-
-extern void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
-				    struct pci_bus_region *region);
+#define ARCH_HAS_GENERIC_PCI_OFFSETS
 
 #define pci_domain_nr(bus) ((struct pci_channel *)(bus)->sysdata)->index
 


^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v2 16/18] sparc/PCI: get rid of device resource fixups
  2012-02-10  2:36 [PATCH v2 00/18] add PCI bus-to-resource offset support in core Bjorn Helgaas
@ 2012-02-10  2:37   ` Bjorn Helgaas
  2012-02-10  2:36 ` [PATCH v2 02/18] PCI: add struct pci_host_bridge and a list of all bridges found Bjorn Helgaas
                     ` (17 subsequent siblings)
  18 siblings, 0 replies; 34+ messages in thread
From: Bjorn Helgaas @ 2012-02-10  2:37 UTC (permalink / raw)
  To: linux-pci; +Cc: linux-arch, sparclinux, David S. Miller

Tell the PCI core about host bridge address translation so it can take
care of bus-to-resource conversion for us.

N.B. Leon apparently never uses initial BAR values, so it didn't matter
that we never fixed up the I/O resources from bus address to CPU addresses.

Other sparc uses pci_of_scan_bus(), which sets device resources directly
to CPU addresses, not bus addresses, so it didn't need pcibios_fixup_bus()
either.  But by telling the core about the offsets, we can nuke
pcibios_resource_to_bus().

CC: "David S. Miller" <davem@davemloft.net>
CC: sparclinux@vger.kernel.org
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
---
 arch/sparc/include/asm/pci_32.h |    8 +------
 arch/sparc/include/asm/pci_64.h |    8 +------
 arch/sparc/kernel/leon_pci.c    |   47 ++++++---------------------------------
 arch/sparc/kernel/pci.c         |   46 +++-----------------------------------
 4 files changed, 13 insertions(+), 96 deletions(-)

diff --git a/arch/sparc/include/asm/pci_32.h b/arch/sparc/include/asm/pci_32.h
index 6de7f7b..6384f30 100644
--- a/arch/sparc/include/asm/pci_32.h
+++ b/arch/sparc/include/asm/pci_32.h
@@ -52,13 +52,7 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev,
  * 64Kbytes by the Host controller.
  */
 
-extern void
-pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
-			struct resource *res);
-
-extern void
-pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
-			struct pci_bus_region *region);
+#define ARCH_HAS_GENERIC_PCI_OFFSETS
 
 static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
 {
diff --git a/arch/sparc/include/asm/pci_64.h b/arch/sparc/include/asm/pci_64.h
index 755a4bb..2918bd1 100644
--- a/arch/sparc/include/asm/pci_64.h
+++ b/arch/sparc/include/asm/pci_64.h
@@ -73,13 +73,7 @@ extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
 			       enum pci_mmap_state mmap_state,
 			       int write_combine);
 
-extern void
-pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
-			struct resource *res);
-
-extern void
-pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
-			struct pci_bus_region *region);
+#define ARCH_HAS_GENERIC_PCI_OFFSETS
 
 static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
 {
diff --git a/arch/sparc/kernel/leon_pci.c b/arch/sparc/kernel/leon_pci.c
index c7bec25..aba6b95 100644
--- a/arch/sparc/kernel/leon_pci.c
+++ b/arch/sparc/kernel/leon_pci.c
@@ -15,14 +15,19 @@
 
 /* The LEON architecture does not rely on a BIOS or bootloader to setup
  * PCI for us. The Linux generic routines are used to setup resources,
- * reset values of confuration-space registers settings ae preseved.
+ * reset values of configuration-space register settings are preserved.
+ *
+ * PCI Memory and Prefetchable Memory is direct-mapped. However I/O Space is
+ * accessed through a Window which is translated to low 64KB in PCI space, the
+ * first 4KB is not used so 60KB is available.
  */
 void leon_pci_init(struct platform_device *ofdev, struct leon_pci_info *info)
 {
 	LIST_HEAD(resources);
 	struct pci_bus *root_bus;
 
-	pci_add_resource(&resources, &info->io_space);
+	pci_add_resource_offset(&resources, &info->io_space,
+				info->io_space.start - 0x1000);
 	pci_add_resource(&resources, &info->mem_space);
 
 	root_bus = pci_scan_root_bus(&ofdev->dev, 0, info->ops, info,
@@ -38,44 +43,6 @@ void leon_pci_init(struct platform_device *ofdev, struct leon_pci_info *info)
 	}
 }
 
-/* PCI Memory and Prefetchable Memory is direct-mapped. However I/O Space is
- * accessed through a Window which is translated to low 64KB in PCI space, the
- * first 4KB is not used so 60KB is available.
- *
- * This function is used by generic code to translate resource addresses into
- * PCI addresses.
- */
-void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
-			     struct resource *res)
-{
-	struct leon_pci_info *info = dev->bus->sysdata;
-
-	region->start = res->start;
-	region->end = res->end;
-
-	if (res->flags & IORESOURCE_IO) {
-		region->start -= (info->io_space.start - 0x1000);
-		region->end -= (info->io_space.start - 0x1000);
-	}
-}
-EXPORT_SYMBOL(pcibios_resource_to_bus);
-
-/* see pcibios_resource_to_bus() comment */
-void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
-			     struct pci_bus_region *region)
-{
-	struct leon_pci_info *info = dev->bus->sysdata;
-
-	res->start = region->start;
-	res->end = region->end;
-
-	if (res->flags & IORESOURCE_IO) {
-		res->start += (info->io_space.start - 0x1000);
-		res->end += (info->io_space.start - 0x1000);
-	}
-}
-EXPORT_SYMBOL(pcibios_bus_to_resource);
-
 void __devinit pcibios_fixup_bus(struct pci_bus *pbus)
 {
 	struct leon_pci_info *info = pbus->sysdata;
diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c
index bb8bc2e..253e8ac 100644
--- a/arch/sparc/kernel/pci.c
+++ b/arch/sparc/kernel/pci.c
@@ -691,8 +691,10 @@ struct pci_bus * __devinit pci_scan_one_pbm(struct pci_pbm_info *pbm,
 
 	printk("PCI: Scanning PBM %s\n", node->full_name);
 
-	pci_add_resource(&resources, &pbm->io_space);
-	pci_add_resource(&resources, &pbm->mem_space);
+	pci_add_resource_offset(&resources, &pbm->io_space,
+				pbm->io_space.start);
+	pci_add_resource_offset(&resources, &pbm->mem_space,
+				pbm->mem_space.start);
 	bus = pci_create_root_bus(parent, pbm->pci_first_busno, pbm->pci_ops,
 				  pbm, &resources);
 	if (!bus) {
@@ -755,46 +757,6 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
 	return 0;
 }
 
-void pcibios_resource_to_bus(struct pci_dev *pdev, struct pci_bus_region *region,
-			     struct resource *res)
-{
-	struct pci_pbm_info *pbm = pdev->bus->sysdata;
-	struct resource zero_res, *root;
-
-	zero_res.start = 0;
-	zero_res.end = 0;
-	zero_res.flags = res->flags;
-
-	if (res->flags & IORESOURCE_IO)
-		root = &pbm->io_space;
-	else
-		root = &pbm->mem_space;
-
-	pci_resource_adjust(&zero_res, root);
-
-	region->start = res->start - zero_res.start;
-	region->end = res->end - zero_res.start;
-}
-EXPORT_SYMBOL(pcibios_resource_to_bus);
-
-void pcibios_bus_to_resource(struct pci_dev *pdev, struct resource *res,
-			     struct pci_bus_region *region)
-{
-	struct pci_pbm_info *pbm = pdev->bus->sysdata;
-	struct resource *root;
-
-	res->start = region->start;
-	res->end = region->end;
-
-	if (res->flags & IORESOURCE_IO)
-		root = &pbm->io_space;
-	else
-		root = &pbm->mem_space;
-
-	pci_resource_adjust(res, root);
-}
-EXPORT_SYMBOL(pcibios_bus_to_resource);
-
 char * __devinit pcibios_setup(char *str)
 {
 	return str;


^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v2 16/18] sparc/PCI: get rid of device resource fixups
@ 2012-02-10  2:37   ` Bjorn Helgaas
  0 siblings, 0 replies; 34+ messages in thread
From: Bjorn Helgaas @ 2012-02-10  2:37 UTC (permalink / raw)
  To: linux-pci; +Cc: linux-arch, sparclinux, David S. Miller

Tell the PCI core about host bridge address translation so it can take
care of bus-to-resource conversion for us.

N.B. Leon apparently never uses initial BAR values, so it didn't matter
that we never fixed up the I/O resources from bus address to CPU addresses.

Other sparc uses pci_of_scan_bus(), which sets device resources directly
to CPU addresses, not bus addresses, so it didn't need pcibios_fixup_bus()
either.  But by telling the core about the offsets, we can nuke
pcibios_resource_to_bus().

CC: "David S. Miller" <davem@davemloft.net>
CC: sparclinux@vger.kernel.org
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
---
 arch/sparc/include/asm/pci_32.h |    8 +------
 arch/sparc/include/asm/pci_64.h |    8 +------
 arch/sparc/kernel/leon_pci.c    |   47 ++++++---------------------------------
 arch/sparc/kernel/pci.c         |   46 +++-----------------------------------
 4 files changed, 13 insertions(+), 96 deletions(-)

diff --git a/arch/sparc/include/asm/pci_32.h b/arch/sparc/include/asm/pci_32.h
index 6de7f7b..6384f30 100644
--- a/arch/sparc/include/asm/pci_32.h
+++ b/arch/sparc/include/asm/pci_32.h
@@ -52,13 +52,7 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev,
  * 64Kbytes by the Host controller.
  */
 
-extern void
-pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
-			struct resource *res);
-
-extern void
-pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
-			struct pci_bus_region *region);
+#define ARCH_HAS_GENERIC_PCI_OFFSETS
 
 static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
 {
diff --git a/arch/sparc/include/asm/pci_64.h b/arch/sparc/include/asm/pci_64.h
index 755a4bb..2918bd1 100644
--- a/arch/sparc/include/asm/pci_64.h
+++ b/arch/sparc/include/asm/pci_64.h
@@ -73,13 +73,7 @@ extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
 			       enum pci_mmap_state mmap_state,
 			       int write_combine);
 
-extern void
-pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
-			struct resource *res);
-
-extern void
-pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
-			struct pci_bus_region *region);
+#define ARCH_HAS_GENERIC_PCI_OFFSETS
 
 static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
 {
diff --git a/arch/sparc/kernel/leon_pci.c b/arch/sparc/kernel/leon_pci.c
index c7bec25..aba6b95 100644
--- a/arch/sparc/kernel/leon_pci.c
+++ b/arch/sparc/kernel/leon_pci.c
@@ -15,14 +15,19 @@
 
 /* The LEON architecture does not rely on a BIOS or bootloader to setup
  * PCI for us. The Linux generic routines are used to setup resources,
- * reset values of confuration-space registers settings ae preseved.
+ * reset values of configuration-space register settings are preserved.
+ *
+ * PCI Memory and Prefetchable Memory is direct-mapped. However I/O Space is
+ * accessed through a Window which is translated to low 64KB in PCI space, the
+ * first 4KB is not used so 60KB is available.
  */
 void leon_pci_init(struct platform_device *ofdev, struct leon_pci_info *info)
 {
 	LIST_HEAD(resources);
 	struct pci_bus *root_bus;
 
-	pci_add_resource(&resources, &info->io_space);
+	pci_add_resource_offset(&resources, &info->io_space,
+				info->io_space.start - 0x1000);
 	pci_add_resource(&resources, &info->mem_space);
 
 	root_bus = pci_scan_root_bus(&ofdev->dev, 0, info->ops, info,
@@ -38,44 +43,6 @@ void leon_pci_init(struct platform_device *ofdev, struct leon_pci_info *info)
 	}
 }
 
-/* PCI Memory and Prefetchable Memory is direct-mapped. However I/O Space is
- * accessed through a Window which is translated to low 64KB in PCI space, the
- * first 4KB is not used so 60KB is available.
- *
- * This function is used by generic code to translate resource addresses into
- * PCI addresses.
- */
-void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
-			     struct resource *res)
-{
-	struct leon_pci_info *info = dev->bus->sysdata;
-
-	region->start = res->start;
-	region->end = res->end;
-
-	if (res->flags & IORESOURCE_IO) {
-		region->start -= (info->io_space.start - 0x1000);
-		region->end -= (info->io_space.start - 0x1000);
-	}
-}
-EXPORT_SYMBOL(pcibios_resource_to_bus);
-
-/* see pcibios_resource_to_bus() comment */
-void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
-			     struct pci_bus_region *region)
-{
-	struct leon_pci_info *info = dev->bus->sysdata;
-
-	res->start = region->start;
-	res->end = region->end;
-
-	if (res->flags & IORESOURCE_IO) {
-		res->start += (info->io_space.start - 0x1000);
-		res->end += (info->io_space.start - 0x1000);
-	}
-}
-EXPORT_SYMBOL(pcibios_bus_to_resource);
-
 void __devinit pcibios_fixup_bus(struct pci_bus *pbus)
 {
 	struct leon_pci_info *info = pbus->sysdata;
diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c
index bb8bc2e..253e8ac 100644
--- a/arch/sparc/kernel/pci.c
+++ b/arch/sparc/kernel/pci.c
@@ -691,8 +691,10 @@ struct pci_bus * __devinit pci_scan_one_pbm(struct pci_pbm_info *pbm,
 
 	printk("PCI: Scanning PBM %s\n", node->full_name);
 
-	pci_add_resource(&resources, &pbm->io_space);
-	pci_add_resource(&resources, &pbm->mem_space);
+	pci_add_resource_offset(&resources, &pbm->io_space,
+				pbm->io_space.start);
+	pci_add_resource_offset(&resources, &pbm->mem_space,
+				pbm->mem_space.start);
 	bus = pci_create_root_bus(parent, pbm->pci_first_busno, pbm->pci_ops,
 				  pbm, &resources);
 	if (!bus) {
@@ -755,46 +757,6 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
 	return 0;
 }
 
-void pcibios_resource_to_bus(struct pci_dev *pdev, struct pci_bus_region *region,
-			     struct resource *res)
-{
-	struct pci_pbm_info *pbm = pdev->bus->sysdata;
-	struct resource zero_res, *root;
-
-	zero_res.start = 0;
-	zero_res.end = 0;
-	zero_res.flags = res->flags;
-
-	if (res->flags & IORESOURCE_IO)
-		root = &pbm->io_space;
-	else
-		root = &pbm->mem_space;
-
-	pci_resource_adjust(&zero_res, root);
-
-	region->start = res->start - zero_res.start;
-	region->end = res->end - zero_res.start;
-}
-EXPORT_SYMBOL(pcibios_resource_to_bus);
-
-void pcibios_bus_to_resource(struct pci_dev *pdev, struct resource *res,
-			     struct pci_bus_region *region)
-{
-	struct pci_pbm_info *pbm = pdev->bus->sysdata;
-	struct resource *root;
-
-	res->start = region->start;
-	res->end = region->end;
-
-	if (res->flags & IORESOURCE_IO)
-		root = &pbm->io_space;
-	else
-		root = &pbm->mem_space;
-
-	pci_resource_adjust(res, root);
-}
-EXPORT_SYMBOL(pcibios_bus_to_resource);
-
 char * __devinit pcibios_setup(char *str)
 {
 	return str;


^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v2 17/18] xtensa/PCI: get rid of device resource fixups
  2012-02-10  2:36 [PATCH v2 00/18] add PCI bus-to-resource offset support in core Bjorn Helgaas
                   ` (15 preceding siblings ...)
  2012-02-10  2:37   ` Bjorn Helgaas
@ 2012-02-10  2:37 ` Bjorn Helgaas
  2012-02-10  2:37 ` [PATCH v2 18/18] PCI: collapse pcibios_resource_to_bus Bjorn Helgaas
  2012-02-10  4:03 ` [PATCH v2 00/18] add PCI bus-to-resource offset support in core Yinghai Lu
  18 siblings, 0 replies; 34+ messages in thread
From: Bjorn Helgaas @ 2012-02-10  2:37 UTC (permalink / raw)
  To: linux-pci; +Cc: linux-arch, Chris Zankel

Tell the PCI core about host bridge address translation so it can take
care of bus-to-resource conversion for us.

CC: Chris Zankel <chris@zankel.net>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
---
 arch/xtensa/kernel/pci.c |   17 +----------------
 1 files changed, 1 insertions(+), 16 deletions(-)

diff --git a/arch/xtensa/kernel/pci.c b/arch/xtensa/kernel/pci.c
index 61045c1..eb30e35 100644
--- a/arch/xtensa/kernel/pci.c
+++ b/arch/xtensa/kernel/pci.c
@@ -153,7 +153,7 @@ static void __init pci_controller_apertures(struct pci_controller *pci_ctrl,
 	}
 	res->start += io_offset;
 	res->end += io_offset;
-	pci_add_resource(resources, res);
+	pci_add_resource_offset(resources, res, io_offset);
 
 	for (i = 0; i < 3; i++) {
 		res = &pci_ctrl->mem_resources[i];
@@ -200,24 +200,9 @@ subsys_initcall(pcibios_init);
 
 void __init pcibios_fixup_bus(struct pci_bus *bus)
 {
-	struct pci_controller *pci_ctrl = bus->sysdata;
-	struct resource *res;
-	unsigned long io_offset;
-	int i;
-
-	io_offset = (unsigned long)pci_ctrl->io_space.base;
 	if (bus->parent) {
 		/* This is a subordinate bridge */
 		pci_read_bridge_bases(bus);
-
-		for (i = 0; i < 4; i++) {
-			if ((res = bus->resource[i]) == NULL || !res->flags)
-				continue;
-			if (io_offset && (res->flags & IORESOURCE_IO)) {
-				res->start += io_offset;
-				res->end += io_offset;
-			}
-		}
 	}
 }
 


^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v2 18/18] PCI: collapse pcibios_resource_to_bus
  2012-02-10  2:36 [PATCH v2 00/18] add PCI bus-to-resource offset support in core Bjorn Helgaas
                   ` (16 preceding siblings ...)
  2012-02-10  2:37 ` [PATCH v2 17/18] xtensa/PCI: " Bjorn Helgaas
@ 2012-02-10  2:37 ` Bjorn Helgaas
  2012-02-10  4:03 ` [PATCH v2 00/18] add PCI bus-to-resource offset support in core Yinghai Lu
  18 siblings, 0 replies; 34+ messages in thread
From: Bjorn Helgaas @ 2012-02-10  2:37 UTC (permalink / raw)
  To: linux-pci; +Cc: linux-arch

Everybody uses the generic pcibios_resource_to_bus() supplied by the core
now, so remove the ARCH_HAS_GENERIC_PCI_OFFSETS used during conversion.

Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
---
 arch/alpha/include/asm/pci.h      |    2 --
 arch/arm/include/asm/pci.h        |    2 --
 arch/ia64/include/asm/pci.h       |    2 --
 arch/microblaze/include/asm/pci.h |    2 --
 arch/mips/include/asm/pci.h       |    2 --
 arch/mn10300/include/asm/pci.h    |    2 --
 arch/parisc/include/asm/pci.h     |    2 --
 arch/powerpc/include/asm/pci.h    |    2 --
 arch/sh/include/asm/pci.h         |    2 --
 arch/sparc/include/asm/pci_32.h   |    2 --
 arch/sparc/include/asm/pci_64.h   |    2 --
 drivers/pci/probe.c               |   44 +++++++++++++------------------------
 include/asm-generic/pci.h         |    2 --
 13 files changed, 15 insertions(+), 53 deletions(-)

diff --git a/arch/alpha/include/asm/pci.h b/arch/alpha/include/asm/pci.h
index dace435..b781200 100644
--- a/arch/alpha/include/asm/pci.h
+++ b/arch/alpha/include/asm/pci.h
@@ -99,8 +99,6 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
 	return channel ? 15 : 14;
 }
 
-#define ARCH_HAS_GENERIC_PCI_OFFSETS
-
 #define pci_domain_nr(bus) ((struct pci_controller *)(bus)->sysdata)->index
 
 static inline int pci_proc_domain(struct pci_bus *bus)
diff --git a/arch/arm/include/asm/pci.h b/arch/arm/include/asm/pci.h
index 4748a75..a98a2e1 100644
--- a/arch/arm/include/asm/pci.h
+++ b/arch/arm/include/asm/pci.h
@@ -57,8 +57,6 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev,
 extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
                                enum pci_mmap_state mmap_state, int write_combine);
 
-#define ARCH_HAS_GENERIC_PCI_OFFSETS
-
 /*
  * Dummy implementation; always return 0.
  */
diff --git a/arch/ia64/include/asm/pci.h b/arch/ia64/include/asm/pci.h
index 519bb5c..b22e5f5 100644
--- a/arch/ia64/include/asm/pci.h
+++ b/arch/ia64/include/asm/pci.h
@@ -108,8 +108,6 @@ static inline int pci_proc_domain(struct pci_bus *bus)
 	return (pci_domain_nr(bus) != 0);
 }
 
-#define ARCH_HAS_GENERIC_PCI_OFFSETS
-
 static inline struct resource *
 pcibios_select_root(struct pci_dev *pdev, struct resource *res)
 {
diff --git a/arch/microblaze/include/asm/pci.h b/arch/microblaze/include/asm/pci.h
index 8db01f7..a0da88b 100644
--- a/arch/microblaze/include/asm/pci.h
+++ b/arch/microblaze/include/asm/pci.h
@@ -94,8 +94,6 @@ extern int pci_mmap_legacy_page_range(struct pci_bus *bus,
  */
 #define PCI_DMA_BUS_IS_PHYS     (1)
 
-#define ARCH_HAS_GENERIC_PCI_OFFSETS
-
 static inline struct resource *pcibios_select_root(struct pci_dev *pdev,
 			struct resource *res)
 {
diff --git a/arch/mips/include/asm/pci.h b/arch/mips/include/asm/pci.h
index 2be0c69..a573bf6 100644
--- a/arch/mips/include/asm/pci.h
+++ b/arch/mips/include/asm/pci.h
@@ -112,8 +112,6 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev,
 }
 #endif
 
-#define ARCH_HAS_GENERIC_PCI_OFFSETS
-
 #define pci_domain_nr(bus) ((struct pci_controller *)(bus)->sysdata)->index
 
 static inline int pci_proc_domain(struct pci_bus *bus)
diff --git a/arch/mn10300/include/asm/pci.h b/arch/mn10300/include/asm/pci.h
index dfe1581..8137c25 100644
--- a/arch/mn10300/include/asm/pci.h
+++ b/arch/mn10300/include/asm/pci.h
@@ -85,8 +85,6 @@ extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
 /* implement the pci_ DMA API in terms of the generic device dma_ one */
 #include <asm-generic/pci-dma-compat.h>
 
-#define ARCH_HAS_GENERIC_PCI_OFFSETS
-
 static inline struct resource *
 pcibios_select_root(struct pci_dev *pdev, struct resource *res)
 {
diff --git a/arch/parisc/include/asm/pci.h b/arch/parisc/include/asm/pci.h
index a8b591f..3234f49 100644
--- a/arch/parisc/include/asm/pci.h
+++ b/arch/parisc/include/asm/pci.h
@@ -215,8 +215,6 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev,
 }
 #endif
 
-#define ARCH_HAS_GENERIC_PCI_OFFSETS
-
 static inline void pcibios_penalize_isa_irq(int irq, int active)
 {
 	/* We don't need to penalize isa irq's */
diff --git a/arch/powerpc/include/asm/pci.h b/arch/powerpc/include/asm/pci.h
index 839178b..201e352 100644
--- a/arch/powerpc/include/asm/pci.h
+++ b/arch/powerpc/include/asm/pci.h
@@ -154,8 +154,6 @@ extern int pci_mmap_legacy_page_range(struct pci_bus *bus,
 
 #endif /* CONFIG_PPC64 */
 
-#define ARCH_HAS_GENERIC_PCI_OFFSETS
-
 extern void pcibios_claim_one_bus(struct pci_bus *b);
 
 extern void pcibios_finish_adding_to_bus(struct pci_bus *bus);
diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h
index 3b5b6ab..bff96c2 100644
--- a/arch/sh/include/asm/pci.h
+++ b/arch/sh/include/asm/pci.h
@@ -114,8 +114,6 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev,
 /* Board-specific fixup routines. */
 int pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin);
 
-#define ARCH_HAS_GENERIC_PCI_OFFSETS
-
 #define pci_domain_nr(bus) ((struct pci_channel *)(bus)->sysdata)->index
 
 static inline int pci_proc_domain(struct pci_bus *bus)
diff --git a/arch/sparc/include/asm/pci_32.h b/arch/sparc/include/asm/pci_32.h
index 6384f30..dc50329 100644
--- a/arch/sparc/include/asm/pci_32.h
+++ b/arch/sparc/include/asm/pci_32.h
@@ -52,8 +52,6 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev,
  * 64Kbytes by the Host controller.
  */
 
-#define ARCH_HAS_GENERIC_PCI_OFFSETS
-
 static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
 {
 	return PCI_IRQ_NONE;
diff --git a/arch/sparc/include/asm/pci_64.h b/arch/sparc/include/asm/pci_64.h
index 2918bd1..1633b71 100644
--- a/arch/sparc/include/asm/pci_64.h
+++ b/arch/sparc/include/asm/pci_64.h
@@ -73,8 +73,6 @@ extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
 			       enum pci_mmap_state mmap_state,
 			       int write_combine);
 
-#define ARCH_HAS_GENERIC_PCI_OFFSETS
-
 static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
 {
 	return PCI_IRQ_NONE;
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index f3c503a..5a74d0f 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -66,8 +66,8 @@ static bool resource_contains(struct resource *res1, struct resource *res2)
 	return res1->start <= res2->start && res1->end >= res2->end;
 }
 
-void pci_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
-			struct resource *res)
+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;
@@ -86,6 +86,7 @@ void pci_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
 	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)
@@ -93,8 +94,8 @@ static bool region_contains(struct pci_bus_region *region1,
 	return region1->start <= region2->start && region1->end >= region2->end;
 }
 
-void pci_bus_to_resource(struct pci_dev *dev, struct resource *res,
-			 struct pci_bus_region *region)
+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;
@@ -117,22 +118,7 @@ void pci_bus_to_resource(struct pci_dev *dev, struct resource *res,
 	res->start = region->start + offset;
 	res->end = region->end + offset;
 }
-
-#ifdef ARCH_HAS_GENERIC_PCI_OFFSETS
-void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
-			     struct resource *res)
-{
-	pci_resource_to_bus(dev, region, res);
-}
-EXPORT_SYMBOL(pcibios_resource_to_bus);
-
-void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
-			     struct pci_bus_region *region)
-{
-	pci_bus_to_resource(dev, res, region);
-}
 EXPORT_SYMBOL(pcibios_bus_to_resource);
-#endif
 
 /*
  * PCI Bus Class
@@ -309,11 +295,11 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
 			pci_write_config_dword(dev, pos + 4, 0);
 			region.start = 0;
 			region.end = sz64;
-			pci_bus_to_resource(dev, res, &region);
+			pcibios_bus_to_resource(dev, res, &region);
 		} else {
 			region.start = l64;
 			region.end = l64 + sz64;
-			pci_bus_to_resource(dev, res, &region);
+			pcibios_bus_to_resource(dev, res, &region);
 			dev_printk(KERN_DEBUG, &dev->dev, "reg %x: %pR\n",
 				   pos, res);
 		}
@@ -325,7 +311,7 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
 
 		region.start = l;
 		region.end = l + sz;
-		pci_bus_to_resource(dev, res, &region);
+		pcibios_bus_to_resource(dev, res, &region);
 
 		dev_printk(KERN_DEBUG, &dev->dev, "reg %x: %pR\n", pos, res);
 	}
@@ -383,7 +369,7 @@ static void __devinit pci_read_bridge_io(struct pci_bus *child)
 		res->flags = (io_base_lo & PCI_IO_RANGE_TYPE_MASK) | IORESOURCE_IO;
 		region.start = base;
 		region.end = limit + 0xfff;
-		pci_bus_to_resource(dev, &res2, &region);
+		pcibios_bus_to_resource(dev, &res2, &region);
 		if (!res->start)
 			res->start = res2.start;
 		if (!res->end)
@@ -409,7 +395,7 @@ static void __devinit pci_read_bridge_mmio(struct pci_bus *child)
 		res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM;
 		region.start = base;
 		region.end = limit + 0xfffff;
-		pci_bus_to_resource(dev, res, &region);
+		pcibios_bus_to_resource(dev, res, &region);
 		dev_printk(KERN_DEBUG, &dev->dev, "  bridge window %pR\n", res);
 	}
 }
@@ -458,7 +444,7 @@ static void __devinit pci_read_bridge_mmio_pref(struct pci_bus *child)
 			res->flags |= IORESOURCE_MEM_64;
 		region.start = base;
 		region.end = limit + 0xfffff;
-		pci_bus_to_resource(dev, res, &region);
+		pcibios_bus_to_resource(dev, res, &region);
 		dev_printk(KERN_DEBUG, &dev->dev, "  bridge window %pR\n", res);
 	}
 }
@@ -1068,24 +1054,24 @@ int pci_setup_device(struct pci_dev *dev)
 				region.end = 0x1F7;
 				res = &dev->resource[0];
 				res->flags = LEGACY_IO_RESOURCE;
-				pci_bus_to_resource(dev, res, &region);
+				pcibios_bus_to_resource(dev, res, &region);
 				region.start = 0x3F6;
 				region.end = 0x3F6;
 				res = &dev->resource[1];
 				res->flags = LEGACY_IO_RESOURCE;
-				pci_bus_to_resource(dev, res, &region);
+				pcibios_bus_to_resource(dev, res, &region);
 			}
 			if ((progif & 4) == 0) {
 				region.start = 0x170;
 				region.end = 0x177;
 				res = &dev->resource[2];
 				res->flags = LEGACY_IO_RESOURCE;
-				pci_bus_to_resource(dev, res, &region);
+				pcibios_bus_to_resource(dev, res, &region);
 				region.start = 0x376;
 				region.end = 0x376;
 				res = &dev->resource[3];
 				res->flags = LEGACY_IO_RESOURCE;
-				pci_bus_to_resource(dev, res, &region);
+				pcibios_bus_to_resource(dev, res, &region);
 			}
 		}
 		break;
diff --git a/include/asm-generic/pci.h b/include/asm-generic/pci.h
index 0410346..e80a049 100644
--- a/include/asm-generic/pci.h
+++ b/include/asm-generic/pci.h
@@ -6,8 +6,6 @@
 #ifndef _ASM_GENERIC_PCI_H
 #define _ASM_GENERIC_PCI_H
 
-#define ARCH_HAS_GENERIC_PCI_OFFSETS
-
 static inline struct resource *
 pcibios_select_root(struct pci_dev *pdev, struct resource *res)
 {


^ permalink raw reply related	[flat|nested] 34+ messages in thread

* Re: [PATCH v2 11/18] mips/PCI: get rid of device resource fixups
  2012-02-10  2:37 ` [PATCH v2 11/18] mips/PCI: " Bjorn Helgaas
@ 2012-02-10  2:43   ` Bjorn Helgaas
  0 siblings, 0 replies; 34+ messages in thread
From: Bjorn Helgaas @ 2012-02-10  2:43 UTC (permalink / raw)
  To: linux-pci; +Cc: linux-arch, Ralf Baechle, Yoichi Yuasa

On Thu, Feb 9, 2012 at 6:37 PM, Bjorn Helgaas <bhelgaas@google.com> wrote:
> Tell the PCI core about host bridge address translation so it can take
> care of bus-to-resource conversion for us.
>
> Here's the wrinkle on Cobalt: we can't generate normal I/O port addresses
> on PCI because the GT-64111 doesn't do any address translation,

Yuasa-san, thanks for testing v1 of this series.  I hope this v2
series fixes the problem you saw.  Let me know if it doesn't.

Bjorn

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2 08/18] ia64/PCI: SN: convert to pci_scan_root_bus() for correct root bus resources
  2012-02-10  2:37 ` [PATCH v2 08/18] ia64/PCI: SN: convert to pci_scan_root_bus() for correct root bus resources Bjorn Helgaas
@ 2012-02-10  2:46   ` Bjorn Helgaas
  0 siblings, 0 replies; 34+ messages in thread
From: Bjorn Helgaas @ 2012-02-10  2:46 UTC (permalink / raw)
  To: linux-pci; +Cc: linux-arch, Tony Luck, Jack Steiner

On Thu, Feb 9, 2012 at 6:37 PM, Bjorn Helgaas <bhelgaas@google.com> wrote:
> Convert from pci_scan_bus() to pci_scan_root_bus().  Supply the root
> bus resources from bussoft.  When we move the resource adjustment from
> pcibios_fixup_resources() to the PCI core, it will be important to have
> the root bus resources correct from the beginning.

Hi Jack, this ia64 box has some of the more complicated PCI code, and
of course, I have no way to test it.  If I understand correctly, these
boxes don't have ACPI.  If any of these still exist and if you're
interested in testing this series on them, I'd be happy to help
resolve any issues.

Bjorn

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2 02/18] PCI: add struct pci_host_bridge and a list of all bridges found
  2012-02-10  2:36 ` [PATCH v2 02/18] PCI: add struct pci_host_bridge and a list of all bridges found Bjorn Helgaas
@ 2012-02-10  3:47   ` Yinghai Lu
  2012-02-10  4:16     ` Bjorn Helgaas
  0 siblings, 1 reply; 34+ messages in thread
From: Yinghai Lu @ 2012-02-10  3:47 UTC (permalink / raw)
  To: Bjorn Helgaas; +Cc: linux-pci, linux-arch

On Thu, Feb 9, 2012 at 6:36 PM, Bjorn Helgaas <bhelgaas@google.com> wrote:
> This adds a list of all PCI host bridges we find and a way to look up
> the host bridge from a pci_dev.
>
> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
> ---
>  drivers/pci/probe.c |   39 ++++++++++++++++++++++++++++++++++-----
>  include/linux/pci.h |    5 +++++
>  2 files changed, 39 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index da0d655..2ffe8a3 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -15,6 +15,8 @@
>  #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);
> @@ -42,6 +44,23 @@ 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;
> +}
> +

so pci_host_bridge(dev) still is expensive.



>  /*
>  * PCI Bus Class
>  */
> @@ -1526,20 +1545,23 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
>                struct pci_ops *ops, void *sysdata, struct list_head *resources)
>  {
>        int error, i;
> +       struct pci_host_bridge *bridge;
>        struct pci_bus *b, *b2;
>        struct device *dev;
>        struct pci_bus_resource *bus_res, *n;
>        struct resource *res;
>
> +       bridge = kzalloc(sizeof(*bridge), GFP_KERNEL);
> +       if (!bridge)
> +               return NULL;
> +
>        b = pci_alloc_bus();
>        if (!b)
> -               return NULL;
> +               goto err_bus;
>
>        dev = kzalloc(sizeof(*dev), GFP_KERNEL);
> -       if (!dev) {
> -               kfree(b);
> -               return NULL;
> -       }
> +       if (!dev)
> +               goto err_dev;
>
>        b->sysdata = sysdata;
>        b->ops = ops;
> @@ -1576,6 +1598,8 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
>
>        b->number = b->secondary = bus;
>
> +       bridge->bus = b;
> +
>        /* Add initial resources to the bus */
>        list_for_each_entry_safe(bus_res, n, resources, list)
>                list_move_tail(&bus_res->list, &b->resources);
> @@ -1591,6 +1615,7 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
>        }
>
>        down_write(&pci_bus_sem);
> +       list_add_tail(&bridge->list, &pci_host_bridges);
>        list_add_tail(&b->node, &pci_root_buses);
>        up_write(&pci_bus_sem);
>
> @@ -1600,11 +1625,15 @@ class_dev_reg_err:
>        device_unregister(dev);
>  dev_reg_err:
>        down_write(&pci_bus_sem);
> +       list_del(&bridge->list);
>        list_del(&b->node);
>        up_write(&pci_bus_sem);
>  err_out:
>        kfree(dev);
> +err_dev:
>        kfree(b);
> +err_bus:
> +       kfree(bridge);
>        return NULL;
>  }
>
> diff --git a/include/linux/pci.h b/include/linux/pci.h
> index a16b1df..dfb2b64 100644
> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
> @@ -388,6 +388,11 @@ static inline void pci_add_saved_cap(struct pci_dev *pci_dev,
>        hlist_add_head(&new_cap->next, &pci_dev->saved_cap_space);
>  }
>
> +struct pci_host_bridge {
> +       struct list_head list;
> +       struct pci_bus *bus;            /* root bus */
> +};
> +

also still have two list: one for host bridges and one for root buses.

Yinghai

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2 03/18] PCI: add struct pci_host_bridge_window with CPU/bus address offset
  2012-02-10  2:36 ` [PATCH v2 03/18] PCI: add struct pci_host_bridge_window with CPU/bus address offset Bjorn Helgaas
@ 2012-02-10  3:49   ` Yinghai Lu
  2012-02-10  4:37     ` Bjorn Helgaas
  0 siblings, 1 reply; 34+ messages in thread
From: Yinghai Lu @ 2012-02-10  3:49 UTC (permalink / raw)
  To: Bjorn Helgaas; +Cc: linux-pci, linux-arch

On Thu, Feb 9, 2012 at 6:36 PM, Bjorn Helgaas <bhelgaas@google.com> wrote:
> Some PCI host bridges apply an address offset, so bus addresses on PCI are
> different from CPU addresses.  This patch adds a way for architectures to
> tell the PCI core about this offset.  For example:
>
>    LIST_HEAD(resources);
>    pci_add_resource_offset(&resources, host->io_space, host->io_offset);
>    pci_add_resource_offset(&resources, host->mem_space, host->mem_offset);
>    pci_scan_root_bus(parent, bus, ops, sysdata, &resources);
>
> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
> ---
>  drivers/pci/bus.c   |   30 +++++++++++++++++++-----------
>  drivers/pci/probe.c |   32 +++++++++++++++++++++++---------
>  include/linux/pci.h |    9 +++++++++
>  3 files changed, 51 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
> index 398f5d8..4ce5ef2 100644
> --- a/drivers/pci/bus.c
> +++ b/drivers/pci/bus.c
> @@ -18,28 +18,36 @@
>
>  #include "pci.h"
>
> -void pci_add_resource(struct list_head *resources, struct resource *res)
> +void pci_add_resource_offset(struct list_head *resources, struct resource *res,
> +                            resource_size_t offset)
>  {
> -       struct pci_bus_resource *bus_res;
> +       struct pci_host_bridge_window *window;
>
> -       bus_res = kzalloc(sizeof(struct pci_bus_resource), GFP_KERNEL);
> -       if (!bus_res) {
> -               printk(KERN_ERR "PCI: can't add bus resource %pR\n", res);
> +       window = kzalloc(sizeof(struct pci_host_bridge_window), GFP_KERNEL);
> +       if (!window) {
> +               printk(KERN_ERR "PCI: can't add host bridge window %pR\n", res);
>                return;
>        }
>
> -       bus_res->res = res;
> -       list_add_tail(&bus_res->list, resources);
> +       window->res = res;
> +       window->offset = offset;
> +       list_add_tail(&window->list, resources);
> +}
> +EXPORT_SYMBOL(pci_add_resource_offset);
> +
> +void pci_add_resource(struct list_head *resources, struct resource *res)
> +{
> +       pci_add_resource_offset(resources, res, 0);
>  }
>  EXPORT_SYMBOL(pci_add_resource);
>
>  void pci_free_resource_list(struct list_head *resources)
>  {
> -       struct pci_bus_resource *bus_res, *tmp;
> +       struct pci_host_bridge_window *window, *tmp;
>
> -       list_for_each_entry_safe(bus_res, tmp, resources, list) {
> -               list_del(&bus_res->list);
> -               kfree(bus_res);
> +       list_for_each_entry_safe(window, tmp, resources, list) {
> +               list_del(&window->list);
> +               kfree(window);
>        }
>  }
>  EXPORT_SYMBOL(pci_free_resource_list);
> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index 2ffe8a3..69c1b11 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -1544,12 +1544,15 @@ unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus)
>  struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
>                struct pci_ops *ops, void *sysdata, struct list_head *resources)
>  {
> -       int error, i;
> +       int error;
>        struct pci_host_bridge *bridge;
>        struct pci_bus *b, *b2;
>        struct device *dev;
> -       struct pci_bus_resource *bus_res, *n;
> +       struct pci_host_bridge_window *window, *n;
>        struct resource *res;
> +       resource_size_t offset;
> +       char bus_addr[64];
> +       char *fmt;
>
>        bridge = kzalloc(sizeof(*bridge), GFP_KERNEL);
>        if (!bridge)
> @@ -1599,19 +1602,30 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
>        b->number = b->secondary = bus;
>
>        bridge->bus = b;
> -
> -       /* Add initial resources to the bus */
> -       list_for_each_entry_safe(bus_res, n, resources, list)
> -               list_move_tail(&bus_res->list, &b->resources);
> +       INIT_LIST_HEAD(&bridge->windows);
>
>        if (parent)
>                dev_info(parent, "PCI host bridge to bus %s\n", dev_name(&b->dev));
>        else
>                printk(KERN_INFO "PCI host bridge to bus %s\n", dev_name(&b->dev));
>
> -       pci_bus_for_each_resource(b, res, i) {
> -               if (res)
> -                       dev_info(&b->dev, "root bus resource %pR\n", res);
> +       /* Add initial resources to the bus */
> +       list_for_each_entry_safe(window, n, resources, list) {
> +               list_move_tail(&window->list, &bridge->windows);
> +               res = window->res;
> +               offset = window->offset;
> +               pci_bus_add_resource(b, res, 0);

you put two copies of root resource list ?

Yinghai

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2 00/18] add PCI bus-to-resource offset support in core
  2012-02-10  2:36 [PATCH v2 00/18] add PCI bus-to-resource offset support in core Bjorn Helgaas
                   ` (17 preceding siblings ...)
  2012-02-10  2:37 ` [PATCH v2 18/18] PCI: collapse pcibios_resource_to_bus Bjorn Helgaas
@ 2012-02-10  4:03 ` Yinghai Lu
  2012-02-10  4:34   ` Bjorn Helgaas
  18 siblings, 1 reply; 34+ messages in thread
From: Yinghai Lu @ 2012-02-10  4:03 UTC (permalink / raw)
  To: Bjorn Helgaas; +Cc: linux-pci, linux-arch

On Thu, Feb 9, 2012 at 6:36 PM, Bjorn Helgaas <bhelgaas@google.com> wrote:
> There's a lot of PCI-related code under arch/, but much of it is not actually
> architecture-specific.  This series removes some of that code by moving most
> of the bus-to-resource conversions into the core.
>
> We currently read PCI bus addresses from BARs in the core (pci_setup_device()).
> Then every arch is responsible for converting those bus addresses to CPU
> resources, usually in pcibios_fixup_bus().
>
> We already have a way for architectures to tell the core what the windows
> through a host bridge are:
>
>    LIST_HEAD(resources);
>    pci_add_resource(&resources, io_space);
>    pci_add_resource(&resources, mem_space);
>    pci_scan_root_bus(parent, bus, ops, sysdata, &resources);
>
> This series extends that so the arch can also tell the core about address
> translation performed by the host bridge:
>
>    LIST_HEAD(resources);
>    pci_add_resource_offset(&resources, io_space, io_offset);
>    pci_add_resource_offset(&resources, mem_space, mem_offset);
>    pci_scan_root_bus(parent, bus, ops, sysdata, &resources);
>
> Given that offset (the difference between bus address and CPU address for
> each aperture), the core can do the bus-to-resource conversion immediately
> when it reads the BARs.
>
> This removes an opportunity for bugs (some PCI fixups currently see bus
> addresses in struct pci_dev resources when they're expecting CPU addresses),
> but the main reason to do this is to make our PCI resource handling simpler
> and more uniform.
>
> These patches are also available in this git repo:
>    git://github.com/bjorn-helgaas/linux.git pci-offset-v2-d15af52258dd
>
> Or you can browse them here:
>    https://github.com/bjorn-helgaas/linux/compare/master...pci-offset-v2-d15af52258dd
>
> I'd like to get these into linux-next soon to be ready for the 3.4 merge
> window, so please let me know if you see any issues.
>
> Changes since v1:
>  - mips: remove Cobalt legacy IDE fixup
>  - show bus address range, not offset, e.g., this:
>        pci_bus 0000:00: root bus resource [mem 0xf0000000000-0xf007edfffff] (bus address [0x80000000-0xfedfffff])
>    instead of this:
>        pci_bus 0000:00: root bus resource [mem 0xf0000000000-0xf007edfffff] (bus offset 0xeff80000000)
>

still think make pci_sysdata to generic and add one offset field to
that would be more simple.

Yinghai

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2 02/18] PCI: add struct pci_host_bridge and a list of all bridges found
  2012-02-10  3:47   ` Yinghai Lu
@ 2012-02-10  4:16     ` Bjorn Helgaas
  0 siblings, 0 replies; 34+ messages in thread
From: Bjorn Helgaas @ 2012-02-10  4:16 UTC (permalink / raw)
  To: Yinghai Lu; +Cc: linux-pci, linux-arch

On Thu, Feb 9, 2012 at 7:47 PM, Yinghai Lu <yinghai@kernel.org> wrote:
> On Thu, Feb 9, 2012 at 6:36 PM, Bjorn Helgaas <bhelgaas@google.com> wrote:
>> This adds a list of all PCI host bridges we find and a way to look up
>> the host bridge from a pci_dev.
>>
>> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
>> ---
>>  drivers/pci/probe.c |   39 ++++++++++++++++++++++++++++++++++-----
>>  include/linux/pci.h |    5 +++++
>>  2 files changed, 39 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
>> index da0d655..2ffe8a3 100644
>> --- a/drivers/pci/probe.c
>> +++ b/drivers/pci/probe.c
>> @@ -15,6 +15,8 @@
>>  #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);
>> @@ -42,6 +44,23 @@ 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;
>> +}
>> +
>
> so pci_host_bridge(dev) still is expensive.

Yes, it is relatively expensive.  However, it is used only when
converting between bus addresses and CPU addresses, which is done
rarely.  We only do it when reading or writing a BAR.  I suppose one
could add a pointer to struct pci_bus or something, but I don't think
it's worth it.

>>  /*
>>  * PCI Bus Class
>>  */
>> @@ -1526,20 +1545,23 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
>>                struct pci_ops *ops, void *sysdata, struct list_head *resources)
>>  {
>>        int error, i;
>> +       struct pci_host_bridge *bridge;
>>        struct pci_bus *b, *b2;
>>        struct device *dev;
>>        struct pci_bus_resource *bus_res, *n;
>>        struct resource *res;
>>
>> +       bridge = kzalloc(sizeof(*bridge), GFP_KERNEL);
>> +       if (!bridge)
>> +               return NULL;
>> +
>>        b = pci_alloc_bus();
>>        if (!b)
>> -               return NULL;
>> +               goto err_bus;
>>
>>        dev = kzalloc(sizeof(*dev), GFP_KERNEL);
>> -       if (!dev) {
>> -               kfree(b);
>> -               return NULL;
>> -       }
>> +       if (!dev)
>> +               goto err_dev;
>>
>>        b->sysdata = sysdata;
>>        b->ops = ops;
>> @@ -1576,6 +1598,8 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
>>
>>        b->number = b->secondary = bus;
>>
>> +       bridge->bus = b;
>> +
>>        /* Add initial resources to the bus */
>>        list_for_each_entry_safe(bus_res, n, resources, list)
>>                list_move_tail(&bus_res->list, &b->resources);
>> @@ -1591,6 +1615,7 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
>>        }
>>
>>        down_write(&pci_bus_sem);
>> +       list_add_tail(&bridge->list, &pci_host_bridges);
>>        list_add_tail(&b->node, &pci_root_buses);
>>        up_write(&pci_bus_sem);
>>
>> @@ -1600,11 +1625,15 @@ class_dev_reg_err:
>>        device_unregister(dev);
>>  dev_reg_err:
>>        down_write(&pci_bus_sem);
>> +       list_del(&bridge->list);
>>        list_del(&b->node);
>>        up_write(&pci_bus_sem);
>>  err_out:
>>        kfree(dev);
>> +err_dev:
>>        kfree(b);
>> +err_bus:
>> +       kfree(bridge);
>>        return NULL;
>>  }
>>
>> diff --git a/include/linux/pci.h b/include/linux/pci.h
>> index a16b1df..dfb2b64 100644
>> --- a/include/linux/pci.h
>> +++ b/include/linux/pci.h
>> @@ -388,6 +388,11 @@ static inline void pci_add_saved_cap(struct pci_dev *pci_dev,
>>        hlist_add_head(&new_cap->next, &pci_dev->saved_cap_space);
>>  }
>>
>> +struct pci_host_bridge {
>> +       struct list_head list;
>> +       struct pci_bus *bus;            /* root bus */
>> +};
>> +
>
> also still have two list: one for host bridges and one for root buses.

Yes.

You previously suggested overloading bus->self.  Currently bus->self
is null for root buses.  For non-root buses, it points to the pci_dev
of the upstream P2P bridge.  So I think you're suggesting that for
root buses, bus->self could point to a struct pci_host_bridge, even
though its type is "struct pci_dev *".  That seems ugly to me.  If
that's not what you mean, can you show an example to help me
understand?

You also suggested adding a "struct pci_host_bridge *" to pci_sysdata.
 That's an x86-specific structure, so doesn't help here, since what
I'm doing is shared across all architectures.

I do agree that the list of host bridges and the list of root buses
are somewhat redundant.  Obviously, it would be trivial to drop the
root bus list and replace it with the host bridge list, and that might
be a good thing to do in the future.

If you have a suggestion here, please write more about it so I can
understand it.

Bjorn

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2 00/18] add PCI bus-to-resource offset support in core
  2012-02-10  4:03 ` [PATCH v2 00/18] add PCI bus-to-resource offset support in core Yinghai Lu
@ 2012-02-10  4:34   ` Bjorn Helgaas
  2012-02-10  4:50     ` Yinghai Lu
  0 siblings, 1 reply; 34+ messages in thread
From: Bjorn Helgaas @ 2012-02-10  4:34 UTC (permalink / raw)
  To: Yinghai Lu; +Cc: linux-pci, linux-arch

On Thu, Feb 9, 2012 at 8:03 PM, Yinghai Lu <yinghai@kernel.org> wrote:
> On Thu, Feb 9, 2012 at 6:36 PM, Bjorn Helgaas <bhelgaas@google.com> wrote:
>> There's a lot of PCI-related code under arch/, but much of it is not actually
>> architecture-specific.  This series removes some of that code by moving most
>> of the bus-to-resource conversions into the core.
>>
>> We currently read PCI bus addresses from BARs in the core (pci_setup_device()).
>> Then every arch is responsible for converting those bus addresses to CPU
>> resources, usually in pcibios_fixup_bus().
>>
>> We already have a way for architectures to tell the core what the windows
>> through a host bridge are:
>>
>>    LIST_HEAD(resources);
>>    pci_add_resource(&resources, io_space);
>>    pci_add_resource(&resources, mem_space);
>>    pci_scan_root_bus(parent, bus, ops, sysdata, &resources);
>>
>> This series extends that so the arch can also tell the core about address
>> translation performed by the host bridge:
>>
>>    LIST_HEAD(resources);
>>    pci_add_resource_offset(&resources, io_space, io_offset);
>>    pci_add_resource_offset(&resources, mem_space, mem_offset);
>>    pci_scan_root_bus(parent, bus, ops, sysdata, &resources);
>>
>> Given that offset (the difference between bus address and CPU address for
>> each aperture), the core can do the bus-to-resource conversion immediately
>> when it reads the BARs.
>>
>> This removes an opportunity for bugs (some PCI fixups currently see bus
>> addresses in struct pci_dev resources when they're expecting CPU addresses),
>> but the main reason to do this is to make our PCI resource handling simpler
>> and more uniform.
>>
>> These patches are also available in this git repo:
>>    git://github.com/bjorn-helgaas/linux.git pci-offset-v2-d15af52258dd
>>
>> Or you can browse them here:
>>    https://github.com/bjorn-helgaas/linux/compare/master...pci-offset-v2-d15af52258dd
>>
>> I'd like to get these into linux-next soon to be ready for the 3.4 merge
>> window, so please let me know if you see any issues.
>>
>> Changes since v1:
>>  - mips: remove Cobalt legacy IDE fixup
>>  - show bus address range, not offset, e.g., this:
>>        pci_bus 0000:00: root bus resource [mem 0xf0000000000-0xf007edfffff] (bus address [0x80000000-0xfedfffff])
>>    instead of this:
>>        pci_bus 0000:00: root bus resource [mem 0xf0000000000-0xf007edfffff] (bus offset 0xeff80000000)
>>
>
> still think make pci_sysdata to generic and add one offset field to
> that would be more simple.

Maybe I'm misunderstanding you, because this doesn't make sense to me at all.

*One* offset field is insufficient.  A host bridge can have an
arbitrary number of apertures, and each aperture can have a different
offset.  So we must have a list or other variable-size structure.

pci_scan_bus() takes a "void *sysdata".  Every arch defines its own
structure (struct pci_sysdata for x86, struct pci_controller for most
others) to supply here.  Are you suggesting that we make a common
structure like this:

    struct pci_sysdata {
        struct list_head windows;
        void *sysdata;  /* arch-specific stuff */
    };

That's possible, but I don't see the advantage over what I've done.
It doesn't seem simpler, because all the arch code that looks at
bus->sysdata would have to change to use
bus->generic_sysdata->sysdata.

If you can show an example of what you mean, maybe it will help me understand.

Bjorn

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2 03/18] PCI: add struct pci_host_bridge_window with CPU/bus address offset
  2012-02-10  3:49   ` Yinghai Lu
@ 2012-02-10  4:37     ` Bjorn Helgaas
  0 siblings, 0 replies; 34+ messages in thread
From: Bjorn Helgaas @ 2012-02-10  4:37 UTC (permalink / raw)
  To: Yinghai Lu; +Cc: linux-pci, linux-arch

On Thu, Feb 9, 2012 at 7:49 PM, Yinghai Lu <yinghai@kernel.org> wrote:
> On Thu, Feb 9, 2012 at 6:36 PM, Bjorn Helgaas <bhelgaas@google.com> wrote:
>> Some PCI host bridges apply an address offset, so bus addresses on PCI are
>> different from CPU addresses.  This patch adds a way for architectures to
>> tell the PCI core about this offset.  For example:
>>
>>    LIST_HEAD(resources);
>>    pci_add_resource_offset(&resources, host->io_space, host->io_offset);
>>    pci_add_resource_offset(&resources, host->mem_space, host->mem_offset);
>>    pci_scan_root_bus(parent, bus, ops, sysdata, &resources);
>>
>> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
>> ---
>>  drivers/pci/bus.c   |   30 +++++++++++++++++++-----------
>>  drivers/pci/probe.c |   32 +++++++++++++++++++++++---------
>>  include/linux/pci.h |    9 +++++++++
>>  3 files changed, 51 insertions(+), 20 deletions(-)
>>
>> diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
>> index 398f5d8..4ce5ef2 100644
>> --- a/drivers/pci/bus.c
>> +++ b/drivers/pci/bus.c
>> @@ -18,28 +18,36 @@
>>
>>  #include "pci.h"
>>
>> -void pci_add_resource(struct list_head *resources, struct resource *res)
>> +void pci_add_resource_offset(struct list_head *resources, struct resource *res,
>> +                            resource_size_t offset)
>>  {
>> -       struct pci_bus_resource *bus_res;
>> +       struct pci_host_bridge_window *window;
>>
>> -       bus_res = kzalloc(sizeof(struct pci_bus_resource), GFP_KERNEL);
>> -       if (!bus_res) {
>> -               printk(KERN_ERR "PCI: can't add bus resource %pR\n", res);
>> +       window = kzalloc(sizeof(struct pci_host_bridge_window), GFP_KERNEL);
>> +       if (!window) {
>> +               printk(KERN_ERR "PCI: can't add host bridge window %pR\n", res);
>>                return;
>>        }
>>
>> -       bus_res->res = res;
>> -       list_add_tail(&bus_res->list, resources);
>> +       window->res = res;
>> +       window->offset = offset;
>> +       list_add_tail(&window->list, resources);
>> +}
>> +EXPORT_SYMBOL(pci_add_resource_offset);
>> +
>> +void pci_add_resource(struct list_head *resources, struct resource *res)
>> +{
>> +       pci_add_resource_offset(resources, res, 0);
>>  }
>>  EXPORT_SYMBOL(pci_add_resource);
>>
>>  void pci_free_resource_list(struct list_head *resources)
>>  {
>> -       struct pci_bus_resource *bus_res, *tmp;
>> +       struct pci_host_bridge_window *window, *tmp;
>>
>> -       list_for_each_entry_safe(bus_res, tmp, resources, list) {
>> -               list_del(&bus_res->list);
>> -               kfree(bus_res);
>> +       list_for_each_entry_safe(window, tmp, resources, list) {
>> +               list_del(&window->list);
>> +               kfree(window);
>>        }
>>  }
>>  EXPORT_SYMBOL(pci_free_resource_list);
>> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
>> index 2ffe8a3..69c1b11 100644
>> --- a/drivers/pci/probe.c
>> +++ b/drivers/pci/probe.c
>> @@ -1544,12 +1544,15 @@ unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus)
>>  struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
>>                struct pci_ops *ops, void *sysdata, struct list_head *resources)
>>  {
>> -       int error, i;
>> +       int error;
>>        struct pci_host_bridge *bridge;
>>        struct pci_bus *b, *b2;
>>        struct device *dev;
>> -       struct pci_bus_resource *bus_res, *n;
>> +       struct pci_host_bridge_window *window, *n;
>>        struct resource *res;
>> +       resource_size_t offset;
>> +       char bus_addr[64];
>> +       char *fmt;
>>
>>        bridge = kzalloc(sizeof(*bridge), GFP_KERNEL);
>>        if (!bridge)
>> @@ -1599,19 +1602,30 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
>>        b->number = b->secondary = bus;
>>
>>        bridge->bus = b;
>> -
>> -       /* Add initial resources to the bus */
>> -       list_for_each_entry_safe(bus_res, n, resources, list)
>> -               list_move_tail(&bus_res->list, &b->resources);
>> +       INIT_LIST_HEAD(&bridge->windows);
>>
>>        if (parent)
>>                dev_info(parent, "PCI host bridge to bus %s\n", dev_name(&b->dev));
>>        else
>>                printk(KERN_INFO "PCI host bridge to bus %s\n", dev_name(&b->dev));
>>
>> -       pci_bus_for_each_resource(b, res, i) {
>> -               if (res)
>> -                       dev_info(&b->dev, "root bus resource %pR\n", res);
>> +       /* Add initial resources to the bus */
>> +       list_for_each_entry_safe(window, n, resources, list) {
>> +               list_move_tail(&window->list, &bridge->windows);
>> +               res = window->res;
>> +               offset = window->offset;
>> +               pci_bus_add_resource(b, res, 0);
>
> you put two copies of root resource list ?

The root bus has a list of resources, as it always has.

The host bridge also has a list that contains the same resources.  In
addition, this list contains the offset the host bridge applies to
each aperture.

So yes, there are two lists, but they are not the same.  I don't think
it makes sense to add the offset information to the resource list of
every bus, because the offset is always zero for P2P bridges.

Bjorn

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2 00/18] add PCI bus-to-resource offset support in core
  2012-02-10  4:34   ` Bjorn Helgaas
@ 2012-02-10  4:50     ` Yinghai Lu
  2012-02-10 16:55       ` Bjorn Helgaas
  0 siblings, 1 reply; 34+ messages in thread
From: Yinghai Lu @ 2012-02-10  4:50 UTC (permalink / raw)
  To: Bjorn Helgaas; +Cc: linux-pci, linux-arch

On Thu, Feb 9, 2012 at 8:34 PM, Bjorn Helgaas <bhelgaas@google.com> wrote:
> On Thu, Feb 9, 2012 at 8:03 PM, Yinghai Lu <yinghai@kernel.org> wrote:
>> On Thu, Feb 9, 2012 at 6:36 PM, Bjorn Helgaas <bhelgaas@google.com> wrote:
>>> There's a lot of PCI-related code under arch/, but much of it is not actually
>>> architecture-specific.  This series removes some of that code by moving most
>>> of the bus-to-resource conversions into the core.
>>>
>>> We currently read PCI bus addresses from BARs in the core (pci_setup_device()).
>>> Then every arch is responsible for converting those bus addresses to CPU
>>> resources, usually in pcibios_fixup_bus().
>>>
>>> We already have a way for architectures to tell the core what the windows
>>> through a host bridge are:
>>>
>>>    LIST_HEAD(resources);
>>>    pci_add_resource(&resources, io_space);
>>>    pci_add_resource(&resources, mem_space);
>>>    pci_scan_root_bus(parent, bus, ops, sysdata, &resources);
>>>
>>> This series extends that so the arch can also tell the core about address
>>> translation performed by the host bridge:
>>>
>>>    LIST_HEAD(resources);
>>>    pci_add_resource_offset(&resources, io_space, io_offset);
>>>    pci_add_resource_offset(&resources, mem_space, mem_offset);
>>>    pci_scan_root_bus(parent, bus, ops, sysdata, &resources);
>>>
>>> Given that offset (the difference between bus address and CPU address for
>>> each aperture), the core can do the bus-to-resource conversion immediately
>>> when it reads the BARs.
>>>
>>> This removes an opportunity for bugs (some PCI fixups currently see bus
>>> addresses in struct pci_dev resources when they're expecting CPU addresses),
>>> but the main reason to do this is to make our PCI resource handling simpler
>>> and more uniform.
>>>
>>> These patches are also available in this git repo:
>>>    git://github.com/bjorn-helgaas/linux.git pci-offset-v2-d15af52258dd
>>>
>>> Or you can browse them here:
>>>    https://github.com/bjorn-helgaas/linux/compare/master...pci-offset-v2-d15af52258dd
>>>
>>> I'd like to get these into linux-next soon to be ready for the 3.4 merge
>>> window, so please let me know if you see any issues.
>>>
>>> Changes since v1:
>>>  - mips: remove Cobalt legacy IDE fixup
>>>  - show bus address range, not offset, e.g., this:
>>>        pci_bus 0000:00: root bus resource [mem 0xf0000000000-0xf007edfffff] (bus address [0x80000000-0xfedfffff])
>>>    instead of this:
>>>        pci_bus 0000:00: root bus resource [mem 0xf0000000000-0xf007edfffff] (bus offset 0xeff80000000)
>>>
>>
>> still think make pci_sysdata to generic and add one offset field to
>> that would be more simple.
>
> Maybe I'm misunderstanding you, because this doesn't make sense to me at all.
>
> *One* offset field is insufficient.  A host bridge can have an
> arbitrary number of apertures, and each aperture can have a different
> offset.  So we must have a list or other variable-size structure.
>
> pci_scan_bus() takes a "void *sysdata".  Every arch defines its own
> structure (struct pci_sysdata for x86, struct pci_controller for most
> others) to supply here.  Are you suggesting that we make a common
> structure like this:
>
>    struct pci_sysdata {
>        struct list_head windows;
>        void *sysdata;  /* arch-specific stuff */
>    };
>
> That's possible, but I don't see the advantage over what I've done.
> It doesn't seem simpler, because all the arch code that looks at
> bus->sysdata would have to change to use
> bus->generic_sysdata->sysdata.

I mean, we can unify sysdata usuage, make them all most the same.

and for some sysdata, already acting like host_bridge struct with
domain, numa_node, and resources.

>
> If you can show an example of what you mean, maybe it will help me understand.

just looked the sys_data of different arch,

looks like pci_sys_data for arm already include the io offset

arch/arm/include/asm/mach/pci.h::

struct pci_sys_data {
#ifdef CONFIG_PCI_DOMAINS
        int             domain;
#endif
        struct list_head node;
        int             busnr;          /* primary bus number
         */
        u64             mem_offset;     /* bus->cpu memory mapping
offset       */
        unsigned long   io_offset;      /* bus->cpu IO mapping offset
         */
        struct pci_bus  *bus;           /* PCI bus
         */
        struct list_head resources;     /* root bus resources (apertures)

Thanks

Yinghai

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2 00/18] add PCI bus-to-resource offset support in core
  2012-02-10  4:50     ` Yinghai Lu
@ 2012-02-10 16:55       ` Bjorn Helgaas
  2012-02-10 17:20         ` Yinghai Lu
  0 siblings, 1 reply; 34+ messages in thread
From: Bjorn Helgaas @ 2012-02-10 16:55 UTC (permalink / raw)
  To: Yinghai Lu; +Cc: linux-pci, linux-arch

On Thu, Feb 9, 2012 at 8:50 PM, Yinghai Lu <yinghai@kernel.org> wrote:
> On Thu, Feb 9, 2012 at 8:34 PM, Bjorn Helgaas <bhelgaas@google.com> wrote:
>> On Thu, Feb 9, 2012 at 8:03 PM, Yinghai Lu <yinghai@kernel.org> wrote:
>>> On Thu, Feb 9, 2012 at 6:36 PM, Bjorn Helgaas <bhelgaas@google.com> wrote:
>>>> There's a lot of PCI-related code under arch/, but much of it is not actually
>>>> architecture-specific.  This series removes some of that code by moving most
>>>> of the bus-to-resource conversions into the core.
>>>>
>>>> We currently read PCI bus addresses from BARs in the core (pci_setup_device()).
>>>> Then every arch is responsible for converting those bus addresses to CPU
>>>> resources, usually in pcibios_fixup_bus().
>>>>
>>>> We already have a way for architectures to tell the core what the windows
>>>> through a host bridge are:
>>>>
>>>>    LIST_HEAD(resources);
>>>>    pci_add_resource(&resources, io_space);
>>>>    pci_add_resource(&resources, mem_space);
>>>>    pci_scan_root_bus(parent, bus, ops, sysdata, &resources);
>>>>
>>>> This series extends that so the arch can also tell the core about address
>>>> translation performed by the host bridge:
>>>>
>>>>    LIST_HEAD(resources);
>>>>    pci_add_resource_offset(&resources, io_space, io_offset);
>>>>    pci_add_resource_offset(&resources, mem_space, mem_offset);
>>>>    pci_scan_root_bus(parent, bus, ops, sysdata, &resources);
>>>>
>>>> Given that offset (the difference between bus address and CPU address for
>>>> each aperture), the core can do the bus-to-resource conversion immediately
>>>> when it reads the BARs.
>>>>
>>>> This removes an opportunity for bugs (some PCI fixups currently see bus
>>>> addresses in struct pci_dev resources when they're expecting CPU addresses),
>>>> but the main reason to do this is to make our PCI resource handling simpler
>>>> and more uniform.
>>>>
>>>> These patches are also available in this git repo:
>>>>    git://github.com/bjorn-helgaas/linux.git pci-offset-v2-d15af52258dd
>>>>
>>>> Or you can browse them here:
>>>>    https://github.com/bjorn-helgaas/linux/compare/master...pci-offset-v2-d15af52258dd
>>>>
>>>> I'd like to get these into linux-next soon to be ready for the 3.4 merge
>>>> window, so please let me know if you see any issues.
>>>>
>>>> Changes since v1:
>>>>  - mips: remove Cobalt legacy IDE fixup
>>>>  - show bus address range, not offset, e.g., this:
>>>>        pci_bus 0000:00: root bus resource [mem 0xf0000000000-0xf007edfffff] (bus address [0x80000000-0xfedfffff])
>>>>    instead of this:
>>>>        pci_bus 0000:00: root bus resource [mem 0xf0000000000-0xf007edfffff] (bus offset 0xeff80000000)
>>>>
>>>
>>> still think make pci_sysdata to generic and add one offset field to
>>> that would be more simple.
>>
>> Maybe I'm misunderstanding you, because this doesn't make sense to me at all.
>>
>> *One* offset field is insufficient.  A host bridge can have an
>> arbitrary number of apertures, and each aperture can have a different
>> offset.  So we must have a list or other variable-size structure.
>>
>> pci_scan_bus() takes a "void *sysdata".  Every arch defines its own
>> structure (struct pci_sysdata for x86, struct pci_controller for most
>> others) to supply here.  Are you suggesting that we make a common
>> structure like this:
>>
>>    struct pci_sysdata {
>>        struct list_head windows;
>>        void *sysdata;  /* arch-specific stuff */
>>    };
>>
>> That's possible, but I don't see the advantage over what I've done.
>> It doesn't seem simpler, because all the arch code that looks at
>> bus->sysdata would have to change to use
>> bus->generic_sysdata->sysdata.
>
> I mean, we can unify sysdata usuage, make them all most the same.
>
> and for some sysdata, already acting like host_bridge struct with
> domain, numa_node, and resources.
>
>> If you can show an example of what you mean, maybe it will help me understand.
>
> just looked the sys_data of different arch,
>
> looks like pci_sys_data for arm already include the io offset
>
> arch/arm/include/asm/mach/pci.h::
>
> struct pci_sys_data {
> #ifdef CONFIG_PCI_DOMAINS
>        int             domain;
> #endif
>        struct list_head node;
>        int             busnr;          /* primary bus number
>         */
>        u64             mem_offset;     /* bus->cpu memory mapping
> offset       */
>        unsigned long   io_offset;      /* bus->cpu IO mapping offset
>         */
>        struct pci_bus  *bus;           /* PCI bus
>         */
>        struct list_head resources;     /* root bus resources (apertures)

Let me try again.  Maybe your idea is that we should create something
like "struct pcibios_sysdata" and require every arch to define a
struct with that name.  Every arch's struct would contain some members
such as "domain," "mem_offset," "io_offset," and "resources."  These
would have standard names & types across all arches and would be
referenced by the PCI core.  In addition, the struct could include
arch-specific data such as "acpi_handle," "iommu," etc.

That way, the core could implement things like pci_domain_nr() and
pci_bus_to_resource() by using the data in struct pcibios_sysdata.
The current "void *sysdata" parameters to pci_scan_bus() and friends
would become "struct pcibios_sysdata *sysdata".

I like the idea of unifying the sysdata struct name and changing from
a "void *" to something like "struct pcibios_sysdata *".  That might
be worth doing.

But the whole point of this patch series is to move things that are
not architecture-specific out of the arch code.  I don't want to end
up with a dozen pcibios_sysdata structs that all contain exactly the
same generic members plus a few arch-specific ones.  That would mean
trying to keep those dozen places consistent all the time, which is a
maintenance hassle.

This series does cause some duplication, e.g., struct pci_host_bridge
will contain a "struct pci_bus *" and some resource information that's
also in the arch-specific struct pci_controller.  That information is
not actually arch-specific at all, so I think it's a good thing if we
gradually remove it from the arch-specific sysdata structs.  In many
cases, that will also remove current arch restrictions such as "all
memory apertures must have the same CPU/bus address offset," and "at
most one I/O aperture and three memory apertures are supported."

Bjorn

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2 00/18] add PCI bus-to-resource offset support in core
  2012-02-10 16:55       ` Bjorn Helgaas
@ 2012-02-10 17:20         ` Yinghai Lu
  2012-02-10 17:24           ` Bjorn Helgaas
  0 siblings, 1 reply; 34+ messages in thread
From: Yinghai Lu @ 2012-02-10 17:20 UTC (permalink / raw)
  To: Bjorn Helgaas; +Cc: linux-pci, linux-arch

On Fri, Feb 10, 2012 at 8:55 AM, Bjorn Helgaas <bhelgaas@google.com> wrote:
...
>>
>> I mean, we can unify sysdata usuage, make them all most the same.
>>
>> and for some sysdata, already acting like host_bridge struct with
>> domain, numa_node, and resources.
>>
>>> If you can show an example of what you mean, maybe it will help me understand.
>>
>> just looked the sys_data of different arch,
>>
>> looks like pci_sys_data for arm already include the io offset
>>
>> arch/arm/include/asm/mach/pci.h::
>>
>> struct pci_sys_data {
>> #ifdef CONFIG_PCI_DOMAINS
>>        int             domain;
>> #endif
>>        struct list_head node;
>>        int             busnr;          /* primary bus number
>>         */
>>        u64             mem_offset;     /* bus->cpu memory mapping
>> offset       */
>>        unsigned long   io_offset;      /* bus->cpu IO mapping offset
>>         */
>>        struct pci_bus  *bus;           /* PCI bus
>>         */
>>        struct list_head resources;     /* root bus resources (apertures)
>
> Let me try again.  Maybe your idea is that we should create something
> like "struct pcibios_sysdata" and require every arch to define a
> struct with that name.  Every arch's struct would contain some members
> such as "domain," "mem_offset," "io_offset," and "resources."  These
> would have standard names & types across all arches and would be
> referenced by the PCI core.  In addition, the struct could include
> arch-specific data such as "acpi_handle," "iommu," etc.
>
> That way, the core could implement things like pci_domain_nr() and
> pci_bus_to_resource() by using the data in struct pcibios_sysdata.
> The current "void *sysdata" parameters to pci_scan_bus() and friends
> would become "struct pcibios_sysdata *sysdata".
>
> I like the idea of unifying the sysdata struct name and changing from
> a "void *" to something like "struct pcibios_sysdata *".  That might
> be worth doing.

what i am mean:
1. make every arch to use same name for the struct, but could have
different contents.
   struct pci_sys_data.
2. unify member field name, by changing name
    pci_first_busno ==> first_busno
    pci_last_busno ==> last_busno
    or adding
    first_busno
    last_busno
3. changing more filed like domain, node
    and io_offset, mem_offset
...

Yinghai

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2 00/18] add PCI bus-to-resource offset support in core
  2012-02-10 17:20         ` Yinghai Lu
@ 2012-02-10 17:24           ` Bjorn Helgaas
  2012-02-10 20:25             ` Yinghai Lu
  0 siblings, 1 reply; 34+ messages in thread
From: Bjorn Helgaas @ 2012-02-10 17:24 UTC (permalink / raw)
  To: Yinghai Lu; +Cc: linux-pci, linux-arch

On Fri, Feb 10, 2012 at 9:20 AM, Yinghai Lu <yinghai@kernel.org> wrote:
> On Fri, Feb 10, 2012 at 8:55 AM, Bjorn Helgaas <bhelgaas@google.com> wrote:
> ...
>>>
>>> I mean, we can unify sysdata usuage, make them all most the same.
>>>
>>> and for some sysdata, already acting like host_bridge struct with
>>> domain, numa_node, and resources.
>>>
>>>> If you can show an example of what you mean, maybe it will help me understand.
>>>
>>> just looked the sys_data of different arch,
>>>
>>> looks like pci_sys_data for arm already include the io offset
>>>
>>> arch/arm/include/asm/mach/pci.h::
>>>
>>> struct pci_sys_data {
>>> #ifdef CONFIG_PCI_DOMAINS
>>>        int             domain;
>>> #endif
>>>        struct list_head node;
>>>        int             busnr;          /* primary bus number
>>>         */
>>>        u64             mem_offset;     /* bus->cpu memory mapping
>>> offset       */
>>>        unsigned long   io_offset;      /* bus->cpu IO mapping offset
>>>         */
>>>        struct pci_bus  *bus;           /* PCI bus
>>>         */
>>>        struct list_head resources;     /* root bus resources (apertures)
>>
>> Let me try again.  Maybe your idea is that we should create something
>> like "struct pcibios_sysdata" and require every arch to define a
>> struct with that name.  Every arch's struct would contain some members
>> such as "domain," "mem_offset," "io_offset," and "resources."  These
>> would have standard names & types across all arches and would be
>> referenced by the PCI core.  In addition, the struct could include
>> arch-specific data such as "acpi_handle," "iommu," etc.
>>
>> That way, the core could implement things like pci_domain_nr() and
>> pci_bus_to_resource() by using the data in struct pcibios_sysdata.
>> The current "void *sysdata" parameters to pci_scan_bus() and friends
>> would become "struct pcibios_sysdata *sysdata".
>>
>> I like the idea of unifying the sysdata struct name and changing from
>> a "void *" to something like "struct pcibios_sysdata *".  That might
>> be worth doing.
>
> what i am mean:
> 1. make every arch to use same name for the struct, but could have
> different contents.
>   struct pci_sys_data.
> 2. unify member field name, by changing name
>    pci_first_busno ==> first_busno
>    pci_last_busno ==> last_busno
>    or adding
>    first_busno
>    last_busno
> 3. changing more filed like domain, node
>    and io_offset, mem_offset
> ...

That's exactly what I said above, isn't it?  (In the paragraph
starting "Let me try again.")

As I said, the reason I don't like that approach is that I don't want
a dozen copies of first_busno, last_busno, domain, node, io_offset,
mem_offset, etc.  That information is not architecture-specific, so we
shouldn't keep it in an architecture-specific struct.

Bjorn

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v2 00/18] add PCI bus-to-resource offset support in core
  2012-02-10 17:24           ` Bjorn Helgaas
@ 2012-02-10 20:25             ` Yinghai Lu
  2012-02-10 22:37               ` Bjorn Helgaas
  0 siblings, 1 reply; 34+ messages in thread
From: Yinghai Lu @ 2012-02-10 20:25 UTC (permalink / raw)
  To: Bjorn Helgaas, jbarnes, Tony Luck, Benjamin Herrenschmidt,
	Linus Torvalds, Andrew Morton
  Cc: linux-pci, linux-arch

[-- Attachment #1: Type: text/plain, Size: 1037 bytes --]

On Fri, Feb 10, 2012 at 9:24 AM, Bjorn Helgaas <bhelgaas@google.com> wrote:
> On Fri, Feb 10, 2012 at 9:20 AM, Yinghai Lu <yinghai@kernel.org> wrote:
>
> That's exactly what I said above, isn't it?  (In the paragraph
> starting "Let me try again.")

no, not create one. make them looks like one struct with some common fields.

>
> As I said, the reason I don't like that approach is that I don't want
> a dozen copies of first_busno, last_busno, domain, node, io_offset,
> mem_offset, etc.  That information is not architecture-specific, so we
> shouldn't keep it in an architecture-specific struct.

but you want to add hostbridge struct list and that just produce
duplicated info.
and search hostbridge for dev looks not good.
Now you try to: for every device or resource find root bus and then
check hostbridge list to get hostbridge and get offset.

use sysdata pointer to get sys data like hostbridge info quickly

i drafted one patch, and it seems not ugly with macro. please check it.

Thanks

Yinghai

[-- Attachment #2: pci_sys_data.patch --]
[-- Type: text/x-patch, Size: 12369 bytes --]

[RFC PATCH] PCI: unify sysdata to pci_sys_data

use macro, so core code could access common member in sysdata

As example, plut first_busno/end_busno there.
for sparc, need to change pci_first_busno to first_busno...
arm already has that.
x86 need to add them.
...

Signed-off-by: Yinghai Lu <yinghai@kernel.org>

diff --git a/arch/alpha/include/asm/pci.h b/arch/alpha/include/asm/pci.h
index 28d0497..f6f8cc6 100644
--- a/arch/alpha/include/asm/pci.h
+++ b/arch/alpha/include/asm/pci.h
@@ -18,6 +18,8 @@ struct resource;
 struct pci_iommu_arena;
 struct page;
 
+#define pci_sys_data pci_controller
+
 /* A controller.  Used to manage multiple PCI busses.  */
 
 struct pci_controller {
@@ -26,6 +28,9 @@ struct pci_controller {
 	struct resource *io_space;
 	struct resource *mem_space;
 
+	unsigned int first_busno;
+	unsigned int last_busno;
+
 	/* The following are for reporting to userland.  The invariant is
 	   that if we report a BWX-capable dense memory, we do not report
 	   a sparse memory at all, even if it exists.  */
diff --git a/arch/arm/include/asm/mach/pci.h b/arch/arm/include/asm/mach/pci.h
index d943b7d..f49a853 100644
--- a/arch/arm/include/asm/mach/pci.h
+++ b/arch/arm/include/asm/mach/pci.h
@@ -28,6 +28,8 @@ struct hw_pci {
 	int		(*map_irq)(const struct pci_dev *dev, u8 slot, u8 pin);
 };
 
+#define pci_sys_data pci_sys_data
+
 /*
  * Per-controller structure
  */
@@ -37,6 +39,8 @@ struct pci_sys_data {
 #endif
 	struct list_head node;
 	int		busnr;		/* primary bus number			*/
+	unsigned int	first_busno;	/* bus number start */
+	unsigned int	last_busno;	/* bus number end */
 	u64		mem_offset;	/* bus->cpu memory mapping offset	*/
 	unsigned long	io_offset;	/* bus->cpu IO mapping offset		*/
 	struct pci_bus	*bus;		/* PCI bus				*/
diff --git a/arch/ia64/include/asm/pci.h b/arch/ia64/include/asm/pci.h
index 279b38a..336fd9f 100644
--- a/arch/ia64/include/asm/pci.h
+++ b/arch/ia64/include/asm/pci.h
@@ -86,12 +86,17 @@ struct pci_window {
 	u64 offset;
 };
 
+#define pci_sys_data pci_controller
+
 struct pci_controller {
 	void *acpi_handle;
 	void *iommu;
 	int segment;
 	int node;		/* nearest node with memory or -1 for global allocation */
 
+	unsigned int first_busno;
+	unsigned int last_busno;
+
 	unsigned int windows;
 	struct pci_window *window;
 
diff --git a/arch/microblaze/include/asm/pci-bridge.h b/arch/microblaze/include/asm/pci-bridge.h
index e9834b2..23fe4a4 100644
--- a/arch/microblaze/include/asm/pci-bridge.h
+++ b/arch/microblaze/include/asm/pci-bridge.h
@@ -24,6 +24,7 @@ static inline int pcibios_vaddr_is_ioport(void __iomem *address)
 }
 #endif
 
+#define pci_sys_data pci_controller
 /*
  * Structure of a PCI controller (host bridge)
  */
@@ -34,8 +35,8 @@ struct pci_controller {
 	struct list_head list_node;
 	struct device *parent;
 
-	int first_busno;
-	int last_busno;
+	unsigned int first_busno;
+	unsigned int last_busno;
 
 	int self_busno;
 
diff --git a/arch/parisc/include/asm/pci.h b/arch/parisc/include/asm/pci.h
index 2242a5c..9a1c241 100644
--- a/arch/parisc/include/asm/pci.h
+++ b/arch/parisc/include/asm/pci.h
@@ -28,6 +28,7 @@
  */
 #define pci_post_reset_delay 50
 
+#define pci_sys_data pci_hba_data
 
 /*
 ** pci_hba_data (aka H2P_OBJECT in HP/UX)
@@ -48,6 +49,8 @@ struct pci_hba_data {
 	struct resource lmmio_space;	/* bus addresses < 4Gb */
 	struct resource elmmio_space;	/* additional bus addresses < 4Gb */
 	struct resource gmmio_space;	/* bus addresses > 4Gb */
+	unsigned int first_busno;
+	unsigned int last_busno;
 
 	/* NOTE: Dino code assumes it can use *all* of the lmmio_space,
 	 * elmmio_space and gmmio_space as a contiguous array of
diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h
index cb21e23..e99d56e 100644
--- a/arch/sh/include/asm/pci.h
+++ b/arch/sh/include/asm/pci.h
@@ -9,6 +9,8 @@
 
 #define pcibios_assign_all_busses()	1
 
+#define pci_sys_data pci_channel
+
 /*
  * A board can define one or more PCI channels that represent built-in (or
  * external) PCI controllers.
@@ -25,6 +27,9 @@ struct pci_channel {
 	unsigned long		io_offset;
 	unsigned long		mem_offset;
 
+	unsigned int		first_busno;
+	unsigned int		last_busno;
+
 	unsigned long		reg_base;
 	unsigned long		io_map_base;
 
diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c
index bb8bc2e..d9667f5 100644
--- a/arch/sparc/kernel/pci.c
+++ b/arch/sparc/kernel/pci.c
@@ -693,7 +693,7 @@ struct pci_bus * __devinit pci_scan_one_pbm(struct pci_pbm_info *pbm,
 
 	pci_add_resource(&resources, &pbm->io_space);
 	pci_add_resource(&resources, &pbm->mem_space);
-	bus = pci_create_root_bus(parent, pbm->pci_first_busno, pbm->pci_ops,
+	bus = pci_create_root_bus(parent, pbm->first_busno, pbm->pci_ops,
 				  pbm, &resources);
 	if (!bus) {
 		printk(KERN_ERR "Failed to create bus for %s\n",
@@ -701,8 +701,8 @@ struct pci_bus * __devinit pci_scan_one_pbm(struct pci_pbm_info *pbm,
 		pci_free_resource_list(&resources);
 		return NULL;
 	}
-	bus->secondary = pbm->pci_first_busno;
-	bus->subordinate = pbm->pci_last_busno;
+	bus->secondary = pbm->first_busno;
+	bus->subordinate = pbm->last_busno;
 
 	pci_of_scan_bus(pbm, node, bus);
 	pci_bus_add_devices(bus);
diff --git a/arch/sparc/kernel/pci_common.c b/arch/sparc/kernel/pci_common.c
index a689598..5d0a2e6 100644
--- a/arch/sparc/kernel/pci_common.c
+++ b/arch/sparc/kernel/pci_common.c
@@ -21,8 +21,8 @@ static int config_out_of_range(struct pci_pbm_info *pbm,
 			       unsigned long devfn,
 			       unsigned long reg)
 {
-	if (bus < pbm->pci_first_busno ||
-	    bus > pbm->pci_last_busno)
+	if (bus < pbm->first_busno ||
+	    bus > pbm->last_busno)
 		return 1;
 	return 0;
 }
@@ -319,8 +319,8 @@ void pci_get_pbm_props(struct pci_pbm_info *pbm)
 {
 	const u32 *val = of_get_property(pbm->op->dev.of_node, "bus-range", NULL);
 
-	pbm->pci_first_busno = val[0];
-	pbm->pci_last_busno = val[1];
+	pbm->first_busno = val[0];
+	pbm->last_busno = val[1];
 
 	val = of_get_property(pbm->op->dev.of_node, "ino-bitmap", NULL);
 	if (val) {
diff --git a/arch/sparc/kernel/pci_impl.h b/arch/sparc/kernel/pci_impl.h
index 6beb60d..664f548 100644
--- a/arch/sparc/kernel/pci_impl.h
+++ b/arch/sparc/kernel/pci_impl.h
@@ -57,6 +57,8 @@ struct sparc64_msiq_cookie {
 };
 #endif
 
+#define pci_sys_data pci_pbm_info
+
 struct pci_pbm_info {
 	struct pci_pbm_info		*next;
 	struct pci_pbm_info		*sibling;
@@ -144,8 +146,8 @@ struct pci_pbm_info {
 	struct iommu			*iommu;
 
 	/* Now things for the actual PCI bus probes. */
-	unsigned int			pci_first_busno;
-	unsigned int			pci_last_busno;
+	unsigned int			first_busno;
+	unsigned int			last_busno;
 	struct pci_bus			*pci_bus;
 	struct pci_ops			*pci_ops;
 
diff --git a/arch/sparc/kernel/pci_psycho.c b/arch/sparc/kernel/pci_psycho.c
index f4d29e1..764efbe 100644
--- a/arch/sparc/kernel/pci_psycho.c
+++ b/arch/sparc/kernel/pci_psycho.c
@@ -356,12 +356,12 @@ static void pbm_config_busmastering(struct pci_pbm_info *pbm)
 	/* Set cache-line size to 64 bytes, this is actually
 	 * a nop but I do it for completeness.
 	 */
-	addr = psycho_pci_config_mkaddr(pbm, pbm->pci_first_busno,
+	addr = psycho_pci_config_mkaddr(pbm, pbm->first_busno,
 					0, PCI_CACHE_LINE_SIZE);
 	pci_config_write8(addr, 64 / sizeof(u32));
 
 	/* Set PBM latency timer to 64 PCI clocks. */
-	addr = psycho_pci_config_mkaddr(pbm, pbm->pci_first_busno,
+	addr = psycho_pci_config_mkaddr(pbm, pbm->first_busno,
 					0, PCI_LATENCY_TIMER);
 	pci_config_write8(addr, 64);
 }
diff --git a/arch/sparc/kernel/pci_schizo.c b/arch/sparc/kernel/pci_schizo.c
index 13d4aa2..898308d 100644
--- a/arch/sparc/kernel/pci_schizo.c
+++ b/arch/sparc/kernel/pci_schizo.c
@@ -82,7 +82,7 @@ static void *schizo_pci_config_mkaddr(struct pci_pbm_info *pbm,
 {
 	if (!pbm)
 		return NULL;
-	bus -= pbm->pci_first_busno;
+	bus -= pbm->first_busno;
 	return (void *)
 		(SCHIZO_CONFIG_BASE(pbm) |
 		 SCHIZO_CONFIG_ENCODE(bus, devfn, where));
@@ -1054,12 +1054,12 @@ static void pbm_config_busmastering(struct pci_pbm_info *pbm)
 	/* Set cache-line size to 64 bytes, this is actually
 	 * a nop but I do it for completeness.
 	 */
-	addr = schizo_pci_config_mkaddr(pbm, pbm->pci_first_busno,
+	addr = schizo_pci_config_mkaddr(pbm, pbm->first_busno,
 					0, PCI_CACHE_LINE_SIZE);
 	pci_config_write8(addr, 64 / sizeof(u32));
 
 	/* Set PBM latency timer to 64 PCI clocks. */
-	addr = schizo_pci_config_mkaddr(pbm, pbm->pci_first_busno,
+	addr = schizo_pci_config_mkaddr(pbm, pbm->first_busno,
 					0, PCI_LATENCY_TIMER);
 	pci_config_write8(addr, 64);
 }
diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
index df75d07..c6bc4f3 100644
--- a/arch/x86/include/asm/pci.h
+++ b/arch/x86/include/asm/pci.h
@@ -11,12 +11,16 @@
 
 #ifdef __KERNEL__
 
+#define pci_sys_data pci_sysdata
+
 struct pci_sysdata {
 	int		domain;		/* PCI domain */
 	int		node;		/* NUMA node */
 #ifdef CONFIG_X86_64
 	void		*iommu;		/* IOMMU private data */
 #endif
+	unsigned int	first_busno;
+	unsigned int	last_busno;
 };
 
 extern int pci_routeirq;
diff --git a/arch/xtensa/include/asm/pci-bridge.h b/arch/xtensa/include/asm/pci-bridge.h
index 00fcbd7..edc021b 100644
--- a/arch/xtensa/include/asm/pci-bridge.h
+++ b/arch/xtensa/include/asm/pci-bridge.h
@@ -28,6 +28,8 @@ struct pci_space {
 	unsigned long base;
 };
 
+#define pci_sys_data pci_controller
+
 /*
  * Structure of a PCI controller (host bridge)
  */
@@ -38,8 +40,8 @@ struct pci_controller {
         struct pci_bus *bus;
 	void *arch_data;
 
-	int first_busno;
-	int last_busno;
+	unsigned int first_busno;
+	unsigned int last_busno;
 
 	struct pci_ops *ops;
 	volatile unsigned int *cfg_addr;
diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c
index 7ff10c1..cdb527c 100644
--- a/drivers/parisc/dino.c
+++ b/drivers/parisc/dino.c
@@ -1004,7 +1004,7 @@ static int __init dino_probe(struct parisc_device *dev)
 	** with configuration accessor functions.
 	*/
 	dino_dev->hba.hba_bus = bus = pci_create_root_bus(&dev->dev,
-			 dino_current_bus, &dino_cfg_ops, NULL, &resources);
+			 dino_current_bus, &dino_cfg_ops, &dino_dev->hba, &resources);
 	if (!bus) {
 		printk(KERN_ERR "ERROR: failed to scan PCI bus on %s (duplicate bus number %d?)\n",
 		       dev_name(&dev->dev), dino_current_bus);
diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c
index d5f3d75..fd62f79 100644
--- a/drivers/parisc/lba_pci.c
+++ b/drivers/parisc/lba_pci.c
@@ -1525,7 +1525,7 @@ lba_driver_probe(struct parisc_device *dev)
 	dev->dev.platform_data = lba_dev;
 	lba_bus = lba_dev->hba.hba_bus =
 		pci_create_root_bus(&dev->dev, lba_dev->hba.bus_num.start,
-				    cfg_ops, NULL, &resources);
+				    cfg_ops, &lba_dev->hba, &resources);
 	if (!lba_bus) {
 		pci_free_resource_list(&resources);
 		return 0;
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index a114173..bcb387d 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1608,6 +1608,14 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
 			dev_info(&b->dev, "root bus resource %pR\n", res);
 	}
 
+	if (sysdata) {
+		struct pci_sys_data *data = sysdata;
+
+		dev_printk(KERN_DEBUG, &b->dev, "bus range: %02x-%02x\n", data->first_busno, data->last_busno);
+	} else {
+		dev_printk(KERN_DEBUG, &b->dev, "bus range: %02x-%02x\n", 0, 0xff);
+	}
+
 	return b;
 
 class_dev_reg_err:
diff --git a/drivers/pci/xen-pcifront.c b/drivers/pci/xen-pcifront.c
index 98387ca..d60fc5b 100644
--- a/drivers/pci/xen-pcifront.c
+++ b/drivers/pci/xen-pcifront.c
@@ -50,7 +50,15 @@ struct pcifront_device {
 };
 
 struct pcifront_sd {
+/* begin same as pci_sysdata for arch/x86/include/asm/pci.h */
 	int domain;
+	int             node;           /* NUMA node */
+#ifdef CONFIG_X86_64
+	void            *iommu;         /* IOMMU private data */
+#endif
+	unsigned int first_busno;
+	unsigned int last_busno;
+/* end */
 	struct pcifront_device *pdev;
 };
 
diff --git a/include/asm-generic/pci.h b/include/asm-generic/pci.h
index 26373cf..1506b06 100644
--- a/include/asm-generic/pci.h
+++ b/include/asm-generic/pci.h
@@ -6,6 +6,15 @@
 #ifndef _ASM_GENERIC_PCI_H
 #define _ASM_GENERIC_PCI_H
 
+#ifndef pci_sys_data
+#define pci_sys_data pci_sys_data
+
+struct pci_sys_data {
+	unsigned int first busno;
+	unsigned int last_busno;
+};
+#endif
+
 /**
  * pcibios_resource_to_bus - convert resource to PCI bus address
  * @dev: device which owns this resource

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* Re: [PATCH v2 00/18] add PCI bus-to-resource offset support in core
  2012-02-10 20:25             ` Yinghai Lu
@ 2012-02-10 22:37               ` Bjorn Helgaas
  0 siblings, 0 replies; 34+ messages in thread
From: Bjorn Helgaas @ 2012-02-10 22:37 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: jbarnes, Tony Luck, Benjamin Herrenschmidt, Linus Torvalds,
	Andrew Morton, linux-pci, linux-arch

On Fri, Feb 10, 2012 at 12:25 PM, Yinghai Lu <yinghai@kernel.org> wrote:
> On Fri, Feb 10, 2012 at 9:24 AM, Bjorn Helgaas <bhelgaas@google.com> wrote:
>> On Fri, Feb 10, 2012 at 9:20 AM, Yinghai Lu <yinghai@kernel.org> wrote:
>>
>> That's exactly what I said above, isn't it?  (In the paragraph
>> starting "Let me try again.")
>
> no, not create one. make them looks like one struct with some common fields.

The difference I see is that you kept the ugliness (enforcing
cut-and-paste of generic members across all architectures) and threw
out the possible goodness (replacing a "void *" with a "struct
pci_sysdata *").

>> As I said, the reason I don't like that approach is that I don't want
>> a dozen copies of first_busno, last_busno, domain, node, io_offset,
>> mem_offset, etc.  That information is not architecture-specific, so we
>> shouldn't keep it in an architecture-specific struct.
>
> but you want to add hostbridge struct list and that just produce
> duplicated info.

You can think of it as merely being duplicated uselessly.  I think of
it as "putting it in the logical place and enabling its removal from
the wrong places."

> and search hostbridge for dev looks not good.
> Now you try to: for every device or resource find root bus and then
> check hostbridge list to get hostbridge and get offset.
>
> use sysdata pointer to get sys data like hostbridge info quickly
>
> i drafted one patch, and it seems not ugly with macro. please check it.

I hate to say it, but I think it's ugly.  It looks like a hack bolted
on at the end because we were too lazy to do a nice design up front.
It might be the fewest lines of code change, but I think it's much
harder to read.  It's much more important that code be easier to read
and understand than it is to minimize code change.

Bjorn

^ permalink raw reply	[flat|nested] 34+ messages in thread

end of thread, other threads:[~2012-02-10 22:37 UTC | newest]

Thread overview: 34+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-02-10  2:36 [PATCH v2 00/18] add PCI bus-to-resource offset support in core Bjorn Helgaas
2012-02-10  2:36 ` [PATCH v2 01/18] PCI: don't publish new root bus until it's fully initialized Bjorn Helgaas
2012-02-10  2:36 ` [PATCH v2 02/18] PCI: add struct pci_host_bridge and a list of all bridges found Bjorn Helgaas
2012-02-10  3:47   ` Yinghai Lu
2012-02-10  4:16     ` Bjorn Helgaas
2012-02-10  2:36 ` [PATCH v2 03/18] PCI: add struct pci_host_bridge_window with CPU/bus address offset Bjorn Helgaas
2012-02-10  3:49   ` Yinghai Lu
2012-02-10  4:37     ` Bjorn Helgaas
2012-02-10  2:36 ` [PATCH v2 04/18] PCI: convert bus addresses to resource when reading BARs Bjorn Helgaas
2012-02-10  2:36 ` [PATCH v2 05/18] PCI: add generic pcibios_resource_to_bus() Bjorn Helgaas
2012-02-10  2:36 ` [PATCH v2 06/18] alpha/PCI: get rid of device resource fixups Bjorn Helgaas
2012-02-10  2:36 ` [PATCH v2 07/18] arm/PCI: " Bjorn Helgaas
2012-02-10  2:37 ` [PATCH v2 08/18] ia64/PCI: SN: convert to pci_scan_root_bus() for correct root bus resources Bjorn Helgaas
2012-02-10  2:46   ` Bjorn Helgaas
2012-02-10  2:37 ` [PATCH v2 09/18] ia64/PCI: get rid of device resource fixups Bjorn Helgaas
2012-02-10  2:37 ` [PATCH v2 10/18] microblaze/PCI: " Bjorn Helgaas
2012-02-10  2:37 ` [PATCH v2 11/18] mips/PCI: " Bjorn Helgaas
2012-02-10  2:43   ` Bjorn Helgaas
2012-02-10  2:37 ` [PATCH v2 12/18] mn10300/PCI: " Bjorn Helgaas
2012-02-10  2:37 ` [PATCH v2 13/18] parisc/PCI: " Bjorn Helgaas
2012-02-10  2:37 ` [PATCH v2 14/18] powerpc/PCI: " Bjorn Helgaas
2012-02-10  2:37 ` [PATCH v2 15/18] sh/PCI: " Bjorn Helgaas
2012-02-10  2:37 ` [PATCH v2 16/18] sparc/PCI: " Bjorn Helgaas
2012-02-10  2:37   ` Bjorn Helgaas
2012-02-10  2:37 ` [PATCH v2 17/18] xtensa/PCI: " Bjorn Helgaas
2012-02-10  2:37 ` [PATCH v2 18/18] PCI: collapse pcibios_resource_to_bus Bjorn Helgaas
2012-02-10  4:03 ` [PATCH v2 00/18] add PCI bus-to-resource offset support in core Yinghai Lu
2012-02-10  4:34   ` Bjorn Helgaas
2012-02-10  4:50     ` Yinghai Lu
2012-02-10 16:55       ` Bjorn Helgaas
2012-02-10 17:20         ` Yinghai Lu
2012-02-10 17:24           ` Bjorn Helgaas
2012-02-10 20:25             ` Yinghai Lu
2012-02-10 22:37               ` Bjorn Helgaas

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.