summaryrefslogtreecommitdiff
path: root/drivers/thunderbolt/cap.c
diff options
context:
space:
mode:
authorMika Westerberg <mika.westerberg@linux.intel.com>2020-06-29 20:15:17 +0300
committerMika Westerberg <mika.westerberg@linux.intel.com>2020-09-03 12:21:07 +0300
commit3c8b228d4371d0556d3d333d63df90172c2c7355 (patch)
tree78c315f5a40434996ea53ffd9690828d7995ab4c /drivers/thunderbolt/cap.c
parent8f8310115e339c5e3d03b6366998d0a11a5e44bd (diff)
downloadlinux-3c8b228d4371d0556d3d333d63df90172c2c7355.tar.xz
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/cap.c')
-rw-r--r--drivers/thunderbolt/cap.c35
1 files changed, 31 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;
}