diff options
author | Mika Westerberg <mika.westerberg@linux.intel.com> | 2020-04-29 17:07:59 +0300 |
---|---|---|
committer | Mika Westerberg <mika.westerberg@linux.intel.com> | 2020-06-22 19:58:19 +0300 |
commit | c64c3f3ac63a101a00bd316eaba63d359e9ba215 (patch) | |
tree | 7bdf8c62b239795d5cd86ee1cd9d369084770187 /drivers/thunderbolt | |
parent | 69eb79f7d294f92696de8010432758dbd3d1ecb3 (diff) |
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: Mika Westerberg <mika.westerberg@linux.intel.com>
Diffstat (limited to 'drivers/thunderbolt')
-rw-r--r-- | drivers/thunderbolt/path.c | 12 | ||||
-rw-r--r-- | drivers/thunderbolt/tb.h | 12 |
2 files changed, 18 insertions, 6 deletions
diff --git a/drivers/thunderbolt/path.c b/drivers/thunderbolt/path.c index ad58559ea88e..77abb1fa80c0 100644 --- a/drivers/thunderbolt/path.c +++ b/drivers/thunderbolt/path.c @@ -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) { diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h index 2eb2bcd3cca3..6916168e2c76 100644 --- a/drivers/thunderbolt/tb.h +++ b/drivers/thunderbolt/tb.h @@ -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); |