summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/thunderbolt/icm.c12
-rw-r--r--drivers/thunderbolt/switch.c18
-rw-r--r--drivers/thunderbolt/tb.c9
-rw-r--r--drivers/thunderbolt/tb.h1
4 files changed, 14 insertions, 26 deletions
diff --git a/drivers/thunderbolt/icm.c b/drivers/thunderbolt/icm.c
index 8b7f9131e9d1..7c923e16a7d8 100644
--- a/drivers/thunderbolt/icm.c
+++ b/drivers/thunderbolt/icm.c
@@ -798,9 +798,11 @@ icm_fr_xdomain_connected(struct tb *tb, const struct icm_pkg_header *hdr)
798 * connected another host to the same port, remove the switch 798 * connected another host to the same port, remove the switch
799 * first. 799 * first.
800 */ 800 */
801 sw = get_switch_at_route(tb->root_switch, route); 801 sw = tb_switch_find_by_route(tb, route);
802 if (sw) 802 if (sw) {
803 remove_switch(sw); 803 remove_switch(sw);
804 tb_switch_put(sw);
805 }
804 806
805 sw = tb_switch_find_by_link_depth(tb, link, depth); 807 sw = tb_switch_find_by_link_depth(tb, link, depth);
806 if (!sw) { 808 if (!sw) {
@@ -1143,9 +1145,11 @@ icm_tr_xdomain_connected(struct tb *tb, const struct icm_pkg_header *hdr)
1143 * connected another host to the same port, remove the switch 1145 * connected another host to the same port, remove the switch
1144 * first. 1146 * first.
1145 */ 1147 */
1146 sw = get_switch_at_route(tb->root_switch, route); 1148 sw = tb_switch_find_by_route(tb, route);
1147 if (sw) 1149 if (sw) {
1148 remove_switch(sw); 1150 remove_switch(sw);
1151 tb_switch_put(sw);
1152 }
1149 1153
1150 sw = tb_switch_find_by_route(tb, get_parent_route(route)); 1154 sw = tb_switch_find_by_route(tb, get_parent_route(route));
1151 if (!sw) { 1155 if (!sw) {
diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c
index 504365d46827..5c2c0201ae7f 100644
--- a/drivers/thunderbolt/switch.c
+++ b/drivers/thunderbolt/switch.c
@@ -644,24 +644,6 @@ int tb_switch_reset(struct tb *tb, u64 route)
644 return res.err; 644 return res.err;
645} 645}
646 646
647struct tb_switch *get_switch_at_route(struct tb_switch *sw, u64 route)
648{
649 u8 next_port = route; /*
650 * Routes use a stride of 8 bits,
651 * eventhough a port index has 6 bits at most.
652 * */
653 if (route == 0)
654 return sw;
655 if (next_port > sw->config.max_port_number)
656 return NULL;
657 if (tb_is_upstream_port(&sw->ports[next_port]))
658 return NULL;
659 if (!sw->ports[next_port].remote)
660 return NULL;
661 return get_switch_at_route(sw->ports[next_port].remote->sw,
662 route >> TB_ROUTE_SHIFT);
663}
664
665/** 647/**
666 * tb_plug_events_active() - enable/disable plug events on a switch 648 * tb_plug_events_active() - enable/disable plug events on a switch
667 * 649 *
diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c
index 30e02c716f6c..d8f4ed0f2ef8 100644
--- a/drivers/thunderbolt/tb.c
+++ b/drivers/thunderbolt/tb.c
@@ -258,7 +258,7 @@ static void tb_handle_hotplug(struct work_struct *work)
258 if (!tcm->hotplug_active) 258 if (!tcm->hotplug_active)
259 goto out; /* during init, suspend or shutdown */ 259 goto out; /* during init, suspend or shutdown */
260 260
261 sw = get_switch_at_route(tb->root_switch, ev->route); 261 sw = tb_switch_find_by_route(tb, ev->route);
262 if (!sw) { 262 if (!sw) {
263 tb_warn(tb, 263 tb_warn(tb,
264 "hotplug event from non existent switch %llx:%x (unplug: %d)\n", 264 "hotplug event from non existent switch %llx:%x (unplug: %d)\n",
@@ -269,14 +269,14 @@ static void tb_handle_hotplug(struct work_struct *work)
269 tb_warn(tb, 269 tb_warn(tb,
270 "hotplug event from non existent port %llx:%x (unplug: %d)\n", 270 "hotplug event from non existent port %llx:%x (unplug: %d)\n",
271 ev->route, ev->port, ev->unplug); 271 ev->route, ev->port, ev->unplug);
272 goto out; 272 goto put_sw;
273 } 273 }
274 port = &sw->ports[ev->port]; 274 port = &sw->ports[ev->port];
275 if (tb_is_upstream_port(port)) { 275 if (tb_is_upstream_port(port)) {
276 tb_warn(tb, 276 tb_warn(tb,
277 "hotplug event for upstream port %llx:%x (unplug: %d)\n", 277 "hotplug event for upstream port %llx:%x (unplug: %d)\n",
278 ev->route, ev->port, ev->unplug); 278 ev->route, ev->port, ev->unplug);
279 goto out; 279 goto put_sw;
280 } 280 }
281 if (ev->unplug) { 281 if (ev->unplug) {
282 if (port->remote) { 282 if (port->remote) {
@@ -306,6 +306,9 @@ static void tb_handle_hotplug(struct work_struct *work)
306 tb_activate_pcie_devices(tb); 306 tb_activate_pcie_devices(tb);
307 } 307 }
308 } 308 }
309
310put_sw:
311 tb_switch_put(sw);
309out: 312out:
310 mutex_unlock(&tb->lock); 313 mutex_unlock(&tb->lock);
311 kfree(ev); 314 kfree(ev);
diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h
index 8058ea02d572..aea668c40d27 100644
--- a/drivers/thunderbolt/tb.h
+++ b/drivers/thunderbolt/tb.h
@@ -399,7 +399,6 @@ void tb_switch_suspend(struct tb_switch *sw);
399int tb_switch_resume(struct tb_switch *sw); 399int tb_switch_resume(struct tb_switch *sw);
400int tb_switch_reset(struct tb *tb, u64 route); 400int tb_switch_reset(struct tb *tb, u64 route);
401void tb_sw_set_unplugged(struct tb_switch *sw); 401void tb_sw_set_unplugged(struct tb_switch *sw);
402struct tb_switch *get_switch_at_route(struct tb_switch *sw, u64 route);
403struct tb_switch *tb_switch_find_by_link_depth(struct tb *tb, u8 link, 402struct tb_switch *tb_switch_find_by_link_depth(struct tb *tb, u8 link,
404 u8 depth); 403 u8 depth);
405struct tb_switch *tb_switch_find_by_uuid(struct tb *tb, const uuid_t *uuid); 404struct tb_switch *tb_switch_find_by_uuid(struct tb *tb, const uuid_t *uuid);