diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/device/pciexp_device.c | 32 | ||||
-rw-r--r-- | src/include/device/pciexp.h | 2 |
2 files changed, 23 insertions, 11 deletions
diff --git a/src/device/pciexp_device.c b/src/device/pciexp_device.c index e0b3544874..c52530196d 100644 --- a/src/device/pciexp_device.c +++ b/src/device/pciexp_device.c @@ -8,29 +8,39 @@ #include <device/pci_ops.h> #include <device/pciexp.h> -unsigned int pciexp_find_extended_cap(const struct device *dev, unsigned int cap) +static unsigned int pciexp_get_ext_cap_offset(const struct device *dev, unsigned int cap, + unsigned int offset) { - unsigned int this_cap_offset, next_cap_offset; - unsigned int this_cap, cafe; - - this_cap_offset = PCIE_EXT_CAP_OFFSET; + unsigned int this_cap_offset = offset; + unsigned int next_cap_offset, this_cap, cafe; do { this_cap = pci_read_config32(dev, this_cap_offset); - next_cap_offset = this_cap >> 20; - this_cap &= 0xffff; cafe = pci_read_config32(dev, this_cap_offset + 4); - cafe &= 0xffff; - if (this_cap == cap) + if ((this_cap & 0xffff) == cap) { return this_cap_offset; - else if (cafe == cap) + } else if ((cafe & 0xffff) == cap) { return this_cap_offset + 4; - else + } else { + next_cap_offset = this_cap >> 20; this_cap_offset = next_cap_offset; + } } while (next_cap_offset != 0); return 0; } +unsigned int pciexp_find_next_extended_cap(const struct device *dev, unsigned int cap, + unsigned int pos) +{ + const unsigned int next_cap_offset = pci_read_config32(dev, pos) >> 20; + return pciexp_get_ext_cap_offset(dev, cap, next_cap_offset); +} + +unsigned int pciexp_find_extended_cap(const struct device *dev, unsigned int cap) +{ + return pciexp_get_ext_cap_offset(dev, cap, PCIE_EXT_CAP_OFFSET); +} + /* * Re-train a PCIe link */ diff --git a/src/include/device/pciexp.h b/src/include/device/pciexp.h index a72c2ec2a9..30c2a54620 100644 --- a/src/include/device/pciexp.h +++ b/src/include/device/pciexp.h @@ -31,6 +31,8 @@ void pciexp_hotplug_scan_bridge(struct device *dev); extern struct device_operations default_pciexp_hotplug_ops_bus; unsigned int pciexp_find_extended_cap(const struct device *dev, unsigned int cap); +unsigned int pciexp_find_next_extended_cap(const struct device *dev, unsigned int cap, + unsigned int offset); static inline bool pciexp_is_downstream_port(int type) { |