提交 3c8b228d 编写于 作者: M Mika Westerberg

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: NMika Westerberg <mika.westerberg@linux.intel.com>
Reviewed-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
上级 8f831011
...@@ -59,23 +59,50 @@ static void tb_port_dummy_read(struct tb_port *port) ...@@ -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) static int __tb_port_find_cap(struct tb_port *port, enum tb_port_cap cap)
{ {
u32 offset = 1; int offset = 0;
do { do {
struct tb_cap_any header; struct tb_cap_any header;
int ret; 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); ret = tb_port_read(port, &header, TB_CFG_PORT, offset, 1);
if (ret) if (ret)
return ret; return ret;
if (header.basic.cap == cap) if (header.basic.cap == cap)
return offset; return offset;
} while (offset > 0);
offset = header.basic.next;
} while (offset);
return -ENOENT; return -ENOENT;
} }
......
...@@ -823,6 +823,7 @@ int tb_port_get_link_speed(struct tb_port *port); ...@@ -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_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_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_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_port_is_enabled(struct tb_port *port);
bool tb_usb3_port_is_enabled(struct tb_port *port); bool tb_usb3_port_is_enabled(struct tb_port *port);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册