aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/search.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/search.c')
-rw-r--r--drivers/pci/search.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/drivers/pci/search.c b/drivers/pci/search.c
index c6e79d01ce3d..b001b5922e33 100644
--- a/drivers/pci/search.c
+++ b/drivers/pci/search.c
@@ -14,6 +14,40 @@
14#include "pci.h" 14#include "pci.h"
15 15
16DECLARE_RWSEM(pci_bus_sem); 16DECLARE_RWSEM(pci_bus_sem);
17/*
18 * find the upstream PCIE-to-PCI bridge of a PCI device
19 * if the device is PCIE, return NULL
20 * if the device isn't connected to a PCIE bridge (that is its parent is a
21 * legacy PCI bridge and the bridge is directly connected to bus 0), return its
22 * parent
23 */
24struct pci_dev *
25pci_find_upstream_pcie_bridge(struct pci_dev *pdev)
26{
27 struct pci_dev *tmp = NULL;
28
29 if (pdev->is_pcie)
30 return NULL;
31 while (1) {
32 if (!pdev->bus->self)
33 break;
34 pdev = pdev->bus->self;
35 /* a p2p bridge */
36 if (!pdev->is_pcie) {
37 tmp = pdev;
38 continue;
39 }
40 /* PCI device should connect to a PCIE bridge */
41 if (pdev->pcie_type != PCI_EXP_TYPE_PCI_BRIDGE) {
42 /* Busted hardware? */
43 WARN_ON_ONCE(1);
44 return NULL;
45 }
46 return pdev;
47 }
48
49 return tmp;
50}
17 51
18static struct pci_bus *pci_do_find_bus(struct pci_bus *bus, unsigned char busnr) 52static struct pci_bus *pci_do_find_bus(struct pci_bus *bus, unsigned char busnr)
19{ 53{