From: Jake Moilanen --- arch/ppc64/kernel/pSeries_pci.c | 26 ++++++++++++++++++++++++++ drivers/pci/probe.c | 7 ++++++- include/asm-alpha/pci.h | 1 + include/asm-arm/pci.h | 2 ++ include/asm-arm26/pci.h | 3 ++- include/asm-generic/pci.h | 2 ++ include/asm-h8300/pci.h | 1 + include/asm-i386/pci.h | 1 + include/asm-ia64/pci.h | 1 + include/asm-m68k/pci.h | 1 + include/asm-m68knommu/pci.h | 2 ++ include/asm-mips/pci.h | 1 + include/asm-parisc/pci.h | 1 + include/asm-ppc/pci.h | 1 + include/asm-ppc64/pci.h | 2 ++ include/asm-sh/pci.h | 1 + include/asm-sparc/pci.h | 1 + include/asm-sparc64/pci.h | 1 + include/asm-um/pci.h | 1 + include/asm-v850/pci.h | 2 ++ include/asm-x86_64/pci.h | 1 + 21 files changed, 57 insertions(+), 2 deletions(-) diff -puN arch/ppc64/kernel/pSeries_pci.c~pci-scan-all-functions arch/ppc64/kernel/pSeries_pci.c --- 25/arch/ppc64/kernel/pSeries_pci.c~pci-scan-all-functions 2004-01-29 23:23:59.000000000 -0800 +++ 25-akpm/arch/ppc64/kernel/pSeries_pci.c 2004-01-29 23:23:59.000000000 -0800 @@ -721,3 +721,29 @@ pci_find_hose_for_OF_device(struct devic } return NULL; } + +/* + * ppc64 can have multifunction devices that do not respond to function 0. + * In this case we must scan all functions. + */ +int +pcibios_scan_all_fns(struct pci_bus *bus, int devfn) +{ + struct device_node *busdn, *dn; + + if (bus->self) + busdn = pci_device_to_OF_node(bus->self); + else + busdn = bus->sysdata; /* must be a phb */ + + /* + * Check to see if there is any of the 8 functions are in the + * device tree. If they are then we need to scan all the + * functions of this slot. + */ + for (dn = busdn->child; dn; dn = dn->sibling) + if ((dn->devfn >> 3) == (devfn >> 3)) + return 1; + + return 0; +} diff -puN drivers/pci/probe.c~pci-scan-all-functions drivers/pci/probe.c --- 25/drivers/pci/probe.c~pci-scan-all-functions 2004-01-29 23:23:59.000000000 -0800 +++ 25-akpm/drivers/pci/probe.c 2004-01-29 23:27:27.000000000 -0800 @@ -8,6 +8,8 @@ #include #include +#include + #undef DEBUG #ifdef DEBUG @@ -633,6 +635,9 @@ pci_scan_single_device(struct pci_bus *b int __devinit pci_scan_slot(struct pci_bus *bus, int devfn) { int func, nr = 0; + int scan_all_fns; + + scan_all_fns = pcibios_scan_all_fns(bus, devfn); for (func = 0; func < 8; func++, devfn++) { struct pci_dev *dev; @@ -653,7 +658,7 @@ int __devinit pci_scan_slot(struct pci_b } } } else { - if (func == 0) + if (func == 0 && !scan_all_fns) break; } } diff -puN include/asm-alpha/pci.h~pci-scan-all-functions include/asm-alpha/pci.h --- 25/include/asm-alpha/pci.h~pci-scan-all-functions 2004-01-29 23:23:59.000000000 -0800 +++ 25-akpm/include/asm-alpha/pci.h 2004-01-29 23:23:59.000000000 -0800 @@ -51,6 +51,7 @@ struct pci_controller { bus numbers. */ #define pcibios_assign_all_busses() 1 +#define pcibios_scan_all_fns(a, b) 0 #define PCIBIOS_MIN_IO alpha_mv.min_io_address #define PCIBIOS_MIN_MEM alpha_mv.min_mem_address diff -puN include/asm-arm26/pci.h~pci-scan-all-functions include/asm-arm26/pci.h --- 25/include/asm-arm26/pci.h~pci-scan-all-functions 2004-01-29 23:23:59.000000000 -0800 +++ 25-akpm/include/asm-arm26/pci.h 2004-01-29 23:23:59.000000000 -0800 @@ -1,5 +1,6 @@ /* Should not be needed. IDE stupidity */ /* JMA 18.05.03 - is kinda needed, if only to tell it we don't have a PCI bus */ -#define PCI_DMA_BUS_IS_PHYS 0 +#define PCI_DMA_BUS_IS_PHYS 0 +#define pcibios_scan_all_fns(a, b) 0 diff -puN include/asm-arm/pci.h~pci-scan-all-functions include/asm-arm/pci.h --- 25/include/asm-arm/pci.h~pci-scan-all-functions 2004-01-29 23:23:59.000000000 -0800 +++ 25-akpm/include/asm-arm/pci.h 2004-01-29 23:23:59.000000000 -0800 @@ -20,6 +20,8 @@ #endif +#define pcibios_scan_all_fns(a, b) 0 + static inline void pcibios_set_master(struct pci_dev *dev) { /* No special bus mastering setup handling */ diff -puN include/asm-generic/pci.h~pci-scan-all-functions include/asm-generic/pci.h --- 25/include/asm-generic/pci.h~pci-scan-all-functions 2004-01-29 23:23:59.000000000 -0800 +++ 25-akpm/include/asm-generic/pci.h 2004-01-29 23:23:59.000000000 -0800 @@ -22,4 +22,6 @@ pcibios_resource_to_bus(struct pci_dev * region->end = res->end; } +#define pcibios_scan_all_fns(a, b) 0 + #endif diff -puN include/asm-h8300/pci.h~pci-scan-all-functions include/asm-h8300/pci.h --- 25/include/asm-h8300/pci.h~pci-scan-all-functions 2004-01-29 23:23:59.000000000 -0800 +++ 25-akpm/include/asm-h8300/pci.h 2004-01-29 23:23:59.000000000 -0800 @@ -8,6 +8,7 @@ */ #define pcibios_assign_all_busses() 0 +#define pcibios_scan_all_fns(a, b) 0 extern inline void pcibios_set_master(struct pci_dev *dev) { diff -puN include/asm-i386/pci.h~pci-scan-all-functions include/asm-i386/pci.h --- 25/include/asm-i386/pci.h~pci-scan-all-functions 2004-01-29 23:23:59.000000000 -0800 +++ 25-akpm/include/asm-i386/pci.h 2004-01-29 23:23:59.000000000 -0800 @@ -15,6 +15,7 @@ extern unsigned int pcibios_assign_all_b #else #define pcibios_assign_all_busses() 0 #endif +#define pcibios_scan_all_fns(a, b) 0 extern unsigned long pci_mem_start; #define PCIBIOS_MIN_IO 0x1000 diff -puN include/asm-ia64/pci.h~pci-scan-all-functions include/asm-ia64/pci.h --- 25/include/asm-ia64/pci.h~pci-scan-all-functions 2004-01-29 23:23:59.000000000 -0800 +++ 25-akpm/include/asm-ia64/pci.h 2004-01-29 23:23:59.000000000 -0800 @@ -16,6 +16,7 @@ * loader. */ #define pcibios_assign_all_busses() 0 +#define pcibios_scan_all_fns(a, b) 0 #define PCIBIOS_MIN_IO 0x1000 #define PCIBIOS_MIN_MEM 0x10000000 diff -puN include/asm-m68knommu/pci.h~pci-scan-all-functions include/asm-m68knommu/pci.h --- 25/include/asm-m68knommu/pci.h~pci-scan-all-functions 2004-01-29 23:23:59.000000000 -0800 +++ 25-akpm/include/asm-m68knommu/pci.h 2004-01-29 23:23:59.000000000 -0800 @@ -11,6 +11,8 @@ #define PCIBIOS_MIN_IO 0x100 #define PCIBIOS_MIN_MEM 0x00010000 +#define pcibios_scan_all_fns(a, b) 0 + /* * Return whether the given PCI device DMA address mask can * be supported properly. For example, if your device can diff -puN include/asm-m68k/pci.h~pci-scan-all-functions include/asm-m68k/pci.h --- 25/include/asm-m68k/pci.h~pci-scan-all-functions 2004-01-29 23:23:59.000000000 -0800 +++ 25-akpm/include/asm-m68k/pci.h 2004-01-29 23:23:59.000000000 -0800 @@ -36,6 +36,7 @@ struct pci_bus_info }; #define pcibios_assign_all_busses() 0 +#define pcibios_scan_all_fns(a, b) 0 static inline void pcibios_set_master(struct pci_dev *dev) { diff -puN include/asm-mips/pci.h~pci-scan-all-functions include/asm-mips/pci.h --- 25/include/asm-mips/pci.h~pci-scan-all-functions 2004-01-29 23:23:59.000000000 -0800 +++ 25-akpm/include/asm-mips/pci.h 2004-01-29 23:23:59.000000000 -0800 @@ -20,6 +20,7 @@ extern unsigned int pcibios_assign_all_b #else #define pcibios_assign_all_busses() 0 #endif +#define pcibios_scan_all_fns(a, b) 0 #define PCIBIOS_MIN_IO 0x1000 #define PCIBIOS_MIN_MEM 0x10000000 diff -puN include/asm-parisc/pci.h~pci-scan-all-functions include/asm-parisc/pci.h --- 25/include/asm-parisc/pci.h~pci-scan-all-functions 2004-01-29 23:23:59.000000000 -0800 +++ 25-akpm/include/asm-parisc/pci.h 2004-01-29 23:23:59.000000000 -0800 @@ -174,6 +174,7 @@ extern inline void pcibios_register_hba( ** to zero for legacy platforms and one for PAT platforms. */ #define pcibios_assign_all_busses() (pdc_type == PDC_TYPE_PAT) +#define pcibios_scan_all_fns(a, b) 0 #define PCIBIOS_MIN_IO 0x10 #define PCIBIOS_MIN_MEM 0x1000 /* NBPG - but pci/setup-res.c dies */ diff -puN include/asm-ppc64/pci.h~pci-scan-all-functions include/asm-ppc64/pci.h --- 25/include/asm-ppc64/pci.h~pci-scan-all-functions 2004-01-29 23:23:59.000000000 -0800 +++ 25-akpm/include/asm-ppc64/pci.h 2004-01-29 23:23:59.000000000 -0800 @@ -19,6 +19,8 @@ #define PCIBIOS_MIN_IO 0x1000 #define PCIBIOS_MIN_MEM 0x10000000 +extern int pcibios_scan_all_fns(struct pci_bus *bus, int devfn); + static inline void pcibios_set_master(struct pci_dev *dev) { /* No special bus mastering setup handling */ diff -puN include/asm-ppc/pci.h~pci-scan-all-functions include/asm-ppc/pci.h --- 25/include/asm-ppc/pci.h~pci-scan-all-functions 2004-01-29 23:23:59.000000000 -0800 +++ 25-akpm/include/asm-ppc/pci.h 2004-01-29 23:23:59.000000000 -0800 @@ -26,6 +26,7 @@ struct pci_dev; extern int pci_assign_all_busses; #define pcibios_assign_all_busses() (pci_assign_all_busses) +#define pcibios_scan_all_fns(a, b) 0 #define PCIBIOS_MIN_IO 0x1000 #define PCIBIOS_MIN_MEM 0x10000000 diff -puN include/asm-sh/pci.h~pci-scan-all-functions include/asm-sh/pci.h --- 25/include/asm-sh/pci.h~pci-scan-all-functions 2004-01-29 23:23:59.000000000 -0800 +++ 25-akpm/include/asm-sh/pci.h 2004-01-29 23:23:59.000000000 -0800 @@ -12,6 +12,7 @@ or architectures with incomplete PCI setup by the loader */ #define pcibios_assign_all_busses() 1 +#define pcibios_scan_all_fns(a, b) 0 /* * A board can define one or more PCI channels that represent built-in (or diff -puN include/asm-sparc64/pci.h~pci-scan-all-functions include/asm-sparc64/pci.h --- 25/include/asm-sparc64/pci.h~pci-scan-all-functions 2004-01-29 23:23:59.000000000 -0800 +++ 25-akpm/include/asm-sparc64/pci.h 2004-01-29 23:23:59.000000000 -0800 @@ -11,6 +11,7 @@ * or architectures with incomplete PCI setup by the loader. */ #define pcibios_assign_all_busses() 0 +#define pcibios_scan_all_fns(a, b) 0 #define PCIBIOS_MIN_IO 0UL #define PCIBIOS_MIN_MEM 0UL diff -puN include/asm-sparc/pci.h~pci-scan-all-functions include/asm-sparc/pci.h --- 25/include/asm-sparc/pci.h~pci-scan-all-functions 2004-01-29 23:23:59.000000000 -0800 +++ 25-akpm/include/asm-sparc/pci.h 2004-01-29 23:23:59.000000000 -0800 @@ -8,6 +8,7 @@ * or architectures with incomplete PCI setup by the loader. */ #define pcibios_assign_all_busses() 0 +#define pcibios_scan_all_fns(a, b) 0 #define PCIBIOS_MIN_IO 0UL #define PCIBIOS_MIN_MEM 0UL diff -puN include/asm-um/pci.h~pci-scan-all-functions include/asm-um/pci.h --- 25/include/asm-um/pci.h~pci-scan-all-functions 2004-01-29 23:23:59.000000000 -0800 +++ 25-akpm/include/asm-um/pci.h 2004-01-29 23:23:59.000000000 -0800 @@ -2,5 +2,6 @@ #define __UM_PCI_H #define PCI_DMA_BUS_IS_PHYS (1) +#define pcibios_scan_all_fns(a, b) 0 #endif diff -puN include/asm-v850/pci.h~pci-scan-all-functions include/asm-v850/pci.h --- 25/include/asm-v850/pci.h~pci-scan-all-functions 2004-01-29 23:23:59.000000000 -0800 +++ 25-akpm/include/asm-v850/pci.h 2004-01-29 23:23:59.000000000 -0800 @@ -17,6 +17,8 @@ /* Get any platform-dependent definitions. */ #include +#define pcibios_scan_all_fns(a, b) 0 + /* Generic declarations. */ struct scatterlist; diff -puN include/asm-x86_64/pci.h~pci-scan-all-functions include/asm-x86_64/pci.h --- 25/include/asm-x86_64/pci.h~pci-scan-all-functions 2004-01-29 23:23:59.000000000 -0800 +++ 25-akpm/include/asm-x86_64/pci.h 2004-01-29 23:23:59.000000000 -0800 @@ -17,6 +17,7 @@ extern unsigned int pcibios_assign_all_b #else #define pcibios_assign_all_busses() 0 #endif +#define pcibios_scan_all_fns(a, b) 0 extern int no_iommu, force_iommu; _