]> git.hungrycats.org Git - linux/commitdiff
[PATCH] PCI Scan all functions
authorAndrew Morton <akpm@osdl.org>
Wed, 4 Feb 2004 02:50:09 +0000 (18:50 -0800)
committerLinus Torvalds <torvalds@home.osdl.org>
Wed, 4 Feb 2004 02:50:09 +0000 (18:50 -0800)
From: Jake Moilanen <moilanen@austin.ibm.com>

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.

21 files changed:
arch/ppc64/kernel/pSeries_pci.c
drivers/pci/probe.c
include/asm-alpha/pci.h
include/asm-arm/pci.h
include/asm-arm26/pci.h
include/asm-generic/pci.h
include/asm-h8300/pci.h
include/asm-i386/pci.h
include/asm-ia64/pci.h
include/asm-m68k/pci.h
include/asm-m68knommu/pci.h
include/asm-mips/pci.h
include/asm-parisc/pci.h
include/asm-ppc/pci.h
include/asm-ppc64/pci.h
include/asm-sh/pci.h
include/asm-sparc/pci.h
include/asm-sparc64/pci.h
include/asm-um/pci.h
include/asm-v850/pci.h
include/asm-x86_64/pci.h

index 9b07f7d138efb84f8e0c8af06a1859ab560ce65d..69e259d35c83dab3cfc41aa84febde0e47042f65 100644 (file)
@@ -721,3 +721,29 @@ pci_find_hose_for_OF_device(struct device_node *node)
        }
        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;
+}
index 5117322ee1ed6ce5ec298993270566fbc9519623..aaa97413baaaeefec02f3336f12357461e1322a6 100644 (file)
@@ -620,6 +620,9 @@ pci_scan_single_device(struct pci_bus *bus, int devfn)
 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;
@@ -640,7 +643,7 @@ int __devinit pci_scan_slot(struct pci_bus *bus, int devfn)
                                }
                        }
                } else {
-                       if (func == 0)
+                       if (func == 0 && !scan_all_fns)
                                break;
                }
        }
index 2289a5350d41456c5e6673062ae885a3049bfb6f..faeee03035188dfef8992f0b301c1f7b883e5daf 100644 (file)
@@ -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
index 67299aff947fe15b5077f19ef8643ee6e76adbc6..ac2ed843eefed7af760bc02ebdec090a43c034c6 100644 (file)
@@ -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 */
index ea14145f145a2bc0bcff5d68e1f00152f7a82978..6ac67ed7718cdc5560d1f858c64b8fbe1a2c836e 100644 (file)
@@ -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
 
index df757d240e9a01683bda1d41f9a7b7f21eca8593..40cca57fe01e80c5388098422a7eb9df3ef44949 100644 (file)
@@ -22,4 +22,6 @@ pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
        region->end = res->end;
 }
 
+#define pcibios_scan_all_fns(a, b)     0
+
 #endif
index 4374b6ac476557e0609bba7c762ef54c99f39e9f..f4813f0a9021dd4ab8bf27989e1ec8f7dfbfaa66 100644 (file)
@@ -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)
 {
index 0fc93a7d3c07c4041af16fde9cd06dee1d1bbaa7..83aede6ce59525aeb953e8a145cbe092054a505d 100644 (file)
@@ -15,6 +15,7 @@ extern unsigned int pcibios_assign_all_busses(void);
 #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
index 4a4e92f463a6ccd939737e549cd88756012d0f92..42f66dda432bbc528ad8a1a61b12e5b683c5f856 100644 (file)
@@ -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
index 0a006a50e801de053b5add45f4475dd821285443..57e1487bac3f3cd7086713d6dca033fda756b1f0 100644 (file)
@@ -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)
 {
index 8720031e4412b0f0da58e8392e8f5342dcce5db9..a99ce768f4a68cf003563e00d3b3d54c77bee0ff 100644 (file)
@@ -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
index cd96c958408f5aca35933d53f1f192317f69157f..3943c111647ea0f930136cc806f10c7eba80e2c2 100644 (file)
@@ -20,6 +20,7 @@ extern unsigned int pcibios_assign_all_busses(void);
 #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
index ce754492efa21dbd5c32e9974373cd31e58bf958..aca998aef8f170b1d358c2718906a4233e4797f5 100644 (file)
@@ -174,6 +174,7 @@ extern inline void pcibios_register_hba(struct pci_hba_data *x)
 **   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 */
index 5dad69a5ee61c63b022ba22bc3a1cee140ddb856..16d61750824266481182d14279c0fe22d11052e4 100644 (file)
@@ -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
index 305ca8cd823550177052728e8d627c126902cf73..f30d4e0786d811bddb69c609e843f96bf77fd510 100644 (file)
@@ -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 */
index d314b8d1b3407dfcb7c33f54a00b7db0a0154785..fe2c08b2e7cdf7f415a92474e446ec153c5c35b2 100644 (file)
@@ -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
index 2c17e7ef1e71d52084e62c21293654e916e50ee1..e97afc5a44db5a247b2aef0dbd56847187aca9a4 100644 (file)
@@ -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
index 2dbd268962e6943f021b61b0137cea319a9da94b..ea722dcb49d83b080f9793160ad8851e416ac301 100644 (file)
@@ -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
index b44cf59ede1edc9ccf610c5e5b270a221257144d..59923199cdc36b439b5b30bdd9c80cbe83db8902 100644 (file)
@@ -2,5 +2,6 @@
 #define __UM_PCI_H
 
 #define PCI_DMA_BUS_IS_PHYS     (1)
+#define pcibios_scan_all_fns(a, b)     0
 
 #endif
index b915819c609b9a30119398026b29ebf2c2a081ce..81addb7df017e0ad007c9d9dd1cd6b7d2cbf9f03 100644 (file)
@@ -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;
index b64f5bd97a2d1c3bbf2dc081f04109456a1634e1..6feb36107d64fd117429c13e1a935c85f47e0c2d 100644 (file)
@@ -17,6 +17,7 @@ extern unsigned int pcibios_assign_all_busses(void);
 #else
 #define pcibios_assign_all_busses()    0
 #endif
+#define pcibios_scan_all_fns(a, b)     0
 
 extern int no_iommu, force_iommu;