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)

请求可选的 fw 模块

参数

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() 的异步变体
  • 尽可能短地休眠,因为它可能会增加内置设备驱动程序在其 ->probe() 方法中请求固件的内核启动时间,如果 gfp 为 GFP_KERNEL。

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