[2.6] PCI Scan all functions
Subsystems (2)
A message that is not in the archive (sent off-list or not yet received): [email protected]
A message that is not in the archive (sent off-list or not yet received): [email protected]
A message that is not in the archive (sent off-list or not yet received): 1075241556.681.19.camel@magik
A message that is not in the archive (sent off-list or not yet received): [email protected]
A message that is not in the archive (sent off-list or not yet received): 1075247559.672.33.camel@magik
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 5 lines · Linus Torvalds
Quoted 3 lines · Jake Moilanen
I tried this patch on my one (and only) machine that exibits this issue. Everything was detected correctly.
Quoted 7 lines
Ok. This at least looks more palatable in that it's now confined a bit better.
However, looking at the logic, we really only want to do the "
pcibios_scan_all_fns()" once per device, not once for each function, no?Linus
Here's a patch that addresses Linus's concerns. Andrew, if you have no objections, please apply.
Thanks,
Jake
arch/ppc64/kernel/pSeries_pci.c +26 -0
@@ -568,3 +568,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 ; +}
drivers/pci/probe.c +6 -1
@@ -7,6 +7,8 @@#include <linux/slab.h> #include <linux/module.h> +#include <asm/pci.h> +#undef DEBUG#ifdef DEBUG
@@ -547,13 +549,16 @@ pci_scan_device(struct pci_bus *bus, intint __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; dev =pci_scan_device (bus, devfn);pci_scan_msi_device (dev); -if (func ==0 ) { +if (!scan_all_fns && func ==0 ) {if (!dev)break ; }else {
include/asm-alpha/pci.h +1 -0
@@ -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
include/asm-arm/pci.h +2 -0
@@ -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 */
include/asm-arm26/pci.h +2 -1
@@ -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
include/asm-generic/pci.h +2 -0
@@ -22,4 +22,6 @@ pcibios_resource_to_bus(struct pci_dev * region->end = res->end; } +#define pcibios_scan_all_fns (a, b) 0 +#endif
include/asm-h8300/pci.h +1 -0
@@ -8,6 +8,7 @@*/ #define pcibios_assign_all_busses () 0 +#define pcibios_scan_all_fns (a, b) 0extern inline void pcibios_set_master (struct pci_dev *dev) {
include/asm-i386/pci.h +1 -0
@@ -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) 0extern unsigned long pci_mem_start;#define PCIBIOS_MIN_IO 0x1000
include/asm-ia64/pci.h +1 -0
@@ -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
include/asm-m68k/pci.h +1 -0
@@ -36,6 +36,7 @@ struct pci_bus_info };#define pcibios_assign_all_busses () 0 +#define pcibios_scan_all_fns (a, b) 0extern inline void pcibios_set_master (struct pci_dev *dev) {
include/asm-m68knommu/pci.h +2 -0
@@ -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
include/asm-mips/pci.h +1 -0
@@ -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
include/asm-parisc/pci.h +1 -0
@@ -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 */
include/asm-ppc/pci.h +1 -0
@@ -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
include/asm-ppc64/pci.h +2 -0
@@ -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 */
include/asm-sh/pci.h +1 -0
@@ -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#if defined(CONFIG_CPU_SUBTYPE_ST40STB1 )/* These are currently the correct values for the STM overdrive board.
include/asm-sparc/pci.h +1 -0
@@ -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
include/asm-sparc64/pci.h +1 -0
@@ -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
include/asm-um/pci.h +1 -0
@@ -2,5 +2,6 @@#define __UM_PCI_H#define PCI_DMA_BUS_IS_PHYS (1) +#define pcibios_scan_all_fns (a, b) 0#endif
include/asm-v850/pci.h +2 -0
@@ -17,6 +17,8 @@/* Get any platform-dependent definitions. */ #include <asm/machdep.h> +#define pcibios_scan_all_fns (a, b) 0 +/* Generic declarations. */ struct scatterlist ;
include/asm-x86_64/pci.h +1 -0
@@ -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) 0extern int no_iommu, force_iommu;
Quoted 10 lines · Jake Moilanen
Quoted 8 lines · Linus Torvalds
Quoted 3 lines · Jake Moilanen
I tried this patch on my one (and only) machine that exibits this issue. Everything was detected correctly.
Ok. This at least looks more palatable in that it's now confined a bit better.
Quoted 7 lines
Quoted 4 lines
However, looking at the logic, we really only want to do the "
pcibios_scan_all_fns()" once per device, not once for each function, no?Linus
Here's a patch that addresses Linus's concerns. Andrew, if you have no objections, please apply.
Could you please send me a changelog description for this patch? A bit of background for posterity, so other kernel developers can come in a year hence and answer the question "what's all this about then?". Thanks.
Quoted 3 lines
Could you please send me a changelog description for this patch? A bit of background for posterity, so other kernel developers can come in a year hence and answer the question "what's all this about then?". Thanks.
Sure.
On a ppc64 logically partitioned system, there can be a setup where function 0 of a PCI-PCI bridge is assigned to one partition and (for example) function 2 is assigned to a second partition. On the second partition, it would appear that function 0 does not exist, but function 2 does. If all the functions are not scanned, everything under function 2 would not be detected.
This patch allows devices that don't respond to function 0, but do respond to other functions to be marked with a quirk and have all of their functions scanned.
Thanks,
Jake