Message ID | 1263901701-16182-1-git-send-email-stefan.bader@canonical.com |
---|---|
State | Accepted |
Delegated to: | Stefan Bader |
Headers | show |
On Tue, Jan 19, 2010 at 12:48:21PM +0100, Stefan Bader wrote: > SRU Justication: > > Impact: On powerpc, the cardbus code needs to run through fixup code, > otherwise the kernel will crash with inserted cards. > > Fix: The patch, backported from upstream, will create a fixup function > which is doing nothing on all architectures but powerpc. And for powerpc > it will call the required fixup code. > For Lucid this has been forwarded to stable@kernel.org, but the 2.6.31.y > support ended now. > > Testcase: see bug report. > > From 8a76c709711ef4d555baa1ba540f45a6c6d8b440 Mon Sep 17 00:00:00 2001 > From: Benjamin Herrenschmidt <benh@kernel.crashing.org> > Date: Wed, 9 Dec 2009 17:52:13 +1100 > Subject: [PATCH] PCI/cardbus: Add a fixup hook and fix powerpc > > BugLink: http://bugs.launchpad.net/bugs/455723 > > commit 2d1c861871d767153538a77c498752b36d4bb4b8 upstream > > The cardbus code creates PCI devices without ever going through the > necessary fixup bits and pieces that normal PCI devices go through. > > There's in fact a commented out call to pcibios_fixup_bus() in there, > it's commented because ... it doesn't work. > > I could make pcibios_fixup_bus() do the right thing on powerpc easily > but I felt it cleaner instead to provide a specific hook pci_fixup_cardbus > for which a weak empty implementation is provided by the PCI core. > > This fixes cardbus on powerbooks and probably all other PowerPC > platforms which was broken completely for ever on some platforms and > since 2.6.31 on others such as PowerBooks when we made the DMA ops > mandatory (since those are setup by the fixups). > > Acked-by: Dominik Brodowski <linux@dominikbrodowski.net> > Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> > Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> > Signed-off-by: Stefan Bader <stefan.bader@canonical.com> > Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> > Acked-by: Jesse Barnes <jbarnes@virtuousgeek.org> > --- > arch/powerpc/kernel/pci-common.c | 13 +++++++++++++ > drivers/pci/pci.c | 5 +++++ > drivers/pcmcia/cardbus.c | 2 +- > include/linux/pci.h | 3 +++ > 4 files changed, 22 insertions(+), 1 deletions(-) > > diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c > index e8dfdbd..cadbed6 100644 > --- a/arch/powerpc/kernel/pci-common.c > +++ b/arch/powerpc/kernel/pci-common.c > @@ -1107,6 +1107,12 @@ void __devinit pcibios_setup_bus_devices(struct pci_bus *bus) > list_for_each_entry(dev, &bus->devices, bus_list) { > struct dev_archdata *sd = &dev->dev.archdata; > > + /* Cardbus can call us to add new devices to a bus, so ignore > + * those who are already fully discovered > + */ > + if (dev->is_added) > + continue; > + > /* Setup OF node pointer in archdata */ > sd->of_node = pci_device_to_OF_node(dev); > > @@ -1147,6 +1153,13 @@ void __devinit pcibios_fixup_bus(struct pci_bus *bus) > } > EXPORT_SYMBOL(pcibios_fixup_bus); > > +void __devinit pci_fixup_cardbus(struct pci_bus *bus) > +{ > + /* Now fixup devices on that bus */ > + pcibios_setup_bus_devices(bus); > +} > + > + > static int skip_isa_ioresource_align(struct pci_dev *dev) > { > if ((ppc_pci_flags & PPC_PCI_CAN_SKIP_ISA_ALIGN) && > diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c > index 4e4c295..6477722 100644 > --- a/drivers/pci/pci.c > +++ b/drivers/pci/pci.c > @@ -2723,6 +2723,11 @@ int __attribute__ ((weak)) pci_ext_cfg_avail(struct pci_dev *dev) > return 1; > } > > +void __weak pci_fixup_cardbus(struct pci_bus *bus) > +{ > +} > +EXPORT_SYMBOL(pci_fixup_cardbus); > + > static int __init pci_setup(char *str) > { > while (str) { > diff --git a/drivers/pcmcia/cardbus.c b/drivers/pcmcia/cardbus.c > index db77e1f..5c26793 100644 > --- a/drivers/pcmcia/cardbus.c > +++ b/drivers/pcmcia/cardbus.c > @@ -214,7 +214,7 @@ int __ref cb_alloc(struct pcmcia_socket * s) > unsigned int max, pass; > > s->functions = pci_scan_slot(bus, PCI_DEVFN(0, 0)); > -// pcibios_fixup_bus(bus); > + pci_fixup_cardbus(bus); > > max = bus->secondary; > for (pass = 0; pass < 2; pass++) > diff --git a/include/linux/pci.h b/include/linux/pci.h > index f5c7cd3..2547515 100644 > --- a/include/linux/pci.h > +++ b/include/linux/pci.h > @@ -564,6 +564,9 @@ void pcibios_align_resource(void *, struct resource *, resource_size_t, > resource_size_t); > void pcibios_update_irq(struct pci_dev *, int irq); > > +/* Weak but can be overriden by arch */ > +void pci_fixup_cardbus(struct pci_bus *); > + > /* Generic PCI functions used internally */ > > extern struct pci_bus *pci_find_bus(int domain, int busnr); Looks to only effect a change on powerpc. Seems ok to me. Acked-by: Andy Whitcroft <apw@canonical.com> -apw
On Wed, 2010-01-27 at 10:38 +0000, Andy Whitcroft wrote: > On Tue, Jan 19, 2010 at 12:48:21PM +0100, Stefan Bader wrote: > > SRU Justication: > > > > Impact: On powerpc, the cardbus code needs to run through fixup code, > > otherwise the kernel will crash with inserted cards. > > > > Fix: The patch, backported from upstream, will create a fixup function > > which is doing nothing on all architectures but powerpc. And for powerpc > > it will call the required fixup code. > > For Lucid this has been forwarded to stable@kernel.org, but the 2.6.31.y > > support ended now. > > > > Testcase: see bug report. > > > > From 8a76c709711ef4d555baa1ba540f45a6c6d8b440 Mon Sep 17 00:00:00 2001 > > From: Benjamin Herrenschmidt <benh@kernel.crashing.org> > > Date: Wed, 9 Dec 2009 17:52:13 +1100 > > Subject: [PATCH] PCI/cardbus: Add a fixup hook and fix powerpc > > > > BugLink: http://bugs.launchpad.net/bugs/455723 > > > > commit 2d1c861871d767153538a77c498752b36d4bb4b8 upstream > > > > The cardbus code creates PCI devices without ever going through the > > necessary fixup bits and pieces that normal PCI devices go through. > > > > There's in fact a commented out call to pcibios_fixup_bus() in there, > > it's commented because ... it doesn't work. > > > > I could make pcibios_fixup_bus() do the right thing on powerpc easily > > but I felt it cleaner instead to provide a specific hook pci_fixup_cardbus > > for which a weak empty implementation is provided by the PCI core. > > > > This fixes cardbus on powerbooks and probably all other PowerPC > > platforms which was broken completely for ever on some platforms and > > since 2.6.31 on others such as PowerBooks when we made the DMA ops > > mandatory (since those are setup by the fixups). > > > > Acked-by: Dominik Brodowski <linux@dominikbrodowski.net> > > Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> > > Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> > > Signed-off-by: Stefan Bader <stefan.bader@canonical.com> > > Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> > > Acked-by: Jesse Barnes <jbarnes@virtuousgeek.org> > > --- > > arch/powerpc/kernel/pci-common.c | 13 +++++++++++++ > > drivers/pci/pci.c | 5 +++++ > > drivers/pcmcia/cardbus.c | 2 +- > > include/linux/pci.h | 3 +++ > > 4 files changed, 22 insertions(+), 1 deletions(-) > > > > diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c > > index e8dfdbd..cadbed6 100644 > > --- a/arch/powerpc/kernel/pci-common.c > > +++ b/arch/powerpc/kernel/pci-common.c > > @@ -1107,6 +1107,12 @@ void __devinit pcibios_setup_bus_devices(struct pci_bus *bus) > > list_for_each_entry(dev, &bus->devices, bus_list) { > > struct dev_archdata *sd = &dev->dev.archdata; > > > > + /* Cardbus can call us to add new devices to a bus, so ignore > > + * those who are already fully discovered > > + */ > > + if (dev->is_added) > > + continue; > > + > > /* Setup OF node pointer in archdata */ > > sd->of_node = pci_device_to_OF_node(dev); > > > > @@ -1147,6 +1153,13 @@ void __devinit pcibios_fixup_bus(struct pci_bus *bus) > > } > > EXPORT_SYMBOL(pcibios_fixup_bus); > > > > +void __devinit pci_fixup_cardbus(struct pci_bus *bus) > > +{ > > + /* Now fixup devices on that bus */ > > + pcibios_setup_bus_devices(bus); > > +} > > + > > + > > static int skip_isa_ioresource_align(struct pci_dev *dev) > > { > > if ((ppc_pci_flags & PPC_PCI_CAN_SKIP_ISA_ALIGN) && > > diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c > > index 4e4c295..6477722 100644 > > --- a/drivers/pci/pci.c > > +++ b/drivers/pci/pci.c > > @@ -2723,6 +2723,11 @@ int __attribute__ ((weak)) pci_ext_cfg_avail(struct pci_dev *dev) > > return 1; > > } > > > > +void __weak pci_fixup_cardbus(struct pci_bus *bus) > > +{ > > +} > > +EXPORT_SYMBOL(pci_fixup_cardbus); > > + > > static int __init pci_setup(char *str) > > { > > while (str) { > > diff --git a/drivers/pcmcia/cardbus.c b/drivers/pcmcia/cardbus.c > > index db77e1f..5c26793 100644 > > --- a/drivers/pcmcia/cardbus.c > > +++ b/drivers/pcmcia/cardbus.c > > @@ -214,7 +214,7 @@ int __ref cb_alloc(struct pcmcia_socket * s) > > unsigned int max, pass; > > > > s->functions = pci_scan_slot(bus, PCI_DEVFN(0, 0)); > > -// pcibios_fixup_bus(bus); > > + pci_fixup_cardbus(bus); > > > > max = bus->secondary; > > for (pass = 0; pass < 2; pass++) > > diff --git a/include/linux/pci.h b/include/linux/pci.h > > index f5c7cd3..2547515 100644 > > --- a/include/linux/pci.h > > +++ b/include/linux/pci.h > > @@ -564,6 +564,9 @@ void pcibios_align_resource(void *, struct resource *, resource_size_t, > > resource_size_t); > > void pcibios_update_irq(struct pci_dev *, int irq); > > > > +/* Weak but can be overriden by arch */ > > +void pci_fixup_cardbus(struct pci_bus *); > > + > > /* Generic PCI functions used internally */ > > > > extern struct pci_bus *pci_find_bus(int domain, int busnr); > > Looks to only effect a change on powerpc. Seems ok to me. > > Acked-by: Andy Whitcroft <apw@canonical.com> Looks fine to me as well. Acked-by: Leann Ogasawara <leann.ogasawara@canonical.com>
applied and pushed
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index e8dfdbd..cadbed6 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c @@ -1107,6 +1107,12 @@ void __devinit pcibios_setup_bus_devices(struct pci_bus *bus) list_for_each_entry(dev, &bus->devices, bus_list) { struct dev_archdata *sd = &dev->dev.archdata; + /* Cardbus can call us to add new devices to a bus, so ignore + * those who are already fully discovered + */ + if (dev->is_added) + continue; + /* Setup OF node pointer in archdata */ sd->of_node = pci_device_to_OF_node(dev); @@ -1147,6 +1153,13 @@ void __devinit pcibios_fixup_bus(struct pci_bus *bus) } EXPORT_SYMBOL(pcibios_fixup_bus); +void __devinit pci_fixup_cardbus(struct pci_bus *bus) +{ + /* Now fixup devices on that bus */ + pcibios_setup_bus_devices(bus); +} + + static int skip_isa_ioresource_align(struct pci_dev *dev) { if ((ppc_pci_flags & PPC_PCI_CAN_SKIP_ISA_ALIGN) && diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 4e4c295..6477722 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -2723,6 +2723,11 @@ int __attribute__ ((weak)) pci_ext_cfg_avail(struct pci_dev *dev) return 1; } +void __weak pci_fixup_cardbus(struct pci_bus *bus) +{ +} +EXPORT_SYMBOL(pci_fixup_cardbus); + static int __init pci_setup(char *str) { while (str) { diff --git a/drivers/pcmcia/cardbus.c b/drivers/pcmcia/cardbus.c index db77e1f..5c26793 100644 --- a/drivers/pcmcia/cardbus.c +++ b/drivers/pcmcia/cardbus.c @@ -214,7 +214,7 @@ int __ref cb_alloc(struct pcmcia_socket * s) unsigned int max, pass; s->functions = pci_scan_slot(bus, PCI_DEVFN(0, 0)); -// pcibios_fixup_bus(bus); + pci_fixup_cardbus(bus); max = bus->secondary; for (pass = 0; pass < 2; pass++) diff --git a/include/linux/pci.h b/include/linux/pci.h index f5c7cd3..2547515 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -564,6 +564,9 @@ void pcibios_align_resource(void *, struct resource *, resource_size_t, resource_size_t); void pcibios_update_irq(struct pci_dev *, int irq); +/* Weak but can be overriden by arch */ +void pci_fixup_cardbus(struct pci_bus *); + /* Generic PCI functions used internally */ extern struct pci_bus *pci_find_bus(int domain, int busnr);