diff options
author | Mika Westerberg <mika.westerberg@linux.intel.com> | 2020-06-29 20:15:17 +0300 |
---|---|---|
committer | Mika Westerberg <mika.westerberg@linux.intel.com> | 2020-09-03 12:21:07 +0300 |
commit | 3c8b228d4371d0556d3d333d63df90172c2c7355 (patch) | |
tree | 78c315f5a40434996ea53ffd9690828d7995ab4c /drivers/thunderbolt | |
parent | 8f8310115e339c5e3d03b6366998d0a11a5e44bd (diff) | |
download | linux-stable-3c8b228d4371d0556d3d333d63df90172c2c7355.tar.gz linux-stable-3c8b228d4371d0556d3d333d63df90172c2c7355.tar.bz2 linux-stable-3c8b228d4371d0556d3d333d63df90172c2c7355.zip |
thunderbolt: Introduce tb_port_next_cap()
This function is useful for walking port config space (adapter)
capability lists. Convert the tb_port_find_cap() to use this as well.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/thunderbolt')
-rw-r--r-- | drivers/thunderbolt/cap.c | 35 | ||||
-rw-r--r-- | drivers/thunderbolt/tb.h | 1 |
2 files changed, 32 insertions, 4 deletions
diff --git a/drivers/thunderbolt/cap.c b/drivers/thunderbolt/cap.c index 1582e4ebac56..c45b3a488412 100644 --- a/drivers/thunderbolt/cap.c +++ b/drivers/thunderbolt/cap.c @@ -59,23 +59,50 @@ static void tb_port_dummy_read(struct tb_port *port) } } +/** + * tb_port_next_cap() - Return next capability in the linked list + * @port: Port to find the capability for + * @offset: Previous capability offset (%0 for start) + * + * Returns dword offset of the next capability in port config space + * capability list and returns it. Passing %0 returns the first entry in + * the capability list. If no next capability is found returns %0. In case + * of failure returns negative errno. + */ +int tb_port_next_cap(struct tb_port *port, unsigned int offset) +{ + struct tb_cap_any header; + int ret; + + if (!offset) + return port->config.first_cap_offset; + + ret = tb_port_read(port, &header, TB_CFG_PORT, offset, 1); + if (ret) + return ret; + + return header.basic.next; +} + static int __tb_port_find_cap(struct tb_port *port, enum tb_port_cap cap) { - u32 offset = 1; + int offset = 0; do { struct tb_cap_any header; int ret; + offset = tb_port_next_cap(port, offset); + if (offset < 0) + return offset; + ret = tb_port_read(port, &header, TB_CFG_PORT, offset, 1); if (ret) return ret; if (header.basic.cap == cap) return offset; - - offset = header.basic.next; - } while (offset); + } while (offset > 0); return -ENOENT; } diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h index 7754c690addc..54e8fad78bee 100644 --- a/drivers/thunderbolt/tb.h +++ b/drivers/thunderbolt/tb.h @@ -823,6 +823,7 @@ int tb_port_get_link_speed(struct tb_port *port); int tb_switch_find_vse_cap(struct tb_switch *sw, enum tb_switch_vse_cap vsec); int tb_switch_find_cap(struct tb_switch *sw, enum tb_switch_cap cap); int tb_port_find_cap(struct tb_port *port, enum tb_port_cap cap); +int tb_port_next_cap(struct tb_port *port, unsigned int offset); bool tb_port_is_enabled(struct tb_port *port); bool tb_usb3_port_is_enabled(struct tb_port *port); |