powerpc/pci: Properly allocate bus resources for hotplug PHBs

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 diff appears a bit messy, this is mainly due to moving everything
one tab to the left in the pcibios_allocate_bus_resources routine.
The 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>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
This commit is contained in:
Nathan Fontenot 2008-10-27 19:48:17 +00:00 committed by Paul Mackerras
parent 6098e2ee14
commit e90a131846
3 changed files with 60 additions and 56 deletions

View File

@ -208,6 +208,8 @@ extern void pcibios_setup_new_device(struct pci_dev *dev);
extern void pcibios_claim_one_bus(struct pci_bus *b); 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 void pcibios_resource_survey(void);
extern struct pci_controller *init_phb_dynamic(struct device_node *dn); extern struct pci_controller *init_phb_dynamic(struct device_node *dn);

View File

@ -1239,14 +1239,12 @@ static int __init reparent_resources(struct resource *parent,
* as well. * 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; int i;
struct resource *res, *pr; 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) { for (i = 0; i < PCI_BUS_NUM_RESOURCES; ++i) {
if ((res = bus->resource[i]) == NULL || !res->flags if ((res = bus->resource[i]) == NULL || !res->flags
|| res->start > res->end) || res->start > res->end)
@ -1293,15 +1291,14 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
if (reparent_resources(pr, res) == 0) if (reparent_resources(pr, res) == 0)
continue; continue;
} }
printk(KERN_WARNING printk(KERN_WARNING "PCI: Cannot allocate resource region "
"PCI: Cannot allocate resource region " "%d of PCI bridge %d, will remap\n", i, bus->number);
"%d of PCI bridge %d, will remap\n",
i, bus->number);
clear_resource: clear_resource:
res->flags = 0; res->flags = 0;
} }
pcibios_allocate_bus_resources(&bus->children);
} 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) static inline void __devinit alloc_resource(struct pci_dev *dev, int idx)
@ -1372,10 +1369,13 @@ static void __init pcibios_allocate_resources(int pass)
void __init pcibios_resource_survey(void) void __init pcibios_resource_survey(void)
{ {
struct pci_bus *b;
/* Allocate and assign resources. If we re-assign everything, then /* Allocate and assign resources. If we re-assign everything, then
* we skip the allocate phase * 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)) { if (!(ppc_pci_flags & PPC_PCI_REASSIGN_ALL_RSRC)) {
pcibios_allocate_resources(0); pcibios_allocate_resources(0);

View File

@ -189,6 +189,7 @@ struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn)
{ {
struct pci_controller *phb; struct pci_controller *phb;
int primary; int primary;
struct pci_bus *b;
primary = list_empty(&hose_list); primary = list_empty(&hose_list);
phb = pcibios_alloc_controller(dn); phb = pcibios_alloc_controller(dn);
@ -203,6 +204,7 @@ struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn)
eeh_add_device_tree_early(dn); eeh_add_device_tree_early(dn);
scan_phb(phb); scan_phb(phb);
pcibios_allocate_bus_resources(phb->bus);
pcibios_fixup_new_pci_devices(phb->bus); pcibios_fixup_new_pci_devices(phb->bus);
pci_bus_add_devices(phb->bus); pci_bus_add_devices(phb->bus);
eeh_add_device_tree_late(phb->bus); eeh_add_device_tree_late(phb->bus);