|
@@ -383,6 +383,15 @@ static void remove_switch(struct tb_switch *sw)
|
|
|
tb_switch_remove(sw);
|
|
|
}
|
|
|
|
|
|
+static void remove_xdomain(struct tb_xdomain *xd)
|
|
|
+{
|
|
|
+ struct tb_switch *sw;
|
|
|
+
|
|
|
+ sw = tb_to_switch(xd->dev.parent);
|
|
|
+ tb_port_at(xd->route, sw)->xdomain = NULL;
|
|
|
+ tb_xdomain_remove(xd);
|
|
|
+}
|
|
|
+
|
|
|
static void
|
|
|
icm_fr_device_connected(struct tb *tb, const struct icm_pkg_header *hdr)
|
|
|
{
|
|
@@ -391,6 +400,7 @@ icm_fr_device_connected(struct tb *tb, const struct icm_pkg_header *hdr)
|
|
|
struct tb_switch *sw, *parent_sw;
|
|
|
struct icm *icm = tb_priv(tb);
|
|
|
bool authorized = false;
|
|
|
+ struct tb_xdomain *xd;
|
|
|
u8 link, depth;
|
|
|
u64 route;
|
|
|
int ret;
|
|
@@ -467,6 +477,13 @@ icm_fr_device_connected(struct tb *tb, const struct icm_pkg_header *hdr)
|
|
|
tb_switch_put(sw);
|
|
|
}
|
|
|
|
|
|
+ /* Remove existing XDomain connection if found */
|
|
|
+ xd = tb_xdomain_find_by_link_depth(tb, link, depth);
|
|
|
+ if (xd) {
|
|
|
+ remove_xdomain(xd);
|
|
|
+ tb_xdomain_put(xd);
|
|
|
+ }
|
|
|
+
|
|
|
parent_sw = tb_switch_find_by_link_depth(tb, link, depth - 1);
|
|
|
if (!parent_sw) {
|
|
|
tb_err(tb, "failed to find parent switch for %u.%u\n",
|
|
@@ -529,15 +546,6 @@ icm_fr_device_disconnected(struct tb *tb, const struct icm_pkg_header *hdr)
|
|
|
tb_switch_put(sw);
|
|
|
}
|
|
|
|
|
|
-static void remove_xdomain(struct tb_xdomain *xd)
|
|
|
-{
|
|
|
- struct tb_switch *sw;
|
|
|
-
|
|
|
- sw = tb_to_switch(xd->dev.parent);
|
|
|
- tb_port_at(xd->route, sw)->xdomain = NULL;
|
|
|
- tb_xdomain_remove(xd);
|
|
|
-}
|
|
|
-
|
|
|
static void
|
|
|
icm_fr_xdomain_connected(struct tb *tb, const struct icm_pkg_header *hdr)
|
|
|
{
|