Felix Held has submitted this change. ( https://review.coreboot.org/c/coreboot/+/57784 )
Change subject: device: Add pciexp_find_next_extended_cap function ......................................................................
device: Add pciexp_find_next_extended_cap function
Some PCIe devices have extended capability lists that contain multiples instances of the same capability. This patch provides a function similar to pciexp_find_extended_cap that can be used to search through multiple instances of the same capability by returning the offset of the next extended capability of the given type following the passed-in offset. The base functionality of searching for a given capability from an offset is extracted to a local helper function and both pciexp_find_extended_cap and pciexp_find_next_extended_cap use this helper.
Change-Id: Ie68dc26012ba57650484c4f2ff53cc694a5347aa Signed-off-by: Tim Wawrzynczak twawrzynczak@chromium.org Reviewed-on: https://review.coreboot.org/c/coreboot/+/57784 Tested-by: build bot (Jenkins) no-reply@coreboot.org Reviewed-by: Karthik Ramasubramanian kramasub@google.com Reviewed-by: Nick Vaccaro nvaccaro@google.com --- M src/device/pciexp_device.c M src/include/device/pciexp.h 2 files changed, 23 insertions(+), 11 deletions(-)
Approvals: build bot (Jenkins): Verified Nick Vaccaro: Looks good to me, approved Karthik Ramasubramanian: Looks good to me, approved
diff --git a/src/device/pciexp_device.c b/src/device/pciexp_device.c index e0b3544..c525301 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 a72c2ec..30c2a54 100644 --- a/src/include/device/pciexp.h +++ b/src/include/device/pciexp.h @@ -31,6 +31,8 @@ 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) {
4 is the latest approved patch-set. No files were changed between the latest approved patch-set and the submitted one.