drivers/base/firmware_loader/fallback.c
Source file repositories/reference/linux-study-clean/drivers/base/firmware_loader/fallback.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/base/firmware_loader/fallback.c- Extension
.c- Size
- 6488 bytes
- Lines
- 240
- Domain
- Driver Families
- Bucket
- drivers/base
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/types.hlinux/kconfig.hlinux/list.hlinux/security.hlinux/umh.hlinux/sysctl.hlinux/module.hfallback.hfirmware.h
Detected Declarations
function fw_fallback_set_cache_timeoutfunction fw_fallback_set_default_timeoutfunction firmware_loading_timeoutfunction fw_sysfs_wait_timeoutfunction kill_pending_fw_fallback_reqsfunction fw_load_sysfs_fallbackfunction fw_load_from_user_helperfunction fw_force_sysfs_fallbackfunction fw_run_sysfs_fallbackfunction firmware_fallback_sysfs
Annotated Snippet
retval = device_add(f_dev);
if (retval) {
dev_err(f_dev, "%s: device_register failed\n", __func__);
goto err_put_dev;
}
mutex_lock(&fw_lock);
if (fw_load_abort_all || fw_state_is_aborted(fw_priv)) {
mutex_unlock(&fw_lock);
retval = -EINTR;
goto out;
}
list_add(&fw_priv->pending_list, &pending_fw_head);
mutex_unlock(&fw_lock);
if (fw_priv->opt_flags & FW_OPT_UEVENT) {
fw_priv->need_uevent = true;
dev_set_uevent_suppress(f_dev, false);
dev_dbg(f_dev, "firmware: requesting %s\n", fw_priv->fw_name);
kobject_uevent(&fw_sysfs->dev.kobj, KOBJ_ADD);
} else {
timeout = MAX_JIFFY_OFFSET;
}
retval = fw_sysfs_wait_timeout(fw_priv, timeout);
if (retval < 0 && retval != -ENOENT) {
mutex_lock(&fw_lock);
fw_load_abort(fw_sysfs);
mutex_unlock(&fw_lock);
}
if (fw_state_is_aborted(fw_priv)) {
if (retval == -ERESTARTSYS)
retval = -EINTR;
} else if (fw_priv->is_paged_buf && !fw_priv->data)
retval = -ENOMEM;
out:
device_del(f_dev);
err_put_dev:
put_device(f_dev);
return retval;
}
static int fw_load_from_user_helper(struct firmware *firmware,
const char *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;
}
static bool fw_force_sysfs_fallback(u32 opt_flags)
{
if (fw_fallback_config.force_sysfs_fallback)
Annotation
- Immediate include surface: `linux/types.h`, `linux/kconfig.h`, `linux/list.h`, `linux/security.h`, `linux/umh.h`, `linux/sysctl.h`, `linux/module.h`, `fallback.h`.
- Detected declarations: `function fw_fallback_set_cache_timeout`, `function fw_fallback_set_default_timeout`, `function firmware_loading_timeout`, `function fw_sysfs_wait_timeout`, `function kill_pending_fw_fallback_reqs`, `function fw_load_sysfs_fallback`, `function fw_load_from_user_helper`, `function fw_force_sysfs_fallback`, `function fw_run_sysfs_fallback`, `function firmware_fallback_sysfs`.
- Atlas domain: Driver Families / drivers/base.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.