[PATCH v3 7/7] PCI: reference bridge window resources explicitly

Bjorn Helgaas bjorn.helgaas at hp.com
Sat Feb 13 04:00:23 EST 2010


No functional change; just be more explicit about this mapping for
bridge resources:

  bridge->res[PCI_BRIDGE_RESOURCES+0]: I/O window (or CB I/O 0 window)
  bridge->res[PCI_BRIDGE_RESOURCES+1]: mem window (or CB I/O 1 window)
  bridge->res[PCI_BRIDGE_RESOURCES+2]: pref mem window (or CB mem 0 window)
  bridge->res[PCI_BRIDGE_RESOURCES+3]: CB mem 1 window

Signed-off-by: Bjorn Helgaas <bjorn.helgaas at hp.com>
---

 arch/powerpc/kernel/pci_64.c      |    4 +--
 arch/powerpc/kernel/pci_of_scan.c |    9 ++++--
 drivers/pci/probe.c               |    6 ++--
 drivers/pci/quirks.c              |    4 +--
 drivers/pci/setup-bus.c           |   57 +++++++++++++++++++++----------------
 drivers/pcmcia/yenta_socket.c     |   39 +++++++++++++++----------
 include/linux/pci.h               |   11 ++++++-
 7 files changed, 78 insertions(+), 52 deletions(-)


diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index 155a2bf..044a4bd 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -99,7 +99,7 @@ int pcibios_unmap_io_space(struct pci_bus *bus)
 	 */
 	if (bridge) {
 #ifdef CONFIG_PPC_STD_MMU_64
-		struct resource *res = &bridge->resource[PCI_BRIDGE_RESOURCES + 0];
+		struct resource *res = &bridge->resource[PCI_BRIDGE_IO_WINDOW];
 #endif
 
 		pr_debug("IO unmapping for PCI-PCI bridge %s\n",
@@ -146,7 +146,7 @@ int __devinit pcibios_map_io_space(struct pci_bus *bus)
 	 * thus HPTEs will be faulted in when needed
 	 */
 	if (bridge) {
-		struct resource *res = &bridge->resource[PCI_BRIDGE_RESOURCES + 0];
+		struct resource *res = &bridge->resource[PCI_BRIDGE_IO_WINDOW];
 
 		pr_debug("IO mapping for PCI-PCI bridge %s\n",
 			 pci_name(bridge));
diff --git a/arch/powerpc/kernel/pci_of_scan.c b/arch/powerpc/kernel/pci_of_scan.c
index 521ad52..39487c3 100644
--- a/arch/powerpc/kernel/pci_of_scan.c
+++ b/arch/powerpc/kernel/pci_of_scan.c
@@ -256,19 +256,22 @@ void __devinit of_scan_pci_bridge(struct device_node *node,
 		if (flags == 0 || size == 0)
 			continue;
 		if (flags & IORESOURCE_IO) {
-			res = &dev->resource[PCI_BRIDGE_RESOURCES + 0];
+			res = &dev->resource[PCI_BRIDGE_IO_WINDOW];
 			if (res->flags) {
 				printk(KERN_ERR "PCI: ignoring extra I/O range"
 				       " for bridge %s\n", node->full_name);
 				continue;
 			}
 		} else {
-			if (i >= PCI_NUM_RESOURCES - PCI_BRIDGE_RESOURCES) {
+			if (i == 1)
+				res = &dev->resource[PCI_BRIDGE_MEM_WINDOW];
+			else if (i == 2)
+				res = &dev->resource[PCI_BRIDGE_PREF_MEM_WINDOW];
+			else {
 				printk(KERN_ERR "PCI: too many memory ranges"
 				       " for bridge %s\n", node->full_name);
 				continue;
 			}
-			res = &dev->resource[PCI_BRIDGE_RESOURCES + i];
 			++i;
 		}
 		res->start = of_read_number(&ranges[1], 2);
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 04e7e97..6d693fb 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -289,7 +289,7 @@ static void __devinit pci_read_bridge_io(struct pci_bus *child)
 	unsigned long base, limit;
 	struct resource *res;
 
-	res = &dev->resource[PCI_BRIDGE_RESOURCES + 0];
+	res = &dev->resource[PCI_BRIDGE_IO_WINDOW];
 
 	pci_read_config_byte(dev, PCI_IO_BASE, &io_base_lo);
 	pci_read_config_byte(dev, PCI_IO_LIMIT, &io_limit_lo);
@@ -325,7 +325,7 @@ static void __devinit pci_read_bridge_mmio(struct pci_bus *child)
 	unsigned long base, limit;
 	struct resource *res;
 
-	res = &dev->resource[PCI_BRIDGE_RESOURCES + 1];
+	res = &dev->resource[PCI_BRIDGE_MEM_WINDOW];
 
 	pci_read_config_word(dev, PCI_MEMORY_BASE, &mem_base_lo);
 	pci_read_config_word(dev, PCI_MEMORY_LIMIT, &mem_limit_lo);
@@ -350,7 +350,7 @@ static void __devinit pci_read_bridge_mmio_pref(struct pci_bus *child)
 	unsigned long base, limit;
 	struct resource *res;
 
-	res = &dev->resource[PCI_BRIDGE_RESOURCES + 2];
+	res = &dev->resource[PCI_BRIDGE_PREF_MEM_WINDOW];
 
 	pci_read_config_word(dev, PCI_PREF_MEMORY_BASE, &mem_base_lo);
 	pci_read_config_word(dev, PCI_PREF_MEMORY_LIMIT, &mem_limit_lo);
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 790eb69..197c6c6 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -1907,7 +1907,7 @@ static void __devinit quirk_p64h2_1k_io(struct pci_dev *dev)
 	u16 en1k;
 	u8 io_base_lo, io_limit_lo;
 	unsigned long base, limit;
-	struct resource *res = dev->resource + PCI_BRIDGE_RESOURCES;
+	struct resource *res = &dev->resource[PCI_BRIDGE_IO_WINDOW];
 
 	pci_read_config_word(dev, 0x40, &en1k);
 
@@ -1934,7 +1934,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,	0x1460,		quirk_p64h2_1k_io);
 static void __devinit quirk_p64h2_1k_io_fix_iobl(struct pci_dev *dev)
 {
 	u16 en1k, iobl_adr, iobl_adr_1k;
-	struct resource *res = dev->resource + PCI_BRIDGE_RESOURCES;
+	struct resource *res = &dev->resource[PCI_BRIDGE_IO_WINDOW];
 
 	pci_read_config_word(dev, 0x40, &en1k);
 
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 8a3b512..182fe54 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -324,8 +324,7 @@ static void pci_bridge_check_ranges(struct pci_bus *bus)
 	struct pci_dev *bridge = bus->self;
 	struct resource *b_res;
 
-	b_res = &bridge->resource[PCI_BRIDGE_RESOURCES];
-	b_res[1].flags |= IORESOURCE_MEM;
+	bridge->resource[PCI_BRIDGE_MEM_WINDOW].flags |= IORESOURCE_MEM;
 
 	pci_read_config_word(bridge, PCI_IO_BASE, &io);
 	if (!io) {
@@ -334,12 +333,15 @@ static void pci_bridge_check_ranges(struct pci_bus *bus)
  		pci_write_config_word(bridge, PCI_IO_BASE, 0x0);
  	}
  	if (io)
-		b_res[0].flags |= IORESOURCE_IO;
+		bridge->resource[PCI_BRIDGE_IO_WINDOW].flags |= IORESOURCE_IO;
+
 	/*  DECchip 21050 pass 2 errata: the bridge may miss an address
 	    disconnect boundary by one PCI data phase.
 	    Workaround: do not use prefetching on this device. */
 	if (bridge->vendor == PCI_VENDOR_ID_DEC && bridge->device == 0x0001)
 		return;
+
+	b_res = &bridge->resource[PCI_BRIDGE_PREF_MEM_WINDOW];
 	pci_read_config_dword(bridge, PCI_PREF_MEMORY_BASE, &pmem);
 	if (!pmem) {
 		pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE,
@@ -348,16 +350,16 @@ static void pci_bridge_check_ranges(struct pci_bus *bus)
 		pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, 0x0);
 	}
 	if (pmem) {
-		b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH;
+		b_res->flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH;
 		if ((pmem & PCI_PREF_RANGE_TYPE_MASK) ==
 		    PCI_PREF_RANGE_TYPE_64) {
-			b_res[2].flags |= IORESOURCE_MEM_64;
-			b_res[2].flags |= PCI_PREF_RANGE_TYPE_64;
+			b_res->flags |= IORESOURCE_MEM_64;
+			b_res->flags |= PCI_PREF_RANGE_TYPE_64;
 		}
 	}
 
 	/* double check if bridge does support 64 bit pref */
-	if (b_res[2].flags & IORESOURCE_MEM_64) {
+	if (b_res->flags & IORESOURCE_MEM_64) {
 		u32 mem_base_hi, tmp;
 		pci_read_config_dword(bridge, PCI_PREF_BASE_UPPER32,
 					 &mem_base_hi);
@@ -365,7 +367,7 @@ static void pci_bridge_check_ranges(struct pci_bus *bus)
 					       0xffffffff);
 		pci_read_config_dword(bridge, PCI_PREF_BASE_UPPER32, &tmp);
 		if (!tmp)
-			b_res[2].flags &= ~IORESOURCE_MEM_64;
+			b_res->flags &= ~IORESOURCE_MEM_64;
 		pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32,
 				       mem_base_hi);
 	}
@@ -544,20 +546,22 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
 static void pci_bus_size_cardbus(struct pci_bus *bus)
 {
 	struct pci_dev *bridge = bus->self;
-	struct resource *b_res = &bridge->resource[PCI_BRIDGE_RESOURCES];
+	struct resource *b_res;
 	u16 ctrl;
 
 	/*
 	 * Reserve some resources for CardBus.  We reserve
 	 * a fixed amount of bus space for CardBus bridges.
 	 */
-	b_res[0].start = 0;
-	b_res[0].end = pci_cardbus_io_size - 1;
-	b_res[0].flags |= IORESOURCE_IO | IORESOURCE_SIZEALIGN;
+	b_res = &bridge->resource[PCI_CB_BRIDGE_IO_0_WINDOW];
+	b_res->start = 0;
+	b_res->end = pci_cardbus_io_size - 1;
+	b_res->flags |= IORESOURCE_IO | IORESOURCE_SIZEALIGN;
 
-	b_res[1].start = 0;
-	b_res[1].end = pci_cardbus_io_size - 1;
-	b_res[1].flags |= IORESOURCE_IO | IORESOURCE_SIZEALIGN;
+	b_res = &bridge->resource[PCI_CB_BRIDGE_IO_1_WINDOW];
+	b_res->start = 0;
+	b_res->end = pci_cardbus_io_size - 1;
+	b_res->flags |= IORESOURCE_IO | IORESOURCE_SIZEALIGN;
 
 	/*
 	 * Check whether prefetchable memory is supported
@@ -576,17 +580,20 @@ static void pci_bus_size_cardbus(struct pci_bus *bus)
 	 * twice the size.
 	 */
 	if (ctrl & PCI_CB_BRIDGE_CTL_PREFETCH_MEM0) {
-		b_res[2].start = 0;
-		b_res[2].end = pci_cardbus_mem_size - 1;
-		b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH | IORESOURCE_SIZEALIGN;
-
-		b_res[3].start = 0;
-		b_res[3].end = pci_cardbus_mem_size - 1;
-		b_res[3].flags |= IORESOURCE_MEM | IORESOURCE_SIZEALIGN;
+		b_res = &bridge->resource[PCI_CB_BRIDGE_MEM_0_WINDOW];
+		b_res->start = 0;
+		b_res->end = pci_cardbus_mem_size - 1;
+		b_res->flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH | IORESOURCE_SIZEALIGN;
+
+		b_res = &bridge->resource[PCI_CB_BRIDGE_MEM_1_WINDOW];
+		b_res->start = 0;
+		b_res->end = pci_cardbus_mem_size - 1;
+		b_res->flags |= IORESOURCE_MEM | IORESOURCE_SIZEALIGN;
 	} else {
-		b_res[3].start = 0;
-		b_res[3].end = pci_cardbus_mem_size * 2 - 1;
-		b_res[3].flags |= IORESOURCE_MEM | IORESOURCE_SIZEALIGN;
+		b_res = &bridge->resource[PCI_CB_BRIDGE_MEM_1_WINDOW];
+		b_res->start = 0;
+		b_res->end = pci_cardbus_mem_size * 2 - 1;
+		b_res->flags |= IORESOURCE_MEM | IORESOURCE_SIZEALIGN;
 	}
 }
 
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c
index 9c5a80e..dc55592 100644
--- a/drivers/pcmcia/yenta_socket.c
+++ b/drivers/pcmcia/yenta_socket.c
@@ -673,7 +673,7 @@ static int yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned type
 	struct pci_bus_region region;
 	unsigned mask;
 
-	res = dev->resource + PCI_BRIDGE_RESOURCES + nr;
+	res = &dev->resource[nr];
 	/* Already allocated? */
 	if (res->parent)
 		return 0;
@@ -690,7 +690,7 @@ static int yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned type
 	region.end = config_readl(socket, addr_end) | ~mask;
 	if (region.start && region.end > region.start && !override_bios) {
 		pcibios_bus_to_resource(dev, res, &region);
-		if (pci_claim_resource(dev, PCI_BRIDGE_RESOURCES + nr) == 0)
+		if (pci_claim_resource(dev, nr) == 0)
 			return 0;
 		dev_printk(KERN_INFO, &dev->dev,
 			   "Preassigned resource %d busy or not available, "
@@ -731,32 +731,39 @@ static int yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned type
 static void yenta_allocate_resources(struct yenta_socket *socket)
 {
 	int program = 0;
-	program += yenta_allocate_res(socket, 0, IORESOURCE_IO,
-			   PCI_CB_IO_BASE_0, PCI_CB_IO_LIMIT_0);
-	program += yenta_allocate_res(socket, 1, IORESOURCE_IO,
-			   PCI_CB_IO_BASE_1, PCI_CB_IO_LIMIT_1);
-	program += yenta_allocate_res(socket, 2, IORESOURCE_MEM|IORESOURCE_PREFETCH,
+	program += yenta_allocate_res(socket, PCI_CB_BRIDGE_IO_0_WINDOW,
+			   IORESOURCE_IO, PCI_CB_IO_BASE_0, PCI_CB_IO_LIMIT_0);
+	program += yenta_allocate_res(socket, PCI_CB_BRIDGE_IO_1_WINDOW,
+			   IORESOURCE_IO, PCI_CB_IO_BASE_1, PCI_CB_IO_LIMIT_1);
+	program += yenta_allocate_res(socket, PCI_CB_BRIDGE_MEM_0_WINDOW,
+			   IORESOURCE_MEM|IORESOURCE_PREFETCH,
 			   PCI_CB_MEMORY_BASE_0, PCI_CB_MEMORY_LIMIT_0);
-	program += yenta_allocate_res(socket, 3, IORESOURCE_MEM,
+	program += yenta_allocate_res(socket, PCI_CB_BRIDGE_MEM_1_WINDOW,
+			   IORESOURCE_MEM,
 			   PCI_CB_MEMORY_BASE_1, PCI_CB_MEMORY_LIMIT_1);
 	if (program)
 		pci_setup_cardbus(socket->dev->subordinate);
 }
 
+static void yenta_free_resource(struct yenta_socket *socket, int nr)
+{
+	struct resource *res;
+
+	res = &socket->dev->resource[nr];
+	if (res->start != 0 && res->end != 0)
+		release_resource(res);
+	res->start = res->end = res->flags = 0;
+}
 
 /*
  * Free the bridge mappings for the device..
  */
 static void yenta_free_resources(struct yenta_socket *socket)
 {
-	int i;
-	for (i = 0; i < 4; i++) {
-		struct resource *res;
-		res = socket->dev->resource + PCI_BRIDGE_RESOURCES + i;
-		if (res->start != 0 && res->end != 0)
-			release_resource(res);
-		res->start = res->end = res->flags = 0;
-	}
+	yenta_free_resource(socket, PCI_CB_BRIDGE_IO_0_WINDOW);
+	yenta_free_resource(socket, PCI_CB_BRIDGE_IO_1_WINDOW);
+	yenta_free_resource(socket, PCI_CB_BRIDGE_MEM_0_WINDOW);
+	yenta_free_resource(socket, PCI_CB_BRIDGE_MEM_1_WINDOW);
 }
 
 
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 44e2f0e..edcabd6 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -101,7 +101,16 @@ enum {
 #endif
 
 	/* resources assigned to buses behind the bridge */
-#define PCI_BRIDGE_RESOURCE_NUM 4
+#define PCI_BRIDGE_IO_WINDOW		(PCI_BRIDGE_RESOURCES + 0)
+#define PCI_BRIDGE_MEM_WINDOW		(PCI_BRIDGE_RESOURCES + 1)
+#define PCI_BRIDGE_PREF_MEM_WINDOW	(PCI_BRIDGE_RESOURCES + 2)
+
+#define PCI_CB_BRIDGE_IO_0_WINDOW	(PCI_BRIDGE_RESOURCES + 0)
+#define PCI_CB_BRIDGE_IO_1_WINDOW	(PCI_BRIDGE_RESOURCES + 1)
+#define PCI_CB_BRIDGE_MEM_0_WINDOW	(PCI_BRIDGE_RESOURCES + 2)
+#define PCI_CB_BRIDGE_MEM_1_WINDOW	(PCI_BRIDGE_RESOURCES + 3)
+
+#define PCI_BRIDGE_RESOURCE_NUM 4	/* max of P2P, cardbus */
 
 	PCI_BRIDGE_RESOURCES,
 	PCI_BRIDGE_RESOURCE_END = PCI_BRIDGE_RESOURCES +



More information about the Linuxppc-dev mailing list