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()

int firmware_request_cache(struct device *device, const char *name)

缓存固件以用于挂起,以便恢复可以使用它

参数

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) 来释放固件映像和任何相关资源。