/* * use small loading timeout for caching devices' firmware because all these * firmware images have been loaded successfully at lease once, also system is * ready for completing firmware loading now. The maximum size of firmware in * current distributions is about 2M bytes, so 10 secs should be enough.
*/ void fw_fallback_set_cache_timeout(void)
{
fw_fallback_config.old_timeout = __firmware_loading_timeout();
__fw_fallback_set_timeout(10);
}
/* Restores the timeout to the value last configured during normal operation */ void fw_fallback_set_default_timeout(void)
{
__fw_fallback_set_timeout(fw_fallback_config.old_timeout);
}
/** * fw_load_sysfs_fallback() - load a firmware via the sysfs fallback mechanism * @fw_sysfs: firmware sysfs information for the firmware to load * @timeout: timeout to wait for the load * * In charge of constructing a sysfs fallback interface for firmware loading.
**/ staticint fw_load_sysfs_fallback(struct fw_sysfs *fw_sysfs, long timeout)
{ int retval = 0; struct device *f_dev = &fw_sysfs->dev; struct fw_priv *fw_priv = fw_sysfs->fw_priv;
/* fall back on userspace loading */ if (!fw_priv->data)
fw_priv->is_paged_buf = true;
staticint fw_load_from_user_helper(struct firmware *firmware, constchar *name, struct device *device,
u32 opt_flags)
{ struct fw_sysfs *fw_sysfs; long timeout; int ret;
timeout = firmware_loading_timeout(); if (opt_flags & FW_OPT_NOWAIT) {
timeout = usermodehelper_read_lock_wait(timeout); if (!timeout) {
dev_dbg(device, "firmware: %s loading timed out\n",
name); return -EBUSY;
}
} else {
ret = usermodehelper_read_trylock(); if (WARN_ON(ret)) {
dev_err(device, "firmware: %s will not be loaded\n",
name); return ret;
}
}
fw_sysfs = fw_create_instance(firmware, name, device, opt_flags); if (IS_ERR(fw_sysfs)) {
ret = PTR_ERR(fw_sysfs); goto out_unlock;
}
fw_sysfs->fw_priv = firmware->priv;
ret = fw_load_sysfs_fallback(fw_sysfs, timeout);
if (!ret)
ret = assign_fw(firmware, device);
out_unlock:
usermodehelper_read_unlock();
return ret;
}
staticbool fw_force_sysfs_fallback(u32 opt_flags)
{ if (fw_fallback_config.force_sysfs_fallback) returntrue; if (!(opt_flags & FW_OPT_USERHELPER)) returnfalse; returntrue;
}
staticbool fw_run_sysfs_fallback(u32 opt_flags)
{ int ret;
if (fw_fallback_config.ignore_sysfs_fallback) {
pr_info_once("Ignoring firmware sysfs fallback due to sysctl knob\n"); returnfalse;
}
if ((opt_flags & FW_OPT_NOFALLBACK_SYSFS)) returnfalse;
/* Also permit LSMs and IMA to fail firmware sysfs fallback */
ret = security_kernel_load_data(LOADING_FIRMWARE, true); if (ret < 0) returnfalse;
return fw_force_sysfs_fallback(opt_flags);
}
/** * firmware_fallback_sysfs() - use the fallback mechanism to find firmware * @fw: pointer to firmware image * @name: name of firmware file to look for * @device: device for which firmware is being loaded * @opt_flags: options to control firmware loading behaviour, as defined by * &enum fw_opt * @ret: return value from direct lookup which triggered the fallback mechanism * * This function is called if direct lookup for the firmware failed, it enables * a fallback mechanism through userspace by exposing a sysfs loading * interface. Userspace is in charge of loading the firmware through the sysfs * loading interface. This sysfs fallback mechanism may be disabled completely * on a system by setting the proc sysctl value ignore_sysfs_fallback to true. * If this is false we check if the internal API caller set the * @FW_OPT_NOFALLBACK_SYSFS flag, if so it would also disable the fallback * mechanism. A system may want to enforce the sysfs fallback mechanism at all * times, it can do this by setting ignore_sysfs_fallback to false and * force_sysfs_fallback to true. * Enabling force_sysfs_fallback is functionally equivalent to build a kernel * with CONFIG_FW_LOADER_USER_HELPER_FALLBACK.
**/ int firmware_fallback_sysfs(struct firmware *fw, constchar *name, struct device *device,
u32 opt_flags, int ret)
{ if (!fw_run_sysfs_fallback(opt_flags)) return ret;
if (!(opt_flags & FW_OPT_NO_WARN))
dev_warn(device, "Falling back to sysfs fallback for: %s\n",
name); else
dev_dbg(device, "Falling back to sysfs fallback for: %s\n",
name); return fw_load_from_user_helper(fw, name, device, opt_flags);
}
Messung V0.5
¤ Dauer der Verarbeitung: 0.15 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.