From: Andrew Morton On Fri, 28 Mar 2008 16:10:11 -0700 (PDT) David Miller wrote: > From: Mariusz Kozlowski > Date: Fri, 28 Mar 2008 23:52:10 +0100 > > > The gregkh-pci-pci-sparc64-use-generic-pci_enable_resources.patch which > > replaces arch-specific code with generic pci_enable_resources() makes my sparc64 > > box unable to boot (that's what quilt bisection says). At first I see these messages: > > Yes, that generic code won't work because of the NULL > r->parent check. > > Alpha, ARM, V32, FRV, IA64, MIPS, MN10300, PARISC, PPC, > SH, V850, X86, and Xtensa are all likely to run into > problems because of this change. > > The only platform that did the check as a test of r->parent > being NULL is Powerpc. > > The rest either didn't check (like sparc64), or tested it by going: > > if (!r->start && r->end) > > So the amount of potential breakage from this change is enormous. Cc: Bjorn Helgaas Cc: Greg KH Signed-off-by: Andrew Morton --- arch/xtensa/kernel/pci.c | 57 ++++++++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff -puN arch/xtensa/kernel/pci.c~revert-gregkh-pci-pci-xtensa-use-generic-pci_enable_resources arch/xtensa/kernel/pci.c --- a/arch/xtensa/kernel/pci.c~revert-gregkh-pci-pci-xtensa-use-generic-pci_enable_resources +++ a/arch/xtensa/kernel/pci.c @@ -91,6 +91,37 @@ pcibios_align_resource(void *data, struc } } +int +pcibios_enable_resources(struct pci_dev *dev, int mask) +{ + u16 cmd, old_cmd; + int idx; + struct resource *r; + + pci_read_config_word(dev, PCI_COMMAND, &cmd); + old_cmd = cmd; + for(idx=0; idx<6; idx++) { + r = &dev->resource[idx]; + if (!r->start && r->end) { + printk (KERN_ERR "PCI: Device %s not available because " + "of resource collisions\n", pci_name(dev)); + return -EINVAL; + } + if (r->flags & IORESOURCE_IO) + cmd |= PCI_COMMAND_IO; + if (r->flags & IORESOURCE_MEM) + cmd |= PCI_COMMAND_MEMORY; + } + if (dev->resource[PCI_ROM_RESOURCE].start) + cmd |= PCI_COMMAND_MEMORY; + if (cmd != old_cmd) { + printk("PCI: Enabling device %s (%04x -> %04x)\n", + pci_name(dev), old_cmd, cmd); + pci_write_config_word(dev, PCI_COMMAND, cmd); + } + return 0; +} + struct pci_controller * __init pcibios_alloc_controller(void) { struct pci_controller *pci_ctrl; @@ -207,7 +238,31 @@ pcibios_update_irq(struct pci_dev *dev, int pcibios_enable_device(struct pci_dev *dev, int mask) { - return pci_enable_resources(dev, mask); + u16 cmd, old_cmd; + int idx; + struct resource *r; + + pci_read_config_word(dev, PCI_COMMAND, &cmd); + old_cmd = cmd; + for (idx=0; idx<6; idx++) { + r = &dev->resource[idx]; + if (!r->start && r->end) { + printk(KERN_ERR "PCI: Device %s not available because " + "of resource collisions\n", pci_name(dev)); + return -EINVAL; + } + if (r->flags & IORESOURCE_IO) + cmd |= PCI_COMMAND_IO; + if (r->flags & IORESOURCE_MEM) + cmd |= PCI_COMMAND_MEMORY; + } + if (cmd != old_cmd) { + printk("PCI: Enabling device %s (%04x -> %04x)\n", + pci_name(dev), old_cmd, cmd); + pci_write_config_word(dev, PCI_COMMAND, cmd); + } + + return 0; } #ifdef CONFIG_PROC_FS _