Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 71967
b: refs/heads/master
c: 994a65e
h: refs/heads/master
i:
  71965: 301a540
  71963: 043b358
  71959: b4f4935
  71951: 1e3d6a9
  71935: a69fa14
v: v3
  • Loading branch information
Keshavamurthy, Anil S authored and Linus Torvalds committed Oct 22, 2007
1 parent bdd9974 commit 8266552
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 10e5247f40f3bf7508a0ed2848c9cae37bddf4bc
refs/heads/master: 994a65e25df85abc465cfee495557200e8205f9e
1 change: 1 addition & 0 deletions trunk/drivers/pci/pci.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,4 @@ pci_match_one_device(const struct pci_device_id *id, const struct pci_dev *dev)
return NULL;
}

struct pci_dev *pci_find_upstream_pcie_bridge(struct pci_dev *pdev);
14 changes: 14 additions & 0 deletions trunk/drivers/pci/probe.c
Original file line number Diff line number Diff line change
Expand Up @@ -837,6 +837,19 @@ static void pci_release_dev(struct device *dev)
kfree(pci_dev);
}

static void set_pcie_port_type(struct pci_dev *pdev)
{
int pos;
u16 reg16;

pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
if (!pos)
return;
pdev->is_pcie = 1;
pci_read_config_word(pdev, pos + PCI_EXP_FLAGS, &reg16);
pdev->pcie_type = (reg16 & PCI_EXP_FLAGS_TYPE) >> 4;
}

/**
* pci_cfg_space_size - get the configuration space size of the PCI device.
* @dev: PCI device
Expand Down Expand Up @@ -951,6 +964,7 @@ pci_scan_device(struct pci_bus *bus, int devfn)
dev->device = (l >> 16) & 0xffff;
dev->cfg_size = pci_cfg_space_size(dev);
dev->error_state = pci_channel_io_normal;
set_pcie_port_type(dev);

/* Assume 32-bit PCI; let 64-bit PCI cards (which are far rarer)
set this higher, assuming the system even supports it. */
Expand Down
34 changes: 34 additions & 0 deletions trunk/drivers/pci/search.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,40 @@
#include "pci.h"

DECLARE_RWSEM(pci_bus_sem);
/*
* find the upstream PCIE-to-PCI bridge of a PCI device
* if the device is PCIE, return NULL
* if the device isn't connected to a PCIE bridge (that is its parent is a
* legacy PCI bridge and the bridge is directly connected to bus 0), return its
* parent
*/
struct pci_dev *
pci_find_upstream_pcie_bridge(struct pci_dev *pdev)
{
struct pci_dev *tmp = NULL;

if (pdev->is_pcie)
return NULL;
while (1) {
if (!pdev->bus->self)
break;
pdev = pdev->bus->self;
/* a p2p bridge */
if (!pdev->is_pcie) {
tmp = pdev;
continue;
}
/* PCI device should connect to a PCIE bridge */
if (pdev->pcie_type != PCI_EXP_TYPE_PCI_BRIDGE) {
/* Busted hardware? */
WARN_ON_ONCE(1);
return NULL;
}
return pdev;
}

return tmp;
}

static struct pci_bus *pci_do_find_bus(struct pci_bus *bus, unsigned char busnr)
{
Expand Down
2 changes: 2 additions & 0 deletions trunk/include/linux/pci.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ struct pci_dev {
unsigned int class; /* 3 bytes: (base,sub,prog-if) */
u8 revision; /* PCI revision, low byte of class word */
u8 hdr_type; /* PCI header type (`multi' flag masked out) */
u8 pcie_type; /* PCI-E device/port type */
u8 rom_base_reg; /* which config register controls the ROM */
u8 pin; /* which interrupt pin this device uses */

Expand Down Expand Up @@ -183,6 +184,7 @@ struct pci_dev {
unsigned int msi_enabled:1;
unsigned int msix_enabled:1;
unsigned int is_managed:1;
unsigned int is_pcie:1;
atomic_t enable_cnt; /* pci_enable_device has been called */

u32 saved_config_space[16]; /* config space saved at suspend time */
Expand Down

0 comments on commit 8266552

Please sign in to comment.