request_firmware API¶
您通常会加载固件,然后以某种方式将其加载到您的设备中。典型的固件工作流程如下所示
if(request_firmware(&fw_entry, $FIRMWARE, device) == 0)
copy_fw_to_device(fw_entry->data, fw_entry->size);
release_firmware(fw_entry);
同步固件请求¶
同步固件请求将等待直到找到固件或返回错误。
request_firmware¶
-
int request_firmware(const struct firmware **firmware_p, const char *name, struct device *device)¶
发送固件请求并等待它
参数
const struct firmware **firmware_p
指向固件映像的指针
const char *name
固件文件的名称
struct device *device
正在为其加载固件的设备
firmware_p 将用于返回设备 device 的名称为 name 的固件映像。
应从允许睡眠的用户上下文中调用。
name 将在 uevent 环境中用作 $FIRMWARE,并且应该足够独特,不会与此设备或任何其他设备的任何其他固件映像混淆。它不能包含任何 “..” 路径组件 - 允许使用 “foo/bar..bin”,但不允许使用 “foo/../bar.bin”。
调用者必须持有 device 的引用计数。
该函数可以在设备的挂起和恢复回调中安全调用。
firmware_request_nowarn¶
-
int firmware_request_nowarn(const struct firmware **firmware, const char *name, struct device *device)¶
请求可选的固件模块
参数
const struct firmware **firmware
指向固件映像的指针
const char *name
固件文件的名称
struct device *device
正在为其加载固件的设备
描述
此函数的行为类似于 request_firmware()
,只是当找不到文件时它不会产生警告消息。如果直接文件系统查找失败,则启用 sysfs 回退机制。但是,仍然会抑制使用它查找固件文件的失败。因此,驱动程序有责任检查此调用的返回值,并决定何时通知用户错误。
firmware_request_platform¶
-
int firmware_request_platform(const struct firmware **firmware, const char *name, struct device *device)¶
请求具有平台固件回退的固件
参数
const struct firmware **firmware
指向固件映像的指针
const char *name
固件文件的名称
struct device *device
正在为其加载固件的设备
描述
此函数的行为类似于 request_firmware,只是如果直接文件系统查找失败,它将回退到查找嵌入在平台主固件(例如 UEFI)中的请求固件的副本。
request_firmware_direct¶
-
int request_firmware_direct(const struct firmware **firmware_p, const char *name, struct device *device)¶
直接加载固件,无需用户模式帮助程序
参数
const struct firmware **firmware_p
指向固件映像的指针
const char *name
固件文件的名称
struct device *device
正在为其加载固件的设备
描述
此函数的工作方式与 request_firmware()
非常相似,但即使无法直接从 fs 加载固件,也不会回退到用户模式帮助程序。因此,它对于加载并非始终存在的可选固件非常有用,而无需 udev 的额外长时间超时。
request_firmware_into_buf¶
-
int request_firmware_into_buf(const struct firmware **firmware_p, const char *name, struct device *device, void *buf, size_t size)¶
将固件加载到预先分配的缓冲区中
参数
const struct firmware **firmware_p
指向固件映像的指针
const char *name
固件文件的名称
struct device *device
正在加载固件的设备和分配的DMA区域
void *buf
要将固件加载到的缓冲区的地址
size_t size
缓冲区的大小
描述
此函数的工作方式与 request_firmware()
非常相似,但它不会分配缓冲区来保存固件数据。相反,固件直接加载到 **buf** 指向的缓冲区中,并且 **firmware_p** 数据成员指向 **buf**。
此函数也不缓存固件。
异步固件请求¶
异步固件请求允许驱动程序代码不必等待固件或错误返回。提供函数回调,以便在找到固件或错误时通过回调通知驱动程序。不能在原子上下文调用 request_firmware_nowait()
。
request_firmware_nowait¶
-
int request_firmware_nowait(struct module *module, bool uevent, const char *name, struct device *device, gfp_t gfp, void *context, void (*cont)(const struct firmware *fw, void *context))¶
request_firmware 的异步版本
参数
struct module *module
请求固件的模块
bool uevent
如果此标志非零,则发送 uevent 以复制固件映像,否则必须手动完成固件复制。
const char *name
固件文件的名称
struct device *device
正在为其加载固件的设备
gfp_t gfp
分配标志
void *context
将被传递给 **cont**,如果固件请求失败,**fw** 可能为
NULL
。void (*cont)(const struct firmware *fw, void *context)
当固件请求完成时,将异步调用该函数。
调用者必须持有 device 的引用计数。
- 用于用户上下文的 request_firmware() 的异步变体
尽可能短的时间睡眠,因为如果 **gfp** 为 GFP_KERNEL,这可能会增加内置设备驱动程序在其 ->probe() 方法中请求固件的内核启动时间。
如果 **gfp** 为 GFP_ATOMIC,则根本不能睡眠。
重启时的特殊优化¶
某些设备具有一项优化,可以在系统重启期间保留固件。当使用此类优化时,驱动程序作者必须确保固件在从挂起恢复时仍然可用,这可以使用 firmware_request_cache()
完成,而不是请求加载固件。
firmware_request_cache()¶
参数
struct device *device
应为其缓存固件的设备
const char *name
固件文件的名称
描述
有些设备具有优化功能,使设备无需在系统重启时加载固件。此优化可能仍然需要在从挂起恢复时存在固件。可以使用此例程来确保在这些情况下,固件在从挂起恢复时存在。此助手与使用 request_firmware_into_buf()
或 request_firmware_nowait()
且未设置 uevent 的驱动程序不兼容。
request firmware API 预期的驱动程序使用¶
一旦 API 调用返回,您将处理固件,然后释放固件。例如,如果您使用 request_firmware()
并且它返回,则驱动程序可以在 fw_entry->{data,size} 中访问固件映像。如果出现问题,request_firmware()
返回非零值,并且 fw_entry 设置为 NULL。一旦您的驱动程序完成固件处理,它就可以调用 release_firmware(fw_entry) 来释放固件映像和任何相关资源。