in switch.c [2952:3034]
int tb_switch_resume(struct tb_switch *sw)
{
struct tb_port *port;
int err;
tb_sw_dbg(sw, "resuming switch\n");
/*
* Check for UID of the connected switches except for root
* switch which we assume cannot be removed.
*/
if (tb_route(sw)) {
u64 uid;
/*
* Check first that we can still read the switch config
* space. It may be that there is now another domain
* connected.
*/
err = tb_cfg_get_upstream_port(sw->tb->ctl, tb_route(sw));
if (err < 0) {
tb_sw_info(sw, "switch not present anymore\n");
return err;
}
if (tb_switch_is_usb4(sw))
err = usb4_switch_read_uid(sw, &uid);
else
err = tb_drom_read_uid_only(sw, &uid);
if (err) {
tb_sw_warn(sw, "uid read failed\n");
return err;
}
if (sw->uid != uid) {
tb_sw_info(sw,
"changed while suspended (uid %#llx -> %#llx)\n",
sw->uid, uid);
return -ENODEV;
}
}
err = tb_switch_configure(sw);
if (err)
return err;
/* Disable wakes */
tb_switch_set_wake(sw, 0);
err = tb_switch_tmu_init(sw);
if (err)
return err;
/* check for surviving downstream switches */
tb_switch_for_each_port(sw, port) {
if (!tb_port_is_null(port))
continue;
if (!tb_port_resume(port))
continue;
if (tb_wait_for_port(port, true) <= 0) {
tb_port_warn(port,
"lost during suspend, disconnecting\n");
if (tb_port_has_remote(port))
tb_sw_set_unplugged(port->remote->sw);
else if (port->xdomain)
port->xdomain->is_unplugged = true;
} else {
/*
* Always unlock the port so the downstream
* switch/domain is accessible.
*/
if (tb_port_unlock(port))
tb_port_warn(port, "failed to unlock port\n");
if (port->remote && tb_switch_resume(port->remote->sw)) {
tb_port_warn(port,
"lost during suspend, disconnecting\n");
tb_sw_set_unplugged(port->remote->sw);
}
}
}
return 0;
}