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

thunderbolt: Do not allocate switch if depth is greater than 6



Maximum depth in Thunderbolt topology is 6 so make sure it is not
possible to allocate switches that exceed the depth limit.

While at it update tb_switch_alloc() to use upper/lower_32_bits()
following tb_switch_alloc_safe_mode().

Signed-off-by: default avatarMika Westerberg <mika.westerberg@linux.intel.com>
parent 09f11b6c
Loading
Loading
Loading
Loading
+2 −3
Original line number Diff line number Diff line
@@ -42,7 +42,6 @@
#define ICM_TIMEOUT			5000	/* ms */
#define ICM_APPROVE_TIMEOUT		10000	/* ms */
#define ICM_MAX_LINK			4
#define ICM_MAX_DEPTH			6

/**
 * struct icm - Internal connection manager private data
@@ -714,7 +713,7 @@ icm_fr_device_disconnected(struct tb *tb, const struct icm_pkg_header *hdr)
	depth = (pkg->link_info & ICM_LINK_INFO_DEPTH_MASK) >>
		ICM_LINK_INFO_DEPTH_SHIFT;

	if (link > ICM_MAX_LINK || depth > ICM_MAX_DEPTH) {
	if (link > ICM_MAX_LINK || depth > TB_SWITCH_MAX_DEPTH) {
		tb_warn(tb, "invalid topology %u.%u, ignoring\n", link, depth);
		return;
	}
@@ -744,7 +743,7 @@ icm_fr_xdomain_connected(struct tb *tb, const struct icm_pkg_header *hdr)
	depth = (pkg->link_info & ICM_LINK_INFO_DEPTH_MASK) >>
		ICM_LINK_INFO_DEPTH_SHIFT;

	if (link > ICM_MAX_LINK || depth > ICM_MAX_DEPTH) {
	if (link > ICM_MAX_LINK || depth > TB_SWITCH_MAX_DEPTH) {
		tb_warn(tb, "invalid topology %u.%u, ignoring\n", link, depth);
		return;
	}
+12 −6
Original line number Diff line number Diff line
@@ -1130,10 +1130,16 @@ static int tb_switch_get_generation(struct tb_switch *sw)
struct tb_switch *tb_switch_alloc(struct tb *tb, struct device *parent,
				  u64 route)
{
	int i;
	int cap;
	struct tb_switch *sw;
	int upstream_port = tb_cfg_get_upstream_port(tb->ctl, route);
	int upstream_port;
	int i, cap, depth;

	/* Make sure we do not exceed maximum topology limit */
	depth = tb_route_length(route);
	if (depth > TB_SWITCH_MAX_DEPTH)
		return NULL;

	upstream_port = tb_cfg_get_upstream_port(tb->ctl, route);
	if (upstream_port < 0)
		return NULL;

@@ -1150,9 +1156,9 @@ struct tb_switch *tb_switch_alloc(struct tb *tb, struct device *parent,

	/* configure switch */
	sw->config.upstream_port_number = upstream_port;
	sw->config.depth = tb_route_length(route);
	sw->config.route_lo = route;
	sw->config.route_hi = route >> 32;
	sw->config.depth = depth;
	sw->config.route_hi = upper_32_bits(route);
	sw->config.route_lo = lower_32_bits(route);
	sw->config.enabled = 0;

	/* initialize ports */
+1 −0
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ struct tb_switch_nvm {
};

#define TB_SWITCH_KEY_SIZE		32
#define TB_SWITCH_MAX_DEPTH		6

/**
 * struct tb_switch - a thunderbolt switch