summaryrefslogtreecommitdiffstats
path: root/src/device/pciexp_device.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/device/pciexp_device.c')
-rw-r--r--src/device/pciexp_device.c32
1 files changed, 21 insertions, 11 deletions
diff --git a/src/device/pciexp_device.c b/src/device/pciexp_device.c
index e0b354487404..c52530196d5a 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
*/