[Karmic] SRU: PCI/cardbus: Add a fixup hook and fix powerpc

Andy Whitcroft apw at canonical.com
Wed Jan 27 10:38:28 GMT 2010


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 at 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 at 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 at dominikbrodowski.net>
> Signed-off-by: Benjamin Herrenschmidt <benh at kernel.crashing.org>
> Signed-off-by: Jesse Barnes <jbarnes at virtuousgeek.org>
> Signed-off-by: Stefan Bader <stefan.bader at canonical.com>
> Acked-by: Benjamin Herrenschmidt <benh at kernel.crashing.org>
> Acked-by: Jesse Barnes <jbarnes at 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 at canonical.com>

-apw



More information about the kernel-team mailing list