in switch.c [1779:1838]
static ssize_t nvm_authenticate_sysfs(struct device *dev, const char *buf,
bool disconnect)
{
struct tb_switch *sw = tb_to_switch(dev);
int val, ret;
pm_runtime_get_sync(&sw->dev);
if (!mutex_trylock(&sw->tb->lock)) {
ret = restart_syscall();
goto exit_rpm;
}
/* If NVMem devices are not yet added */
if (!sw->nvm) {
ret = -EAGAIN;
goto exit_unlock;
}
ret = kstrtoint(buf, 10, &val);
if (ret)
goto exit_unlock;
/* Always clear the authentication status */
nvm_clear_auth_status(sw);
if (val > 0) {
if (val == AUTHENTICATE_ONLY) {
if (disconnect)
ret = -EINVAL;
else
ret = nvm_authenticate(sw, true);
} else {
if (!sw->nvm->flushed) {
if (!sw->nvm->buf) {
ret = -EINVAL;
goto exit_unlock;
}
ret = nvm_validate_and_write(sw);
if (ret || val == WRITE_ONLY)
goto exit_unlock;
}
if (val == WRITE_AND_AUTHENTICATE) {
if (disconnect)
ret = tb_lc_force_power(sw);
else
ret = nvm_authenticate(sw, false);
}
}
}
exit_unlock:
mutex_unlock(&sw->tb->lock);
exit_rpm:
pm_runtime_mark_last_busy(&sw->dev);
pm_runtime_put_autosuspend(&sw->dev);
return ret;
}