linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/10] powerpc/pci: Fix PCI Hotplug
@ 2008-10-28  5:48 Benjamin Herrenschmidt
  2008-10-28  5:48 ` [PATCH 1/10] powerpc/pci: Properly allocate bus resources for hotplug PHBs Benjamin Herrenschmidt
                   ` (10 more replies)
  0 siblings, 11 replies; 14+ messages in thread
From: Benjamin Herrenschmidt @ 2008-10-28  5:48 UTC (permalink / raw)
  To: linuxppc-dev

This series of patches is aimed at fixing all sort of issues
with the PCI hotplug support on pSeries. The meant is in the
second to last patch, but it relies on a whole bunch of small
changes to separate the bus fixup operation in two that are
needed to fix the root of most problems.

Please review/test asap as I would like that in 2.6.28 despite
being a bit late, as without these, PCI hotplug on pseries pretty
much doesn't work. It should also make it easier in the future to
implement hotplug support on other platforms.

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

* [PATCH 1/10] powerpc/pci: Properly allocate bus resources for hotplug PHBs
  2008-10-28  5:48 [PATCH 0/10] powerpc/pci: Fix PCI Hotplug Benjamin Herrenschmidt
@ 2008-10-28  5:48 ` Benjamin Herrenschmidt
  2008-10-28  5:48 ` [PATCH 2/10] powerpc/pci: Cleanup debug printk's Benjamin Herrenschmidt
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Benjamin Herrenschmidt @ 2008-10-28  5:48 UTC (permalink / raw)
  To: linuxppc-dev

From: Nathan Fontenot <nfont@austin.ibm.com>

Resources for PHB's that are dynamically added to a system are not
properly allocated in the resource tree.

Not having these resources allocated causes an oops when removing
the PHB when we try to release them.

The patch appears a bit messy, this is mainly due to moving everything
one tab to the left in the pcibios_allocate_bus_resources routine.  The
big functionality change in this routine is only that the 
list_for_each_entry() loop is pulled out and moved to the necessary
calling routine.

Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com>
---

 arch/powerpc/include/asm/pci.h             |    2 
 arch/powerpc/kernel/pci-common.c           |  110 ++++++++++++++---------------
 arch/powerpc/platforms/pseries/pci_dlpar.c |    2 
 3 files changed, 59 insertions(+), 55 deletions(-)

--- linux-work.orig/arch/powerpc/kernel/pci-common.c	2008-10-28 15:02:27.000000000 +1100
+++ linux-work/arch/powerpc/kernel/pci-common.c	2008-10-28 15:02:50.000000000 +1100
@@ -1239,69 +1239,66 @@ static int __init reparent_resources(str
  *	    as well.
  */
 
-static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
+void pcibios_allocate_bus_resources(struct pci_bus *bus)
 {
-	struct pci_bus *bus;
+	struct pci_bus *b;
 	int i;
 	struct resource *res, *pr;
 
-	/* Depth-First Search on bus tree */
-	list_for_each_entry(bus, bus_list, node) {
-		for (i = 0; i < PCI_BUS_NUM_RESOURCES; ++i) {
-			if ((res = bus->resource[i]) == NULL || !res->flags
-			    || res->start > res->end)
-				continue;
-			if (bus->parent == NULL)
-				pr = (res->flags & IORESOURCE_IO) ?
-					&ioport_resource : &iomem_resource;
-			else {
-				/* Don't bother with non-root busses when
-				 * re-assigning all resources. We clear the
-				 * resource flags as if they were colliding
-				 * and as such ensure proper re-allocation
-				 * later.
+	for (i = 0; i < PCI_BUS_NUM_RESOURCES; ++i) {
+		if ((res = bus->resource[i]) == NULL || !res->flags
+		    || res->start > res->end)
+			continue;
+		if (bus->parent == NULL)
+			pr = (res->flags & IORESOURCE_IO) ?
+				&ioport_resource : &iomem_resource;
+		else {
+			/* Don't bother with non-root busses when
+			 * re-assigning all resources. We clear the
+			 * resource flags as if they were colliding
+			 * and as such ensure proper re-allocation
+			 * later.
+			 */
+			if (ppc_pci_flags & PPC_PCI_REASSIGN_ALL_RSRC)
+				goto clear_resource;
+			pr = pci_find_parent_resource(bus->self, res);
+			if (pr == res) {
+				/* this happens when the generic PCI
+				 * code (wrongly) decides that this
+				 * bridge is transparent  -- paulus
 				 */
-				if (ppc_pci_flags & PPC_PCI_REASSIGN_ALL_RSRC)
-					goto clear_resource;
-				pr = pci_find_parent_resource(bus->self, res);
-				if (pr == res) {
-					/* this happens when the generic PCI
-					 * code (wrongly) decides that this
-					 * bridge is transparent  -- paulus
-					 */
-					continue;
-				}
+				continue;
 			}
+		}
 
-			DBG("PCI: %s (bus %d) bridge rsrc %d: %016llx-%016llx "
-			    "[0x%x], parent %p (%s)\n",
-			    bus->self ? pci_name(bus->self) : "PHB",
-			    bus->number, i,
-			    (unsigned long long)res->start,
-			    (unsigned long long)res->end,
-			    (unsigned int)res->flags,
-			    pr, (pr && pr->name) ? pr->name : "nil");
-
-			if (pr && !(pr->flags & IORESOURCE_UNSET)) {
-				if (request_resource(pr, res) == 0)
-					continue;
-				/*
-				 * Must be a conflict with an existing entry.
-				 * Move that entry (or entries) under the
-				 * bridge resource and try again.
-				 */
-				if (reparent_resources(pr, res) == 0)
-					continue;
-			}
-			printk(KERN_WARNING
-			       "PCI: Cannot allocate resource region "
-			       "%d of PCI bridge %d, will remap\n",
-			       i, bus->number);
-clear_resource:
-			res->flags = 0;
+		DBG("PCI: %s (bus %d) bridge rsrc %d: %016llx-%016llx "
+		    "[0x%x], parent %p (%s)\n",
+		    bus->self ? pci_name(bus->self) : "PHB",
+		    bus->number, i,
+		    (unsigned long long)res->start,
+		    (unsigned long long)res->end,
+		    (unsigned int)res->flags,
+		    pr, (pr && pr->name) ? pr->name : "nil");
+
+		if (pr && !(pr->flags & IORESOURCE_UNSET)) {
+			if (request_resource(pr, res) == 0)
+				continue;
+			/*
+			 * Must be a conflict with an existing entry.
+			 * Move that entry (or entries) under the
+			 * bridge resource and try again.
+			 */
+			if (reparent_resources(pr, res) == 0)
+				continue;
 		}
-		pcibios_allocate_bus_resources(&bus->children);
+		printk(KERN_WARNING "PCI: Cannot allocate resource region "
+		       "%d of PCI bridge %d, will remap\n", i, bus->number);
+clear_resource:
+		res->flags = 0;
 	}
+
+	list_for_each_entry(b, &bus->children, node)
+		pcibios_allocate_bus_resources(b);
 }
 
 static inline void __devinit alloc_resource(struct pci_dev *dev, int idx)
@@ -1372,10 +1369,13 @@ static void __init pcibios_allocate_reso
 
 void __init pcibios_resource_survey(void)
 {
+	struct pci_bus *b;
+
 	/* Allocate and assign resources. If we re-assign everything, then
 	 * we skip the allocate phase
 	 */
-	pcibios_allocate_bus_resources(&pci_root_buses);
+	list_for_each_entry(b, &pci_root_buses, node)
+		pcibios_allocate_bus_resources(b);
 
 	if (!(ppc_pci_flags & PPC_PCI_REASSIGN_ALL_RSRC)) {
 		pcibios_allocate_resources(0);
Index: linux-work/arch/powerpc/include/asm/pci.h
===================================================================
--- linux-work.orig/arch/powerpc/include/asm/pci.h	2008-10-28 15:02:27.000000000 +1100
+++ linux-work/arch/powerpc/include/asm/pci.h	2008-10-28 15:02:50.000000000 +1100
@@ -208,6 +208,8 @@ extern void pcibios_setup_new_device(str
 
 extern void pcibios_claim_one_bus(struct pci_bus *b);
 
+extern void pcibios_allocate_bus_resources(struct pci_bus *bus);
+
 extern void pcibios_resource_survey(void);
 
 extern struct pci_controller *init_phb_dynamic(struct device_node *dn);
Index: linux-work/arch/powerpc/platforms/pseries/pci_dlpar.c
===================================================================
--- linux-work.orig/arch/powerpc/platforms/pseries/pci_dlpar.c	2008-10-28 15:02:27.000000000 +1100
+++ linux-work/arch/powerpc/platforms/pseries/pci_dlpar.c	2008-10-28 15:02:50.000000000 +1100
@@ -189,6 +189,7 @@ struct pci_controller * __devinit init_p
 {
 	struct pci_controller *phb;
 	int primary;
+	struct pci_bus *b;
 
 	primary = list_empty(&hose_list);
 	phb = pcibios_alloc_controller(dn);
@@ -203,6 +204,7 @@ struct pci_controller * __devinit init_p
 		eeh_add_device_tree_early(dn);
 
 	scan_phb(phb);
+	pcibios_allocate_bus_resources(phb->bus);
 	pcibios_fixup_new_pci_devices(phb->bus);
 	pci_bus_add_devices(phb->bus);
 	eeh_add_device_tree_late(phb->bus);

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

* [PATCH 2/10] powerpc/pci: Cleanup debug printk's
  2008-10-28  5:48 [PATCH 0/10] powerpc/pci: Fix PCI Hotplug Benjamin Herrenschmidt
  2008-10-28  5:48 ` [PATCH 1/10] powerpc/pci: Properly allocate bus resources for hotplug PHBs Benjamin Herrenschmidt
@ 2008-10-28  5:48 ` Benjamin Herrenschmidt
  2008-10-28  5:48 ` [PATCH 3/10] powerpc/pci: Use commont PHB resource hookup Benjamin Herrenschmidt
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Benjamin Herrenschmidt @ 2008-10-28  5:48 UTC (permalink / raw)
  To: linuxppc-dev

This removes the various DBG() macro from the powerpc PCI code and
make it use the standard pr_debug instead.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---

 arch/powerpc/kernel/pci-common.c |   77 +++++++++++++++------------------
 arch/powerpc/kernel/pci_32.c     |   12 +----
 arch/powerpc/kernel/pci_64.c     |   90 ++++++++++++++++++---------------------
 3 files changed, 82 insertions(+), 97 deletions(-)

--- linux-work.orig/arch/powerpc/kernel/pci-common.c	2008-10-28 11:56:18.000000000 +1100
+++ linux-work/arch/powerpc/kernel/pci-common.c	2008-10-28 11:56:41.000000000 +1100
@@ -38,13 +38,6 @@
 #include <asm/ppc-pci.h>
 #include <asm/firmware.h>
 
-#ifdef DEBUG
-#include <asm/udbg.h>
-#define DBG(fmt...) printk(fmt)
-#else
-#define DBG(fmt...)
-#endif
-
 static DEFINE_SPINLOCK(hose_spinlock);
 
 /* XXX kill that some day ... */
@@ -214,8 +207,8 @@ void __devinit pcibios_setup_new_device(
 
 	sd->of_node = pci_device_to_OF_node(dev);
 
-	DBG("PCI: device %s OF node: %s\n", pci_name(dev),
-	    sd->of_node ? sd->of_node->full_name : "<none>");
+	pr_debug("PCI: device %s OF node: %s\n", pci_name(dev),
+		 sd->of_node ? sd->of_node->full_name : "<none>");
 
 	sd->dma_ops = pci_dma_ops;
 #ifdef CONFIG_PPC32
@@ -252,7 +245,7 @@ int pci_read_irq_line(struct pci_dev *pc
 		return -1;
 #endif
 
-	DBG("Try to map irq for %s...\n", pci_name(pci_dev));
+	pr_debug("PCI: Try to map irq for %s...\n", pci_name(pci_dev));
 
 #ifdef DEBUG
 	memset(&oirq, 0xff, sizeof(oirq));
@@ -276,26 +269,26 @@ int pci_read_irq_line(struct pci_dev *pc
 		    line == 0xff || line == 0) {
 			return -1;
 		}
-		DBG(" -> no map ! Using line %d (pin %d) from PCI config\n",
-		    line, pin);
+		pr_debug(" No map ! Using line %d (pin %d) from PCI config\n",
+			 line, pin);
 
 		virq = irq_create_mapping(NULL, line);
 		if (virq != NO_IRQ)
 			set_irq_type(virq, IRQ_TYPE_LEVEL_LOW);
 	} else {
-		DBG(" -> got one, spec %d cells (0x%08x 0x%08x...) on %s\n",
-		    oirq.size, oirq.specifier[0], oirq.specifier[1],
+		pr_debug(" Got one, spec %d cells (0x%08x 0x%08x...) on %s\n",
+			 oirq.size, oirq.specifier[0], oirq.specifier[1],
 		    oirq.controller->full_name);
 
 		virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
 					     oirq.size);
 	}
 	if(virq == NO_IRQ) {
-		DBG(" -> failed to map !\n");
+		pr_debug(" Failed to map !\n");
 		return -1;
 	}
 
-	DBG(" -> mapped to linux irq %d\n", virq);
+	pr_debug(" Mapped to linux irq %d\n", virq);
 
 	pci_dev->irq = virq;
 
@@ -451,8 +444,8 @@ pgprot_t pci_phys_mem_access_prot(struct
 		pci_dev_put(pdev);
 	}
 
-	DBG("non-PCI map for %llx, prot: %lx\n",
-	    (unsigned long long)offset, prot);
+	pr_debug("PCI: Non-PCI map for %llx, prot: %lx\n",
+		 (unsigned long long)offset, prot);
 
 	return __pgprot(prot);
 }
@@ -1198,10 +1191,10 @@ static int __init reparent_resources(str
 	*pp = NULL;
 	for (p = res->child; p != NULL; p = p->sibling) {
 		p->parent = res;
-		DBG(KERN_INFO "PCI: reparented %s [%llx..%llx] under %s\n",
-		    p->name,
-		    (unsigned long long)p->start,
-		    (unsigned long long)p->end, res->name);
+		pr_debug("PCI: Reparented %s [%llx..%llx] under %s\n",
+			 p->name,
+			 (unsigned long long)p->start,
+			 (unsigned long long)p->end, res->name);
 	}
 	return 0;
 }
@@ -1271,14 +1264,14 @@ void pcibios_allocate_bus_resources(stru
 			}
 		}
 
-		DBG("PCI: %s (bus %d) bridge rsrc %d: %016llx-%016llx "
-		    "[0x%x], parent %p (%s)\n",
-		    bus->self ? pci_name(bus->self) : "PHB",
-		    bus->number, i,
-		    (unsigned long long)res->start,
-		    (unsigned long long)res->end,
-		    (unsigned int)res->flags,
-		    pr, (pr && pr->name) ? pr->name : "nil");
+		pr_debug("PCI: %s (bus %d) bridge rsrc %d: %016llx-%016llx "
+			 "[0x%x], parent %p (%s)\n",
+			 bus->self ? pci_name(bus->self) : "PHB",
+			 bus->number, i,
+			 (unsigned long long)res->start,
+			 (unsigned long long)res->end,
+			 (unsigned int)res->flags,
+			 pr, (pr && pr->name) ? pr->name : "nil");
 
 		if (pr && !(pr->flags & IORESOURCE_UNSET)) {
 			if (request_resource(pr, res) == 0)
@@ -1305,11 +1298,11 @@ static inline void __devinit alloc_resou
 {
 	struct resource *pr, *r = &dev->resource[idx];
 
-	DBG("PCI: Allocating %s: Resource %d: %016llx..%016llx [%x]\n",
-	    pci_name(dev), idx,
-	    (unsigned long long)r->start,
-	    (unsigned long long)r->end,
-	    (unsigned int)r->flags);
+	pr_debug("PCI: Allocating %s: Resource %d: %016llx..%016llx [%x]\n",
+		 pci_name(dev), idx,
+		 (unsigned long long)r->start,
+		 (unsigned long long)r->end,
+		 (unsigned int)r->flags);
 
 	pr = pci_find_parent_resource(dev, r);
 	if (!pr || (pr->flags & IORESOURCE_UNSET) ||
@@ -1317,10 +1310,11 @@ static inline void __devinit alloc_resou
 		printk(KERN_WARNING "PCI: Cannot allocate resource region %d"
 		       " of device %s, will remap\n", idx, pci_name(dev));
 		if (pr)
-			DBG("PCI:  parent is %p: %016llx-%016llx [%x]\n", pr,
-			    (unsigned long long)pr->start,
-			    (unsigned long long)pr->end,
-			    (unsigned int)pr->flags);
+			pr_debug("PCI:  parent is %p: %016llx-%016llx [%x]\n",
+				 pr,
+				 (unsigned long long)pr->start,
+				 (unsigned long long)pr->end,
+				 (unsigned int)pr->flags);
 		/* We'll assign a new address later */
 		r->flags |= IORESOURCE_UNSET;
 		r->end -= r->start;
@@ -1358,7 +1352,8 @@ static void __init pcibios_allocate_reso
 			 * but keep it unregistered.
 			 */
 			u32 reg;
-			DBG("PCI: Switching off ROM of %s\n", pci_name(dev));
+			pr_debug("PCI: Switching off ROM of %s\n",
+				 pci_name(dev));
 			r->flags &= ~IORESOURCE_ROM_ENABLE;
 			pci_read_config_dword(dev, dev->rom_base_reg, &reg);
 			pci_write_config_dword(dev, dev->rom_base_reg,
@@ -1383,7 +1378,7 @@ void __init pcibios_resource_survey(void
 	}
 
 	if (!(ppc_pci_flags & PPC_PCI_PROBE_ONLY)) {
-		DBG("PCI: Assigning unassigned resouces...\n");
+		pr_debug("PCI: Assigning unassigned resouces...\n");
 		pci_assign_unassigned_resources();
 	}
 
Index: linux-work/arch/powerpc/kernel/pci_32.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/pci_32.c	2008-10-28 11:56:09.000000000 +1100
+++ linux-work/arch/powerpc/kernel/pci_32.c	2008-10-28 11:56:25.000000000 +1100
@@ -26,12 +26,6 @@
 
 #undef DEBUG
 
-#ifdef DEBUG
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif
-
 unsigned long isa_io_base     = 0;
 unsigned long pci_dram_offset = 0;
 int pcibios_assign_bus_offset = 1;
@@ -275,14 +269,14 @@ pci_busdev_to_OF_node(struct pci_bus *bu
 	if (!have_of)
 		return NULL;
 
-	DBG("pci_busdev_to_OF_node(%d,0x%x)\n", bus->number, devfn);
+	pr_debug("pci_busdev_to_OF_node(%d,0x%x)\n", bus->number, devfn);
 	parent = scan_OF_for_pci_bus(bus);
 	if (parent == NULL)
 		return NULL;
-	DBG(" parent is %s\n", parent ? parent->full_name : "<NULL>");
+	pr_debug(" parent is %s\n", parent ? parent->full_name : "<NULL>");
 	np = scan_OF_for_pci_dev(parent, devfn);
 	of_node_put(parent);
-	DBG(" result is %s\n", np ? np->full_name : "<NULL>");
+	pr_debug(" result is %s\n", np ? np->full_name : "<NULL>");
 
 	/* XXX most callers don't release the returned node
 	 * mostly because ppc64 doesn't increase the refcount,
Index: linux-work/arch/powerpc/kernel/pci_64.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/pci_64.c	2008-10-28 11:56:09.000000000 +1100
+++ linux-work/arch/powerpc/kernel/pci_64.c	2008-10-28 11:56:25.000000000 +1100
@@ -32,13 +32,6 @@
 #include <asm/machdep.h>
 #include <asm/ppc-pci.h>
 
-#ifdef DEBUG
-#include <asm/udbg.h>
-#define DBG(fmt...) printk(fmt)
-#else
-#define DBG(fmt...)
-#endif
-
 unsigned long pci_probe_only = 1;
 
 /* pci_io_base -- the base address from which io bars are offsets.
@@ -102,7 +95,7 @@ static void pci_parse_of_addrs(struct de
 	addrs = of_get_property(node, "assigned-addresses", &proplen);
 	if (!addrs)
 		return;
-	DBG("    parse addresses (%d bytes) @ %p\n", proplen, addrs);
+	pr_debug("    parse addresses (%d bytes) @ %p\n", proplen, addrs);
 	for (; proplen >= 20; proplen -= 20, addrs += 5) {
 		flags = pci_parse_of_flags(addrs[0]);
 		if (!flags)
@@ -112,8 +105,9 @@ static void pci_parse_of_addrs(struct de
 		if (!size)
 			continue;
 		i = addrs[0] & 0xff;
-		DBG("  base: %llx, size: %llx, i: %x\n",
-		    (unsigned long long)base, (unsigned long long)size, i);
+		pr_debug("  base: %llx, size: %llx, i: %x\n",
+			 (unsigned long long)base,
+			 (unsigned long long)size, i);
 
 		if (PCI_BASE_ADDRESS_0 <= i && i <= PCI_BASE_ADDRESS_5) {
 			res = &dev->resource[(i - PCI_BASE_ADDRESS_0) >> 2];
@@ -144,7 +138,7 @@ struct pci_dev *of_create_pci_dev(struct
 	if (type == NULL)
 		type = "";
 
-	DBG("    create device, devfn: %x, type: %s\n", devfn, type);
+	pr_debug("    create device, devfn: %x, type: %s\n", devfn, type);
 
 	dev->bus = bus;
 	dev->sysdata = node;
@@ -165,8 +159,8 @@ struct pci_dev *of_create_pci_dev(struct
 	dev->class = get_int_prop(node, "class-code", 0);
 	dev->revision = get_int_prop(node, "revision-id", 0);
 
-	DBG("    class: 0x%x\n", dev->class);
-	DBG("    revision: 0x%x\n", dev->revision);
+	pr_debug("    class: 0x%x\n", dev->class);
+	pr_debug("    revision: 0x%x\n", dev->revision);
 
 	dev->current_state = 4;		/* unknown power state */
 	dev->error_state = pci_channel_io_normal;
@@ -187,7 +181,7 @@ struct pci_dev *of_create_pci_dev(struct
 
 	pci_parse_of_addrs(node, dev);
 
-	DBG("    adding to system ...\n");
+	pr_debug("    adding to system ...\n");
 
 	pci_device_add(dev, bus);
 
@@ -203,11 +197,12 @@ void __devinit of_scan_bus(struct device
 	int reglen, devfn;
 	struct pci_dev *dev;
 
-	DBG("of_scan_bus(%s) bus no %d... \n", node->full_name, bus->number);
+	pr_debug("of_scan_bus(%s) bus no %d... \n",
+		 node->full_name, bus->number);
 
 	/* Scan direct children */
 	for_each_child_of_node(node, child) {
-		DBG("  * %s\n", child->full_name);
+		pr_debug("  * %s\n", child->full_name);
 		reg = of_get_property(child, "reg", &reglen);
 		if (reg == NULL || reglen < 20)
 			continue;
@@ -217,7 +212,7 @@ void __devinit of_scan_bus(struct device
 		dev = of_create_pci_dev(child, bus, devfn);
 		if (!dev)
 			continue;
-		DBG("    dev header type: %x\n", dev->hdr_type);
+		pr_debug("    dev header type: %x\n", dev->hdr_type);
 	}
 
 	/* Ally all fixups */
@@ -245,7 +240,7 @@ void __devinit of_scan_pci_bridge(struct
 	unsigned int flags;
 	u64 size;
 
-	DBG("of_scan_pci_bridge(%s)\n", node->full_name);
+	pr_debug("of_scan_pci_bridge(%s)\n", node->full_name);
 
 	/* parse bus-range property */
 	busrange = of_get_property(node, "bus-range", &len);
@@ -309,12 +304,12 @@ void __devinit of_scan_pci_bridge(struct
 	}
 	sprintf(bus->name, "PCI Bus %04x:%02x", pci_domain_nr(bus),
 		bus->number);
-	DBG("    bus name: %s\n", bus->name);
+	pr_debug("    bus name: %s\n", bus->name);
 
 	mode = PCI_PROBE_NORMAL;
 	if (ppc_md.pci_probe_mode)
 		mode = ppc_md.pci_probe_mode(bus);
-	DBG("    probe mode: %d\n", mode);
+	pr_debug("    probe mode: %d\n", mode);
 
 	if (mode == PCI_PROBE_DEVTREE)
 		of_scan_bus(node, bus);
@@ -329,7 +324,8 @@ void __devinit scan_phb(struct pci_contr
 	struct device_node *node = hose->dn;
 	int i, mode;
 
-	DBG("PCI: Scanning PHB %s\n", node ? node->full_name : "<NO NAME>");
+	pr_debug("PCI: Scanning PHB %s\n",
+		 node ? node->full_name : "<NO NAME>");
 
 	/* Create an empty bus for the toplevel */
 	bus = pci_create_bus(hose->parent, hose->first_busno, hose->ops, node);
@@ -345,26 +341,26 @@ void __devinit scan_phb(struct pci_contr
 	pcibios_map_io_space(bus);
 
 	/* Wire up PHB bus resources */
-	DBG("PCI: PHB IO resource    = %016lx-%016lx [%lx]\n",
-	    hose->io_resource.start, hose->io_resource.end,
-	    hose->io_resource.flags);
+	pr_debug("PCI: PHB IO resource    = %016lx-%016lx [%lx]\n",
+		 hose->io_resource.start, hose->io_resource.end,
+		 hose->io_resource.flags);
 	bus->resource[0] = &hose->io_resource;
 	for (i = 0; i < 3; ++i) {
-		DBG("PCI: PHB MEM resource %d = %016lx-%016lx [%lx]\n", i,
-		    hose->mem_resources[i].start,
-		    hose->mem_resources[i].end,
-		    hose->mem_resources[i].flags);
+		pr_debug("PCI: PHB MEM resource %d = %016lx-%016lx [%lx]\n", i,
+			 hose->mem_resources[i].start,
+			 hose->mem_resources[i].end,
+			 hose->mem_resources[i].flags);
 		bus->resource[i+1] = &hose->mem_resources[i];
 	}
-	DBG("PCI: PHB MEM offset     = %016lx\n", hose->pci_mem_offset);
-	DBG("PCI: PHB IO  offset     = %08lx\n",
+	pr_debug("PCI: PHB MEM offset     = %016lx\n", hose->pci_mem_offset);
+	pr_debug("PCI: PHB IO  offset     = %08lx\n",
 	    (unsigned long)hose->io_base_virt - _IO_BASE);
 
 	/* Get probe mode and perform scan */
 	mode = PCI_PROBE_NORMAL;
 	if (node && ppc_md.pci_probe_mode)
 		mode = ppc_md.pci_probe_mode(bus);
-	DBG("    probe mode: %d\n", mode);
+	pr_debug("    probe mode: %d\n", mode);
 	if (mode == PCI_PROBE_DEVTREE) {
 		bus->subordinate = hose->last_busno;
 		of_scan_bus(node, bus);
@@ -422,8 +418,8 @@ int pcibios_unmap_io_space(struct pci_bu
 	if (bus->self) {
 		struct resource *res = bus->resource[0];
 
-		DBG("IO unmapping for PCI-PCI bridge %s\n",
-		    pci_name(bus->self));
+		pr_debug("IO unmapping for PCI-PCI bridge %s\n",
+			 pci_name(bus->self));
 
 		__flush_hash_table_range(&init_mm, res->start + _IO_BASE,
 					 res->end - res->start + 1);
@@ -437,8 +433,8 @@ int pcibios_unmap_io_space(struct pci_bu
 	if (hose->io_base_alloc == 0)
 		return 0;
 
-	DBG("IO unmapping for PHB %s\n", hose->dn->full_name);
-	DBG("  alloc=0x%p\n", hose->io_base_alloc);
+	pr_debug("IO unmapping for PHB %s\n", hose->dn->full_name);
+	pr_debug("  alloc=0x%p\n", hose->io_base_alloc);
 
 	/* This is a PHB, we fully unmap the IO area */
 	vunmap(hose->io_base_alloc);
@@ -463,11 +459,11 @@ int __devinit pcibios_map_io_space(struc
 	 * thus HPTEs will be faulted in when needed
 	 */
 	if (bus->self) {
-		DBG("IO mapping for PCI-PCI bridge %s\n",
-		    pci_name(bus->self));
-		DBG("  virt=0x%016lx...0x%016lx\n",
-		    bus->resource[0]->start + _IO_BASE,
-		    bus->resource[0]->end + _IO_BASE);
+		pr_debug("IO mapping for PCI-PCI bridge %s\n",
+			 pci_name(bus->self));
+		pr_debug("  virt=0x%016lx...0x%016lx\n",
+			 bus->resource[0]->start + _IO_BASE,
+			 bus->resource[0]->end + _IO_BASE);
 		return 0;
 	}
 
@@ -496,11 +492,11 @@ int __devinit pcibios_map_io_space(struc
 	hose->io_base_virt = (void __iomem *)(area->addr +
 					      hose->io_base_phys - phys_page);
 
-	DBG("IO mapping for PHB %s\n", hose->dn->full_name);
-	DBG("  phys=0x%016lx, virt=0x%p (alloc=0x%p)\n",
-	    hose->io_base_phys, hose->io_base_virt, hose->io_base_alloc);
-	DBG("  size=0x%016lx (alloc=0x%016lx)\n",
-	    hose->pci_io_size, size_page);
+	pr_debug("IO mapping for PHB %s\n", hose->dn->full_name);
+	pr_debug("  phys=0x%016lx, virt=0x%p (alloc=0x%p)\n",
+		 hose->io_base_phys, hose->io_base_virt, hose->io_base_alloc);
+	pr_debug("  size=0x%016lx (alloc=0x%016lx)\n",
+		 hose->pci_io_size, size_page);
 
 	/* Establish the mapping */
 	if (__ioremap_at(phys_page, area->addr, size_page,
@@ -512,8 +508,8 @@ int __devinit pcibios_map_io_space(struc
 	hose->io_resource.start += io_virt_offset;
 	hose->io_resource.end += io_virt_offset;
 
-	DBG("  hose->io_resource=0x%016lx...0x%016lx\n",
-	    hose->io_resource.start, hose->io_resource.end);
+	pr_debug("  hose->io_resource=0x%016lx...0x%016lx\n",
+		 hose->io_resource.start, hose->io_resource.end);
 
 	return 0;
 }

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

* [PATCH 3/10] powerpc/pci: Use commont PHB resource hookup
  2008-10-28  5:48 [PATCH 0/10] powerpc/pci: Fix PCI Hotplug Benjamin Herrenschmidt
  2008-10-28  5:48 ` [PATCH 1/10] powerpc/pci: Properly allocate bus resources for hotplug PHBs Benjamin Herrenschmidt
  2008-10-28  5:48 ` [PATCH 2/10] powerpc/pci: Cleanup debug printk's Benjamin Herrenschmidt
@ 2008-10-28  5:48 ` Benjamin Herrenschmidt
  2008-10-28  5:48 ` [PATCH 4/10] powerpc/pci: Remove pcibios_do_bus_setup() Benjamin Herrenschmidt
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Benjamin Herrenschmidt @ 2008-10-28  5:48 UTC (permalink / raw)
  To: linuxppc-dev

The 32-bit and 64-bit powerpc PCI code used to setup the resource
pointers of the root bus of a given PHB in completely different
places.

This unifies this in large part, but making 32-bit use a routine very
similar to what 64-bit does when initially scanning the PCI busses.

The actual setup of the PHB resources itself is then moved to a
common function in pci-common.c

This should cause no functional change on 64-bit. On 32-bit, the effect
is that the PHB resources are going to be setup a bit earlier, instead
of being setup from pcibios_fixup_bus().

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---

This is a pre-requisite to be able to remove pcibios_do_bus_setup()
in order to make the pcibios_fixup_bus() codepath common.

 arch/powerpc/include/asm/pci-bridge.h |    1 
 arch/powerpc/kernel/pci-common.c      |   58 +++++++++++++++++++++++++
 arch/powerpc/kernel/pci_32.c          |   78 ++++++++++++++--------------------
 arch/powerpc/kernel/pci_64.c          |   19 +-------
 4 files changed, 96 insertions(+), 60 deletions(-)

--- linux-work.orig/arch/powerpc/include/asm/pci-bridge.h	2008-10-28 15:35:56.000000000 +1100
+++ linux-work/arch/powerpc/include/asm/pci-bridge.h	2008-10-28 15:37:23.000000000 +1100
@@ -290,6 +290,7 @@ extern void pci_process_bridge_OF_ranges
 /* Allocate & free a PCI host bridge structure */
 extern struct pci_controller *pcibios_alloc_controller(struct device_node *dev);
 extern void pcibios_free_controller(struct pci_controller *phb);
+extern void pcibios_setup_phb_resources(struct pci_controller *hose);
 
 #ifdef CONFIG_PCI
 extern unsigned long pci_address_to_pio(phys_addr_t address);
Index: linux-work/arch/powerpc/kernel/pci-common.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/pci-common.c	2008-10-28 15:35:56.000000000 +1100
+++ linux-work/arch/powerpc/kernel/pci-common.c	2008-10-28 15:37:23.000000000 +1100
@@ -1423,3 +1423,61 @@ int pcibios_enable_device(struct pci_dev
 
 	return pci_enable_resources(dev, mask);
 }
+
+void __devinit pcibios_setup_phb_resources(struct pci_controller *hose)
+{
+	struct pci_bus *bus = hose->bus;
+	struct resource *res;
+	int i;
+
+	/* Hookup PHB IO resource */
+	bus->resource[0] = res = &hose->io_resource;
+
+	if (!res->flags) {
+		printk(KERN_WARNING "PCI: I/O resource not set for host"
+		       " bridge %s (domain %d)\n",
+		       hose->dn->full_name, hose->global_number);
+#ifdef CONFIG_PPC32
+		/* Workaround for lack of IO resource only on 32-bit */
+		res->start = (unsigned long)hose->io_base_virt - isa_io_base;
+		res->end = res->start + IO_SPACE_LIMIT;
+		res->flags = IORESOURCE_IO;
+#endif /* CONFIG_PPC32 */
+	}
+
+	pr_debug("PCI: PHB IO resource    = %016llx-%016llx [%lx]\n",
+		 (unsigned long long)res->start,
+		 (unsigned long long)res->end,
+		 (unsigned long)res->flags);
+
+	/* Hookup PHB Memory resources */
+	for (i = 0; i < 3; ++i) {
+		res = &hose->mem_resources[i];
+		if (!res->flags) {
+			if (i > 0)
+				continue;
+			printk(KERN_ERR "PCI: Memory resource 0 not set for "
+			       "host bridge %s (domain %d)\n",
+			       hose->dn->full_name, hose->global_number);
+#ifdef CONFIG_PPC32
+			/* Workaround for lack of MEM resource only on 32-bit */
+			res->start = hose->pci_mem_offset;
+			res->end = (resource_size_t)-1LL;
+			res->flags = IORESOURCE_MEM;
+#endif /* CONFIG_PPC32 */
+		}
+		bus->resource[i+1] = res;
+
+		pr_debug("PCI: PHB MEM resource %d = %016llx-%016llx [%lx]\n", i,
+			 (unsigned long long)res->start,
+			 (unsigned long long)res->end,
+			 (unsigned long)res->flags);
+	}
+
+	pr_debug("PCI: PHB MEM offset     = %016llx\n",
+		 (unsigned long long)hose->pci_mem_offset);
+	pr_debug("PCI: PHB IO  offset     = %08lx\n",
+		 (unsigned long)hose->io_base_virt - _IO_BASE);
+
+}
+
Index: linux-work/arch/powerpc/kernel/pci_32.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/pci_32.c	2008-10-28 15:35:56.000000000 +1100
+++ linux-work/arch/powerpc/kernel/pci_32.c	2008-10-28 15:42:13.000000000 +1100
@@ -373,10 +373,41 @@ void pcibios_make_OF_bus_map(void)
 }
 #endif /* CONFIG_PPC_OF */
 
+static void __devinit pcibios_scan_phb(struct pci_controller *hose)
+{
+	struct pci_bus *bus;
+	struct device_node *node = hose->dn;
+	unsigned long io_offset;
+	struct resource *res = &hose->io_resource;
+
+	pr_debug("PCI: Scanning PHB %s\n",
+		 node ? node->full_name : "<NO NAME>");
+
+	/* Create an empty bus for the toplevel */
+	bus = pci_create_bus(hose->parent, hose->first_busno, hose->ops, hose);
+	if (bus == NULL) {
+		printk(KERN_ERR "Failed to create bus for PCI domain %04x\n",
+		       hose->global_number);
+		return;
+	}
+	bus->secondary = hose->first_busno;
+	hose->bus = bus;
+
+	/* Fixup IO space offset */
+	io_offset = (unsigned long)hose->io_base_virt - isa_io_base;
+	res->start = (res->start + io_offset) & 0xffffffffu;
+	res->end = (res->end + io_offset) & 0xffffffffu;
+
+	/* Wire up PHB bus resources */
+	pcibios_setup_phb_resources(hose);
+
+	/* Scan children */
+	hose->last_busno = bus->subordinate = pci_scan_child_bus(bus);
+}
+
 static int __init pcibios_init(void)
 {
 	struct pci_controller *hose, *tmp;
-	struct pci_bus *bus;
 	int next_busno = 0;
 
 	printk(KERN_INFO "PCI: Probing PCI hardware\n");
@@ -389,12 +420,8 @@ static int __init pcibios_init(void)
 		if (pci_assign_all_buses)
 			hose->first_busno = next_busno;
 		hose->last_busno = 0xff;
-		bus = pci_scan_bus_parented(hose->parent, hose->first_busno,
-					    hose->ops, hose);
-		if (bus) {
-			pci_bus_add_devices(bus);
-			hose->last_busno = bus->subordinate;
-		}
+		pcibios_scan_phb(hose);
+		pci_bus_add_devices(hose->bus);
 		if (pci_assign_all_buses || next_busno <= hose->last_busno)
 			next_busno = hose->last_busno + pcibios_assign_bus_offset;
 	}
@@ -421,45 +448,8 @@ subsys_initcall(pcibios_init);
 
 void __devinit pcibios_do_bus_setup(struct pci_bus *bus)
 {
-	struct pci_controller *hose = (struct pci_controller *) bus->sysdata;
-	unsigned long io_offset;
-	struct resource *res;
-	int i;
 	struct pci_dev *dev;
 
-	/* Hookup PHB resources */
-	io_offset = (unsigned long)hose->io_base_virt - isa_io_base;
-	if (bus->parent == NULL) {
-		/* This is a host bridge - fill in its resources */
-		hose->bus = bus;
-
-		bus->resource[0] = res = &hose->io_resource;
-		if (!res->flags) {
-			if (io_offset)
-				printk(KERN_ERR "I/O resource not set for host"
-				       " bridge %d\n", hose->global_number);
-			res->start = 0;
-			res->end = IO_SPACE_LIMIT;
-			res->flags = IORESOURCE_IO;
-		}
-		res->start = (res->start + io_offset) & 0xffffffffu;
-		res->end = (res->end + io_offset) & 0xffffffffu;
-
-		for (i = 0; i < 3; ++i) {
-			res = &hose->mem_resources[i];
-			if (!res->flags) {
-				if (i > 0)
-					continue;
-				printk(KERN_ERR "Memory resource not set for "
-				       "host bridge %d\n", hose->global_number);
-				res->start = hose->pci_mem_offset;
-				res->end = ~0U;
-				res->flags = IORESOURCE_MEM;
-			}
-			bus->resource[i+1] = res;
-		}
-	}
-
 	if (ppc_md.pci_dma_bus_setup)
 		ppc_md.pci_dma_bus_setup(bus);
 
Index: linux-work/arch/powerpc/kernel/pci_64.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/pci_64.c	2008-10-28 15:35:56.000000000 +1100
+++ linux-work/arch/powerpc/kernel/pci_64.c	2008-10-28 15:37:23.000000000 +1100
@@ -322,7 +322,7 @@ void __devinit scan_phb(struct pci_contr
 {
 	struct pci_bus *bus;
 	struct device_node *node = hose->dn;
-	int i, mode;
+	int mode;
 
 	pr_debug("PCI: Scanning PHB %s\n",
 		 node ? node->full_name : "<NO NAME>");
@@ -341,20 +341,7 @@ void __devinit scan_phb(struct pci_contr
 	pcibios_map_io_space(bus);
 
 	/* Wire up PHB bus resources */
-	pr_debug("PCI: PHB IO resource    = %016lx-%016lx [%lx]\n",
-		 hose->io_resource.start, hose->io_resource.end,
-		 hose->io_resource.flags);
-	bus->resource[0] = &hose->io_resource;
-	for (i = 0; i < 3; ++i) {
-		pr_debug("PCI: PHB MEM resource %d = %016lx-%016lx [%lx]\n", i,
-			 hose->mem_resources[i].start,
-			 hose->mem_resources[i].end,
-			 hose->mem_resources[i].flags);
-		bus->resource[i+1] = &hose->mem_resources[i];
-	}
-	pr_debug("PCI: PHB MEM offset     = %016lx\n", hose->pci_mem_offset);
-	pr_debug("PCI: PHB IO  offset     = %08lx\n",
-	    (unsigned long)hose->io_base_virt - _IO_BASE);
+	pcibios_setup_phb_resources(hose);
 
 	/* Get probe mode and perform scan */
 	mode = PCI_PROBE_NORMAL;
@@ -376,7 +363,7 @@ static int __init pcibios_init(void)
 
 	printk(KERN_INFO "PCI: Probing PCI hardware\n");
 
-	/* For now, override phys_mem_access_prot. If we need it,
+	/* For now, override phys_mem_access_prot. If we need it,g
 	 * later, we may move that initialization to each ppc_md
 	 */
 	ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot;

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

* [PATCH 4/10] powerpc/pci: Remove pcibios_do_bus_setup()
  2008-10-28  5:48 [PATCH 0/10] powerpc/pci: Fix PCI Hotplug Benjamin Herrenschmidt
                   ` (2 preceding siblings ...)
  2008-10-28  5:48 ` [PATCH 3/10] powerpc/pci: Use commont PHB resource hookup Benjamin Herrenschmidt
@ 2008-10-28  5:48 ` Benjamin Herrenschmidt
  2008-10-28  5:48 ` [PATCH 5/10] powerpc/pci: Split pcibios_fixup_bus() into bus setup and devices setup Benjamin Herrenschmidt
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Benjamin Herrenschmidt @ 2008-10-28  5:48 UTC (permalink / raw)
  To: linuxppc-dev

The function pcibios_do_bus_setup() was used by pcibios_fixup_bus()
to perform setup that is different between the 32-bit and 64-bit
code. This difference no longer exist, thus the function is removed
and the setup now done directly from pci-common.c

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---

 arch/powerpc/include/asm/pci.h   |    1 -
 arch/powerpc/kernel/pci-common.c |   16 +++++++++++-----
 arch/powerpc/kernel/pci_32.c     |   11 -----------
 arch/powerpc/kernel/pci_64.c     |   11 -----------
 4 files changed, 11 insertions(+), 28 deletions(-)

--- linux-work.orig/arch/powerpc/include/asm/pci.h	2008-10-28 11:56:18.000000000 +1100
+++ linux-work/arch/powerpc/include/asm/pci.h	2008-10-28 11:56:46.000000000 +1100
@@ -235,7 +235,6 @@ extern void pci_resource_to_user(const s
 				 const struct resource *rsrc,
 				 resource_size_t *start, resource_size_t *end);
 
-extern void pcibios_do_bus_setup(struct pci_bus *bus);
 extern void pcibios_fixup_of_probed_bus(struct pci_bus *bus);
 
 
Index: linux-work/arch/powerpc/kernel/pci-common.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/pci-common.c	2008-10-28 11:56:45.000000000 +1100
+++ linux-work/arch/powerpc/kernel/pci-common.c	2008-10-28 11:56:46.000000000 +1100
@@ -1078,18 +1078,24 @@ static void __devinit pcibios_fixup_brid
 
 static void __devinit __pcibios_fixup_bus(struct pci_bus *bus)
 {
-	struct pci_dev *dev = bus->self;
+	struct pci_dev *dev;
 
-	pr_debug("PCI: Fixup bus %d (%s)\n", bus->number, dev ? pci_name(dev) : "PHB");
+	pr_debug("PCI: Fixup bus %d (%s)\n",
+		 bus->number, bus->self ? pci_name(bus->self) : "PHB");
 
 	/* Fixup PCI<->PCI bridges. Host bridges are handled separately, for
 	 * now differently between 32 and 64 bits.
 	 */
-	if (dev != NULL)
+	if (bus->self != NULL)
 		pcibios_fixup_bridge(bus);
 
-	/* Additional setup that is different between 32 and 64 bits for now */
-	pcibios_do_bus_setup(bus);
+	/* Setup bus DMA mappings */
+	if (ppc_md.pci_dma_bus_setup)
+		ppc_md.pci_dma_bus_setup(bus);
+
+	/* Setup DMA for all PCI devices on that bus */
+	list_for_each_entry(dev, &bus->devices, bus_list)
+		pcibios_setup_new_device(dev);
 
 	/* Platform specific bus fixups */
 	if (ppc_md.pcibios_fixup_bus)
Index: linux-work/arch/powerpc/kernel/pci_32.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/pci_32.c	2008-10-28 11:56:45.000000000 +1100
+++ linux-work/arch/powerpc/kernel/pci_32.c	2008-10-28 11:56:46.000000000 +1100
@@ -446,17 +446,6 @@ static int __init pcibios_init(void)
 
 subsys_initcall(pcibios_init);
 
-void __devinit pcibios_do_bus_setup(struct pci_bus *bus)
-{
-	struct pci_dev *dev;
-
-	if (ppc_md.pci_dma_bus_setup)
-		ppc_md.pci_dma_bus_setup(bus);
-
-	list_for_each_entry(dev, &bus->devices, bus_list)
-		pcibios_setup_new_device(dev);
-}
-
 /* the next one is stolen from the alpha port... */
 void __init
 pcibios_update_irq(struct pci_dev *dev, int irq)
Index: linux-work/arch/powerpc/kernel/pci_64.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/pci_64.c	2008-10-28 11:56:45.000000000 +1100
+++ linux-work/arch/powerpc/kernel/pci_64.c	2008-10-28 11:56:46.000000000 +1100
@@ -502,17 +502,6 @@ int __devinit pcibios_map_io_space(struc
 }
 EXPORT_SYMBOL_GPL(pcibios_map_io_space);
 
-void __devinit pcibios_do_bus_setup(struct pci_bus *bus)
-{
-	struct pci_dev *dev;
-
-	if (ppc_md.pci_dma_bus_setup)
-		ppc_md.pci_dma_bus_setup(bus);
-
-	list_for_each_entry(dev, &bus->devices, bus_list)
-		pcibios_setup_new_device(dev);
-}
-
 unsigned long pci_address_to_pio(phys_addr_t address)
 {
 	struct pci_controller *hose, *tmp;

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

* [PATCH 5/10] powerpc/pci: Split pcibios_fixup_bus() into bus setup and devices setup
  2008-10-28  5:48 [PATCH 0/10] powerpc/pci: Fix PCI Hotplug Benjamin Herrenschmidt
                   ` (3 preceding siblings ...)
  2008-10-28  5:48 ` [PATCH 4/10] powerpc/pci: Remove pcibios_do_bus_setup() Benjamin Herrenschmidt
@ 2008-10-28  5:48 ` Benjamin Herrenschmidt
  2008-10-28  5:48 ` [PATCH 6/10] powerpc/eeh: Make EEH device add/remove more robust Benjamin Herrenschmidt
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Benjamin Herrenschmidt @ 2008-10-28  5:48 UTC (permalink / raw)
  To: linuxppc-dev

Currently, or PCI code uses the pcibios_fixup_bus() callback, which is
called by the generic code when probing PCI busses, for two different
thnings.

One is to setup things related to the bus itself, such as
reading bridge resources for P2P bridges, fixing them up, or setting
up the iommu's associated with bridges on some platfornms.

The other does some setup for each individual device under that
bridge, mostly setting up DMA mappings and interrupts.

The problem is that this approach doesn't work well with PCI hotplug
when an existing bus is re-probed for new children. This patch allows
this to be fixed by splitting it into two routines:

	pcibios_setup_bus_self() is now called to setup the bus itself

	pcibios_setup_bus_devices() is now called to setup devices

pcibios_fixup_bus() is then modified to call these two after reading the
bridge bases, and the OF based PCI probe is modified to avoid calling
into the first one when rescanning an existing bridge.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---


 arch/powerpc/include/asm/pci.h   |    5 +--
 arch/powerpc/kernel/pci-common.c |   59 +++++++++++++++++++--------------------
 arch/powerpc/kernel/pci_64.c     |   27 ++++++++++++++---
 3 files changed, 55 insertions(+), 36 deletions(-)

--- linux-work.orig/arch/powerpc/kernel/pci-common.c	2008-10-28 12:06:00.000000000 +1100
+++ linux-work/arch/powerpc/kernel/pci-common.c	2008-10-28 14:58:41.000000000 +1100
@@ -37,6 +37,7 @@
 #include <asm/machdep.h>
 #include <asm/ppc-pci.h>
 #include <asm/firmware.h>
+#include <asm/eeh.h>
 
 static DEFINE_SPINLOCK(hose_spinlock);
 
@@ -1076,31 +1077,17 @@ static void __devinit pcibios_fixup_brid
 	}
 }
 
-static void __devinit __pcibios_fixup_bus(struct pci_bus *bus)
+void __devinit pcibios_setup_bus_devices(struct pci_bus *bus)
 {
 	struct pci_dev *dev;
 
 	pr_debug("PCI: Fixup bus %d (%s)\n",
 		 bus->number, bus->self ? pci_name(bus->self) : "PHB");
 
-	/* Fixup PCI<->PCI bridges. Host bridges are handled separately, for
-	 * now differently between 32 and 64 bits.
-	 */
-	if (bus->self != NULL)
-		pcibios_fixup_bridge(bus);
-
-	/* Setup bus DMA mappings */
-	if (ppc_md.pci_dma_bus_setup)
-		ppc_md.pci_dma_bus_setup(bus);
-
 	/* Setup DMA for all PCI devices on that bus */
 	list_for_each_entry(dev, &bus->devices, bus_list)
 		pcibios_setup_new_device(dev);
 
-	/* Platform specific bus fixups */
-	if (ppc_md.pcibios_fixup_bus)
-		ppc_md.pcibios_fixup_bus(bus);
-
 	/* Read default IRQs and fixup if necessary */
 	list_for_each_entry(dev, &bus->devices, bus_list) {
 		pci_read_irq_line(dev);
@@ -1109,25 +1096,39 @@ static void __devinit __pcibios_fixup_bu
 	}
 }
 
+void __devinit pcibios_setup_bus_self(struct pci_bus *bus)
+{
+	/* Fix up the bus resources */
+	if (bus->self != NULL)
+		pcibios_fixup_bridge(bus);
+
+	/* Platform specific bus fixups. This is currently only used
+	 * by fsl_pci and I'm hoping getting rid of it at some point
+	 */
+	if (ppc_md.pcibios_fixup_bus)
+		ppc_md.pcibios_fixup_bus(bus);
+
+	/* Setup bus DMA mappings */
+	if (ppc_md.pci_dma_bus_setup)
+		ppc_md.pci_dma_bus_setup(bus);
+}
+
 void __devinit pcibios_fixup_bus(struct pci_bus *bus)
 {
 	/* When called from the generic PCI probe, read PCI<->PCI bridge
-	 * bases before proceeding
+	 * bases. This isn't called when generating the PCI tree from
+	 * the OF device-tree.
 	 */
 	if (bus->self != NULL)
 		pci_read_bridge_bases(bus);
-	__pcibios_fixup_bus(bus);
-}
-EXPORT_SYMBOL(pcibios_fixup_bus);
 
-/* When building a bus from the OF tree rather than probing, we need a
- * slightly different version of the fixup which doesn't read the
- * bridge bases using config space accesses
- */
-void __devinit pcibios_fixup_of_probed_bus(struct pci_bus *bus)
-{
-	__pcibios_fixup_bus(bus);
+	/* Now fixup the bus bus */
+	pcibios_setup_bus_self(bus);
+
+	/* Now fixup devices on that bus */
+	pcibios_setup_bus_devices(bus);
 }
+EXPORT_SYMBOL(pcibios_fixup_bus);
 
 static int skip_isa_ioresource_align(struct pci_dev *dev)
 {
@@ -1238,7 +1239,7 @@ static int __init reparent_resources(str
  *	    as well.
  */
 
-void pcibios_allocate_bus_resources(struct pci_bus *bus)
+static void pcibios_allocate_bus_resources(struct pci_bus *bus)
 {
 	struct pci_bus *b;
 	int i;
@@ -1394,11 +1395,12 @@ void __init pcibios_resource_survey(void
 }
 
 #ifdef CONFIG_HOTPLUG
+
 /* This is used by the pSeries hotplug driver to allocate resource
  * of newly plugged busses. We can try to consolidate with the
  * rest of the code later, for now, keep it as-is
  */
-void __devinit pcibios_claim_one_bus(struct pci_bus *bus)
+static void __devinit pcibios_claim_one_bus(struct pci_bus *bus)
 {
 	struct pci_dev *dev;
 	struct pci_bus *child_bus;
@@ -1418,7 +1420,6 @@ void __devinit pcibios_claim_one_bus(str
 	list_for_each_entry(child_bus, &bus->children, node)
 		pcibios_claim_one_bus(child_bus);
 }
-EXPORT_SYMBOL_GPL(pcibios_claim_one_bus);
 #endif /* CONFIG_HOTPLUG */
 
 int pcibios_enable_device(struct pci_dev *dev, int mask)
Index: linux-work/arch/powerpc/include/asm/pci.h
===================================================================
--- linux-work.orig/arch/powerpc/include/asm/pci.h	2008-10-28 13:03:13.000000000 +1100
+++ linux-work/arch/powerpc/include/asm/pci.h	2008-10-28 14:56:52.000000000 +1100
@@ -221,6 +221,7 @@ extern void of_scan_pci_bridge(struct de
 				struct pci_dev *dev);
 
 extern void of_scan_bus(struct device_node *node, struct pci_bus *bus);
+extern void of_rescan_bus(struct device_node *node, struct pci_bus *bus);
 
 extern int pci_read_irq_line(struct pci_dev *dev);
 
@@ -235,8 +236,8 @@ extern void pci_resource_to_user(const s
 				 const struct resource *rsrc,
 				 resource_size_t *start, resource_size_t *end);
 
-extern void pcibios_fixup_of_probed_bus(struct pci_bus *bus);
-
+extern void pcibios_setup_bus_devices(struct pci_bus *bus);
+extern void pcibios_setup_bus_self(struct pci_bus *bus);
 
 #endif	/* __KERNEL__ */
 #endif /* __ASM_POWERPC_PCI_H */
Index: linux-work/arch/powerpc/kernel/pci_64.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/pci_64.c	2008-10-28 13:03:54.000000000 +1100
+++ linux-work/arch/powerpc/kernel/pci_64.c	2008-10-28 14:24:25.000000000 +1100
@@ -189,8 +189,8 @@ struct pci_dev *of_create_pci_dev(struct
 }
 EXPORT_SYMBOL(of_create_pci_dev);
 
-void __devinit of_scan_bus(struct device_node *node,
-			   struct pci_bus *bus)
+static void __devinit __of_scan_bus(struct device_node *node,
+				    struct pci_bus *bus, int rescan_existing)
 {
 	struct device_node *child;
 	const u32 *reg;
@@ -215,8 +215,12 @@ void __devinit of_scan_bus(struct device
 		pr_debug("    dev header type: %x\n", dev->hdr_type);
 	}
 
-	/* Ally all fixups */
-	pcibios_fixup_of_probed_bus(bus);
+	/* Apply all fixups necessary. We don't fixup the bus "self"
+	 * for an existing bridge that is being rescanned
+	 */
+	if (!rescan_existing)
+		pcibios_setup_bus_self(bus);
+	pcibios_setup_bus_devices(bus);
 
 	/* Now scan child busses */
 	list_for_each_entry(dev, &bus->devices, bus_list) {
@@ -228,7 +232,20 @@ void __devinit of_scan_bus(struct device
 		}
 	}
 }
-EXPORT_SYMBOL(of_scan_bus);
+
+void __devinit of_scan_bus(struct device_node *node,
+			   struct pci_bus *bus)
+{
+	__of_scan_bus(node, bus, 0);
+}
+EXPORT_SYMBOL_GPL(of_scan_bus);
+
+void __devinit of_rescan_bus(struct device_node *node,
+			     struct pci_bus *bus)
+{
+	__of_scan_bus(node, bus, 1);
+}
+EXPORT_SYMBOL_GPL(of_rescan_bus);
 
 void __devinit of_scan_pci_bridge(struct device_node *node,
 				  struct pci_dev *dev)

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

* [PATCH 6/10] powerpc/eeh: Make EEH device add/remove more robust
  2008-10-28  5:48 [PATCH 0/10] powerpc/pci: Fix PCI Hotplug Benjamin Herrenschmidt
                   ` (4 preceding siblings ...)
  2008-10-28  5:48 ` [PATCH 5/10] powerpc/pci: Split pcibios_fixup_bus() into bus setup and devices setup Benjamin Herrenschmidt
@ 2008-10-28  5:48 ` Benjamin Herrenschmidt
  2008-10-28  5:48 ` [PATCH 7/10] powerpc/pci: Make pcibios_allocate_bus_resources " Benjamin Herrenschmidt
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Benjamin Herrenschmidt @ 2008-10-28  5:48 UTC (permalink / raw)
  To: linuxppc-dev

To properly fix PCI hotplug, it's useful to be able to make
the fixup passes on all devices whether they were just hot
plugged or already there.

The EEH code however used to not be very friendly with calling
eeh_add_device_late() multiple time, and not very rebust in
the way it generally tests whether a device is in the expected
state vs. the EEH code.

This improves it, along with cleaning up a couple of debug printk's

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---

 arch/powerpc/include/asm/eeh.h       |    9 +++----
 arch/powerpc/platforms/pseries/eeh.c |   44 +++++++++++++++++++----------------
 2 files changed, 29 insertions(+), 24 deletions(-)

--- linux-work.orig/arch/powerpc/platforms/pseries/eeh.c	2008-10-23 14:41:05.000000000 +1100
+++ linux-work/arch/powerpc/platforms/pseries/eeh.c	2008-10-28 14:03:26.000000000 +1100
@@ -21,6 +21,8 @@
  * Please address comments and feedback to Linas Vepstas <linas@austin.ibm.com>
  */
 
+#undef DEBUG
+
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/list.h>
@@ -488,10 +490,8 @@ int eeh_dn_check_failure(struct device_n
 	if (!(pdn->eeh_mode & EEH_MODE_SUPPORTED) ||
 	    pdn->eeh_mode & EEH_MODE_NOCHECK) {
 		ignored_check++;
-#ifdef DEBUG
-		printk ("EEH:ignored check (%x) for %s %s\n", 
-		        pdn->eeh_mode, pci_name (dev), dn->full_name);
-#endif
+		pr_debug("EEH: Ignored check (%x) for %s %s\n",
+			 pdn->eeh_mode, pci_name (dev), dn->full_name);
 		return 0;
 	}
 
@@ -1014,10 +1014,9 @@ static void *early_enable_eeh(struct dev
 			eeh_subsystem_enabled = 1;
 			pdn->eeh_mode |= EEH_MODE_SUPPORTED;
 
-#ifdef DEBUG
-			printk(KERN_DEBUG "EEH: %s: eeh enabled, config=%x pe_config=%x\n",
-			       dn->full_name, pdn->eeh_config_addr, pdn->eeh_pe_config_addr);
-#endif
+			pr_debug("EEH: %s: eeh enabled, config=%x pe_config=%x\n",
+				 dn->full_name, pdn->eeh_config_addr,
+				 pdn->eeh_pe_config_addr);
 		} else {
 
 			/* This device doesn't support EEH, but it may have an
@@ -1161,13 +1160,17 @@ static void eeh_add_device_late(struct p
 	if (!dev || !eeh_subsystem_enabled)
 		return;
 
-#ifdef DEBUG
-	printk(KERN_DEBUG "EEH: adding device %s\n", pci_name(dev));
-#endif
+	pr_debug("EEH: Adding device %s\n", pci_name(dev));
 
-	pci_dev_get (dev);
 	dn = pci_device_to_OF_node(dev);
 	pdn = PCI_DN(dn);
+	if (pdn->pcidev == dev) {
+		pr_debug("EEH: Already referenced !\n");
+		return;
+	}
+	WARN_ON(pdn->pcidev);
+
+	pci_dev_get (dev);
 	pdn->pcidev = dev;
 
 	pci_addr_cache_insert_device(dev);
@@ -1206,17 +1209,18 @@ static void eeh_remove_device(struct pci
 		return;
 
 	/* Unregister the device with the EEH/PCI address search system */
-#ifdef DEBUG
-	printk(KERN_DEBUG "EEH: remove device %s\n", pci_name(dev));
-#endif
-	pci_addr_cache_remove_device(dev);
-	eeh_sysfs_remove_device(dev);
+	pr_debug("EEH: Removing device %s\n", pci_name(dev));
 
 	dn = pci_device_to_OF_node(dev);
-	if (PCI_DN(dn)->pcidev) {
-		PCI_DN(dn)->pcidev = NULL;
-		pci_dev_put (dev);
+	if (PCI_DN(dn)->pcidev == NULL) {
+		pr_debug("EEH: Not referenced !\n");
+		return;
 	}
+	PCI_DN(dn)->pcidev = NULL;
+	pci_dev_put (dev);
+
+	pci_addr_cache_remove_device(dev);
+	eeh_sysfs_remove_device(dev);
 }
 
 void eeh_remove_bus_device(struct pci_dev *dev)
Index: linux-work/arch/powerpc/include/asm/eeh.h
===================================================================
--- linux-work.orig/arch/powerpc/include/asm/eeh.h	2008-10-28 14:07:47.000000000 +1100
+++ linux-work/arch/powerpc/include/asm/eeh.h	2008-10-28 14:08:44.000000000 +1100
@@ -17,8 +17,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  */
 
-#ifndef _PPC64_EEH_H
-#define _PPC64_EEH_H
+#ifndef _POWERPC_EEH_H
+#define _POWERPC_EEH_H
 #ifdef __KERNEL__
 
 #include <linux/init.h>
@@ -110,6 +110,7 @@ static inline void eeh_remove_bus_device
 #define EEH_IO_ERROR_VALUE(size) (-1UL)
 #endif /* CONFIG_EEH */
 
+#ifdef CONFIG_PPC64
 /*
  * MMIO read/write operations with EEH support.
  */
@@ -206,6 +207,6 @@ static inline void eeh_readsl(const vola
 	if (EEH_POSSIBLE_ERROR((*(((u32*)buf)+nl-1)), u32))
 		eeh_check_failure(addr, *(u32*)buf);
 }
-
+#endif /* CONFIG_PPC64 */
 #endif /* __KERNEL__ */
-#endif /* _PPC64_EEH_H */
+#endif /* _POWERPC_EEH_H */

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

* [PATCH 7/10] powerpc/pci: Make pcibios_allocate_bus_resources more robust
  2008-10-28  5:48 [PATCH 0/10] powerpc/pci: Fix PCI Hotplug Benjamin Herrenschmidt
                   ` (5 preceding siblings ...)
  2008-10-28  5:48 ` [PATCH 6/10] powerpc/eeh: Make EEH device add/remove more robust Benjamin Herrenschmidt
@ 2008-10-28  5:48 ` Benjamin Herrenschmidt
  2008-10-28  5:48 ` [PATCH 8/10] powerpc/pci: Fix unmapping of IO space on 64-bit Benjamin Herrenschmidt
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Benjamin Herrenschmidt @ 2008-10-28  5:48 UTC (permalink / raw)
  To: linuxppc-dev

To properly fix PCI hotplug, it's useful to be able to make
the fixup passes on all devices whether they were just hot
plugged or already there.

However, pcibios_allocate_bus_resources() wouldn't cope well
with being called twice for a given bus. This patch makes it
ignore resources that have already been allocated, along with
adding a bit of debug output.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---

 arch/powerpc/kernel/pci-common.c |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

--- linux-work.orig/arch/powerpc/kernel/pci-common.c	2008-10-28 14:04:45.000000000 +1100
+++ linux-work/arch/powerpc/kernel/pci-common.c	2008-10-28 14:04:57.000000000 +1100
@@ -1245,9 +1245,12 @@ static void pcibios_allocate_bus_resourc
 	int i;
 	struct resource *res, *pr;
 
+	pr_debug("PCI: Allocating bus resources for %04x:%02x...\n",
+		 pci_domain_nr(bus), bus->number);
+
 	for (i = 0; i < PCI_BUS_NUM_RESOURCES; ++i) {
 		if ((res = bus->resource[i]) == NULL || !res->flags
-		    || res->start > res->end)
+		    || res->start > res->end || res->parent)
 			continue;
 		if (bus->parent == NULL)
 			pr = (res->flags & IORESOURCE_IO) ?

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

* [PATCH 8/10] powerpc/pci: Fix unmapping of IO space on 64-bit
  2008-10-28  5:48 [PATCH 0/10] powerpc/pci: Fix PCI Hotplug Benjamin Herrenschmidt
                   ` (6 preceding siblings ...)
  2008-10-28  5:48 ` [PATCH 7/10] powerpc/pci: Make pcibios_allocate_bus_resources " Benjamin Herrenschmidt
@ 2008-10-28  5:48 ` Benjamin Herrenschmidt
  2008-10-28  5:48 ` [PATCH 9/10] powerpc/pci: Fix various pseries PCI Hotplug issues Benjamin Herrenschmidt
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Benjamin Herrenschmidt @ 2008-10-28  5:48 UTC (permalink / raw)
  To: linuxppc-dev

A typo/thinko made us pass the wrong argument to __flush_hash_table_range
when unplugging bridges, thus not flushing all the translations for
the IO space on unplug.

This causes the hypervisor to refuse unplugging slots.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---

 arch/powerpc/kernel/pci_64.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- linux-work.orig/arch/powerpc/kernel/pci_64.c	2008-10-28 16:33:48.000000000 +1100
+++ linux-work/arch/powerpc/kernel/pci_64.c	2008-10-28 16:38:45.000000000 +1100
@@ -426,7 +426,7 @@ int pcibios_unmap_io_space(struct pci_bu
 			 pci_name(bus->self));
 
 		__flush_hash_table_range(&init_mm, res->start + _IO_BASE,
-					 res->end - res->start + 1);
+					 res->end + _IO_BASE + 1);
 		return 0;
 	}
 

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

* [PATCH 9/10] powerpc/pci: Fix various pseries PCI Hotplug issues
  2008-10-28  5:48 [PATCH 0/10] powerpc/pci: Fix PCI Hotplug Benjamin Herrenschmidt
                   ` (7 preceding siblings ...)
  2008-10-28  5:48 ` [PATCH 8/10] powerpc/pci: Fix unmapping of IO space on 64-bit Benjamin Herrenschmidt
@ 2008-10-28  5:48 ` Benjamin Herrenschmidt
  2008-11-05 11:34   ` Paul Mackerras
  2008-10-28  5:48 ` [PATCH 10/10] powerpc/pci: Cosmetic cleanups of pci-common.c Benjamin Herrenschmidt
  2008-10-28  5:54 ` [PATCH 0/10] powerpc/pci: Fix PCI Hotplug Benjamin Herrenschmidt
  10 siblings, 1 reply; 14+ messages in thread
From: Benjamin Herrenschmidt @ 2008-10-28  5:48 UTC (permalink / raw)
  To: linuxppc-dev

The pseries PCI Hotplug code has a number of issues, ranging from
incorrect resource setup to crashes, depending on what is added,
when, whether it contains a bridge, etc etc....

This patch fixes a whole bunch of these, while actually simplifying
the code a bit, using more generic code in the process and factoring
out common code between adding of a PHB, a slot or a device.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---

 arch/powerpc/include/asm/pci-bridge.h      |    3 
 arch/powerpc/include/asm/pci.h             |    7 -
 arch/powerpc/kernel/pci-common.c           |   41 ++++++-
 arch/powerpc/kernel/rtas_pci.c             |   48 --------
 arch/powerpc/platforms/pseries/pci_dlpar.c |  164 ++++++++++++++---------------
 drivers/pci/hotplug/rpadlpar_core.c        |   69 +++++-------
 6 files changed, 150 insertions(+), 182 deletions(-)

--- linux-work.orig/arch/powerpc/include/asm/pci-bridge.h	2008-10-28 14:56:52.000000000 +1100
+++ linux-work/arch/powerpc/include/asm/pci-bridge.h	2008-10-28 14:58:54.000000000 +1100
@@ -241,9 +241,6 @@ extern void pcibios_remove_pci_devices(s
 
 /** Discover new pci devices under this bus, and add them */
 extern void pcibios_add_pci_devices(struct pci_bus *bus);
-extern void pcibios_fixup_new_pci_devices(struct pci_bus *bus);
-
-extern int pcibios_remove_root_bus(struct pci_controller *phb);
 
 static inline struct pci_controller *pci_bus_to_host(const struct pci_bus *bus)
 {
Index: linux-work/arch/powerpc/include/asm/pci.h
===================================================================
--- linux-work.orig/arch/powerpc/include/asm/pci.h	2008-10-28 14:56:52.000000000 +1100
+++ linux-work/arch/powerpc/include/asm/pci.h	2008-10-28 14:58:54.000000000 +1100
@@ -204,15 +204,12 @@ static inline struct resource *pcibios_s
 	return root;
 }
 
-extern void pcibios_setup_new_device(struct pci_dev *dev);
-
-extern void pcibios_claim_one_bus(struct pci_bus *b);
-
-extern void pcibios_allocate_bus_resources(struct pci_bus *bus);
+extern void pcibios_finish_adding_to_bus(struct pci_bus *bus);
 
 extern void pcibios_resource_survey(void);
 
 extern struct pci_controller *init_phb_dynamic(struct device_node *dn);
+extern int remove_phb_dynamic(struct pci_controller *phb);
 
 extern struct pci_dev *of_create_pci_dev(struct device_node *node,
 					struct pci_bus *bus, int devfn);
Index: linux-work/arch/powerpc/kernel/pci-common.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/pci-common.c	2008-10-28 14:58:48.000000000 +1100
+++ linux-work/arch/powerpc/kernel/pci-common.c	2008-10-28 14:59:16.000000000 +1100
@@ -202,7 +202,7 @@ char __devinit *pcibios_setup(char *str)
 	return str;
 }
 
-void __devinit pcibios_setup_new_device(struct pci_dev *dev)
+static void __devinit pcibios_setup_new_device(struct pci_dev *dev)
 {
 	struct dev_archdata *sd = &dev->dev.archdata;
 
@@ -220,7 +220,6 @@ void __devinit pcibios_setup_new_device(
 	if (ppc_md.pci_dma_dev_setup)
 		ppc_md.pci_dma_dev_setup(dev);
 }
-EXPORT_SYMBOL(pcibios_setup_new_device);
 
 /*
  * Reads the interrupt pin to determine if interrupt is use by card.
@@ -1399,9 +1398,10 @@ void __init pcibios_resource_survey(void
 
 #ifdef CONFIG_HOTPLUG
 
-/* This is used by the pSeries hotplug driver to allocate resource
+/* This is used by the PCI hotplug driver to allocate resource
  * of newly plugged busses. We can try to consolidate with the
- * rest of the code later, for now, keep it as-is
+ * rest of the code later, for now, keep it as-is as our main
+ * resource allocation function doesn't deal with sub-trees yet.
  */
 static void __devinit pcibios_claim_one_bus(struct pci_bus *bus)
 {
@@ -1416,6 +1416,14 @@ static void __devinit pcibios_claim_one_
 
 			if (r->parent || !r->start || !r->flags)
 				continue;
+
+			pr_debug("PCI: Claiming %s: "
+				 "Resource %d: %016llx..%016llx [%x]\n",
+				 pci_name(dev), i,
+				 (unsigned long long)r->start,
+				 (unsigned long long)r->end,
+				 (unsigned int)r->flags);
+
 			pci_claim_resource(dev, i);
 		}
 	}
@@ -1423,6 +1431,31 @@ static void __devinit pcibios_claim_one_
 	list_for_each_entry(child_bus, &bus->children, node)
 		pcibios_claim_one_bus(child_bus);
 }
+
+
+/* pcibios_finish_adding_to_bus
+ *
+ * This is to be called by the hotplug code after devices have been
+ * added to a bus, this include calling it for a PHB that is just
+ * being added
+ */
+void pcibios_finish_adding_to_bus(struct pci_bus *bus)
+{
+	pr_debug("PCI: Finishing adding to hotplug bus %04x:%02x\n",
+		 pci_domain_nr(bus), bus->number);
+
+	/* Allocate bus and devices resources */
+	pcibios_allocate_bus_resources(bus);
+	pcibios_claim_one_bus(bus);
+
+	/* Add new devices to global lists.  Register in proc, sysfs. */
+	pci_bus_add_devices(bus);
+
+	/* Fixup EEH */
+	eeh_add_device_tree_late(bus);
+}
+EXPORT_SYMBOL_GPL(pcibios_finish_adding_to_bus);
+
 #endif /* CONFIG_HOTPLUG */
 
 int pcibios_enable_device(struct pci_dev *dev, int mask)
Index: linux-work/arch/powerpc/kernel/rtas_pci.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/rtas_pci.c	2008-10-28 14:56:52.000000000 +1100
+++ linux-work/arch/powerpc/kernel/rtas_pci.c	2008-10-28 14:58:54.000000000 +1100
@@ -301,51 +301,3 @@ void __init find_and_init_phbs(void)
 #endif /* CONFIG_PPC32 */
 	}
 }
-
-/* RPA-specific bits for removing PHBs */
-int pcibios_remove_root_bus(struct pci_controller *phb)
-{
-	struct pci_bus *b = phb->bus;
-	struct resource *res;
-	int rc, i;
-
-	res = b->resource[0];
-	if (!res->flags) {
-		printk(KERN_ERR "%s: no IO resource for PHB %s\n", __func__,
-				b->name);
-		return 1;
-	}
-
-	rc = pcibios_unmap_io_space(b);
-	if (rc) {
-		printk(KERN_ERR "%s: failed to unmap IO on bus %s\n",
-			__func__, b->name);
-		return 1;
-	}
-
-	if (release_resource(res)) {
-		printk(KERN_ERR "%s: failed to release IO on bus %s\n",
-				__func__, b->name);
-		return 1;
-	}
-
-	for (i = 1; i < 3; ++i) {
-		res = b->resource[i];
-		if (!res->flags && i == 0) {
-			printk(KERN_ERR "%s: no MEM resource for PHB %s\n",
-				__func__, b->name);
-			return 1;
-		}
-		if (res->flags && release_resource(res)) {
-			printk(KERN_ERR
-			       "%s: failed to release IO %d on bus %s\n",
-				__func__, i, b->name);
-			return 1;
-		}
-	}
-
-	pcibios_free_controller(phb);
-
-	return 0;
-}
-EXPORT_SYMBOL(pcibios_remove_root_bus);
Index: linux-work/arch/powerpc/platforms/pseries/pci_dlpar.c
===================================================================
--- linux-work.orig/arch/powerpc/platforms/pseries/pci_dlpar.c	2008-10-28 14:56:52.000000000 +1100
+++ linux-work/arch/powerpc/platforms/pseries/pci_dlpar.c	2008-10-28 14:58:54.000000000 +1100
@@ -25,6 +25,8 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#undef DEBUG
+
 #include <linux/pci.h>
 #include <asm/pci-bridge.h>
 #include <asm/ppc-pci.h>
@@ -69,74 +71,25 @@ EXPORT_SYMBOL_GPL(pcibios_find_pci_bus);
  * Remove all of the PCI devices under this bus both from the
  * linux pci device tree, and from the powerpc EEH address cache.
  */
-void
-pcibios_remove_pci_devices(struct pci_bus *bus)
+void pcibios_remove_pci_devices(struct pci_bus *bus)
 {
-	struct pci_dev *dev, *tmp;
+ 	struct pci_dev *dev, *tmp;
+	struct pci_bus *child_bus;
+
+	/* First go down child busses */
+	list_for_each_entry(child_bus, &bus->children, node)
+		pcibios_remove_pci_devices(child_bus);
 
+	pr_debug("PCI: Removing devices on bus %04x:%02x\n",
+		 pci_domain_nr(bus),  bus->number);
 	list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) {
+		pr_debug("     * Removing %s...\n", pci_name(dev));
 		eeh_remove_bus_device(dev);
-		pci_remove_bus_device(dev);
-	}
+ 		pci_remove_bus_device(dev);
+ 	}
 }
 EXPORT_SYMBOL_GPL(pcibios_remove_pci_devices);
 
-/* Must be called before pci_bus_add_devices */
-void
-pcibios_fixup_new_pci_devices(struct pci_bus *bus)
-{
-	struct pci_dev *dev;
-
-	list_for_each_entry(dev, &bus->devices, bus_list) {
-		/* Skip already-added devices */
-		if (!dev->is_added) {
-			int i;
-
-			/* Fill device archdata and setup iommu table */
-			pcibios_setup_new_device(dev);
-
-			pci_read_irq_line(dev);
-			for (i = 0; i < PCI_NUM_RESOURCES; i++) {
-				struct resource *r = &dev->resource[i];
-
-				if (r->parent || !r->start || !r->flags)
-					continue;
-				pci_claim_resource(dev, i);
-			}
-		}
-	}
-}
-EXPORT_SYMBOL_GPL(pcibios_fixup_new_pci_devices);
-
-static int
-pcibios_pci_config_bridge(struct pci_dev *dev)
-{
-	u8 sec_busno;
-	struct pci_bus *child_bus;
-
-	/* Get busno of downstream bus */
-	pci_read_config_byte(dev, PCI_SECONDARY_BUS, &sec_busno);
-
-	/* Add to children of PCI bridge dev->bus */
-	child_bus = pci_add_new_bus(dev->bus, dev, sec_busno);
-	if (!child_bus) {
-		printk (KERN_ERR "%s: could not add second bus\n", __func__);
-		return -EIO;
-	}
-	sprintf(child_bus->name, "PCI Bus #%02x", child_bus->number);
-
-	pci_scan_child_bus(child_bus);
-
-	/* Fixup new pci devices */
-	pcibios_fixup_new_pci_devices(child_bus);
-
-	/* Make the discovered devices available */
-	pci_bus_add_devices(child_bus);
-
-	eeh_add_device_tree_late(child_bus);
-	return 0;
-}
-
 /**
  * pcibios_add_pci_devices - adds new pci devices to bus
  *
@@ -147,10 +100,9 @@ pcibios_pci_config_bridge(struct pci_dev
  * is how this routine differs from other, similar pcibios
  * routines.)
  */
-void
-pcibios_add_pci_devices(struct pci_bus * bus)
+void pcibios_add_pci_devices(struct pci_bus * bus)
 {
-	int slotno, num, mode;
+	int slotno, num, mode, pass, max;
 	struct pci_dev *dev;
 	struct device_node *dn = pci_bus_to_OF_node(bus);
 
@@ -162,26 +114,23 @@ pcibios_add_pci_devices(struct pci_bus *
 
 	if (mode == PCI_PROBE_DEVTREE) {
 		/* use ofdt-based probe */
-		of_scan_bus(dn, bus);
-		if (!list_empty(&bus->devices)) {
-			pcibios_fixup_new_pci_devices(bus);
-			pci_bus_add_devices(bus);
-			eeh_add_device_tree_late(bus);
-		}
+		of_rescan_bus(dn, bus);
 	} else if (mode == PCI_PROBE_NORMAL) {
 		/* use legacy probe */
 		slotno = PCI_SLOT(PCI_DN(dn->child)->devfn);
 		num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0));
-		if (num) {
-			pcibios_fixup_new_pci_devices(bus);
-			pci_bus_add_devices(bus);
-			eeh_add_device_tree_late(bus);
+		if (!num)
+			return;
+		pcibios_setup_bus_devices(bus);
+		max = bus->secondary;
+		for (pass=0; pass < 2; pass++)
+			list_for_each_entry(dev, &bus->devices, bus_list) {
+			if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
+			    dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
+				max = pci_scan_bridge(bus, dev, max, pass);
 		}
-
-		list_for_each_entry(dev, &bus->devices, bus_list)
-			if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)
-				pcibios_pci_config_bridge(dev);
 	}
+	pcibios_finish_adding_to_bus(bus);
 }
 EXPORT_SYMBOL_GPL(pcibios_add_pci_devices);
 
@@ -189,7 +138,8 @@ struct pci_controller * __devinit init_p
 {
 	struct pci_controller *phb;
 	int primary;
-	struct pci_bus *b;
+
+	pr_debug("PCI: Initializing new hotplug PHB %s\n", dn->full_name);
 
 	primary = list_empty(&hose_list);
 	phb = pcibios_alloc_controller(dn);
@@ -204,11 +154,59 @@ struct pci_controller * __devinit init_p
 		eeh_add_device_tree_early(dn);
 
 	scan_phb(phb);
-	pcibios_allocate_bus_resources(phb->bus);
-	pcibios_fixup_new_pci_devices(phb->bus);
-	pci_bus_add_devices(phb->bus);
-	eeh_add_device_tree_late(phb->bus);
+	pcibios_finish_adding_to_bus(phb->bus);
 
 	return phb;
 }
 EXPORT_SYMBOL_GPL(init_phb_dynamic);
+
+/* RPA-specific bits for removing PHBs */
+int remove_phb_dynamic(struct pci_controller *phb)
+{
+	struct pci_bus *b = phb->bus;
+	struct resource *res;
+	int rc, i;
+
+	pr_debug("PCI: Removing PHB %04x:%02x... \n",
+		 pci_domain_nr(b), b->number);
+
+	/* We cannot to remove a root bus that has children */
+	if (!(list_empty(&b->children) && list_empty(&b->devices)))
+		return -EBUSY;
+
+	/* We -know- there aren't any child devices anymore at this stage
+	 * and thus, we can safely unmap the IO space as it's not in use
+	 */
+	res = &phb->io_resource;
+	if (res->flags & IORESOURCE_IO) {
+		rc = pcibios_unmap_io_space(b);
+		if (rc) {
+			printk(KERN_ERR "%s: failed to unmap IO on bus %s\n",
+			       __func__, b->name);
+			return 1;
+		}
+	}
+
+	/* Unregister the bridge device from sysfs and remove the PCI bus */
+	device_unregister(b->bridge);
+	phb->bus = NULL;
+	pci_remove_bus(b);
+
+	/* Now release the IO resource */
+	if (res->flags & IORESOURCE_IO)
+		release_resource(res);
+
+	/* Release memory resources */
+	for (i = 0; i < 3; ++i) {
+		res = &phb->mem_resources[i];
+		if (!(res->flags & IORESOURCE_MEM))
+			continue;
+		release_resource(res);
+	}
+
+	/* Free pci_controller data structure */
+	pcibios_free_controller(phb);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(remove_phb_dynamic);
Index: linux-work/drivers/pci/hotplug/rpadlpar_core.c
===================================================================
--- linux-work.orig/drivers/pci/hotplug/rpadlpar_core.c	2008-10-28 14:56:52.000000000 +1100
+++ linux-work/drivers/pci/hotplug/rpadlpar_core.c	2008-10-28 14:58:54.000000000 +1100
@@ -14,6 +14,9 @@
  *      as published by the Free Software Foundation; either version
  *      2 of the License, or (at your option) any later version.
  */
+
+#undef DEBUG
+
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/string.h>
@@ -151,20 +154,20 @@ static void dlpar_pci_add_bus(struct dev
 		return;
 	}
 
+	/* Scan below the new bridge */
 	if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
 	    dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
 		of_scan_pci_bridge(dn, dev);
 
-	pcibios_fixup_new_pci_devices(dev->subordinate);
-
-	/* Claim new bus resources */
-	pcibios_claim_one_bus(dev->bus);
-
 	/* Map IO space for child bus, which may or may not succeed */
 	pcibios_map_io_space(dev->subordinate);
 
-	/* Add new devices to global lists.  Register in proc, sysfs. */
-	pci_bus_add_devices(phb->bus);
+	/* Finish adding it : resource allocation, adding devices, etc...
+	 * Note that we need to perform the finish pass on the -parent-
+	 * bus of the EADS bridge so the bridge device itself gets
+	 * properly added
+	 */
+	pcibios_finish_adding_to_bus(phb->bus);
 }
 
 static int dlpar_add_pci_slot(char *drc_name, struct device_node *dn)
@@ -203,27 +206,6 @@ static int dlpar_add_pci_slot(char *drc_
 	return 0;
 }
 
-static int dlpar_remove_root_bus(struct pci_controller *phb)
-{
-	struct pci_bus *phb_bus;
-	int rc;
-
-	phb_bus = phb->bus;
-	if (!(list_empty(&phb_bus->children) &&
-	      list_empty(&phb_bus->devices))) {
-		return -EBUSY;
-	}
-
-	rc = pcibios_remove_root_bus(phb);
-	if (rc)
-		return -EIO;
-
-	device_unregister(phb_bus->bridge);
-	pci_remove_bus(phb_bus);
-
-	return 0;
-}
-
 static int dlpar_remove_phb(char *drc_name, struct device_node *dn)
 {
 	struct slot *slot;
@@ -235,18 +217,15 @@ static int dlpar_remove_phb(char *drc_na
 
 	/* If pci slot is hotplugable, use hotplug to remove it */
 	slot = find_php_slot(dn);
-	if (slot) {
-		if (rpaphp_deregister_slot(slot)) {
-			printk(KERN_ERR
-				"%s: unable to remove hotplug slot %s\n",
-				__func__, drc_name);
-			return -EIO;
-		}
+	if (slot && rpaphp_deregister_slot(slot)) {
+		printk(KERN_ERR "%s: unable to remove hotplug slot %s\n",
+		       __func__, drc_name);
+		return -EIO;
 	}
 
 	pdn = dn->data;
 	BUG_ON(!pdn || !pdn->phb);
-	rc = dlpar_remove_root_bus(pdn->phb);
+	rc = remove_phb_dynamic(pdn->phb);
 	if (rc < 0)
 		return rc;
 
@@ -378,26 +357,38 @@ int dlpar_remove_pci_slot(char *drc_name
 	if (!bus)
 		return -EINVAL;
 
-	/* If pci slot is hotplugable, use hotplug to remove it */
+	pr_debug("PCI: Removing PCI slot below EADS bridge %s\n",
+		 bus->self ? pci_name(bus->self) : "<!PHB!>");
+
 	slot = find_php_slot(dn);
 	if (slot) {
+		pr_debug("PCI: Removing hotplug slot for %04x:%02x...\n",
+			 pci_domain_nr(bus), bus->number);
+
 		if (rpaphp_deregister_slot(slot)) {
 			printk(KERN_ERR
 				"%s: unable to remove hotplug slot %s\n",
 				__func__, drc_name);
 			return -EIO;
 		}
-	} else
-		pcibios_remove_pci_devices(bus);
+	}
+
+	/* Remove all devices below slot */
+	pcibios_remove_pci_devices(bus);
 
+	/* Unmap PCI IO space */
 	if (pcibios_unmap_io_space(bus)) {
 		printk(KERN_ERR "%s: failed to unmap bus range\n",
 			__func__);
 		return -ERANGE;
 	}
 
+	/* Remove the EADS bridge device itself */
 	BUG_ON(!bus->self);
+	pr_debug("PCI: Now removing bridge device %s\n", pci_name(bus->self));
+	eeh_remove_bus_device(bus->self);
 	pci_remove_bus_device(bus->self);
+
 	return 0;
 }
 

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

* [PATCH 10/10] powerpc/pci: Cosmetic cleanups of pci-common.c
  2008-10-28  5:48 [PATCH 0/10] powerpc/pci: Fix PCI Hotplug Benjamin Herrenschmidt
                   ` (8 preceding siblings ...)
  2008-10-28  5:48 ` [PATCH 9/10] powerpc/pci: Fix various pseries PCI Hotplug issues Benjamin Herrenschmidt
@ 2008-10-28  5:48 ` Benjamin Herrenschmidt
  2008-10-28  5:54 ` [PATCH 0/10] powerpc/pci: Fix PCI Hotplug Benjamin Herrenschmidt
  10 siblings, 0 replies; 14+ messages in thread
From: Benjamin Herrenschmidt @ 2008-10-28  5:48 UTC (permalink / raw)
  To: linuxppc-dev

This does a few costmetic cleanups, moving a couple of things
around but without actually changing what the code does.

(There is a minor change in ordering of operations in
pcibios_setup_bus_devices but it should have no impact).

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---

 arch/powerpc/kernel/pci-common.c |   77 ++++++++++++++++++---------------------
 1 file changed, 36 insertions(+), 41 deletions(-)

--- linux-work.orig/arch/powerpc/kernel/pci-common.c	2008-10-28 16:39:53.000000000 +1100
+++ linux-work/arch/powerpc/kernel/pci-common.c	2008-10-28 16:39:54.000000000 +1100
@@ -202,25 +202,6 @@ char __devinit *pcibios_setup(char *str)
 	return str;
 }
 
-static void __devinit pcibios_setup_new_device(struct pci_dev *dev)
-{
-	struct dev_archdata *sd = &dev->dev.archdata;
-
-	sd->of_node = pci_device_to_OF_node(dev);
-
-	pr_debug("PCI: device %s OF node: %s\n", pci_name(dev),
-		 sd->of_node ? sd->of_node->full_name : "<none>");
-
-	sd->dma_ops = pci_dma_ops;
-#ifdef CONFIG_PPC32
-	sd->dma_data = (void *)PCI_DRAM_OFFSET;
-#endif
-	set_dev_node(&dev->dev, pcibus_to_node(dev->bus));
-
-	if (ppc_md.pci_dma_dev_setup)
-		ppc_md.pci_dma_dev_setup(dev);
-}
-
 /*
  * Reads the interrupt pin to determine if interrupt is use by card.
  * If the interrupt is used, then gets the interrupt line from the
@@ -1076,33 +1057,14 @@ static void __devinit pcibios_fixup_brid
 	}
 }
 
-void __devinit pcibios_setup_bus_devices(struct pci_bus *bus)
-{
-	struct pci_dev *dev;
-
-	pr_debug("PCI: Fixup bus %d (%s)\n",
-		 bus->number, bus->self ? pci_name(bus->self) : "PHB");
-
-	/* Setup DMA for all PCI devices on that bus */
-	list_for_each_entry(dev, &bus->devices, bus_list)
-		pcibios_setup_new_device(dev);
-
-	/* Read default IRQs and fixup if necessary */
-	list_for_each_entry(dev, &bus->devices, bus_list) {
-		pci_read_irq_line(dev);
-		if (ppc_md.pci_irq_fixup)
-			ppc_md.pci_irq_fixup(dev);
-	}
-}
-
 void __devinit pcibios_setup_bus_self(struct pci_bus *bus)
 {
-	/* Fix up the bus resources */
+	/* Fix up the bus resources for P2P bridges */
 	if (bus->self != NULL)
 		pcibios_fixup_bridge(bus);
 
 	/* Platform specific bus fixups. This is currently only used
-	 * by fsl_pci and I'm hoping getting rid of it at some point
+	 * by fsl_pci and I'm hoping to get rid of it at some point
 	 */
 	if (ppc_md.pcibios_fixup_bus)
 		ppc_md.pcibios_fixup_bus(bus);
@@ -1112,10 +1074,43 @@ void __devinit pcibios_setup_bus_self(st
 		ppc_md.pci_dma_bus_setup(bus);
 }
 
+void __devinit pcibios_setup_bus_devices(struct pci_bus *bus)
+{
+	struct pci_dev *dev;
+
+	pr_debug("PCI: Fixup bus devices %d (%s)\n",
+		 bus->number, bus->self ? pci_name(bus->self) : "PHB");
+
+	list_for_each_entry(dev, &bus->devices, bus_list) {
+		struct dev_archdata *sd = &dev->dev.archdata;
+
+		/* Setup OF node pointer in archdata */
+		sd->of_node = pci_device_to_OF_node(dev);
+
+		/* Fixup NUMA node as it may not be setup yet by the generic
+		 * code and is needed by the DMA init
+		 */
+		set_dev_node(&dev->dev, pcibus_to_node(dev->bus));
+
+		/* Hook up default DMA ops */
+		sd->dma_ops = pci_dma_ops;
+		sd->dma_data = (void *)PCI_DRAM_OFFSET;
+
+		/* Additional platform DMA/iommu setup */
+		if (ppc_md.pci_dma_dev_setup)
+			ppc_md.pci_dma_dev_setup(dev);
+
+		/* Read default IRQs and fixup if necessary */
+		pci_read_irq_line(dev);
+		if (ppc_md.pci_irq_fixup)
+			ppc_md.pci_irq_fixup(dev);
+	}
+}
+
 void __devinit pcibios_fixup_bus(struct pci_bus *bus)
 {
 	/* When called from the generic PCI probe, read PCI<->PCI bridge
-	 * bases. This isn't called when generating the PCI tree from
+	 * bases. This is -not- called when generating the PCI tree from
 	 * the OF device-tree.
 	 */
 	if (bus->self != NULL)

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

* Re: [PATCH 0/10] powerpc/pci: Fix PCI Hotplug
  2008-10-28  5:48 [PATCH 0/10] powerpc/pci: Fix PCI Hotplug Benjamin Herrenschmidt
                   ` (9 preceding siblings ...)
  2008-10-28  5:48 ` [PATCH 10/10] powerpc/pci: Cosmetic cleanups of pci-common.c Benjamin Herrenschmidt
@ 2008-10-28  5:54 ` Benjamin Herrenschmidt
  10 siblings, 0 replies; 14+ messages in thread
From: Benjamin Herrenschmidt @ 2008-10-28  5:54 UTC (permalink / raw)
  To: linuxppc-dev

On Tue, 2008-10-28 at 16:48 +1100, Benjamin Herrenschmidt wrote:
> This series of patches is aimed at fixing all sort of issues
> with the PCI hotplug support on pSeries. The meant is in the
> second to last patch, but it relies on a whole bunch of small
> changes to separate the bus fixup operation in two that are
> needed to fix the root of most problems.
> 
> Please review/test asap as I would like that in 2.6.28 despite
> being a bit late, as without these, PCI hotplug on pseries pretty
> much doesn't work. It should also make it easier in the future to
> implement hotplug support on other platforms.

Specifically, Kumar and Josh, can you give a couple of spins
of kernels with those patches on your respective platforms to
make sure I haven't broken something ?

Cheers,
Ben.

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

* Re: [PATCH 9/10] powerpc/pci: Fix various pseries PCI Hotplug issues
  2008-10-28  5:48 ` [PATCH 9/10] powerpc/pci: Fix various pseries PCI Hotplug issues Benjamin Herrenschmidt
@ 2008-11-05 11:34   ` Paul Mackerras
  2008-11-05 20:30     ` Benjamin Herrenschmidt
  0 siblings, 1 reply; 14+ messages in thread
From: Paul Mackerras @ 2008-11-05 11:34 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev

Benjamin Herrenschmidt writes:

> The pseries PCI Hotplug code has a number of issues, ranging from
> incorrect resource setup to crashes, depending on what is added,
> when, whether it contains a bridge, etc etc....
> 
> This patch fixes a whole bunch of these, while actually simplifying
> the code a bit, using more generic code in the process and factoring
> out common code between adding of a PHB, a slot or a device.

This causes a compile error on Cell:

arch/powerpc/kernel/of_platform.c: In function 'of_pci_phb_probe':
arch/powerpc/kernel/of_platform.c:287: error: implicit declaration of function 'pcibios_claim_one_bus'
make[2]: *** [arch/powerpc/kernel/of_platform.o] Error 1

Paul.

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

* Re: [PATCH 9/10] powerpc/pci: Fix various pseries PCI Hotplug issues
  2008-11-05 11:34   ` Paul Mackerras
@ 2008-11-05 20:30     ` Benjamin Herrenschmidt
  0 siblings, 0 replies; 14+ messages in thread
From: Benjamin Herrenschmidt @ 2008-11-05 20:30 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev

On Wed, 2008-11-05 at 22:34 +1100, Paul Mackerras wrote:
> Benjamin Herrenschmidt writes:
> 
> > The pseries PCI Hotplug code has a number of issues, ranging from
> > incorrect resource setup to crashes, depending on what is added,
> > when, whether it contains a bridge, etc etc....
> > 
> > This patch fixes a whole bunch of these, while actually simplifying
> > the code a bit, using more generic code in the process and factoring
> > out common code between adding of a PHB, a slot or a device.
> 
> This causes a compile error on Cell:
> 
> arch/powerpc/kernel/of_platform.c: In function 'of_pci_phb_probe':
> arch/powerpc/kernel/of_platform.c:287: error: implicit declaration of function 'pcibios_claim_one_bus'
> make[2]: *** [arch/powerpc/kernel/of_platform.o] Error 1

Ah right, cell +/- uses the hotplug PCI stuff to probe it's PHB, a
bit strange I admit. Probably have to take that out of CONFIG_HOTPLUG.

Ben.

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

end of thread, other threads:[~2008-11-05 20:30 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-10-28  5:48 [PATCH 0/10] powerpc/pci: Fix PCI Hotplug Benjamin Herrenschmidt
2008-10-28  5:48 ` [PATCH 1/10] powerpc/pci: Properly allocate bus resources for hotplug PHBs Benjamin Herrenschmidt
2008-10-28  5:48 ` [PATCH 2/10] powerpc/pci: Cleanup debug printk's Benjamin Herrenschmidt
2008-10-28  5:48 ` [PATCH 3/10] powerpc/pci: Use commont PHB resource hookup Benjamin Herrenschmidt
2008-10-28  5:48 ` [PATCH 4/10] powerpc/pci: Remove pcibios_do_bus_setup() Benjamin Herrenschmidt
2008-10-28  5:48 ` [PATCH 5/10] powerpc/pci: Split pcibios_fixup_bus() into bus setup and devices setup Benjamin Herrenschmidt
2008-10-28  5:48 ` [PATCH 6/10] powerpc/eeh: Make EEH device add/remove more robust Benjamin Herrenschmidt
2008-10-28  5:48 ` [PATCH 7/10] powerpc/pci: Make pcibios_allocate_bus_resources " Benjamin Herrenschmidt
2008-10-28  5:48 ` [PATCH 8/10] powerpc/pci: Fix unmapping of IO space on 64-bit Benjamin Herrenschmidt
2008-10-28  5:48 ` [PATCH 9/10] powerpc/pci: Fix various pseries PCI Hotplug issues Benjamin Herrenschmidt
2008-11-05 11:34   ` Paul Mackerras
2008-11-05 20:30     ` Benjamin Herrenschmidt
2008-10-28  5:48 ` [PATCH 10/10] powerpc/pci: Cosmetic cleanups of pci-common.c Benjamin Herrenschmidt
2008-10-28  5:54 ` [PATCH 0/10] powerpc/pci: Fix PCI Hotplug Benjamin Herrenschmidt

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).