thunderbolt: Introduce tb_port_next_cap()
authorMika Westerberg <mika.westerberg@linux.intel.com>
Mon, 29 Jun 2020 17:15:17 +0000 (20:15 +0300)
committerMika Westerberg <mika.westerberg@linux.intel.com>
Thu, 3 Sep 2020 09:21:07 +0000 (12:21 +0300)
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>
drivers/thunderbolt/cap.c
drivers/thunderbolt/tb.h

index 1582e4e..c45b3a4 100644 (file)
@@ -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;
 }
index 7754c69..54e8fad 100644 (file)
@@ -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);