Commit c64c3f3a authored by Mika Westerberg's avatar Mika Westerberg
Browse files

thunderbolt: Make tb_path_alloc() work with tree topologies



With USB4, topologies are not limited to daisy-chains anymore so when
calculating how many hops are between two ports we need to walk the
whole path instead.

Add helper function tb_for_each_port_on_path() that can be used to walk
over each port on a path and make tb_path_alloc() to use it.

Signed-off-by: default avatarMika Westerberg <mika.westerberg@linux.intel.com>
parent 69eb79f7
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -239,12 +239,12 @@ struct tb_path *tb_path_alloc(struct tb *tb, struct tb_port *src, int src_hopid,
	if (!path)
		return NULL;

	/*
	 * Number of hops on a path is the distance between the two
	 * switches plus the source adapter port.
	 */
	num_hops = abs(tb_route_length(tb_route(src->sw)) -
		       tb_route_length(tb_route(dst->sw))) + 1;
	i = 0;
	tb_for_each_port_on_path(src, dst, in_port)
		i++;

	/* Each hop takes two ports */
	num_hops = i / 2;

	path->hops = kcalloc(num_hops, sizeof(*path->hops), GFP_KERNEL);
	if (!path->hops) {
+12 −0
Original line number Diff line number Diff line
@@ -741,6 +741,18 @@ void tb_port_release_out_hopid(struct tb_port *port, int hopid);
struct tb_port *tb_next_port_on_path(struct tb_port *start, struct tb_port *end,
				     struct tb_port *prev);

/**
 * tb_for_each_port_on_path() - Iterate over each port on path
 * @src: Source port
 * @dst: Destination port
 * @p: Port used as iterator
 *
 * Walks over each port on path from @src to @dst.
 */
#define tb_for_each_port_on_path(src, dst, p)				\
	for ((p) = tb_next_port_on_path((src), (dst), NULL); (p);	\
	     (p) = tb_next_port_on_path((src), (dst), (p)))

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);