linux-arch.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH v1 00/18] add PCI bus-to-resource offset support in core
@ 2012-01-30 16:57 Bjorn Helgaas
  2012-01-30 16:57 ` Bjorn Helgaas
                   ` (18 more replies)
  0 siblings, 19 replies; 57+ messages in thread
From: Bjorn Helgaas @ 2012-01-30 16:57 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.

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.

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.

I've built most of the architectures I touched, but unfortunately my only
test machines are x86, which don't do any address translation, so I haven't
been able to test the most interesting changes.

These patches are also in this git repo:
    git://github.com/bjorn-helgaas/linux.git pci-offset-v1-9a9b9533de00

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

---

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/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                   |  202 ++++++++++++++++++++++++++-------
 include/asm-generic/pci.h             |   24 ----
 include/linux/pci.h                   |   18 +++
 47 files changed, 324 insertions(+), 951 deletions(-)

-- 
Bjorn

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

* [RFC PATCH v1 00/18] add PCI bus-to-resource offset support in core
  2012-01-30 16:57 [RFC PATCH v1 00/18] add PCI bus-to-resource offset support in core Bjorn Helgaas
@ 2012-01-30 16:57 ` Bjorn Helgaas
  2012-01-30 16:57 ` [RFC PATCH v1 01/18] PCI: don't publish new root bus until it's fully initialized Bjorn Helgaas
                   ` (17 subsequent siblings)
  18 siblings, 0 replies; 57+ messages in thread
From: Bjorn Helgaas @ 2012-01-30 16:57 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.

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.

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.

I've built most of the architectures I touched, but unfortunately my only
test machines are x86, which don't do any address translation, so I haven't
been able to test the most interesting changes.

These patches are also in this git repo:
    git://github.com/bjorn-helgaas/linux.git pci-offset-v1-9a9b9533de00

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

---

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/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                   |  202 ++++++++++++++++++++++++++-------
 include/asm-generic/pci.h             |   24 ----
 include/linux/pci.h                   |   18 +++
 47 files changed, 324 insertions(+), 951 deletions(-)

-- 
Bjorn

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

* [RFC PATCH v1 01/18] PCI: don't publish new root bus until it's fully initialized
  2012-01-30 16:57 [RFC PATCH v1 00/18] add PCI bus-to-resource offset support in core Bjorn Helgaas
  2012-01-30 16:57 ` Bjorn Helgaas
@ 2012-01-30 16:57 ` Bjorn Helgaas
  2012-01-30 16:57   ` Bjorn Helgaas
  2012-01-30 16:57 ` [RFC PATCH v1 02/18] PCI: add struct pci_host_bridge and a list of all bridges found Bjorn Helgaas
                   ` (16 subsequent siblings)
  18 siblings, 1 reply; 57+ messages in thread
From: Bjorn Helgaas @ 2012-01-30 16:57 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.
---
 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] 57+ messages in thread

* [RFC PATCH v1 01/18] PCI: don't publish new root bus until it's fully initialized
  2012-01-30 16:57 ` [RFC PATCH v1 01/18] PCI: don't publish new root bus until it's fully initialized Bjorn Helgaas
@ 2012-01-30 16:57   ` Bjorn Helgaas
  0 siblings, 0 replies; 57+ messages in thread
From: Bjorn Helgaas @ 2012-01-30 16:57 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.
---
 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] 57+ messages in thread

* [RFC PATCH v1 02/18] PCI: add struct pci_host_bridge and a list of all bridges found
  2012-01-30 16:57 [RFC PATCH v1 00/18] add PCI bus-to-resource offset support in core Bjorn Helgaas
  2012-01-30 16:57 ` Bjorn Helgaas
  2012-01-30 16:57 ` [RFC PATCH v1 01/18] PCI: don't publish new root bus until it's fully initialized Bjorn Helgaas
@ 2012-01-30 16:57 ` Bjorn Helgaas
  2012-01-30 16:57   ` Bjorn Helgaas
  2012-01-30 20:52   ` Yinghai Lu
  2012-01-30 16:57 ` [RFC PATCH v1 03/18] PCI: add struct pci_host_bridge_window with CPU/bus address offset Bjorn Helgaas
                   ` (15 subsequent siblings)
  18 siblings, 2 replies; 57+ messages in thread
From: Bjorn Helgaas @ 2012-01-30 16:57 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.
---
 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] 57+ messages in thread

* [RFC PATCH v1 02/18] PCI: add struct pci_host_bridge and a list of all bridges found
  2012-01-30 16:57 ` [RFC PATCH v1 02/18] PCI: add struct pci_host_bridge and a list of all bridges found Bjorn Helgaas
@ 2012-01-30 16:57   ` Bjorn Helgaas
  2012-01-30 20:52   ` Yinghai Lu
  1 sibling, 0 replies; 57+ messages in thread
From: Bjorn Helgaas @ 2012-01-30 16:57 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.
---
 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] 57+ messages in thread

* [RFC PATCH v1 03/18] PCI: add struct pci_host_bridge_window with CPU/bus address offset
  2012-01-30 16:57 [RFC PATCH v1 00/18] add PCI bus-to-resource offset support in core Bjorn Helgaas
                   ` (2 preceding siblings ...)
  2012-01-30 16:57 ` [RFC PATCH v1 02/18] PCI: add struct pci_host_bridge and a list of all bridges found Bjorn Helgaas
@ 2012-01-30 16:57 ` Bjorn Helgaas
  2012-01-30 16:57   ` Bjorn Helgaas
  2012-01-30 16:57 ` [RFC PATCH v1 04/18] PCI: convert bus addresses to resource when reading BARs Bjorn Helgaas
                   ` (14 subsequent siblings)
  18 siblings, 1 reply; 57+ messages in thread
From: Bjorn Helgaas @ 2012-01-30 16:57 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);
---
 drivers/pci/bus.c   |   30 +++++++++++++++++++-----------
 drivers/pci/probe.c |   26 ++++++++++++++++----------
 include/linux/pci.h |    9 +++++++++
 3 files changed, 44 insertions(+), 21 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..4c28aec 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1544,12 +1544,12 @@ 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 resource *res;
+	struct pci_host_bridge_window *window, *n;
+	char offset_text[40];
 
 	bridge = kzalloc(sizeof(*bridge), GFP_KERNEL);
 	if (!bridge)
@@ -1599,19 +1599,25 @@ 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);
+		pci_bus_add_resource(b, window->res, 0);
+		if (window->offset)
+			snprintf(offset_text, sizeof(offset_text),
+				 " (bus offset %#llx)",
+				 (unsigned long long) window->offset);
+		else
+			offset_text[0] = '\0';
+		dev_info(&b->dev, "root bus resource %pR%s\n", window->res,
+			 offset_text);
 	}
 
 	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] 57+ messages in thread

* [RFC PATCH v1 03/18] PCI: add struct pci_host_bridge_window with CPU/bus address offset
  2012-01-30 16:57 ` [RFC PATCH v1 03/18] PCI: add struct pci_host_bridge_window with CPU/bus address offset Bjorn Helgaas
@ 2012-01-30 16:57   ` Bjorn Helgaas
  0 siblings, 0 replies; 57+ messages in thread
From: Bjorn Helgaas @ 2012-01-30 16:57 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);
---
 drivers/pci/bus.c   |   30 +++++++++++++++++++-----------
 drivers/pci/probe.c |   26 ++++++++++++++++----------
 include/linux/pci.h |    9 +++++++++
 3 files changed, 44 insertions(+), 21 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..4c28aec 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1544,12 +1544,12 @@ 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 resource *res;
+	struct pci_host_bridge_window *window, *n;
+	char offset_text[40];
 
 	bridge = kzalloc(sizeof(*bridge), GFP_KERNEL);
 	if (!bridge)
@@ -1599,19 +1599,25 @@ 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);
+		pci_bus_add_resource(b, window->res, 0);
+		if (window->offset)
+			snprintf(offset_text, sizeof(offset_text),
+				 " (bus offset %#llx)",
+				 (unsigned long long) window->offset);
+		else
+			offset_text[0] = '\0';
+		dev_info(&b->dev, "root bus resource %pR%s\n", window->res,
+			 offset_text);
 	}
 
 	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] 57+ messages in thread

* [RFC PATCH v1 04/18] PCI: convert bus addresses to resource when reading BARs
  2012-01-30 16:57 [RFC PATCH v1 00/18] add PCI bus-to-resource offset support in core Bjorn Helgaas
                   ` (3 preceding siblings ...)
  2012-01-30 16:57 ` [RFC PATCH v1 03/18] PCI: add struct pci_host_bridge_window with CPU/bus address offset Bjorn Helgaas
@ 2012-01-30 16:57 ` Bjorn Helgaas
  2012-01-30 16:57 ` [RFC PATCH v1 05/18] PCI: add generic pcibios_resource_to_bus() Bjorn Helgaas
                   ` (13 subsequent siblings)
  18 siblings, 0 replies; 57+ messages in thread
From: Bjorn Helgaas @ 2012-01-30 16:57 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
---
 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 4c28aec..ba60f41 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] 57+ messages in thread

* [RFC PATCH v1 05/18] PCI: add generic pcibios_resource_to_bus()
  2012-01-30 16:57 [RFC PATCH v1 00/18] add PCI bus-to-resource offset support in core Bjorn Helgaas
                   ` (4 preceding siblings ...)
  2012-01-30 16:57 ` [RFC PATCH v1 04/18] PCI: convert bus addresses to resource when reading BARs Bjorn Helgaas
@ 2012-01-30 16:57 ` Bjorn Helgaas
  2012-01-30 16:57 ` [RFC PATCH v1 06/18] alpha/PCI: get rid of device resource fixups Bjorn Helgaas
                   ` (12 subsequent siblings)
  18 siblings, 0 replies; 57+ messages in thread
From: Bjorn Helgaas @ 2012-01-30 16:57 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.
---
 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 ba60f41..6aefa5a 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] 57+ messages in thread

* [RFC PATCH v1 06/18] alpha/PCI: get rid of device resource fixups
  2012-01-30 16:57 [RFC PATCH v1 00/18] add PCI bus-to-resource offset support in core Bjorn Helgaas
                   ` (5 preceding siblings ...)
  2012-01-30 16:57 ` [RFC PATCH v1 05/18] PCI: add generic pcibios_resource_to_bus() Bjorn Helgaas
@ 2012-01-30 16:57 ` Bjorn Helgaas
  2012-01-30 16:57   ` Bjorn Helgaas
  2012-01-30 16:57 ` [RFC PATCH v1 07/18] arm/PCI: " Bjorn Helgaas
                   ` (11 subsequent siblings)
  18 siblings, 1 reply; 57+ messages in thread
From: Bjorn Helgaas @ 2012-01-30 16:57 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
---
 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] 57+ messages in thread

* [RFC PATCH v1 06/18] alpha/PCI: get rid of device resource fixups
  2012-01-30 16:57 ` [RFC PATCH v1 06/18] alpha/PCI: get rid of device resource fixups Bjorn Helgaas
@ 2012-01-30 16:57   ` Bjorn Helgaas
  0 siblings, 0 replies; 57+ messages in thread
From: Bjorn Helgaas @ 2012-01-30 16:57 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
---
 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] 57+ messages in thread

* [RFC PATCH v1 07/18] arm/PCI: get rid of device resource fixups
  2012-01-30 16:57 [RFC PATCH v1 00/18] add PCI bus-to-resource offset support in core Bjorn Helgaas
                   ` (6 preceding siblings ...)
  2012-01-30 16:57 ` [RFC PATCH v1 06/18] alpha/PCI: get rid of device resource fixups Bjorn Helgaas
@ 2012-01-30 16:57 ` Bjorn Helgaas
  2012-01-30 16:57   ` Bjorn Helgaas
  2012-02-03 16:01   ` Russell King - ARM Linux
  2012-01-30 16:57 ` [RFC PATCH v1 08/18] ia64/PCI: SN: convert to pci_scan_root_bus() for correct root bus resources Bjorn Helgaas
                   ` (10 subsequent siblings)
  18 siblings, 2 replies; 57+ messages in thread
From: Bjorn Helgaas @ 2012-01-30 16:57 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>
---
 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] 57+ messages in thread

* [RFC PATCH v1 07/18] arm/PCI: get rid of device resource fixups
  2012-01-30 16:57 ` [RFC PATCH v1 07/18] arm/PCI: " Bjorn Helgaas
@ 2012-01-30 16:57   ` Bjorn Helgaas
  2012-02-03 16:01   ` Russell King - ARM Linux
  1 sibling, 0 replies; 57+ messages in thread
From: Bjorn Helgaas @ 2012-01-30 16:57 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>
---
 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] 57+ messages in thread

* [RFC PATCH v1 08/18] ia64/PCI: SN: convert to pci_scan_root_bus() for correct root bus resources
  2012-01-30 16:57 [RFC PATCH v1 00/18] add PCI bus-to-resource offset support in core Bjorn Helgaas
                   ` (7 preceding siblings ...)
  2012-01-30 16:57 ` [RFC PATCH v1 07/18] arm/PCI: " Bjorn Helgaas
@ 2012-01-30 16:57 ` Bjorn Helgaas
  2012-01-30 16:57 ` [RFC PATCH v1 09/18] ia64/PCI: get rid of device resource fixups Bjorn Helgaas
                   ` (9 subsequent siblings)
  18 siblings, 0 replies; 57+ messages in thread
From: Bjorn Helgaas @ 2012-01-30 16:57 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>
---
 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] 57+ messages in thread

* [RFC PATCH v1 09/18] ia64/PCI: get rid of device resource fixups
  2012-01-30 16:57 [RFC PATCH v1 00/18] add PCI bus-to-resource offset support in core Bjorn Helgaas
                   ` (8 preceding siblings ...)
  2012-01-30 16:57 ` [RFC PATCH v1 08/18] ia64/PCI: SN: convert to pci_scan_root_bus() for correct root bus resources Bjorn Helgaas
@ 2012-01-30 16:57 ` Bjorn Helgaas
  2012-01-30 16:57   ` Bjorn Helgaas
  2012-01-30 16:58 ` [RFC PATCH v1 10/18] microblaze/PCI: " Bjorn Helgaas
                   ` (8 subsequent siblings)
  18 siblings, 1 reply; 57+ messages in thread
From: Bjorn Helgaas @ 2012-01-30 16:57 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>
---
 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] 57+ messages in thread

* [RFC PATCH v1 09/18] ia64/PCI: get rid of device resource fixups
  2012-01-30 16:57 ` [RFC PATCH v1 09/18] ia64/PCI: get rid of device resource fixups Bjorn Helgaas
@ 2012-01-30 16:57   ` Bjorn Helgaas
  0 siblings, 0 replies; 57+ messages in thread
From: Bjorn Helgaas @ 2012-01-30 16:57 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>
---
 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] 57+ messages in thread

* [RFC PATCH v1 10/18] microblaze/PCI: get rid of device resource fixups
  2012-01-30 16:57 [RFC PATCH v1 00/18] add PCI bus-to-resource offset support in core Bjorn Helgaas
                   ` (9 preceding siblings ...)
  2012-01-30 16:57 ` [RFC PATCH v1 09/18] ia64/PCI: get rid of device resource fixups Bjorn Helgaas
@ 2012-01-30 16:58 ` Bjorn Helgaas
  2012-01-30 16:58   ` Bjorn Helgaas
  2012-02-02 10:50   ` Michal Simek
  2012-01-30 16:58 ` [RFC PATCH v1 11/18] mips/PCI: " Bjorn Helgaas
                   ` (7 subsequent siblings)
  18 siblings, 2 replies; 57+ messages in thread
From: Bjorn Helgaas @ 2012-01-30 16:58 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.

N.B. We might need to tweak the I/O range and offset to account for the
32-bit mask previously used in pcibios_resource_to_bus().  I don't
know the details of this mapping.  If anybody can help me test and
fix this, please let me know.

CC: Michal Simek <monstr@monstr.eu>
---
 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] 57+ messages in thread

* [RFC PATCH v1 10/18] microblaze/PCI: get rid of device resource fixups
  2012-01-30 16:58 ` [RFC PATCH v1 10/18] microblaze/PCI: " Bjorn Helgaas
@ 2012-01-30 16:58   ` Bjorn Helgaas
  2012-02-02 10:50   ` Michal Simek
  1 sibling, 0 replies; 57+ messages in thread
From: Bjorn Helgaas @ 2012-01-30 16:58 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.

N.B. We might need to tweak the I/O range and offset to account for the
32-bit mask previously used in pcibios_resource_to_bus().  I don't
know the details of this mapping.  If anybody can help me test and
fix this, please let me know.

CC: Michal Simek <monstr@monstr.eu>
---
 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] 57+ messages in thread

* [RFC PATCH v1 11/18] mips/PCI: get rid of device resource fixups
  2012-01-30 16:57 [RFC PATCH v1 00/18] add PCI bus-to-resource offset support in core Bjorn Helgaas
                   ` (10 preceding siblings ...)
  2012-01-30 16:58 ` [RFC PATCH v1 10/18] microblaze/PCI: " Bjorn Helgaas
@ 2012-01-30 16:58 ` Bjorn Helgaas
  2012-01-30 16:58   ` Bjorn Helgaas
  2012-01-31  2:42   ` Yoichi Yuasa
  2012-01-30 16:58 ` [RFC PATCH v1 12/18] mn10300/PCI: " Bjorn Helgaas
                   ` (6 subsequent siblings)
  18 siblings, 2 replies; 57+ messages in thread
From: Bjorn Helgaas @ 2012-01-30 16:58 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.

N.B. cobalt_legacy_ide_fixup() does scary things with resources, but I
*think* it will still work because we're still making the same adjustments,
just in the opposite order.  Here are the legacy IDE resource.start
values I expect:

         current                                        new

           0x1f0   (pci_setup_device)                 0x1f0
                   (pci_bus_to_resource)       + 0xf0000000
    - 0xf0000000   (cobalt_legacy_ide_fixup)   - 0xf0000000
    + 0xf0000000   (pcibios_fixup_bus)
    ------------                               ------------
           0x1f0    final value                       0x1f0

CC: Ralf Baechle <ralf@linux-mips.org>
CC: Yoichi Yuasa <yuasa@linux-mips.org>
---
 arch/mips/include/asm/pci.h |    6 +---
 arch/mips/pci/pci.c         |   70 ++-----------------------------------------
 2 files changed, 4 insertions(+), 72 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/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] 57+ messages in thread

* [RFC PATCH v1 11/18] mips/PCI: get rid of device resource fixups
  2012-01-30 16:58 ` [RFC PATCH v1 11/18] mips/PCI: " Bjorn Helgaas
@ 2012-01-30 16:58   ` Bjorn Helgaas
  2012-01-31  2:42   ` Yoichi Yuasa
  1 sibling, 0 replies; 57+ messages in thread
From: Bjorn Helgaas @ 2012-01-30 16:58 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.

N.B. cobalt_legacy_ide_fixup() does scary things with resources, but I
*think* it will still work because we're still making the same adjustments,
just in the opposite order.  Here are the legacy IDE resource.start
values I expect:

         current                                        new

           0x1f0   (pci_setup_device)                 0x1f0
                   (pci_bus_to_resource)       + 0xf0000000
    - 0xf0000000   (cobalt_legacy_ide_fixup)   - 0xf0000000
    + 0xf0000000   (pcibios_fixup_bus)
    ------------                               ------------
           0x1f0    final value                       0x1f0

CC: Ralf Baechle <ralf@linux-mips.org>
CC: Yoichi Yuasa <yuasa@linux-mips.org>
---
 arch/mips/include/asm/pci.h |    6 +---
 arch/mips/pci/pci.c         |   70 ++-----------------------------------------
 2 files changed, 4 insertions(+), 72 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/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] 57+ messages in thread

* [RFC PATCH v1 12/18] mn10300/PCI: get rid of device resource fixups
  2012-01-30 16:57 [RFC PATCH v1 00/18] add PCI bus-to-resource offset support in core Bjorn Helgaas
                   ` (11 preceding siblings ...)
  2012-01-30 16:58 ` [RFC PATCH v1 11/18] mips/PCI: " Bjorn Helgaas
@ 2012-01-30 16:58 ` Bjorn Helgaas
  2012-01-30 16:58   ` Bjorn Helgaas
  2012-01-30 16:58 ` [RFC PATCH v1 13/18] parisc/PCI: " Bjorn Helgaas
                   ` (5 subsequent siblings)
  18 siblings, 1 reply; 57+ messages in thread
From: Bjorn Helgaas @ 2012-01-30 16:58 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.

N.B. I'm replacing some masking and boolean OR with simple addition.  I
think this will work, but verification/testing would be good.  For example,
with a PCI MMIO resource [mem 0xb8000000-0xbbffffff] (CPU addresses) and
MEM_PAGING_REG of 0xe8000000, we currently convert to a bus address like
this:

    bus_addr(0xb8000000) = (0xb8000000 & 0x03ffffff) | MEM_PAGING_REG
                         = (0xb8000000 & 0x03ffffff) | 0xe8000000
                         =  0xe8000000

    cpu_addr(0xe8000000) = (0xe8000000 & 0x03ffffff) | 0xb8000000
                         =  0xb8000000

I computed a mem offset as:

    mem_offset = pci_iomem_resource.start -
        ((pci_iomem_resource.start & 0x03ffffff) | MEM_PAGING_REG);
    mem_offset = 0xb8000000 - ((0xb8000000 & 0x03ffffff) | 0xe8000000)
               = 0xd0000000

And then convert with addition:

    bus_addr(0xb8000000) = 0xb8000000 - mem_offset
                         = 0xb8000000 - 0xd0000000
                         = 0xe8000000

    cpu_addr(0xe8000000) = 0xe8000000 + mem_offset
                         = 0xe8000000 + 0xd0000000
                         = 0xb8000000

If resource_size_t is a u64, the offset works out to 0xffffffffd0000000,
but the bus/resource conversions still work correctly.

CC: David Howells <dhowells@redhat.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] 57+ messages in thread

* [RFC PATCH v1 12/18] mn10300/PCI: get rid of device resource fixups
  2012-01-30 16:58 ` [RFC PATCH v1 12/18] mn10300/PCI: " Bjorn Helgaas
@ 2012-01-30 16:58   ` Bjorn Helgaas
  0 siblings, 0 replies; 57+ messages in thread
From: Bjorn Helgaas @ 2012-01-30 16:58 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.

N.B. I'm replacing some masking and boolean OR with simple addition.  I
think this will work, but verification/testing would be good.  For example,
with a PCI MMIO resource [mem 0xb8000000-0xbbffffff] (CPU addresses) and
MEM_PAGING_REG of 0xe8000000, we currently convert to a bus address like
this:

    bus_addr(0xb8000000) = (0xb8000000 & 0x03ffffff) | MEM_PAGING_REG
                         = (0xb8000000 & 0x03ffffff) | 0xe8000000
                         =  0xe8000000

    cpu_addr(0xe8000000) = (0xe8000000 & 0x03ffffff) | 0xb8000000
                         =  0xb8000000

I computed a mem offset as:

    mem_offset = pci_iomem_resource.start -
        ((pci_iomem_resource.start & 0x03ffffff) | MEM_PAGING_REG);
    mem_offset = 0xb8000000 - ((0xb8000000 & 0x03ffffff) | 0xe8000000)
               = 0xd0000000

And then convert with addition:

    bus_addr(0xb8000000) = 0xb8000000 - mem_offset
                         = 0xb8000000 - 0xd0000000
                         = 0xe8000000

    cpu_addr(0xe8000000) = 0xe8000000 + mem_offset
                         = 0xe8000000 + 0xd0000000
                         = 0xb8000000

If resource_size_t is a u64, the offset works out to 0xffffffffd0000000,
but the bus/resource conversions still work correctly.

CC: David Howells <dhowells@redhat.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] 57+ messages in thread

* [RFC PATCH v1 13/18] parisc/PCI: get rid of device resource fixups
  2012-01-30 16:57 [RFC PATCH v1 00/18] add PCI bus-to-resource offset support in core Bjorn Helgaas
                   ` (12 preceding siblings ...)
  2012-01-30 16:58 ` [RFC PATCH v1 12/18] mn10300/PCI: " Bjorn Helgaas
@ 2012-01-30 16:58 ` Bjorn Helgaas
  2012-01-30 16:58   ` Bjorn Helgaas
  2012-01-30 16:58 ` [RFC PATCH v1 14/18] powerpc/PCI: " Bjorn Helgaas
                   ` (4 subsequent siblings)
  18 siblings, 1 reply; 57+ messages in thread
From: Bjorn Helgaas @ 2012-01-30 16:58 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.

N.B. parisc has far more complicated code for bus/resource conversion than
most arches.  I don't think the actual hardware behavior is any more
complicated, and I tried to compute the simple offset between the bus
address and the CPU address, but it's likely that I didn't get all the
details just right here, and I haven't been able to test it.

CC: linux-parisc@vger.kernel.org
---
 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] 57+ messages in thread

* [RFC PATCH v1 13/18] parisc/PCI: get rid of device resource fixups
  2012-01-30 16:58 ` [RFC PATCH v1 13/18] parisc/PCI: " Bjorn Helgaas
@ 2012-01-30 16:58   ` Bjorn Helgaas
  0 siblings, 0 replies; 57+ messages in thread
From: Bjorn Helgaas @ 2012-01-30 16:58 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.

N.B. parisc has far more complicated code for bus/resource conversion than
most arches.  I don't think the actual hardware behavior is any more
complicated, and I tried to compute the simple offset between the bus
address and the CPU address, but it's likely that I didn't get all the
details just right here, and I haven't been able to test it.

CC: linux-parisc@vger.kernel.org
---
 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] 57+ messages in thread

* [RFC PATCH v1 14/18] powerpc/PCI: get rid of device resource fixups
  2012-01-30 16:57 [RFC PATCH v1 00/18] add PCI bus-to-resource offset support in core Bjorn Helgaas
                   ` (13 preceding siblings ...)
  2012-01-30 16:58 ` [RFC PATCH v1 13/18] parisc/PCI: " Bjorn Helgaas
@ 2012-01-30 16:58 ` Bjorn Helgaas
  2012-01-30 20:49   ` Benjamin Herrenschmidt
  2012-01-30 16:58 ` [RFC PATCH v1 15/18] sh/PCI: " Bjorn Helgaas
                   ` (3 subsequent siblings)
  18 siblings, 1 reply; 57+ messages in thread
From: Bjorn Helgaas @ 2012-01-30 16:58 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.

N.B. powerpc used a 32-bit mask when converting IO addresses.  If we
figure out the right offset, I think simple addition should do the
same thing, but I might not have it exactly right yet.

CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
 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] 57+ messages in thread

* [RFC PATCH v1 15/18] sh/PCI: get rid of device resource fixups
  2012-01-30 16:57 [RFC PATCH v1 00/18] add PCI bus-to-resource offset support in core Bjorn Helgaas
                   ` (14 preceding siblings ...)
  2012-01-30 16:58 ` [RFC PATCH v1 14/18] powerpc/PCI: " Bjorn Helgaas
@ 2012-01-30 16:58 ` Bjorn Helgaas
  2012-01-30 16:58 ` [RFC PATCH v1 16/18] sparc/PCI: " Bjorn Helgaas
                   ` (2 subsequent siblings)
  18 siblings, 0 replies; 57+ messages in thread
From: Bjorn Helgaas @ 2012-01-30 16:58 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>
---
 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 8f18dd0..e5aacef 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] 57+ messages in thread

* [RFC PATCH v1 16/18] sparc/PCI: get rid of device resource fixups
  2012-01-30 16:57 [RFC PATCH v1 00/18] add PCI bus-to-resource offset support in core Bjorn Helgaas
                   ` (15 preceding siblings ...)
  2012-01-30 16:58 ` [RFC PATCH v1 15/18] sh/PCI: " Bjorn Helgaas
@ 2012-01-30 16:58 ` Bjorn Helgaas
  2012-01-30 16:58 ` [RFC PATCH v1 17/18] xtensa/PCI: " Bjorn Helgaas
  2012-01-30 16:58 ` [RFC PATCH v1 18/18] PCI: collapse pcibios_resource_to_bus Bjorn Helgaas
  18 siblings, 0 replies; 57+ messages in thread
From: Bjorn Helgaas @ 2012-01-30 16:58 UTC (permalink / raw)
  To: linux-pci; +Cc: linux-arch

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().
---
 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] 57+ messages in thread

* [RFC PATCH v1 17/18] xtensa/PCI: get rid of device resource fixups
  2012-01-30 16:57 [RFC PATCH v1 00/18] add PCI bus-to-resource offset support in core Bjorn Helgaas
                   ` (16 preceding siblings ...)
  2012-01-30 16:58 ` [RFC PATCH v1 16/18] sparc/PCI: " Bjorn Helgaas
@ 2012-01-30 16:58 ` Bjorn Helgaas
  2012-01-30 16:58   ` Bjorn Helgaas
  2012-01-30 16:58 ` [RFC PATCH v1 18/18] PCI: collapse pcibios_resource_to_bus Bjorn Helgaas
  18 siblings, 1 reply; 57+ messages in thread
From: Bjorn Helgaas @ 2012-01-30 16:58 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>
---
 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] 57+ messages in thread

* [RFC PATCH v1 17/18] xtensa/PCI: get rid of device resource fixups
  2012-01-30 16:58 ` [RFC PATCH v1 17/18] xtensa/PCI: " Bjorn Helgaas
@ 2012-01-30 16:58   ` Bjorn Helgaas
  0 siblings, 0 replies; 57+ messages in thread
From: Bjorn Helgaas @ 2012-01-30 16:58 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>
---
 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] 57+ messages in thread

* [RFC PATCH v1 18/18] PCI: collapse pcibios_resource_to_bus
  2012-01-30 16:57 [RFC PATCH v1 00/18] add PCI bus-to-resource offset support in core Bjorn Helgaas
                   ` (17 preceding siblings ...)
  2012-01-30 16:58 ` [RFC PATCH v1 17/18] xtensa/PCI: " Bjorn Helgaas
@ 2012-01-30 16:58 ` Bjorn Helgaas
  18 siblings, 0 replies; 57+ messages in thread
From: Bjorn Helgaas @ 2012-01-30 16:58 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.
---
 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 6aefa5a..e479033 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] 57+ messages in thread

* Re: [RFC PATCH v1 14/18] powerpc/PCI: get rid of device resource fixups
  2012-01-30 16:58 ` [RFC PATCH v1 14/18] powerpc/PCI: " Bjorn Helgaas
@ 2012-01-30 20:49   ` Benjamin Herrenschmidt
  2012-01-30 21:46     ` Bjorn Helgaas
  0 siblings, 1 reply; 57+ messages in thread
From: Benjamin Herrenschmidt @ 2012-01-30 20:49 UTC (permalink / raw)
  To: Bjorn Helgaas; +Cc: linux-pci, linux-arch

On Mon, 2012-01-30 at 09:58 -0700, Bjorn Helgaas wrote:
> Tell the PCI core about host bridge address translation so it can take
> care of bus-to-resource conversion for us.
> 
> N.B. powerpc used a 32-bit mask when converting IO addresses.  If we
> figure out the right offset, I think simple addition should do the
> same thing, but I might not have it exactly right yet.

Wow that's going to be a big change :-) A quick look... seems like you
do a per-resource offset right ? I will need that (was about to change
powerpc) as we have hardware that provides us with two different windows
to MMIO space with different offsets unfortunately.

One thing I also want to generalize is the whole "REASSIGN_ALL_RSRC"
flag, ie, avoid reading & printing all those resources we know we are
just going to kill off.

I'll try to test your stuff asap (I'm doing 3 things at once right now
so it might take a few days unless I find somebody to look at it).

Cheers,
Ben.

> CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> ---
>  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	[flat|nested] 57+ messages in thread

* Re: [RFC PATCH v1 02/18] PCI: add struct pci_host_bridge and a list of all bridges found
  2012-01-30 16:57 ` [RFC PATCH v1 02/18] PCI: add struct pci_host_bridge and a list of all bridges found Bjorn Helgaas
  2012-01-30 16:57   ` Bjorn Helgaas
@ 2012-01-30 20:52   ` Yinghai Lu
  2012-01-30 20:52     ` Yinghai Lu
  2012-01-30 22:00     ` Bjorn Helgaas
  1 sibling, 2 replies; 57+ messages in thread
From: Yinghai Lu @ 2012-01-30 20:52 UTC (permalink / raw)
  To: Bjorn Helgaas; +Cc: linux-pci, linux-arch

On Mon, Jan 30, 2012 at 8:57 AM, 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.
> ---
>  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);

we already have list for root_bus. So there will be two lists.

wonder if we can overload bus->self point to struct host_bridge.

or just do not add host_bridge , and instead only add another field
like struct list_head windows in pci_sysdata?

Thanks

Yinghai

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

* Re: [RFC PATCH v1 02/18] PCI: add struct pci_host_bridge and a list of all bridges found
  2012-01-30 20:52   ` Yinghai Lu
@ 2012-01-30 20:52     ` Yinghai Lu
  2012-01-30 22:00     ` Bjorn Helgaas
  1 sibling, 0 replies; 57+ messages in thread
From: Yinghai Lu @ 2012-01-30 20:52 UTC (permalink / raw)
  To: Bjorn Helgaas; +Cc: linux-pci, linux-arch

On Mon, Jan 30, 2012 at 8:57 AM, 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.
> ---
>  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);

we already have list for root_bus. So there will be two lists.

wonder if we can overload bus->self point to struct host_bridge.

or just do not add host_bridge , and instead only add another field
like struct list_head windows in pci_sysdata?

Thanks

Yinghai

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

* Re: [RFC PATCH v1 14/18] powerpc/PCI: get rid of device resource fixups
  2012-01-30 20:49   ` Benjamin Herrenschmidt
@ 2012-01-30 21:46     ` Bjorn Helgaas
  2012-01-30 21:46       ` Bjorn Helgaas
  0 siblings, 1 reply; 57+ messages in thread
From: Bjorn Helgaas @ 2012-01-30 21:46 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linux-pci, linux-arch

On Mon, Jan 30, 2012 at 12:49 PM, Benjamin Herrenschmidt
<benh@kernel.crashing.org> wrote:
> On Mon, 2012-01-30 at 09:58 -0700, Bjorn Helgaas wrote:
>> Tell the PCI core about host bridge address translation so it can take
>> care of bus-to-resource conversion for us.
>>
>> N.B. powerpc used a 32-bit mask when converting IO addresses.  If we
>> figure out the right offset, I think simple addition should do the
>> same thing, but I might not have it exactly right yet.
>
> Wow that's going to be a big change :-) A quick look... seems like you
> do a per-resource offset right ? I will need that (was about to change
> powerpc) as we have hardware that provides us with two different windows
> to MMIO space with different offsets unfortunately.

Exactly ... the offset is per-aperture.

> One thing I also want to generalize is the whole "REASSIGN_ALL_RSRC"
> flag, ie, avoid reading & printing all those resources we know we are
> just going to kill off.
>
> I'll try to test your stuff asap (I'm doing 3 things at once right now
> so it might take a few days unless I find somebody to look at it).

Thanks!  No particular rush on my side; I'm expecting to have to
iterate a few times to get this right.

Bjorn

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

* Re: [RFC PATCH v1 14/18] powerpc/PCI: get rid of device resource fixups
  2012-01-30 21:46     ` Bjorn Helgaas
@ 2012-01-30 21:46       ` Bjorn Helgaas
  0 siblings, 0 replies; 57+ messages in thread
From: Bjorn Helgaas @ 2012-01-30 21:46 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linux-pci, linux-arch

On Mon, Jan 30, 2012 at 12:49 PM, Benjamin Herrenschmidt
<benh@kernel.crashing.org> wrote:
> On Mon, 2012-01-30 at 09:58 -0700, Bjorn Helgaas wrote:
>> Tell the PCI core about host bridge address translation so it can take
>> care of bus-to-resource conversion for us.
>>
>> N.B. powerpc used a 32-bit mask when converting IO addresses.  If we
>> figure out the right offset, I think simple addition should do the
>> same thing, but I might not have it exactly right yet.
>
> Wow that's going to be a big change :-) A quick look... seems like you
> do a per-resource offset right ? I will need that (was about to change
> powerpc) as we have hardware that provides us with two different windows
> to MMIO space with different offsets unfortunately.

Exactly ... the offset is per-aperture.

> One thing I also want to generalize is the whole "REASSIGN_ALL_RSRC"
> flag, ie, avoid reading & printing all those resources we know we are
> just going to kill off.
>
> I'll try to test your stuff asap (I'm doing 3 things at once right now
> so it might take a few days unless I find somebody to look at it).

Thanks!  No particular rush on my side; I'm expecting to have to
iterate a few times to get this right.

Bjorn

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

* Re: [RFC PATCH v1 02/18] PCI: add struct pci_host_bridge and a list of all bridges found
  2012-01-30 20:52   ` Yinghai Lu
  2012-01-30 20:52     ` Yinghai Lu
@ 2012-01-30 22:00     ` Bjorn Helgaas
  2012-01-30 22:00       ` Bjorn Helgaas
  2012-01-30 22:29       ` Yinghai Lu
  1 sibling, 2 replies; 57+ messages in thread
From: Bjorn Helgaas @ 2012-01-30 22:00 UTC (permalink / raw)
  To: Yinghai Lu; +Cc: linux-pci, linux-arch

On Mon, Jan 30, 2012 at 12:52 PM, Yinghai Lu <yinghai@kernel.org> wrote:
> On Mon, Jan 30, 2012 at 8:57 AM, 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.
>> ---
>>  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);
>
> we already have list for root_bus. So there will be two lists.

Yeah, I'm not sure we need both either.  If we do end up adding a
struct pci_host_bridge, then I think it makes sense to keep a list of
*those* (and possibly remove the root_bus list), since that's a
slightly higher-level abstraction than root_bus is.

> wonder if we can overload bus->self point to struct host_bridge.

pci_bus->self points to a struct pci_dev.  A host bridge is not a
pci_dev.  I don't think it's a good idea to simply reuse "self" to
point to something of a different type, but maybe you have something
different in mind.

> or just do not add host_bridge , and instead only add another field
> like struct list_head windows in pci_sysdata?

The pci_sysdata I see is an x86-specific thing, so I don't see how
that would help.

Bjorn

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

* Re: [RFC PATCH v1 02/18] PCI: add struct pci_host_bridge and a list of all bridges found
  2012-01-30 22:00     ` Bjorn Helgaas
@ 2012-01-30 22:00       ` Bjorn Helgaas
  2012-01-30 22:29       ` Yinghai Lu
  1 sibling, 0 replies; 57+ messages in thread
From: Bjorn Helgaas @ 2012-01-30 22:00 UTC (permalink / raw)
  To: Yinghai Lu; +Cc: linux-pci, linux-arch

On Mon, Jan 30, 2012 at 12:52 PM, Yinghai Lu <yinghai@kernel.org> wrote:
> On Mon, Jan 30, 2012 at 8:57 AM, 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.
>> ---
>>  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);
>
> we already have list for root_bus. So there will be two lists.

Yeah, I'm not sure we need both either.  If we do end up adding a
struct pci_host_bridge, then I think it makes sense to keep a list of
*those* (and possibly remove the root_bus list), since that's a
slightly higher-level abstraction than root_bus is.

> wonder if we can overload bus->self point to struct host_bridge.

pci_bus->self points to a struct pci_dev.  A host bridge is not a
pci_dev.  I don't think it's a good idea to simply reuse "self" to
point to something of a different type, but maybe you have something
different in mind.

> or just do not add host_bridge , and instead only add another field
> like struct list_head windows in pci_sysdata?

The pci_sysdata I see is an x86-specific thing, so I don't see how
that would help.

Bjorn

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

* Re: [RFC PATCH v1 02/18] PCI: add struct pci_host_bridge and a list of all bridges found
  2012-01-30 22:00     ` Bjorn Helgaas
  2012-01-30 22:00       ` Bjorn Helgaas
@ 2012-01-30 22:29       ` Yinghai Lu
  2012-01-30 22:29         ` Yinghai Lu
  1 sibling, 1 reply; 57+ messages in thread
From: Yinghai Lu @ 2012-01-30 22:29 UTC (permalink / raw)
  To: Bjorn Helgaas; +Cc: linux-pci, linux-arch

On Mon, Jan 30, 2012 at 2:00 PM, Bjorn Helgaas <bhelgaas@google.com> wrote:

>>
>
> pci_bus->self points to a struct pci_dev.  A host bridge is not a
> pci_dev.  I don't think it's a good idea to simply reuse "self" to
> point to something of a different type, but maybe you have something
> different in mind.

oh, maybe some root bus will not self to null. (that is why
is_pci_root_bus() is checking parent).

>
>> or just do not add host_bridge , and instead only add another field
>> like struct list_head windows in pci_sysdata?
>
> The pci_sysdata I see is an x86-specific thing, so I don't see how
> that would help.

then expand it.

after that you don't need to go over up to find root bus for one pci
dev and compare root bus with hostbridge list to find out hostbridge.

Yinghai

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

* Re: [RFC PATCH v1 02/18] PCI: add struct pci_host_bridge and a list of all bridges found
  2012-01-30 22:29       ` Yinghai Lu
@ 2012-01-30 22:29         ` Yinghai Lu
  0 siblings, 0 replies; 57+ messages in thread
From: Yinghai Lu @ 2012-01-30 22:29 UTC (permalink / raw)
  To: Bjorn Helgaas; +Cc: linux-pci, linux-arch

On Mon, Jan 30, 2012 at 2:00 PM, Bjorn Helgaas <bhelgaas@google.com> wrote:

>>
>
> pci_bus->self points to a struct pci_dev.  A host bridge is not a
> pci_dev.  I don't think it's a good idea to simply reuse "self" to
> point to something of a different type, but maybe you have something
> different in mind.

oh, maybe some root bus will not self to null. (that is why
is_pci_root_bus() is checking parent).

>
>> or just do not add host_bridge , and instead only add another field
>> like struct list_head windows in pci_sysdata?
>
> The pci_sysdata I see is an x86-specific thing, so I don't see how
> that would help.

then expand it.

after that you don't need to go over up to find root bus for one pci
dev and compare root bus with hostbridge list to find out hostbridge.

Yinghai

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

* Re: [RFC PATCH v1 11/18] mips/PCI: get rid of device resource fixups
  2012-01-30 16:58 ` [RFC PATCH v1 11/18] mips/PCI: " Bjorn Helgaas
  2012-01-30 16:58   ` Bjorn Helgaas
@ 2012-01-31  2:42   ` Yoichi Yuasa
  2012-01-31  2:42     ` Yoichi Yuasa
  2012-01-31  3:54     ` Bjorn Helgaas
  1 sibling, 2 replies; 57+ messages in thread
From: Yoichi Yuasa @ 2012-01-31  2:42 UTC (permalink / raw)
  To: Bjorn Helgaas; +Cc: yuasa, linux-pci, linux-arch, Ralf Baechle

Hi,

On Mon, 30 Jan 2012 09:58:05 -0700
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.
> 
> N.B. cobalt_legacy_ide_fixup() does scary things with resources, but I
> *think* it will still work because we're still making the same adjustments,
> just in the opposite order.  Here are the legacy IDE resource.start
> values I expect:
> 
>          current                                        new
> 
>            0x1f0   (pci_setup_device)                 0x1f0
>                    (pci_bus_to_resource)       + 0xf0000000
>     - 0xf0000000   (cobalt_legacy_ide_fixup)   - 0xf0000000
>     + 0xf0000000   (pcibios_fixup_bus)
>     ------------                               ------------
>            0x1f0    final value                       0x1f0

It seems to be unable to handle the offset correctly.

failed on Cobalt:

pata_via 0000:00:09.1: BAR 0: can't reserve [io  0x100001f0-0x100001f7]         
pata_via 0000:00:09.1: failed to request/iomap BARs for port 0 (errno=-16)      
pata_via 0000:00:09.1: BAR 2: can't reserve [io  0x10000170-0x10000177]         
pata_via 0000:00:09.1: failed to request/iomap BARs for port 1 (errno=-16)      
pata_via 0000:00:09.1: no available native port 

Yoichi

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

* Re: [RFC PATCH v1 11/18] mips/PCI: get rid of device resource fixups
  2012-01-31  2:42   ` Yoichi Yuasa
@ 2012-01-31  2:42     ` Yoichi Yuasa
  2012-01-31  3:54     ` Bjorn Helgaas
  1 sibling, 0 replies; 57+ messages in thread
From: Yoichi Yuasa @ 2012-01-31  2:42 UTC (permalink / raw)
  To: Bjorn Helgaas; +Cc: yuasa, linux-pci, linux-arch, Ralf Baechle

Hi,

On Mon, 30 Jan 2012 09:58:05 -0700
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.
> 
> N.B. cobalt_legacy_ide_fixup() does scary things with resources, but I
> *think* it will still work because we're still making the same adjustments,
> just in the opposite order.  Here are the legacy IDE resource.start
> values I expect:
> 
>          current                                        new
> 
>            0x1f0   (pci_setup_device)                 0x1f0
>                    (pci_bus_to_resource)       + 0xf0000000
>     - 0xf0000000   (cobalt_legacy_ide_fixup)   - 0xf0000000
>     + 0xf0000000   (pcibios_fixup_bus)
>     ------------                               ------------
>            0x1f0    final value                       0x1f0

It seems to be unable to handle the offset correctly.

failed on Cobalt:

pata_via 0000:00:09.1: BAR 0: can't reserve [io  0x100001f0-0x100001f7]         
pata_via 0000:00:09.1: failed to request/iomap BARs for port 0 (errno=-16)      
pata_via 0000:00:09.1: BAR 2: can't reserve [io  0x10000170-0x10000177]         
pata_via 0000:00:09.1: failed to request/iomap BARs for port 1 (errno=-16)      
pata_via 0000:00:09.1: no available native port 

Yoichi

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

* Re: [RFC PATCH v1 11/18] mips/PCI: get rid of device resource fixups
  2012-01-31  2:42   ` Yoichi Yuasa
  2012-01-31  2:42     ` Yoichi Yuasa
@ 2012-01-31  3:54     ` Bjorn Helgaas
  2012-01-31  3:54       ` Bjorn Helgaas
  2012-02-08  2:56       ` Bjorn Helgaas
  1 sibling, 2 replies; 57+ messages in thread
From: Bjorn Helgaas @ 2012-01-31  3:54 UTC (permalink / raw)
  To: Yoichi Yuasa; +Cc: linux-pci, linux-arch, Ralf Baechle

On Mon, Jan 30, 2012 at 6:42 PM, Yoichi Yuasa <yuasa@linux-mips.org> wrote:
> Hi,
>
> On Mon, 30 Jan 2012 09:58:05 -0700
> 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.
>>
>> N.B. cobalt_legacy_ide_fixup() does scary things with resources, but I
>> *think* it will still work because we're still making the same adjustments,
>> just in the opposite order.  Here are the legacy IDE resource.start
>> values I expect:
>>
>>          current                                        new
>>
>>            0x1f0   (pci_setup_device)                 0x1f0
>>                    (pci_bus_to_resource)       + 0xf0000000
>>     - 0xf0000000   (cobalt_legacy_ide_fixup)   - 0xf0000000
>>     + 0xf0000000   (pcibios_fixup_bus)
>>     ------------                               ------------
>>            0x1f0    final value                       0x1f0
>
> It seems to be unable to handle the offset correctly.
>
> failed on Cobalt:
>
> pata_via 0000:00:09.1: BAR 0: can't reserve [io  0x100001f0-0x100001f7]
> pata_via 0000:00:09.1: failed to request/iomap BARs for port 0 (errno=-16)
> pata_via 0000:00:09.1: BAR 2: can't reserve [io  0x10000170-0x10000177]
> pata_via 0000:00:09.1: failed to request/iomap BARs for port 1 (errno=-16)
> pata_via 0000:00:09.1: no available native port

Thank you very much for testing this.  Could you collect the complete
dmesg and /proc/ioport contents, before and after my patches?

Bjorn

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

* Re: [RFC PATCH v1 11/18] mips/PCI: get rid of device resource fixups
  2012-01-31  3:54     ` Bjorn Helgaas
@ 2012-01-31  3:54       ` Bjorn Helgaas
  2012-02-08  2:56       ` Bjorn Helgaas
  1 sibling, 0 replies; 57+ messages in thread
From: Bjorn Helgaas @ 2012-01-31  3:54 UTC (permalink / raw)
  To: Yoichi Yuasa; +Cc: linux-pci, linux-arch, Ralf Baechle

On Mon, Jan 30, 2012 at 6:42 PM, Yoichi Yuasa <yuasa@linux-mips.org> wrote:
> Hi,
>
> On Mon, 30 Jan 2012 09:58:05 -0700
> 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.
>>
>> N.B. cobalt_legacy_ide_fixup() does scary things with resources, but I
>> *think* it will still work because we're still making the same adjustments,
>> just in the opposite order.  Here are the legacy IDE resource.start
>> values I expect:
>>
>>          current                                        new
>>
>>            0x1f0   (pci_setup_device)                 0x1f0
>>                    (pci_bus_to_resource)       + 0xf0000000
>>     - 0xf0000000   (cobalt_legacy_ide_fixup)   - 0xf0000000
>>     + 0xf0000000   (pcibios_fixup_bus)
>>     ------------                               ------------
>>            0x1f0    final value                       0x1f0
>
> It seems to be unable to handle the offset correctly.
>
> failed on Cobalt:
>
> pata_via 0000:00:09.1: BAR 0: can't reserve [io  0x100001f0-0x100001f7]
> pata_via 0000:00:09.1: failed to request/iomap BARs for port 0 (errno=-16)
> pata_via 0000:00:09.1: BAR 2: can't reserve [io  0x10000170-0x10000177]
> pata_via 0000:00:09.1: failed to request/iomap BARs for port 1 (errno=-16)
> pata_via 0000:00:09.1: no available native port

Thank you very much for testing this.  Could you collect the complete
dmesg and /proc/ioport contents, before and after my patches?

Bjorn

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

* Re: [RFC PATCH v1 10/18] microblaze/PCI: get rid of device resource fixups
  2012-01-30 16:58 ` [RFC PATCH v1 10/18] microblaze/PCI: " Bjorn Helgaas
  2012-01-30 16:58   ` Bjorn Helgaas
@ 2012-02-02 10:50   ` Michal Simek
  2012-02-02 10:50     ` Michal Simek
  2012-02-03 11:46     ` Benjamin Herrenschmidt
  1 sibling, 2 replies; 57+ messages in thread
From: Michal Simek @ 2012-02-02 10:50 UTC (permalink / raw)
  To: Bjorn Helgaas; +Cc: linux-pci, linux-arch

Hi,

Bjorn Helgaas wrote:
> Tell the PCI core about host bridge address translation so it can take
> care of bus-to-resource conversion for us.
> 
> N.B. We might need to tweak the I/O range and offset to account for the
> 32-bit mask previously used in pcibios_resource_to_bus().  I don't
> know the details of this mapping.  If anybody can help me test and
> fix this, please let me know.
> 
> CC: Michal Simek <monstr@monstr.eu>
> ---
>  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,
> 

I don't have any pci board for testing this. The most of things come from ppc.
We share pci IPs with xilinx ppc405/440.

Sorry that I can't help you with it and I have no problem with unification patches.
If someone has any problem with it can be bisected and solved in future.

Thanks,
Michal


-- 
Michal Simek, Ing. (M.Eng)
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel 2.6 Microblaze Linux - http://www.monstr.eu/fdt/
Microblaze U-BOOT custodian

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

* Re: [RFC PATCH v1 10/18] microblaze/PCI: get rid of device resource fixups
  2012-02-02 10:50   ` Michal Simek
@ 2012-02-02 10:50     ` Michal Simek
  2012-02-03 11:46     ` Benjamin Herrenschmidt
  1 sibling, 0 replies; 57+ messages in thread
From: Michal Simek @ 2012-02-02 10:50 UTC (permalink / raw)
  To: Bjorn Helgaas; +Cc: linux-pci, linux-arch

Hi,

Bjorn Helgaas wrote:
> Tell the PCI core about host bridge address translation so it can take
> care of bus-to-resource conversion for us.
> 
> N.B. We might need to tweak the I/O range and offset to account for the
> 32-bit mask previously used in pcibios_resource_to_bus().  I don't
> know the details of this mapping.  If anybody can help me test and
> fix this, please let me know.
> 
> CC: Michal Simek <monstr@monstr.eu>
> ---
>  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,
> 

I don't have any pci board for testing this. The most of things come from ppc.
We share pci IPs with xilinx ppc405/440.

Sorry that I can't help you with it and I have no problem with unification patches.
If someone has any problem with it can be bisected and solved in future.

Thanks,
Michal


-- 
Michal Simek, Ing. (M.Eng)
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel 2.6 Microblaze Linux - http://www.monstr.eu/fdt/
Microblaze U-BOOT custodian

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

* Re: [RFC PATCH v1 10/18] microblaze/PCI: get rid of device resource fixups
  2012-02-02 10:50   ` Michal Simek
  2012-02-02 10:50     ` Michal Simek
@ 2012-02-03 11:46     ` Benjamin Herrenschmidt
  2012-02-03 11:46       ` Benjamin Herrenschmidt
  1 sibling, 1 reply; 57+ messages in thread
From: Benjamin Herrenschmidt @ 2012-02-03 11:46 UTC (permalink / raw)
  To: monstr; +Cc: Bjorn Helgaas, linux-pci, linux-arch

On Thu, 2012-02-02 at 11:50 +0100, Michal Simek wrote:

> I don't have any pci board for testing this. The most of things come from ppc.
> We share pci IPs with xilinx ppc405/440.
> 
> Sorry that I can't help you with it and I have no problem with unification patches.
> If someone has any problem with it can be bisected and solved in future.

Yeah I'll have to test that one :-) Give me a few more days to sort out
some other stuff and I'll give this series a good go.

Cheers,
Ben.

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

* Re: [RFC PATCH v1 10/18] microblaze/PCI: get rid of device resource fixups
  2012-02-03 11:46     ` Benjamin Herrenschmidt
@ 2012-02-03 11:46       ` Benjamin Herrenschmidt
  0 siblings, 0 replies; 57+ messages in thread
From: Benjamin Herrenschmidt @ 2012-02-03 11:46 UTC (permalink / raw)
  To: monstr; +Cc: Bjorn Helgaas, linux-pci, linux-arch

On Thu, 2012-02-02 at 11:50 +0100, Michal Simek wrote:

> I don't have any pci board for testing this. The most of things come from ppc.
> We share pci IPs with xilinx ppc405/440.
> 
> Sorry that I can't help you with it and I have no problem with unification patches.
> If someone has any problem with it can be bisected and solved in future.

Yeah I'll have to test that one :-) Give me a few more days to sort out
some other stuff and I'll give this series a good go.

Cheers,
Ben.



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

* Re: [RFC PATCH v1 07/18] arm/PCI: get rid of device resource fixups
  2012-01-30 16:57 ` [RFC PATCH v1 07/18] arm/PCI: " Bjorn Helgaas
  2012-01-30 16:57   ` Bjorn Helgaas
@ 2012-02-03 16:01   ` Russell King - ARM Linux
  2012-02-03 16:01     ` Russell King - ARM Linux
  2012-02-03 16:12     ` Bjorn Helgaas
  1 sibling, 2 replies; 57+ messages in thread
From: Russell King - ARM Linux @ 2012-02-03 16:01 UTC (permalink / raw)
  To: Bjorn Helgaas; +Cc: linux-pci, linux-arch

On Mon, Jan 30, 2012 at 09:57:45AM -0700, Bjorn Helgaas wrote:
> Tell the PCI core about host bridge address translation so it can take
> care of bus-to-resource conversion for us.

Are the rest of these patches (in particular whereever is introduced
the generic versions) available somewhere?

Thanks.

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

* Re: [RFC PATCH v1 07/18] arm/PCI: get rid of device resource fixups
  2012-02-03 16:01   ` Russell King - ARM Linux
@ 2012-02-03 16:01     ` Russell King - ARM Linux
  2012-02-03 16:12     ` Bjorn Helgaas
  1 sibling, 0 replies; 57+ messages in thread
From: Russell King - ARM Linux @ 2012-02-03 16:01 UTC (permalink / raw)
  To: Bjorn Helgaas; +Cc: linux-pci, linux-arch

On Mon, Jan 30, 2012 at 09:57:45AM -0700, Bjorn Helgaas wrote:
> Tell the PCI core about host bridge address translation so it can take
> care of bus-to-resource conversion for us.

Are the rest of these patches (in particular whereever is introduced
the generic versions) available somewhere?

Thanks.

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

* Re: [RFC PATCH v1 07/18] arm/PCI: get rid of device resource fixups
  2012-02-03 16:01   ` Russell King - ARM Linux
  2012-02-03 16:01     ` Russell King - ARM Linux
@ 2012-02-03 16:12     ` Bjorn Helgaas
  2012-02-03 16:55       ` Russell King - ARM Linux
  1 sibling, 1 reply; 57+ messages in thread
From: Bjorn Helgaas @ 2012-02-03 16:12 UTC (permalink / raw)
  To: Russell King - ARM Linux; +Cc: linux-pci, linux-arch

On Fri, Feb 3, 2012 at 8:01 AM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> On Mon, Jan 30, 2012 at 09:57:45AM -0700, Bjorn Helgaas wrote:
>> Tell the PCI core about host bridge address translation so it can take
>> care of bus-to-resource conversion for us.
>
> Are the rest of these patches (in particular whereever is introduced
> the generic versions) available somewhere?

Oh, sorry, this doesn't mean much without the context.  Here's a
pointer to the overview, with a git tree and so on:

http://marc.info/?l=linux-arch&m=132794281821723&w=2

Bjorn

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

* Re: [RFC PATCH v1 07/18] arm/PCI: get rid of device resource fixups
  2012-02-03 16:12     ` Bjorn Helgaas
@ 2012-02-03 16:55       ` Russell King - ARM Linux
  2012-02-03 16:55         ` Russell King - ARM Linux
  2012-02-03 17:51         ` Bjorn Helgaas
  0 siblings, 2 replies; 57+ messages in thread
From: Russell King - ARM Linux @ 2012-02-03 16:55 UTC (permalink / raw)
  To: Bjorn Helgaas; +Cc: linux-pci, linux-arch

On Fri, Feb 03, 2012 at 08:12:02AM -0800, Bjorn Helgaas wrote:
> On Fri, Feb 3, 2012 at 8:01 AM, Russell King - ARM Linux
> <linux@arm.linux.org.uk> wrote:
> > On Mon, Jan 30, 2012 at 09:57:45AM -0700, Bjorn Helgaas wrote:
> >> Tell the PCI core about host bridge address translation so it can take
> >> care of bus-to-resource conversion for us.
> >
> > Are the rest of these patches (in particular whereever is introduced
> > the generic versions) available somewhere?
> 
> Oh, sorry, this doesn't mean much without the context.  Here's a
> pointer to the overview, with a git tree and so on:
> 
> http://marc.info/?l=linux-arch&m=132794281821723&w=2

Trying to read github in elinks isn't very nice.  But from what I could
see it looks fine.  When I get around to pulling my private patchsets
forward, I'll try to remember to give this a test.

The thing which was concerning me is that I have been carrying the
following patches for the last 10 years or more in various forms to
make PCMCIA work on a couple of platforms I have here.  It's more
or less the same problem, and it uses the bus_to_resource stuff to
fix it for Yenta.

These patches address PCMCIA's idea of 'lowmem' windows always being
at the low 640K of _CPU_ memory rather than the low 640K of _bus_
memory.  When your bus starts at an offset of more than 640K in CPU
memory, the resource handling doesn't work as well.

I've never pushed these upstream because I'm not entirely sure why
PCMCIA deals with lowmem windows on a card-by-card basis, rather than
a socket basis (surely its more to do with the capabilities of the
socket interface than the card itself...)

=== Patch 1 - generic bits ===

diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c
index 9da9656..8825c49 100644
--- a/drivers/pcmcia/rsrc_nonstatic.c
+++ b/drivers/pcmcia/rsrc_nonstatic.c
@@ -53,10 +53,17 @@ struct resource_map {
 	struct resource_map	*next;
 };
 
+struct resource_limit {
+	resource_size_t		start;
+	resource_size_t		end;
+};
+
 struct socket_data {
 	struct resource_map		mem_db;
 	struct resource_map		mem_db_valid;
 	struct resource_map		io_db;
+	struct resource_limit		low;
+	struct resource_limit		high;
 };
 
 #define MEM_PROBE_LOW	(1 << 0)
@@ -464,11 +471,11 @@ static u_long inv_probe(struct resource_map *m, struct pcmcia_socket *s)
 		return 0;
 	ok = inv_probe(m->next, s);
 	if (ok) {
-		if (m->base >= 0x100000)
+		if (m->base < s_data->low.start || m->base > s_data->low.end)
 			sub_interval(&s_data->mem_db, m->base, m->num);
 		return ok;
 	}
-	if (m->base < 0x100000)
+	if (m->base > s_data->low.start && m->base <= s_data->low.end)
 		return 0;
 	return do_mem_probe(s, m->base, m->num, readable, checksum);
 }
@@ -502,8 +509,8 @@ static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
 
 	for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {
 		mm = *m;
-		/* Only probe < 1 MB */
-		if (mm.base >= 0x100000)
+		/* Only probe low memory mappings */
+		if (mm.base < s_data->low.start || mm.base > s_data->low.end)
 			continue;
 		if ((mm.base | mm.num) & 0xffff) {
 			ok += do_mem_probe(s, mm.base, mm.num, readable,
@@ -512,7 +519,7 @@ static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
 		}
 		/* Special probe for 64K-aligned block */
 		for (i = 0; i < 4; i++) {
-			b = order[i] << 12;
+			b = s_data->low.start + (order[i] << 12);
 			if ((b >= mm.base) && (b+0x10000 <= mm.base+mm.num)) {
 				if (ok >= mem_limit)
 					sub_interval(&s_data->mem_db, b, 0x10000);
@@ -820,14 +827,13 @@ static struct resource *nonstatic_find_mem_region(u_long base, u_long num,
 	data.offset = base & data.mask;
 
 	for (i = 0; i < 2; i++) {
+		struct resource_limit *lim = low ? &s_data->low : &s_data->high;
+		max = lim->end;
+		min = lim->start + base;
+		if (min > max)
+			min = lim->start;
+
 		data.map = &s_data->mem_db_valid;
-		if (low) {
-			max = 0x100000UL;
-			min = base < max ? base : 0;
-		} else {
-			max = ~0UL;
-			min = 0x100000UL + base;
-		}
 
 		for (j = 0; j < 2; j++) {
 #ifdef CONFIG_PCI
@@ -1028,13 +1034,38 @@ static int nonstatic_init(struct pcmcia_socket *s)
 	data->mem_db_valid.next = &data->mem_db_valid;
 	data->io_db.next = &data->io_db;
 
+	/*
+	 * Setup the default resource limits
+	 */
+	data->low.start = 0;
+	data->low.end = 0xfffffUL;
+	data->high.start = 0x100000UL;
+	data->high.end = ~0UL;
+
 	s->resource_data = (void *) data;
 
+	if (s->ops->set_resource_limits)
+		s->ops->set_resource_limits(s);
+
 	nonstatic_autoadd_resources(s);
 
 	return 0;
 }
 
+void pccard_nonstatic_set_resource_limit(struct pcmcia_socket *s, int low,
+	resource_size_t start, resource_size_t end)
+{
+	struct socket_data *data = s->resource_data;
+	struct resource_limit *lim = low ? &data->low : &data->high;
+	lim->start = start;
+	lim->end = end;
+	dev_printk(KERN_INFO, &s->dev,
+		   "setting %s memory limit to 0x%08llx-0x%08llx\n",
+		   low ? "low" : "extended",
+		   (unsigned long long)start, (unsigned long long)end);
+}
+EXPORT_SYMBOL_GPL(pccard_nonstatic_set_resource_limit);
+
 static void nonstatic_release_resource_db(struct pcmcia_socket *s)
 {
 	struct socket_data *data = s->resource_data;
diff --git a/include/pcmcia/ss.h b/include/pcmcia/ss.h
index 731cde0..d358b16 100644
--- a/include/pcmcia/ss.h
+++ b/include/pcmcia/ss.h
@@ -128,6 +128,7 @@ struct pccard_operations {
 	int (*set_socket)(struct pcmcia_socket *s, socket_state_t *state);
 	int (*set_io_map)(struct pcmcia_socket *s, struct pccard_io_map *io);
 	int (*set_mem_map)(struct pcmcia_socket *s, struct pccard_mem_map *mem);
+	void (*set_resource_limits)(struct pcmcia_socket *s);
 };
 
 struct pcmcia_socket {
@@ -253,6 +254,8 @@ extern struct pccard_resource_ops pccard_nonstatic_ops;
 #define pccard_nonstatic_ops pccard_static_ops
 #endif
 
+void pccard_nonstatic_set_resource_limit(struct pcmcia_socket *s, int low,
+	resource_size_t start, resource_size_t end);
 
 /* socket drivers use this callback in their IRQ handler */
 extern void pcmcia_parse_events(struct pcmcia_socket *socket,

=== Patch 2 - yenta specific bits ===

diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c
index 9dc565c..8ed7b11 100644
--- a/drivers/pcmcia/yenta_socket.c
+++ b/drivers/pcmcia/yenta_socket.c
@@ -203,6 +203,21 @@ static ssize_t show_yenta_registers(struct device *yentadev, struct device_attri
 
 static DEVICE_ATTR(yenta_registers, S_IRUSR, show_yenta_registers, NULL);
 
+static void yenta_set_resource_limit(struct yenta_socket *s, int low,
+	resource_size_t start, resource_size_t end)
+{
+	struct pci_bus_region region;
+	struct resource res = {
+		.start = start,
+		.end = end,
+		.flags = IORESOURCE_MEM,
+	};
+
+	pcibios_resource_to_bus(s->dev, &region, &res);
+	pccard_nonstatic_set_resource_limit(&s->socket, low, region.start,
+					region.end);
+}
+
 /*
  * Ugh, mixed-mode cardbus and 16-bit pccard state: things depend
  * on what kind of card is inserted..
@@ -811,6 +826,14 @@ static void __devexit yenta_close(struct pci_dev *dev)
 	pci_set_drvdata(dev, NULL);
 }
 
+static void yenta_set_resource_limits(struct pcmcia_socket *s)
+{
+	struct yenta_socket *socket = container_of(s, struct yenta_socket, socket);
+
+	yenta_set_resource_limit(socket, 1, 0UL, 0xfffffUL);
+	yenta_set_resource_limit(socket, 0, 0x100000UL, ~0UL);
+}
+
 
 static struct pccard_operations yenta_socket_operations = {
 	.init			= yenta_sock_init,
@@ -819,6 +842,7 @@ static struct pccard_operations yenta_socket_operations = {
 	.set_socket		= yenta_set_socket,
 	.set_io_map		= yenta_set_io_map,
 	.set_mem_map		= yenta_set_mem_map,
+	.set_resource_limits	= yenta_set_resource_limits,
 };
 
 
=== Patch 3 - really fun i82365 bits, not PCI related but illustrates
  the same problem on a system without PCI but with an ISA PCMCIA
  controller offset in the system.  It also has some IRQ weirdness... ===

9d4189629d05c4091eb9b28504d83e3a6114d41d
diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c
index 72a033a..05c0ce4 100644
--- a/drivers/pcmcia/i82365.c
+++ b/drivers/pcmcia/i82365.c
@@ -60,6 +60,17 @@
 #include "vg468.h"
 #include "ricoh.h"
 
+#ifdef CONFIG_ARCH_EBSA110
+#include <mach/hardware.h>
+#define I365_MASK		(1 << 6)
+#define SOCKIRQ2REG(sock,irq)	((irq) ? ((sock) ? 3 : 4) : 0)
+#define RES_TO_I365(r)		((r) - ISAMEM_PHYS)
+#define BUS_TO_RESOURCE(x)	((x) + ISAMEM_PHYS)
+#else
+#define SOCKIRQ2REG(sock,irq)	(irq)
+#define RES_TO_I365(r)		(r)
+#define BUS_TO_RESOURCE(x)	(x)
+#endif
 
 static irqreturn_t i365_count_irq(int, void *);
 static inline int _check_irq(int irq, int flags)
@@ -162,7 +173,9 @@ static struct i82365_socket socket[8] = {
 };
 
 /* Default ISA interrupt mask */
+#ifndef I365_MASK
 #define I365_MASK	0xdeb8	/* irq 15,14,12,11,10,9,7,5,4,3 */
+#endif
 
 static int grab_irq;
 static DEFINE_SPINLOCK(isa_lock);
@@ -502,7 +515,7 @@ static u_int __init test_irq(u_short sock, int irq)
     }
 
     /* Generate one interrupt */
-    i365_set(sock, I365_CSCINT, I365_CSC_DETECT | (irq << 4));
+    i365_set(sock, I365_CSCINT, I365_CSC_DETECT | (SOCKIRQ2REG(sock, irq) << 4));
     i365_bset(sock, I365_GENCTL, I365_CTL_SW_IRQ);
     udelay(1000);
 
@@ -934,7 +947,7 @@ static int i365_set_socket(u_short sock, socket_state_t *state)
     
     /* IO card, RESET flag, IO interrupt */
     reg = t->intr;
-    reg |= state->io_irq;
+    reg |= SOCKIRQ2REG(sock, state->io_irq);
     reg |= (state->flags & SS_RESET) ? 0 : I365_PC_RESET;
     reg |= (state->flags & SS_IOCARD) ? I365_PC_IOCARD : 0;
     i365_set(sock, I365_INTCTL, reg);
@@ -1013,7 +1026,7 @@ static int i365_set_socket(u_short sock, socket_state_t *state)
     }
     
     /* Card status change interrupt mask */
-    reg = t->cs_irq << 4;
+    reg = SOCKIRQ2REG(sock, t->cs_irq) << 4;
     if (state->csc_mask & SS_DETECT) reg |= I365_CSC_DETECT;
     if (state->flags & SS_IOCARD) {
 	if (state->csc_mask & SS_STSCHG) reg |= I365_CSC_STSCHG;
@@ -1061,19 +1074,23 @@ static int i365_set_io_map(u_short sock, struct pccard_io_map *io)
 
 static int i365_set_mem_map(u_short sock, struct pccard_mem_map *mem)
 {
+    resource_size_t start, end;
     u_short base, i;
     u_char map;
-    
+
+    start = RES_TO_I365(mem->res->start);
+    end = RES_TO_I365(mem->res->end);
+
     pr_debug("SetMemMap(%d, %d, %#2.2x, %d ns, %#llx-%#llx, "
 	  "%#x)\n", sock, mem->map, mem->flags, mem->speed,
-	  (unsigned long long)mem->res->start,
-	  (unsigned long long)mem->res->end, mem->card_start);
+	  (unsigned long long)start,
+	  (unsigned long long)end, mem->card_start);
 
     map = mem->map;
     if ((map > 4) || (mem->card_start > 0x3ffffff) ||
-	(mem->res->start > mem->res->end) || (mem->speed > 1000))
+	(start > end) || (mem->speed > 1000))
 	return -EINVAL;
-    if ((mem->res->start > 0xffffff) || (mem->res->end > 0xffffff))
+    if ((start > 0xffffff) || (end > 0xffffff))
 	return -EINVAL;
 	
     /* Turn off the window before changing anything */
@@ -1081,12 +1098,12 @@ static int i365_set_mem_map(u_short sock, struct pccard_mem_map *mem)
 	i365_bclr(sock, I365_ADDRWIN, I365_ENA_MEM(map));
     
     base = I365_MEM(map);
-    i = (mem->res->start >> 12) & 0x0fff;
+    i = (start >> 12) & 0x0fff;
     if (mem->flags & MAP_16BIT) i |= I365_MEM_16BIT;
     if (mem->flags & MAP_0WS) i |= I365_MEM_0WS;
     i365_set_pair(sock, base+I365_W_START, i);
     
-    i = (mem->res->end >> 12) & 0x0fff;
+    i = (end >> 12) & 0x0fff;
     switch (to_cycles(mem->speed)) {
     case 0:	break;
     case 1:	i |= I365_MEM_WS0; break;
@@ -1095,7 +1112,7 @@ static int i365_set_mem_map(u_short sock, struct pccard_mem_map *mem)
     }
     i365_set_pair(sock, base+I365_W_STOP, i);
     
-    i = ((mem->card_start - mem->res->start) >> 12) & 0x3fff;
+    i = ((mem->card_start - start) >> 12) & 0x3fff;
     if (mem->flags & MAP_WRPROT) i |= I365_MEM_WRPROT;
     if (mem->flags & MAP_ATTRIB) i |= I365_MEM_REG;
     i365_set_pair(sock, base+I365_W_OFF, i);
@@ -1220,6 +1237,14 @@ static int pcic_init(struct pcmcia_socket *s)
 	return 0;
 }
 
+static void pcic_set_resource_limits(struct pcmcia_socket *s)
+{
+	pccard_nonstatic_set_resource_limit(s, 1,
+			BUS_TO_RESOURCE(0), BUS_TO_RESOURCE(0xfffffUL));
+	pccard_nonstatic_set_resource_limit(s, 0,
+			BUS_TO_RESOURCE(0x100000UL), ~0UL);
+}
+
 
 static struct pccard_operations pcic_operations = {
 	.init			= pcic_init,
@@ -1227,6 +1252,7 @@ static struct pccard_operations pcic_operations = {
 	.set_socket		= pcic_set_socket,
 	.set_io_map		= pcic_set_io_map,
 	.set_mem_map		= pcic_set_mem_map,
+	.set_resource_limits	= pcic_set_resource_limits,
 };
 
 /*====================================================================*/

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

* Re: [RFC PATCH v1 07/18] arm/PCI: get rid of device resource fixups
  2012-02-03 16:55       ` Russell King - ARM Linux
@ 2012-02-03 16:55         ` Russell King - ARM Linux
  2012-02-03 17:51         ` Bjorn Helgaas
  1 sibling, 0 replies; 57+ messages in thread
From: Russell King - ARM Linux @ 2012-02-03 16:55 UTC (permalink / raw)
  To: Bjorn Helgaas; +Cc: linux-pci, linux-arch

On Fri, Feb 03, 2012 at 08:12:02AM -0800, Bjorn Helgaas wrote:
> On Fri, Feb 3, 2012 at 8:01 AM, Russell King - ARM Linux
> <linux@arm.linux.org.uk> wrote:
> > On Mon, Jan 30, 2012 at 09:57:45AM -0700, Bjorn Helgaas wrote:
> >> Tell the PCI core about host bridge address translation so it can take
> >> care of bus-to-resource conversion for us.
> >
> > Are the rest of these patches (in particular whereever is introduced
> > the generic versions) available somewhere?
> 
> Oh, sorry, this doesn't mean much without the context.  Here's a
> pointer to the overview, with a git tree and so on:
> 
> http://marc.info/?l=linux-arch&m=132794281821723&w=2

Trying to read github in elinks isn't very nice.  But from what I could
see it looks fine.  When I get around to pulling my private patchsets
forward, I'll try to remember to give this a test.

The thing which was concerning me is that I have been carrying the
following patches for the last 10 years or more in various forms to
make PCMCIA work on a couple of platforms I have here.  It's more
or less the same problem, and it uses the bus_to_resource stuff to
fix it for Yenta.

These patches address PCMCIA's idea of 'lowmem' windows always being
at the low 640K of _CPU_ memory rather than the low 640K of _bus_
memory.  When your bus starts at an offset of more than 640K in CPU
memory, the resource handling doesn't work as well.

I've never pushed these upstream because I'm not entirely sure why
PCMCIA deals with lowmem windows on a card-by-card basis, rather than
a socket basis (surely its more to do with the capabilities of the
socket interface than the card itself...)

=== Patch 1 - generic bits ===

diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c
index 9da9656..8825c49 100644
--- a/drivers/pcmcia/rsrc_nonstatic.c
+++ b/drivers/pcmcia/rsrc_nonstatic.c
@@ -53,10 +53,17 @@ struct resource_map {
 	struct resource_map	*next;
 };
 
+struct resource_limit {
+	resource_size_t		start;
+	resource_size_t		end;
+};
+
 struct socket_data {
 	struct resource_map		mem_db;
 	struct resource_map		mem_db_valid;
 	struct resource_map		io_db;
+	struct resource_limit		low;
+	struct resource_limit		high;
 };
 
 #define MEM_PROBE_LOW	(1 << 0)
@@ -464,11 +471,11 @@ static u_long inv_probe(struct resource_map *m, struct pcmcia_socket *s)
 		return 0;
 	ok = inv_probe(m->next, s);
 	if (ok) {
-		if (m->base >= 0x100000)
+		if (m->base < s_data->low.start || m->base > s_data->low.end)
 			sub_interval(&s_data->mem_db, m->base, m->num);
 		return ok;
 	}
-	if (m->base < 0x100000)
+	if (m->base > s_data->low.start && m->base <= s_data->low.end)
 		return 0;
 	return do_mem_probe(s, m->base, m->num, readable, checksum);
 }
@@ -502,8 +509,8 @@ static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
 
 	for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {
 		mm = *m;
-		/* Only probe < 1 MB */
-		if (mm.base >= 0x100000)
+		/* Only probe low memory mappings */
+		if (mm.base < s_data->low.start || mm.base > s_data->low.end)
 			continue;
 		if ((mm.base | mm.num) & 0xffff) {
 			ok += do_mem_probe(s, mm.base, mm.num, readable,
@@ -512,7 +519,7 @@ static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
 		}
 		/* Special probe for 64K-aligned block */
 		for (i = 0; i < 4; i++) {
-			b = order[i] << 12;
+			b = s_data->low.start + (order[i] << 12);
 			if ((b >= mm.base) && (b+0x10000 <= mm.base+mm.num)) {
 				if (ok >= mem_limit)
 					sub_interval(&s_data->mem_db, b, 0x10000);
@@ -820,14 +827,13 @@ static struct resource *nonstatic_find_mem_region(u_long base, u_long num,
 	data.offset = base & data.mask;
 
 	for (i = 0; i < 2; i++) {
+		struct resource_limit *lim = low ? &s_data->low : &s_data->high;
+		max = lim->end;
+		min = lim->start + base;
+		if (min > max)
+			min = lim->start;
+
 		data.map = &s_data->mem_db_valid;
-		if (low) {
-			max = 0x100000UL;
-			min = base < max ? base : 0;
-		} else {
-			max = ~0UL;
-			min = 0x100000UL + base;
-		}
 
 		for (j = 0; j < 2; j++) {
 #ifdef CONFIG_PCI
@@ -1028,13 +1034,38 @@ static int nonstatic_init(struct pcmcia_socket *s)
 	data->mem_db_valid.next = &data->mem_db_valid;
 	data->io_db.next = &data->io_db;
 
+	/*
+	 * Setup the default resource limits
+	 */
+	data->low.start = 0;
+	data->low.end = 0xfffffUL;
+	data->high.start = 0x100000UL;
+	data->high.end = ~0UL;
+
 	s->resource_data = (void *) data;
 
+	if (s->ops->set_resource_limits)
+		s->ops->set_resource_limits(s);
+
 	nonstatic_autoadd_resources(s);
 
 	return 0;
 }
 
+void pccard_nonstatic_set_resource_limit(struct pcmcia_socket *s, int low,
+	resource_size_t start, resource_size_t end)
+{
+	struct socket_data *data = s->resource_data;
+	struct resource_limit *lim = low ? &data->low : &data->high;
+	lim->start = start;
+	lim->end = end;
+	dev_printk(KERN_INFO, &s->dev,
+		   "setting %s memory limit to 0x%08llx-0x%08llx\n",
+		   low ? "low" : "extended",
+		   (unsigned long long)start, (unsigned long long)end);
+}
+EXPORT_SYMBOL_GPL(pccard_nonstatic_set_resource_limit);
+
 static void nonstatic_release_resource_db(struct pcmcia_socket *s)
 {
 	struct socket_data *data = s->resource_data;
diff --git a/include/pcmcia/ss.h b/include/pcmcia/ss.h
index 731cde0..d358b16 100644
--- a/include/pcmcia/ss.h
+++ b/include/pcmcia/ss.h
@@ -128,6 +128,7 @@ struct pccard_operations {
 	int (*set_socket)(struct pcmcia_socket *s, socket_state_t *state);
 	int (*set_io_map)(struct pcmcia_socket *s, struct pccard_io_map *io);
 	int (*set_mem_map)(struct pcmcia_socket *s, struct pccard_mem_map *mem);
+	void (*set_resource_limits)(struct pcmcia_socket *s);
 };
 
 struct pcmcia_socket {
@@ -253,6 +254,8 @@ extern struct pccard_resource_ops pccard_nonstatic_ops;
 #define pccard_nonstatic_ops pccard_static_ops
 #endif
 
+void pccard_nonstatic_set_resource_limit(struct pcmcia_socket *s, int low,
+	resource_size_t start, resource_size_t end);
 
 /* socket drivers use this callback in their IRQ handler */
 extern void pcmcia_parse_events(struct pcmcia_socket *socket,

=== Patch 2 - yenta specific bits ===

diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c
index 9dc565c..8ed7b11 100644
--- a/drivers/pcmcia/yenta_socket.c
+++ b/drivers/pcmcia/yenta_socket.c
@@ -203,6 +203,21 @@ static ssize_t show_yenta_registers(struct device *yentadev, struct device_attri
 
 static DEVICE_ATTR(yenta_registers, S_IRUSR, show_yenta_registers, NULL);
 
+static void yenta_set_resource_limit(struct yenta_socket *s, int low,
+	resource_size_t start, resource_size_t end)
+{
+	struct pci_bus_region region;
+	struct resource res = {
+		.start = start,
+		.end = end,
+		.flags = IORESOURCE_MEM,
+	};
+
+	pcibios_resource_to_bus(s->dev, &region, &res);
+	pccard_nonstatic_set_resource_limit(&s->socket, low, region.start,
+					region.end);
+}
+
 /*
  * Ugh, mixed-mode cardbus and 16-bit pccard state: things depend
  * on what kind of card is inserted..
@@ -811,6 +826,14 @@ static void __devexit yenta_close(struct pci_dev *dev)
 	pci_set_drvdata(dev, NULL);
 }
 
+static void yenta_set_resource_limits(struct pcmcia_socket *s)
+{
+	struct yenta_socket *socket = container_of(s, struct yenta_socket, socket);
+
+	yenta_set_resource_limit(socket, 1, 0UL, 0xfffffUL);
+	yenta_set_resource_limit(socket, 0, 0x100000UL, ~0UL);
+}
+
 
 static struct pccard_operations yenta_socket_operations = {
 	.init			= yenta_sock_init,
@@ -819,6 +842,7 @@ static struct pccard_operations yenta_socket_operations = {
 	.set_socket		= yenta_set_socket,
 	.set_io_map		= yenta_set_io_map,
 	.set_mem_map		= yenta_set_mem_map,
+	.set_resource_limits	= yenta_set_resource_limits,
 };
 
 
=== Patch 3 - really fun i82365 bits, not PCI related but illustrates
  the same problem on a system without PCI but with an ISA PCMCIA
  controller offset in the system.  It also has some IRQ weirdness... ===

9d4189629d05c4091eb9b28504d83e3a6114d41d
diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c
index 72a033a..05c0ce4 100644
--- a/drivers/pcmcia/i82365.c
+++ b/drivers/pcmcia/i82365.c
@@ -60,6 +60,17 @@
 #include "vg468.h"
 #include "ricoh.h"
 
+#ifdef CONFIG_ARCH_EBSA110
+#include <mach/hardware.h>
+#define I365_MASK		(1 << 6)
+#define SOCKIRQ2REG(sock,irq)	((irq) ? ((sock) ? 3 : 4) : 0)
+#define RES_TO_I365(r)		((r) - ISAMEM_PHYS)
+#define BUS_TO_RESOURCE(x)	((x) + ISAMEM_PHYS)
+#else
+#define SOCKIRQ2REG(sock,irq)	(irq)
+#define RES_TO_I365(r)		(r)
+#define BUS_TO_RESOURCE(x)	(x)
+#endif
 
 static irqreturn_t i365_count_irq(int, void *);
 static inline int _check_irq(int irq, int flags)
@@ -162,7 +173,9 @@ static struct i82365_socket socket[8] = {
 };
 
 /* Default ISA interrupt mask */
+#ifndef I365_MASK
 #define I365_MASK	0xdeb8	/* irq 15,14,12,11,10,9,7,5,4,3 */
+#endif
 
 static int grab_irq;
 static DEFINE_SPINLOCK(isa_lock);
@@ -502,7 +515,7 @@ static u_int __init test_irq(u_short sock, int irq)
     }
 
     /* Generate one interrupt */
-    i365_set(sock, I365_CSCINT, I365_CSC_DETECT | (irq << 4));
+    i365_set(sock, I365_CSCINT, I365_CSC_DETECT | (SOCKIRQ2REG(sock, irq) << 4));
     i365_bset(sock, I365_GENCTL, I365_CTL_SW_IRQ);
     udelay(1000);
 
@@ -934,7 +947,7 @@ static int i365_set_socket(u_short sock, socket_state_t *state)
     
     /* IO card, RESET flag, IO interrupt */
     reg = t->intr;
-    reg |= state->io_irq;
+    reg |= SOCKIRQ2REG(sock, state->io_irq);
     reg |= (state->flags & SS_RESET) ? 0 : I365_PC_RESET;
     reg |= (state->flags & SS_IOCARD) ? I365_PC_IOCARD : 0;
     i365_set(sock, I365_INTCTL, reg);
@@ -1013,7 +1026,7 @@ static int i365_set_socket(u_short sock, socket_state_t *state)
     }
     
     /* Card status change interrupt mask */
-    reg = t->cs_irq << 4;
+    reg = SOCKIRQ2REG(sock, t->cs_irq) << 4;
     if (state->csc_mask & SS_DETECT) reg |= I365_CSC_DETECT;
     if (state->flags & SS_IOCARD) {
 	if (state->csc_mask & SS_STSCHG) reg |= I365_CSC_STSCHG;
@@ -1061,19 +1074,23 @@ static int i365_set_io_map(u_short sock, struct pccard_io_map *io)
 
 static int i365_set_mem_map(u_short sock, struct pccard_mem_map *mem)
 {
+    resource_size_t start, end;
     u_short base, i;
     u_char map;
-    
+
+    start = RES_TO_I365(mem->res->start);
+    end = RES_TO_I365(mem->res->end);
+
     pr_debug("SetMemMap(%d, %d, %#2.2x, %d ns, %#llx-%#llx, "
 	  "%#x)\n", sock, mem->map, mem->flags, mem->speed,
-	  (unsigned long long)mem->res->start,
-	  (unsigned long long)mem->res->end, mem->card_start);
+	  (unsigned long long)start,
+	  (unsigned long long)end, mem->card_start);
 
     map = mem->map;
     if ((map > 4) || (mem->card_start > 0x3ffffff) ||
-	(mem->res->start > mem->res->end) || (mem->speed > 1000))
+	(start > end) || (mem->speed > 1000))
 	return -EINVAL;
-    if ((mem->res->start > 0xffffff) || (mem->res->end > 0xffffff))
+    if ((start > 0xffffff) || (end > 0xffffff))
 	return -EINVAL;
 	
     /* Turn off the window before changing anything */
@@ -1081,12 +1098,12 @@ static int i365_set_mem_map(u_short sock, struct pccard_mem_map *mem)
 	i365_bclr(sock, I365_ADDRWIN, I365_ENA_MEM(map));
     
     base = I365_MEM(map);
-    i = (mem->res->start >> 12) & 0x0fff;
+    i = (start >> 12) & 0x0fff;
     if (mem->flags & MAP_16BIT) i |= I365_MEM_16BIT;
     if (mem->flags & MAP_0WS) i |= I365_MEM_0WS;
     i365_set_pair(sock, base+I365_W_START, i);
     
-    i = (mem->res->end >> 12) & 0x0fff;
+    i = (end >> 12) & 0x0fff;
     switch (to_cycles(mem->speed)) {
     case 0:	break;
     case 1:	i |= I365_MEM_WS0; break;
@@ -1095,7 +1112,7 @@ static int i365_set_mem_map(u_short sock, struct pccard_mem_map *mem)
     }
     i365_set_pair(sock, base+I365_W_STOP, i);
     
-    i = ((mem->card_start - mem->res->start) >> 12) & 0x3fff;
+    i = ((mem->card_start - start) >> 12) & 0x3fff;
     if (mem->flags & MAP_WRPROT) i |= I365_MEM_WRPROT;
     if (mem->flags & MAP_ATTRIB) i |= I365_MEM_REG;
     i365_set_pair(sock, base+I365_W_OFF, i);
@@ -1220,6 +1237,14 @@ static int pcic_init(struct pcmcia_socket *s)
 	return 0;
 }
 
+static void pcic_set_resource_limits(struct pcmcia_socket *s)
+{
+	pccard_nonstatic_set_resource_limit(s, 1,
+			BUS_TO_RESOURCE(0), BUS_TO_RESOURCE(0xfffffUL));
+	pccard_nonstatic_set_resource_limit(s, 0,
+			BUS_TO_RESOURCE(0x100000UL), ~0UL);
+}
+
 
 static struct pccard_operations pcic_operations = {
 	.init			= pcic_init,
@@ -1227,6 +1252,7 @@ static struct pccard_operations pcic_operations = {
 	.set_socket		= pcic_set_socket,
 	.set_io_map		= pcic_set_io_map,
 	.set_mem_map		= pcic_set_mem_map,
+	.set_resource_limits	= pcic_set_resource_limits,
 };
 
 /*====================================================================*/


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

* Re: [RFC PATCH v1 07/18] arm/PCI: get rid of device resource fixups
  2012-02-03 16:55       ` Russell King - ARM Linux
  2012-02-03 16:55         ` Russell King - ARM Linux
@ 2012-02-03 17:51         ` Bjorn Helgaas
  1 sibling, 0 replies; 57+ messages in thread
From: Bjorn Helgaas @ 2012-02-03 17:51 UTC (permalink / raw)
  To: Russell King - ARM Linux; +Cc: linux-pci, linux-arch

On Fri, Feb 3, 2012 at 8:55 AM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> On Fri, Feb 03, 2012 at 08:12:02AM -0800, Bjorn Helgaas wrote:
>> On Fri, Feb 3, 2012 at 8:01 AM, Russell King - ARM Linux
>> <linux@arm.linux.org.uk> wrote:
>> > On Mon, Jan 30, 2012 at 09:57:45AM -0700, Bjorn Helgaas wrote:
>> >> Tell the PCI core about host bridge address translation so it can take
>> >> care of bus-to-resource conversion for us.
>> >
>> > Are the rest of these patches (in particular whereever is introduced
>> > the generic versions) available somewhere?
>>
>> Oh, sorry, this doesn't mean much without the context.  Here's a
>> pointer to the overview, with a git tree and so on:
>>
>> http://marc.info/?l=linux-arch&m=132794281821723&w=2
>
> Trying to read github in elinks isn't very nice.  But from what I could
> see it looks fine.  When I get around to pulling my private patchsets
> forward, I'll try to remember to give this a test.

Thanks for taking a look.  Let me know if you find issues.

> The thing which was concerning me is that I have been carrying the
> following patches for the last 10 years or more in various forms to
> make PCMCIA work on a couple of platforms I have here.  It's more
> or less the same problem, and it uses the bus_to_resource stuff to
> fix it for Yenta.
>
> These patches address PCMCIA's idea of 'lowmem' windows always being
> at the low 640K of _CPU_ memory rather than the low 640K of _bus_
> memory.  When your bus starts at an offset of more than 640K in CPU
> memory, the resource handling doesn't work as well.

My patches only affect devices below a PCI host bridge, and from the
device's point of view, it should see no difference -- the values in
its BARs shouldn't change.

I know very little about PCMCIA.  The dependency on the CPU addresses
is interesting.   I would think such a dependency would mean we're
missing a bus/resource conversion somewhere, but it must be more
complicated than that.

But in any event, my *intent* is that neither CPU addresses nor bus
addresses should change.  If they do change, that's a bug in my
series.

> I've never pushed these upstream because I'm not entirely sure why
> PCMCIA deals with lowmem windows on a card-by-card basis, rather than
> a socket basis (surely its more to do with the capabilities of the
> socket interface than the card itself...)

Bjorn

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

* Re: [RFC PATCH v1 11/18] mips/PCI: get rid of device resource fixups
  2012-01-31  3:54     ` Bjorn Helgaas
  2012-01-31  3:54       ` Bjorn Helgaas
@ 2012-02-08  2:56       ` Bjorn Helgaas
  2012-02-08  2:56         ` Bjorn Helgaas
       [not found]         ` <20120208132234.710f19be.yuasa@linux-mips.org>
  1 sibling, 2 replies; 57+ messages in thread
From: Bjorn Helgaas @ 2012-02-08  2:56 UTC (permalink / raw)
  To: Yoichi Yuasa; +Cc: linux-pci, linux-arch, Ralf Baechle

On Mon, Jan 30, 2012 at 7:54 PM, Bjorn Helgaas <bhelgaas@google.com> wrote:
> On Mon, Jan 30, 2012 at 6:42 PM, Yoichi Yuasa <yuasa@linux-mips.org> wrote:
>> Hi,
>>
>> On Mon, 30 Jan 2012 09:58:05 -0700
>> 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.
>>>
>>> N.B. cobalt_legacy_ide_fixup() does scary things with resources, but I
>>> *think* it will still work because we're still making the same adjustments,
>>> just in the opposite order.  Here are the legacy IDE resource.start
>>> values I expect:
>>>
>>>          current                                        new
>>>
>>>            0x1f0   (pci_setup_device)                 0x1f0
>>>                    (pci_bus_to_resource)       + 0xf0000000
>>>     - 0xf0000000   (cobalt_legacy_ide_fixup)   - 0xf0000000
>>>     + 0xf0000000   (pcibios_fixup_bus)
>>>     ------------                               ------------
>>>            0x1f0    final value                       0x1f0
>>
>> It seems to be unable to handle the offset correctly.
>>
>> failed on Cobalt:
>>
>> pata_via 0000:00:09.1: BAR 0: can't reserve [io  0x100001f0-0x100001f7]
>> pata_via 0000:00:09.1: failed to request/iomap BARs for port 0 (errno=-16)
>> pata_via 0000:00:09.1: BAR 2: can't reserve [io  0x10000170-0x10000177]
>> pata_via 0000:00:09.1: failed to request/iomap BARs for port 1 (errno=-16)
>> pata_via 0000:00:09.1: no available native port
>
> Thank you very much for testing this.  Could you collect the complete
> dmesg and /proc/ioport contents, before and after my patches?

Ping :)  I'll try to figure this out, but it would be easier if I had
the info mentioned above.  Thanks!

Bjorn

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

* Re: [RFC PATCH v1 11/18] mips/PCI: get rid of device resource fixups
  2012-02-08  2:56       ` Bjorn Helgaas
@ 2012-02-08  2:56         ` Bjorn Helgaas
       [not found]         ` <20120208132234.710f19be.yuasa@linux-mips.org>
  1 sibling, 0 replies; 57+ messages in thread
From: Bjorn Helgaas @ 2012-02-08  2:56 UTC (permalink / raw)
  To: Yoichi Yuasa; +Cc: linux-pci, linux-arch, Ralf Baechle

On Mon, Jan 30, 2012 at 7:54 PM, Bjorn Helgaas <bhelgaas@google.com> wrote:
> On Mon, Jan 30, 2012 at 6:42 PM, Yoichi Yuasa <yuasa@linux-mips.org> wrote:
>> Hi,
>>
>> On Mon, 30 Jan 2012 09:58:05 -0700
>> 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.
>>>
>>> N.B. cobalt_legacy_ide_fixup() does scary things with resources, but I
>>> *think* it will still work because we're still making the same adjustments,
>>> just in the opposite order.  Here are the legacy IDE resource.start
>>> values I expect:
>>>
>>>          current                                        new
>>>
>>>            0x1f0   (pci_setup_device)                 0x1f0
>>>                    (pci_bus_to_resource)       + 0xf0000000
>>>     - 0xf0000000   (cobalt_legacy_ide_fixup)   - 0xf0000000
>>>     + 0xf0000000   (pcibios_fixup_bus)
>>>     ------------                               ------------
>>>            0x1f0    final value                       0x1f0
>>
>> It seems to be unable to handle the offset correctly.
>>
>> failed on Cobalt:
>>
>> pata_via 0000:00:09.1: BAR 0: can't reserve [io  0x100001f0-0x100001f7]
>> pata_via 0000:00:09.1: failed to request/iomap BARs for port 0 (errno=-16)
>> pata_via 0000:00:09.1: BAR 2: can't reserve [io  0x10000170-0x10000177]
>> pata_via 0000:00:09.1: failed to request/iomap BARs for port 1 (errno=-16)
>> pata_via 0000:00:09.1: no available native port
>
> Thank you very much for testing this.  Could you collect the complete
> dmesg and /proc/ioport contents, before and after my patches?

Ping :)  I'll try to figure this out, but it would be easier if I had
the info mentioned above.  Thanks!

Bjorn

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

* Re: [RFC PATCH v1 11/18] mips/PCI: get rid of device resource fixups
       [not found]         ` <20120208132234.710f19be.yuasa@linux-mips.org>
@ 2012-02-08 21:16           ` Bjorn Helgaas
  0 siblings, 0 replies; 57+ messages in thread
From: Bjorn Helgaas @ 2012-02-08 21:16 UTC (permalink / raw)
  To: Yoichi Yuasa, linux-arch, linux-pci, Ralf Baechle

On Tue, Feb 7, 2012 at 8:22 PM, Yoichi Yuasa <yuasa@linux-mips.org> wrote:
> Hi,
>
> On Tue, 7 Feb 2012 18:56:46 -0800
> Bjorn Helgaas <bhelgaas@google.com> wrote:
>
>> On Mon, Jan 30, 2012 at 7:54 PM, Bjorn Helgaas <bhelgaas@google.com> wrote:
>> > On Mon, Jan 30, 2012 at 6:42 PM, Yoichi Yuasa <yuasa@linux-mips.org> wrote:
>> >> Hi,
>> >>
>> >> On Mon, 30 Jan 2012 09:58:05 -0700
>> >> 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.
>> >>>
>> >>> N.B. cobalt_legacy_ide_fixup() does scary things with resources, but I
>> >>> *think* it will still work because we're still making the same adjustments,
>> >>> just in the opposite order.  Here are the legacy IDE resource.start
>> >>> values I expect:
>> >>>
>> >>>          current                                        new
>> >>>
>> >>>            0x1f0   (pci_setup_device)                 0x1f0
>> >>>                    (pci_bus_to_resource)       + 0xf0000000
>> >>>     - 0xf0000000   (cobalt_legacy_ide_fixup)   - 0xf0000000
>> >>>     + 0xf0000000   (pcibios_fixup_bus)
>> >>>     ------------                               ------------
>> >>>            0x1f0    final value                       0x1f0
>> >>
>> >> It seems to be unable to handle the offset correctly.
>> >>
>> >> failed on Cobalt:
>> >>
>> >> pata_via 0000:00:09.1: BAR 0: can't reserve [io  0x100001f0-0x100001f7]
>> >> pata_via 0000:00:09.1: failed to request/iomap BARs for port 0 (errno=-16)
>> >> pata_via 0000:00:09.1: BAR 2: can't reserve [io  0x10000170-0x10000177]
>> >> pata_via 0000:00:09.1: failed to request/iomap BARs for port 1 (errno=-16)
>> >> pata_via 0000:00:09.1: no available native port
>> >
>> > Thank you very much for testing this.  Could you collect the complete
>> > dmesg and /proc/ioport contents, before and after my patches?
>>
>> Ping :)  I'll try to figure this out, but it would be easier if I had
>> the info mentioned above.  Thanks!
>
> It cannot mount rootfs with your patches.
> I cannot get /proc/ioports yet.
>
> I attach only boot logs.

Ah, I see the trouble.  The original MIPS pcibios_fixup_bus() applied
the io_offset to all IORESOURE_IO resources, but the generic
pcibios_bus_to_resource() only applies the offset to things that are
in the host bridge's window.

The legacy IDE addresses aren't in the window, so we didn't apply the
offset, and it didn't work.

I'll rework this and update my patches.

Thanks!

Bjorn

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

end of thread, other threads:[~2012-02-08 21:17 UTC | newest]

Thread overview: 57+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-01-30 16:57 [RFC PATCH v1 00/18] add PCI bus-to-resource offset support in core Bjorn Helgaas
2012-01-30 16:57 ` Bjorn Helgaas
2012-01-30 16:57 ` [RFC PATCH v1 01/18] PCI: don't publish new root bus until it's fully initialized Bjorn Helgaas
2012-01-30 16:57   ` Bjorn Helgaas
2012-01-30 16:57 ` [RFC PATCH v1 02/18] PCI: add struct pci_host_bridge and a list of all bridges found Bjorn Helgaas
2012-01-30 16:57   ` Bjorn Helgaas
2012-01-30 20:52   ` Yinghai Lu
2012-01-30 20:52     ` Yinghai Lu
2012-01-30 22:00     ` Bjorn Helgaas
2012-01-30 22:00       ` Bjorn Helgaas
2012-01-30 22:29       ` Yinghai Lu
2012-01-30 22:29         ` Yinghai Lu
2012-01-30 16:57 ` [RFC PATCH v1 03/18] PCI: add struct pci_host_bridge_window with CPU/bus address offset Bjorn Helgaas
2012-01-30 16:57   ` Bjorn Helgaas
2012-01-30 16:57 ` [RFC PATCH v1 04/18] PCI: convert bus addresses to resource when reading BARs Bjorn Helgaas
2012-01-30 16:57 ` [RFC PATCH v1 05/18] PCI: add generic pcibios_resource_to_bus() Bjorn Helgaas
2012-01-30 16:57 ` [RFC PATCH v1 06/18] alpha/PCI: get rid of device resource fixups Bjorn Helgaas
2012-01-30 16:57   ` Bjorn Helgaas
2012-01-30 16:57 ` [RFC PATCH v1 07/18] arm/PCI: " Bjorn Helgaas
2012-01-30 16:57   ` Bjorn Helgaas
2012-02-03 16:01   ` Russell King - ARM Linux
2012-02-03 16:01     ` Russell King - ARM Linux
2012-02-03 16:12     ` Bjorn Helgaas
2012-02-03 16:55       ` Russell King - ARM Linux
2012-02-03 16:55         ` Russell King - ARM Linux
2012-02-03 17:51         ` Bjorn Helgaas
2012-01-30 16:57 ` [RFC PATCH v1 08/18] ia64/PCI: SN: convert to pci_scan_root_bus() for correct root bus resources Bjorn Helgaas
2012-01-30 16:57 ` [RFC PATCH v1 09/18] ia64/PCI: get rid of device resource fixups Bjorn Helgaas
2012-01-30 16:57   ` Bjorn Helgaas
2012-01-30 16:58 ` [RFC PATCH v1 10/18] microblaze/PCI: " Bjorn Helgaas
2012-01-30 16:58   ` Bjorn Helgaas
2012-02-02 10:50   ` Michal Simek
2012-02-02 10:50     ` Michal Simek
2012-02-03 11:46     ` Benjamin Herrenschmidt
2012-02-03 11:46       ` Benjamin Herrenschmidt
2012-01-30 16:58 ` [RFC PATCH v1 11/18] mips/PCI: " Bjorn Helgaas
2012-01-30 16:58   ` Bjorn Helgaas
2012-01-31  2:42   ` Yoichi Yuasa
2012-01-31  2:42     ` Yoichi Yuasa
2012-01-31  3:54     ` Bjorn Helgaas
2012-01-31  3:54       ` Bjorn Helgaas
2012-02-08  2:56       ` Bjorn Helgaas
2012-02-08  2:56         ` Bjorn Helgaas
     [not found]         ` <20120208132234.710f19be.yuasa@linux-mips.org>
2012-02-08 21:16           ` Bjorn Helgaas
2012-01-30 16:58 ` [RFC PATCH v1 12/18] mn10300/PCI: " Bjorn Helgaas
2012-01-30 16:58   ` Bjorn Helgaas
2012-01-30 16:58 ` [RFC PATCH v1 13/18] parisc/PCI: " Bjorn Helgaas
2012-01-30 16:58   ` Bjorn Helgaas
2012-01-30 16:58 ` [RFC PATCH v1 14/18] powerpc/PCI: " Bjorn Helgaas
2012-01-30 20:49   ` Benjamin Herrenschmidt
2012-01-30 21:46     ` Bjorn Helgaas
2012-01-30 21:46       ` Bjorn Helgaas
2012-01-30 16:58 ` [RFC PATCH v1 15/18] sh/PCI: " Bjorn Helgaas
2012-01-30 16:58 ` [RFC PATCH v1 16/18] sparc/PCI: " Bjorn Helgaas
2012-01-30 16:58 ` [RFC PATCH v1 17/18] xtensa/PCI: " Bjorn Helgaas
2012-01-30 16:58   ` Bjorn Helgaas
2012-01-30 16:58 ` [RFC PATCH v1 18/18] PCI: collapse pcibios_resource_to_bus Bjorn Helgaas

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).