diff options
Diffstat (limited to 'drivers/thunderbolt/path.c')
| -rw-r--r-- | drivers/thunderbolt/path.c | 42 | 
1 files changed, 25 insertions, 17 deletions
diff --git a/drivers/thunderbolt/path.c b/drivers/thunderbolt/path.c index 564e2f42cebd..299712accfe9 100644 --- a/drivers/thunderbolt/path.c +++ b/drivers/thunderbolt/path.c @@ -85,11 +85,12 @@ static int tb_path_find_src_hopid(struct tb_port *src,   * @dst_hopid: HopID to the @dst (%-1 if don't care)   * @last: Last port is filled here if not %NULL   * @name: Name of the path + * @alloc_hopid: Allocate HopIDs for the ports   *   * Follows a path starting from @src and @src_hopid to the last output - * port of the path. Allocates HopIDs for the visited ports. Call - * tb_path_free() to release the path and allocated HopIDs when the path - * is not needed anymore. + * port of the path. Allocates HopIDs for the visited ports (if + * @alloc_hopid is true). Call tb_path_free() to release the path and + * allocated HopIDs when the path is not needed anymore.   *   * Note function discovers also incomplete paths so caller should check   * that the @dst port is the expected one. If it is not, the path can be @@ -99,7 +100,8 @@ static int tb_path_find_src_hopid(struct tb_port *src,   */  struct tb_path *tb_path_discover(struct tb_port *src, int src_hopid,  				 struct tb_port *dst, int dst_hopid, -				 struct tb_port **last, const char *name) +				 struct tb_port **last, const char *name, +				 bool alloc_hopid)  {  	struct tb_port *out_port;  	struct tb_regs_hop hop; @@ -156,6 +158,7 @@ struct tb_path *tb_path_discover(struct tb_port *src, int src_hopid,  	path->tb = src->sw->tb;  	path->path_length = num_hops;  	path->activated = true; +	path->alloc_hopid = alloc_hopid;  	path->hops = kcalloc(num_hops, sizeof(*path->hops), GFP_KERNEL);  	if (!path->hops) { @@ -177,13 +180,14 @@ struct tb_path *tb_path_discover(struct tb_port *src, int src_hopid,  			goto err;  		} -		if (tb_port_alloc_in_hopid(p, h, h) < 0) +		if (alloc_hopid && tb_port_alloc_in_hopid(p, h, h) < 0)  			goto err;  		out_port = &sw->ports[hop.out_port];  		next_hop = hop.next_hop; -		if (tb_port_alloc_out_hopid(out_port, next_hop, next_hop) < 0) { +		if (alloc_hopid && +		    tb_port_alloc_out_hopid(out_port, next_hop, next_hop) < 0) {  			tb_port_release_in_hopid(p, h);  			goto err;  		} @@ -263,6 +267,8 @@ struct tb_path *tb_path_alloc(struct tb *tb, struct tb_port *src, int src_hopid,  		return NULL;  	} +	path->alloc_hopid = true; +  	in_hopid = src_hopid;  	out_port = NULL; @@ -345,17 +351,19 @@ err:   */  void tb_path_free(struct tb_path *path)  { -	int i; - -	for (i = 0; i < path->path_length; i++) { -		const struct tb_path_hop *hop = &path->hops[i]; - -		if (hop->in_port) -			tb_port_release_in_hopid(hop->in_port, -						 hop->in_hop_index); -		if (hop->out_port) -			tb_port_release_out_hopid(hop->out_port, -						  hop->next_hop_index); +	if (path->alloc_hopid) { +		int i; + +		for (i = 0; i < path->path_length; i++) { +			const struct tb_path_hop *hop = &path->hops[i]; + +			if (hop->in_port) +				tb_port_release_in_hopid(hop->in_port, +							 hop->in_hop_index); +			if (hop->out_port) +				tb_port_release_out_hopid(hop->out_port, +							  hop->next_hop_index); +		}  	}  	kfree(path->hops);  |