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) 以釋放韌體映像和任何相關資源。