[2.6] PCI Scan all functions
Subsystems (2)
PATCH 1/1 [2.6] PCI Scan all functions
There are some arch, like PPC64, that need to be able to scan all the PCI functions. The problem comes in on a logically partitioned system where function 0 on a PCI-PCI bridge is assigned to one partition and say function 2 is assiged to another 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.
Thanks,
Jake
drivers/pci/probe.c +3 -1
@@ -7,6 +7,8 @@#include <linux/slab.h> #include <linux/module.h> +#include <asm/pci.h> +#undef DEBUG#ifdef DEBUG
@@ -553,7 +555,7 @@ int __devinit pci_scan_slot(struct pci_b dev =pci_scan_device (bus, devfn);pci_scan_msi_device (dev); -if (func ==0 ) { +if (!pcibios_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 () 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 () 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 () 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 () 0 +#endif
include/asm-h8300/pci.h +1 -0
@@ -8,6 +8,7 @@*/ #define pcibios_assign_all_busses () 0 +#define pcibios_scan_all_fns () 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 () 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 () 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 () 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 () 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 () 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 () 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 () 0#define PCIBIOS_MIN_IO 0x1000#define PCIBIOS_MIN_MEM 0x10000000
include/asm-ppc64/pci.h +6 -0
@@ -19,6 +19,12 @@#define PCIBIOS_MIN_IO 0x1000#define PCIBIOS_MIN_MEM 0x10000000 +/* +* ppc64 can have multifunction devices that do not respond to function 0. +* In this case we must scan all functions. +*/ +#define pcibios_scan_all_fns () 1 +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 () 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 () 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 () 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 () 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 () 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 () 0extern int no_iommu, force_iommu;
Quoted 7 lines · Jake Moilanen
There are some arch, like PPC64, that need to be able to scan all the PCI functions. The problem comes in on a logically partitioned system where function 0 on a PCI-PCI bridge is assigned to one partition and say function 2 is assiged to another 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.
Heh, I think the PPC64 people need to get together and all talk about this, as I just got a different patch, that solves much the same problem from John Rose (it's on the linuxppc64 mailing list.)
Can you two get together and not patch the same section of code to do the same thing in different ways?
thanks,
greg k-h
Quoted 10 lines · Greg KH
Quoted 7 lines · Jake Moilanen
There are some arch, like PPC64, that need to be able to scan all the PCI functions. The problem comes in on a logically partitioned system where function 0 on a PCI-PCI bridge is assigned to one partition and say function 2 is assiged to another 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.
Quoted 6 lines
Heh, I think the PPC64 people need to get together and all talk about this, as I just got a different patch, that solves much the same problem from John Rose (it's on the linuxppc64 mailing list.)
Can you two get together and not patch the same section of code to do the same thing in different ways?
While we're on the topic, what's with the below patch? I've had it in -mm for ages but apparently there's some disagreement over it.
From: Anton Blanchard <[email protected]>
We have IO BARs on ppc64 machines that begin at address 0. The current pci probe code will ignore anything that starts at 0. Remove these checks.
---
drivers/pci/probe.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-)
drivers/pci/probe.c renamed from drivers/pci/probe.c~ppc64-bar-0-fix +3 -3
@@ -176,7 +176,7 @@ void __devinit pci_read_bridge_bases(str limit |= (io_limit_hi <<16 ); } -if (base && base <= limit) { +if (base <= limit) { res->flags = (io_base_lo &PCI_IO_RANGE_TYPE_MASK ) |IORESOURCE_IO ; res->start = base; res->end = limit +0xfff ;
@@ -187,7 +187,7 @@ void __devinit pci_read_bridge_bases(strpci_read_config_word (dev,PCI_MEMORY_LIMIT , &mem_limit_lo); base = (mem_base_lo &PCI_MEMORY_RANGE_MASK ) <<16 ; limit = (mem_limit_lo &PCI_MEMORY_RANGE_MASK ) <<16 ; -if (base && base <= limit) { +if (base <= limit) { res->flags = (mem_base_lo &PCI_MEMORY_RANGE_TYPE_MASK ) |IORESOURCE_MEM ; res->start = base; res->end = limit +0xfffff ;
@@ -213,7 +213,7 @@ void __devinit pci_read_bridge_bases(str }#endif } -if (base && base <= limit) { +if (base <= limit) { res->flags = (mem_base_lo &PCI_MEMORY_RANGE_TYPE_MASK ) |IORESOURCE_MEM |IORESOURCE_PREFETCH ; res->start = base; res->end = limit +0xfffff ;
_
Quoted 15 lines · Andrew Morton
Quoted 14 lines · Greg KH
Quoted 7 lines · Jake Moilanen
There are some arch, like PPC64, that need to be able to scan all the PCI functions. The problem comes in on a logically partitioned system where function 0 on a PCI-PCI bridge is assigned to one partition and say function 2 is assiged to another 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.
Heh, I think the PPC64 people need to get together and all talk about this, as I just got a different patch, that solves much the same problem from John Rose (it's on the linuxppc64 mailing list.)
Quoted 5 lines
Quoted 2 lines
Can you two get together and not patch the same section of code to do the same thing in different ways?
While we're on the topic, what's with the below patch? I've had it in -mm for ages but apparently there's some disagreement over it.
It looks ok to me, but Linus and Ivan were the ones disagreeing over how to implement this correctly, as they understand the resource management logic a lot better than I.
They should be the ones to say if this is ok or not.
thanks,
greg k-h
Quoted 44 lines
From: Anton Blanchard <[email protected]>
We have IO BARs on ppc64 machines that begin at address 0. The current pci probe code will ignore anything that starts at 0. Remove these checks.
---
drivers/pci/probe.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-)diff -puN
drivers/pci/probe.c~ppc64-bar-0-fixdrivers/pci/probe.cdrivers/pci/probe.c renamed from drivers/pci/probe.c~ppc64-bar-0-fix +3
-3@@ -176,7 +176,7 @@ void __devinit pci_read_bridge_bases(str limit |= (io_limit_hi <<16 ); } -if (base && base <= limit) { +if (base <= limit) { res->flags = (io_base_lo &PCI_IO_RANGE_TYPE_MASK ) |IORESOURCE_IO ; res->start = base; res->end = limit +0xfff ;@@ -187,7 +187,7 @@ void __devinit pci_read_bridge_bases(strpci_read_config_word (dev,PCI_MEMORY_LIMIT , &mem_limit_lo); base = (mem_base_lo &PCI_MEMORY_RANGE_MASK ) <<16 ; limit = (mem_limit_lo &PCI_MEMORY_RANGE_MASK ) <<16 ; -if (base && base <= limit) { +if (base <= limit) { res->flags = (mem_base_lo &PCI_MEMORY_RANGE_TYPE_MASK ) |IORESOURCE_MEM ; res->start = base; res->end = limit +0xfffff ;@@ -213,7 +213,7 @@ void __devinit pci_read_bridge_bases(str }#endif } -if (base && base <= limit) { +if (base <= limit) { res->flags = (mem_base_lo &PCI_MEMORY_RANGE_TYPE_MASK ) |IORESOURCE_MEM |IORESOURCE_PREFETCH ; res->start = base; res->end = limit +0xfffff ;_
Quoted 2 lines · Greg KH
Review
Quoted 2 lines
(quoted diff) +1
-1- if (base && base <= limit) { + if (base <= limit) {
I think the patch is safe. Architectures that don't accept bridge windows (and regular BARs) at bus address 0 already have that check elsewhere.
For example, in arch/i386/pci/i386.c:pcibios_allocate_bus_resources():
...
for (idx = PCI_BRIDGE_RESOURCES; idx < PCI_NUM_RESOURCES; idx++) {
r = &dev->resource[idx];
if (!r->start)
^^^^^^^^^
continue;...
Ivan.
Quoted 3 lines · Andrew Morton
While we're on the topic, what's with the below patch? I've had it in -mm for ages but apparently there's some disagreement over it.
I'd be very worried, since I'm pretty sure that there _are_ devices where "zero means disabled".
On the other hand, the resource management should do the right thing anyway, so I guess it should be safe. Especially if it's been in -mm for a long time..
Linus
Hi-
Quoted 6 lines
Heh, I think the PPC64 people need to get together and all talk about this, as I just got a different patch, that solves much the same problem from John Rose (it's on the linuxppc64 mailing list.)
Can you two get together and not patch the same section of code to do the same thing in different ways?
These patches don't address the same problem. Jake's problem has to do with pci_scan_slot() ending too soon when going from function 0->7 at boot time. My problem has to do with pci_scan_slot() going too far from function 0->7 at dlpar add time. Greg, will follow up with you outside of this thread.
Thanks-
John
Signature · 1 line
John Rose <[email protected]>
Hello!
Quoted 7 lines
There are some arch, like PPC64, that need to be able to scan all the PCI functions. The problem comes in on a logically partitioned system where function 0 on a PCI-PCI bridge is assigned to one partition and say function 2 is assiged to another 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.
Enabling scan of all functions globally is probably going to cause troubles, because there are single-function devices which respond to all function numbers. You need to enable this quirk selectively.
Have a nice fortnight
Signature · 3 lines
Martin `MJ' Mares <[email protected]> http://atrey.karlin.mff.cuni.cz/~mj/ Faculty of Math and Physics, Charles University, Prague, Czech Rep., Earth "God doesn't play dice." -- Albert Einstein