in switch.c [2413:2505]
static int tb_switch_add_dma_port(struct tb_switch *sw)
{
u32 status;
int ret;
switch (sw->generation) {
case 2:
/* Only root switch can be upgraded */
if (tb_route(sw))
return 0;
fallthrough;
case 3:
case 4:
ret = tb_switch_set_uuid(sw);
if (ret)
return ret;
break;
default:
/*
* DMA port is the only thing available when the switch
* is in safe mode.
*/
if (!sw->safe_mode)
return 0;
break;
}
if (sw->no_nvm_upgrade)
return 0;
if (tb_switch_is_usb4(sw)) {
ret = usb4_switch_nvm_authenticate_status(sw, &status);
if (ret)
return ret;
if (status) {
tb_sw_info(sw, "switch flash authentication failed\n");
nvm_set_auth_status(sw, status);
}
return 0;
}
/* Root switch DMA port requires running firmware */
if (!tb_route(sw) && !tb_switch_is_icm(sw))
return 0;
sw->dma_port = dma_port_alloc(sw);
if (!sw->dma_port)
return 0;
/*
* If there is status already set then authentication failed
* when the dma_port_flash_update_auth() returned. Power cycling
* is not needed (it was done already) so only thing we do here
* is to unblock runtime PM of the root port.
*/
nvm_get_auth_status(sw, &status);
if (status) {
if (!tb_route(sw))
nvm_authenticate_complete_dma_port(sw);
return 0;
}
/*
* Check status of the previous flash authentication. If there
* is one we need to power cycle the switch in any case to make
* it functional again.
*/
ret = dma_port_flash_update_auth_status(sw->dma_port, &status);
if (ret <= 0)
return ret;
/* Now we can allow root port to suspend again */
if (!tb_route(sw))
nvm_authenticate_complete_dma_port(sw);
if (status) {
tb_sw_info(sw, "switch flash authentication failed\n");
nvm_set_auth_status(sw, status);
}
tb_sw_info(sw, "power cycling the switch now\n");
dma_port_power_cycle(sw->dma_port);
/*
* We return error here which causes the switch adding failure.
* It should appear back after power cycle is complete.
*/
return -ESHUTDOWN;
}