Blob Blame History Raw
From 8e9267bb3559065fddecf344cb54501704fcb68e Mon Sep 17 00:00:00 2001
From: Radion Mirchevsky <radion.mirchevsky@intel.com>
Date: Wed, 4 Oct 2017 15:24:14 +0300
Subject: [PATCH] thunderbolt: Add tb_switch_find_by_route()
Git-commit: 8e9267bb3559065fddecf344cb54501704fcb68e
Patch-mainline: v4.17
References: FATE#324324

With the new ICM messaging there is need for find switch by route string
instead of link and depth. Add new function that makes it possible.

Signed-off-by: Radion Mirchevsky <radion.mirchevsky@intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Signed-off-by: Oliver Neukum <oneukum@suse.com>
---
 drivers/thunderbolt/switch.c |   33 +++++++++++++++++++++++++++++++++
 drivers/thunderbolt/tb.h     |    1 +
 2 files changed, 34 insertions(+)

--- a/drivers/thunderbolt/switch.c
+++ b/drivers/thunderbolt/switch.c
@@ -1478,6 +1478,7 @@ struct tb_sw_lookup {
 	u8 link;
 	u8 depth;
 	const uuid_be *uuid;
+	u64 route;
 };
 
 static int tb_switch_match(struct device *dev, void *data)
@@ -1493,6 +1494,11 @@ static int tb_switch_match(struct device
 	if (lookup->uuid)
 		return !memcmp(sw->uuid, lookup->uuid, sizeof(*lookup->uuid));
 
+	if (lookup->route) {
+		return sw->config.route_lo == lower_32_bits(lookup->route) &&
+		       sw->config.route_hi == upper_32_bits(lookup->route);
+	}
+
 	/* Root switch is matched only by depth */
 	if (!lookup->depth)
 		return !sw->depth;
@@ -1545,6 +1551,33 @@ struct tb_switch *tb_switch_find_by_uuid
 
 	dev = bus_find_device(&tb_bus_type, NULL, &lookup, tb_switch_match);
 	if (dev)
+		return tb_to_switch(dev);
+
+	return NULL;
+}
+
+/**
+ * tb_switch_find_by_route() - Find switch by route string
+ * @tb: Domain the switch belongs
+ * @route: Route string to look for
+ *
+ * Returned switch has reference count increased so the caller needs to
+ * call tb_switch_put() when done with the switch.
+ */
+struct tb_switch *tb_switch_find_by_route(struct tb *tb, u64 route)
+{
+	struct tb_sw_lookup lookup;
+	struct device *dev;
+
+	if (!route)
+		return tb_switch_get(tb->root_switch);
+
+	memset(&lookup, 0, sizeof(lookup));
+	lookup.tb = tb;
+	lookup.route = route;
+
+	dev = bus_find_device(&tb_bus_type, NULL, &lookup, tb_switch_match);
+	if (dev)
 		return tb_to_switch(dev);
 
 	return NULL;
--- a/drivers/thunderbolt/tb.h
+++ b/drivers/thunderbolt/tb.h
@@ -385,6 +385,7 @@ struct tb_switch *get_switch_at_route(st
 struct tb_switch *tb_switch_find_by_link_depth(struct tb *tb, u8 link,
 					       u8 depth);
 struct tb_switch *tb_switch_find_by_uuid(struct tb *tb, const uuid_be *uuid);
+struct tb_switch *tb_switch_find_by_route(struct tb *tb, u64 route);
 
 #define TB_LINKS_PER_PHY_PORT  2