裝置驅動程式基礎設施

基本裝置驅動程式模型結構

struct subsys_interface

裝置功能介面

定義:

struct subsys_interface {
    const char *name;
    const struct bus_type *subsys;
    struct list_head node;
    int (*add_dev)(struct device *dev, struct subsys_interface *sif);
    void (*remove_dev)(struct device *dev, struct subsys_interface *sif);
};

成員

name

裝置功能名稱

subsys

要附加到的裝置的子系統

node

在子系統中註冊的功能列表

add_dev

裝置與裝置功能處理程式的連線

remove_dev

裝置與裝置功能處理程式的連線

描述

附加到子系統的簡單介面。多個介面可以附加到子系統及其裝置。與驅動程式不同,它們不獨佔宣告或控制裝置。介面通常表示子系統/裝置類別的特定功能。

struct device_attribute

用於匯出裝置屬性的介面。

定義:

struct device_attribute {
    struct attribute        attr;
    ssize_t (*show)(struct device *dev, struct device_attribute *attr, char *buf);
    ssize_t (*store)(struct device *dev, struct device_attribute *attr, const char *buf, size_t count);
};

成員

attr

sysfs 屬性定義。

show

顯示處理程式。

store

儲存處理程式。

struct dev_ext_attribute

帶有額外上下文的匯出裝置屬性。

定義:

struct dev_ext_attribute {
    struct device_attribute attr;
    void *var;
};

成員

attr

匯出的裝置屬性。

var

上下文指標。

DEVICE_ATTR

DEVICE_ATTR (_name, _mode, _show, _store)

定義裝置屬性。

引數

_name

屬性名稱。

_mode

檔案模式。

_show

顯示處理程式。可選,但如果屬性可讀則強制。

_store

儲存處理程式。可選,但如果屬性可寫則強制。

描述

定義 struct device_attribute 的便捷宏。

例如,DEVICE_ATTR(foo, 0644, foo_show, foo_store); 展開為

struct device_attribute dev_attr_foo = {
        .attr   = { .name = "foo", .mode = 0644 },
        .show   = foo_show,
        .store  = foo_store,
};
DEVICE_ATTR_PREALLOC

DEVICE_ATTR_PREALLOC (_name, _mode, _show, _store)

定義一個預分配裝置屬性。

引數

_name

屬性名稱。

_mode

檔案模式。

_show

顯示處理程式。可選,但如果屬性可讀則強制。

_store

儲存處理程式。可選,但如果屬性可寫則強制。

描述

DEVICE_ATTR() 類似,但 SYSFS_PREALLOC 設定在 _mode 上。

DEVICE_ATTR_RW

DEVICE_ATTR_RW (_name)

定義一個讀寫裝置屬性。

引數

_name

屬性名稱。

描述

DEVICE_ATTR() 類似,但 _mode 是 0644,_show 是 <_name>_show,並且 _store 是 <_name>_store。

DEVICE_ATTR_ADMIN_RW

DEVICE_ATTR_ADMIN_RW (_name)

定義一個僅限管理員的讀寫裝置屬性。

引數

_name

屬性名稱。

描述

DEVICE_ATTR_RW() 類似,但 _mode 是 0600。

DEVICE_ATTR_RO

DEVICE_ATTR_RO (_name)

定義一個可讀裝置屬性。

引數

_name

屬性名稱。

描述

DEVICE_ATTR() 類似,但 _mode 是 0444 並且 _show 是 <_name>_show。

DEVICE_ATTR_ADMIN_RO

DEVICE_ATTR_ADMIN_RO (_name)

定義一個僅限管理員的可讀裝置屬性。

引數

_name

屬性名稱。

描述

DEVICE_ATTR_RO() 類似,但 _mode 是 0400。

DEVICE_ATTR_WO

DEVICE_ATTR_WO (_name)

定義一個僅限管理員的可寫裝置屬性。

引數

_name

屬性名稱。

描述

DEVICE_ATTR() 類似,但 _mode 是 0200 並且 _store 是 <_name>_store。

DEVICE_ULONG_ATTR

DEVICE_ULONG_ATTR (_name, _mode, _var)

定義一個由無符號長整型支援的裝置屬性。

引數

_name

屬性名稱。

_mode

檔案模式。

_var

無符號長整型識別符號。

描述

DEVICE_ATTR() 類似,但 _show_store 自動提供,以便使用者空間對屬性的讀寫影響 _var

DEVICE_INT_ATTR

DEVICE_INT_ATTR (_name, _mode, _var)

定義一個由整型支援的裝置屬性。

引數

_name

屬性名稱。

_mode

檔案模式。

_var

整型識別符號。

描述

DEVICE_ULONG_ATTR() 類似,但 _var 是一個整型。

DEVICE_BOOL_ATTR

DEVICE_BOOL_ATTR (_name, _mode, _var)

定義一個由布林型支援的裝置屬性。

引數

_name

屬性名稱。

_mode

檔案模式。

_var

布林型識別符號。

描述

DEVICE_ULONG_ATTR() 類似,但 _var 是一個布林型。

DEVICE_STRING_ATTR_RO

DEVICE_STRING_ATTR_RO (_name, _mode, _var)

定義一個由只讀字串支援的裝置屬性。

引數

_name

屬性名稱。

_mode

檔案模式。

_var

字串識別符號。

描述

DEVICE_ULONG_ATTR() 類似,但 _var 是一個字串。由於字串分配的長度未知,該屬性必須是隻讀的。

devm_alloc_percpu

devm_alloc_percpu (dev, type)

資源管理的 alloc_percpu

引數

dev

要分配每 CPU 記憶體的裝置

type

要分配每 CPU 記憶體的型別

描述

受管理的 alloc_percpu。使用此函式分配的每 CPU 記憶體會在驅動程式分離時自動釋放。

返回

成功時返回指向已分配記憶體的指標,失敗時返回 NULL。

enum dl_dev_state

裝置驅動程式存在跟蹤資訊。

常量

DL_DEV_NO_DRIVER

沒有驅動程式附加到裝置。

DL_DEV_PROBING

驅動程式正在探測。

DL_DEV_DRIVER_BOUND

驅動程式已繫結到裝置。

DL_DEV_UNBINDING

驅動程式正在從裝置解綁。

enum device_removable

裝置是否可移動。裝置被分類為可移動的標準由其子系統或匯流排決定。

常量

DEVICE_REMOVABLE_NOT_SUPPORTED

此裝置不支援此屬性(預設)。

DEVICE_REMOVABLE_UNKNOWN

裝置位置未知。

DEVICE_FIXED

使用者無法移除裝置。

DEVICE_REMOVABLE

使用者可以移除裝置。

與裝置連結相關的裝置資料。

定義:

struct dev_links_info {
    struct list_head suppliers;
    struct list_head consumers;
    struct list_head defer_sync;
    enum dl_dev_state status;
};

成員

suppliers

指向供應商裝置的連結列表。

consumers

指向消費者裝置的連結列表。

defer_sync

掛鉤到已延遲 sync_state 的裝置全域性列表。

status

驅動程式狀態資訊。

struct dev_msi_info

與 MSI 相關的裝置資料

定義:

struct dev_msi_info {
#ifdef CONFIG_GENERIC_MSI_IRQ;
    struct irq_domain       *domain;
    struct msi_device_data  *data;
#endif;
};

成員

domain

與裝置關聯的 MSI 中斷域

data

指向 MSI 裝置資料的指標

enum device_physical_location_panel

描述裝置連線點位於系統外殼的哪個面板表面。

常量

DEVICE_PANEL_TOP

裝置連線點在頂部面板上。

DEVICE_PANEL_BOTTOM

裝置連線點在底部面板上。

DEVICE_PANEL_LEFT

裝置連線點在左側面板上。

DEVICE_PANEL_RIGHT

裝置連線點在右側面板上。

DEVICE_PANEL_FRONT

裝置連線點在前面板上。

DEVICE_PANEL_BACK

裝置連線點在後面板上。

DEVICE_PANEL_UNKNOWN

帶有裝置連線點的面板未知。

enum device_physical_location_vertical_position

描述裝置連線點在面板表面上的垂直位置。

常量

DEVICE_VERT_POS_UPPER

裝置連線點在面板的上部。

DEVICE_VERT_POS_CENTER

裝置連線點在面板的中心部分。

DEVICE_VERT_POS_LOWER

裝置連線點在面板的下部。

enum device_physical_location_horizontal_position

描述裝置連線點在面板表面上的水平位置。

常量

DEVICE_HORI_POS_LEFT

裝置連線點在面板的左側。

DEVICE_HORI_POS_CENTER

裝置連線點在面板的中心部分。

DEVICE_HORI_POS_RIGHT

裝置連線點在面板的右側。

struct device_physical_location

與裝置連線點物理位置相關的裝置資料。

定義:

struct device_physical_location {
    enum device_physical_location_panel panel;
    enum device_physical_location_vertical_position vertical_position;
    enum device_physical_location_horizontal_position horizontal_position;
    bool dock;
    bool lid;
};

成員

panel

裝置連線點所在的系統外殼面板表面。

vertical_position

裝置連線點在面板內的垂直位置。

horizontal_position

裝置連線點在面板內的水平位置。

dock

如果裝置連線點位於塢站或埠複製器中,則設定此項。

lid

如果此裝置連線點位於筆記本系統蓋子上,則設定此項。

struct device

基本裝置結構

定義:

struct device {
    struct kobject kobj;
    struct device           *parent;
    struct device_private   *p;
    const char              *init_name;
    const struct device_type *type;
    const struct bus_type   *bus;
    struct device_driver *driver;
    void *platform_data;
    void *driver_data;
    struct mutex            mutex;
    struct dev_links_info   links;
    struct dev_pm_info      power;
    struct dev_pm_domain    *pm_domain;
#ifdef CONFIG_ENERGY_MODEL;
    struct em_perf_domain   *em_pd;
#endif;
#ifdef CONFIG_PINCTRL;
    struct dev_pin_info     *pins;
#endif;
    struct dev_msi_info     msi;
#ifdef CONFIG_ARCH_HAS_DMA_OPS;
    const struct dma_map_ops *dma_ops;
#endif;
    u64 *dma_mask;
    u64 coherent_dma_mask;
    u64 bus_dma_limit;
    const struct bus_dma_region *dma_range_map;
    struct device_dma_parameters *dma_parms;
    struct list_head        dma_pools;
#ifdef CONFIG_DMA_DECLARE_COHERENT;
    struct dma_coherent_mem *dma_mem;
#endif;
#ifdef CONFIG_DMA_CMA;
    struct cma *cma_area;
#endif;
#ifdef CONFIG_SWIOTLB;
    struct io_tlb_mem *dma_io_tlb_mem;
#endif;
#ifdef CONFIG_SWIOTLB_DYNAMIC;
    struct list_head dma_io_tlb_pools;
    spinlock_t dma_io_tlb_lock;
    bool dma_uses_io_tlb;
#endif;
    struct dev_archdata     archdata;
    struct device_node      *of_node;
    struct fwnode_handle    *fwnode;
#ifdef CONFIG_NUMA;
    int numa_node;
#endif;
    dev_t devt;
    u32 id;
    spinlock_t devres_lock;
    struct list_head        devres_head;
    const struct class      *class;
    const struct attribute_group **groups;
    void (*release)(struct device *dev);
    struct iommu_group      *iommu_group;
    struct dev_iommu        *iommu;
    struct device_physical_location *physical_location;
    enum device_removable   removable;
    bool offline_disabled:1;
    bool offline:1;
    bool of_node_reused:1;
    bool state_synced:1;
    bool can_match:1;
#if defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_DEVICE) ||     defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU) ||     defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU_ALL);
    bool dma_coherent:1;
#endif;
#ifdef CONFIG_DMA_OPS_BYPASS;
    bool dma_ops_bypass : 1;
#endif;
#ifdef CONFIG_DMA_NEED_SYNC;
    bool dma_skip_sync:1;
#endif;
#ifdef CONFIG_IOMMU_DMA;
    bool dma_iommu:1;
#endif;
};

成員

kobj

一個頂層抽象類,其他類由此派生。

parent

裝置的“父”裝置,即它所連線的裝置。在大多數情況下,父裝置是某種匯流排或主機控制器。如果 parent 為 NULL,則該裝置是一個頂級裝置,這通常不是您想要的。

p

儲存裝置驅動核心部分的私有資料。詳情請參閱 struct device_private 的註釋。

init_name

裝置的初始名稱。

type

裝置型別。這標識了裝置型別並攜帶型別特定資訊。

bus

裝置所在的匯流排型別。

driver

哪個驅動程式分配了此項

platform_data

裝置特定的平臺數據。

driver_data

用於驅動程式特定資訊的私有指標。

mutex

用於同步對其驅動程式呼叫的互斥鎖。

links

指向此裝置供應商和消費者的連結。

power

用於裝置電源管理。詳情請參閱裝置電源管理基礎

pm_domain

提供在系統掛起、休眠、系統恢復以及執行時 PM 轉換期間執行的回撥,以及子系統級和驅動程式級回撥。

em_pd

裝置的能源模型效能域

pins

用於裝置引腳管理。詳情請參閱PINCTRL (引腳控制) 子系統

msi

MSI 相關資料

dma_ops

此裝置的 DMA 對映操作。

dma_mask

DMA 掩碼(如果裝置可進行 DMA)。

coherent_dma_mask

類似於 dma_mask,但用於 alloc_coherent 對映,因為並非所有硬體都支援用於一致性分配(例如描述符)的 64 位地址。

bus_dma_limit

上游橋或匯流排的限制,其施加的 DMA 限制小於裝置本身支援的限制。

dma_range_map

DMA 記憶體範圍相對於 RAM 的對映

dma_parms

低階驅動程式可以設定這些引數,以告知 IOMMU 程式碼有關段限制的資訊。

dma_pools

DMA 池(如果裝置可進行 DMA)。

dma_mem

用於相干記憶體覆蓋的內部。

cma_area

用於 DMA 分配的連續記憶體區域

dma_io_tlb_mem

軟體 IO TLB 分配器。不供驅動程式使用。

dma_io_tlb_pools

瞬態 swiotlb 記憶體池列表。

dma_io_tlb_lock

保護活動池列表的更改。

dma_uses_io_tlb

如果裝置使用了軟體 IO TLB,則為true

archdata

用於架構特定的新增。

of_node

關聯的裝置樹節點。

fwnode

平臺韌體提供的關聯裝置節點。

numa_node

此裝置接近的 NUMA 節點。

devt

用於建立 sysfs “dev”。

id

裝置例項

devres_lock

用於保護裝置資源的自旋鎖。

devres_head

裝置的資源列表。

class

裝置的類。

groups

可選屬性組。

release

在所有引用消失後釋放裝置的回撥。這應該由裝置的分配器(即發現裝置的匯流排驅動程式)設定。

iommu_group

裝置所屬的 IOMMU 組。

iommu

每個裝置的通用 IOMMU 執行時資料

physical_location

描述裝置連線點在系統外殼中的物理位置。

removable

裝置是否可以從系統中移除。這應該由發現裝置的子系統/匯流排驅動程式設定。

offline_disabled

如果設定,裝置將永久線上。

offline

在成功呼叫匯流排型別的 .offline() 後設置。

of_node_reused

如果裝置樹節點與祖先裝置共享,則設定此項。

state_synced

透過呼叫驅動程式/匯流排 sync_state() 回撥,此裝置的硬體狀態已同步以匹配此裝置的軟體狀態。

can_match

該裝置已至少一次與驅動程式匹配,或者它位於一個匯流排(如 AMBA)上,該匯流排無法在其他裝置成功探測之前檢查匹配的驅動程式。

dma_coherent

此特定裝置是 DMA 相干的,即使架構支援非相干裝置。

dma_ops_bypass

如果設定為 true,則流式 DMA 操作(->map_* / ->unmap_* / ->sync_*)會繞過 dma_ops,並且可選地(如果相干掩碼足夠大)也用於 DMA 分配。此標誌由 ->dma_supported 的 DMA 操作例項管理。

dma_skip_sync

相干緩衝區可以跳過 DMA 同步操作。

dma_iommu

裝置正在使用預設的 IOMMU 實現進行 DMA,並且不依賴於 dma_ops 結構。

示例

對於定製板上的裝置,正如嵌入式和基於 SoC 的硬體所常見的那樣,Linux 通常使用 platform_data 指向描述裝置及其接線方式的板特定結構。這可以包括可用的埠、晶片變體、哪些 GPIO 引腳充當哪些附加角色等等。這縮小了“板級支援包”(BSPs)並最大程度地減少了驅動程式中板特定的 #ifdef。

在基於SOC的硬體中,Linux通常使用platform_data指向板級特定結構,描述裝置及其連線方式。這可以包括可用的埠、晶片變體、哪些GPIO引腳扮演什麼額外角色等等。這縮小了“板級支援包”(BSPs)的範圍,並最大限度地減少了驅動程式中板級特定的#ifdefs

描述

在最低層,Linux 系統中的每個裝置都由 struct device 的一個例項表示。裝置結構包含裝置模型核心建模系統所需的資訊。然而,大多數子系統會跟蹤其託管裝置的額外資訊。因此,裝置很少由裸裝置結構表示;相反,該結構(如 kobject 結構)通常嵌入在裝置的更高級別表示中。

裝置連結表示。

定義:

struct device_link {
    struct device *supplier;
    struct list_head s_node;
    struct device *consumer;
    struct list_head c_node;
    struct device link_dev;
    enum device_link_state status;
    u32 flags;
    refcount_t rpm_active;
    struct kref kref;
    struct work_struct rm_work;
    bool supplier_preactivated;
};

成員

supplier

連結供應商端的裝置。

s_node

掛鉤到供應商裝置的消費者連結列表。

consumer

連結消費者端的裝置。

c_node

掛鉤到消費者裝置的供應商連結列表。

link_dev

用於在 sysfs 中公開連結詳細資訊的裝置

status

連結的狀態(相對於驅動程式的存在)。

flags

連結標誌。

rpm_active

消費者裝置是否處於執行時 PM 活躍狀態。

kref

計算相同連結的重複新增次數。

rm_work

用於移除連結的工作結構。

supplier_preactivated

供應商在消費者探測前已被啟用。

bool device_iommu_mapped(struct device *dev)

當裝置 DMA 由 IOMMU 轉換時返回 true

引數

struct device *dev

要進行檢查的裝置

const char *dev_name(const struct device *dev)

返回裝置的名稱。

引數

const struct device *dev

要獲取名稱的裝置。

返回

裝置的 kobject 名稱,如果不可用則為其初始名稱。

const char *dev_bus_name(const struct device *dev)

如果可能,返回裝置的匯流排/類別名稱

引數

const struct device *dev

struct device 以獲取匯流排/類別名稱

描述

將返回裝置所連線的匯流排/類別的名稱。如果它未連線到匯流排/類別,將返回一個空字串。

struct device *device_find_child_by_name(struct device *parent, const char *name)

用於定位子裝置的裝置迭代器。

引數

struct device *parent

struct device

const char *name

子裝置的名稱

描述

這類似於上面的 device_find_child() 函式,但它返回一個指向具有名稱 name 的裝置的引用。

注意

使用後您需要透過 put_device() 釋放引用。

struct device *device_find_any_child(struct device *parent)

用於定位任何子裝置的裝置迭代器。

引數

struct device *parent

struct device

描述

這類似於上面的 device_find_child() 函式,但它返回一個指向子裝置的引用(如果有的話)。

注意

使用後您需要透過 put_device() 釋放引用。

device_lock_set_class

device_lock_set_class (dev, key)

在裝置附加到驅動程式時指定臨時鎖類別

引數

dev

要修改的裝置

key

鎖類別鍵資料

描述

此函式必須在 device_lock() 已經被持有的情況下呼叫,例如在驅動程式的 ->probe() 中。請注意只覆蓋預設的 lockdep_no_validate 類別。

device_lock_reset_class

device_lock_reset_class (dev)

將裝置返回到預設的 lockdep 無驗證狀態

引數

dev

要修改的裝置

描述

此函式必須在 device_lock() 已經被持有的情況下呼叫,例如在驅動程式的 ->remove() 中。

struct bus_type

裝置的匯流排型別

定義:

struct bus_type {
    const char              *name;
    const char              *dev_name;
    const struct attribute_group **bus_groups;
    const struct attribute_group **dev_groups;
    const struct attribute_group **drv_groups;
    int (*match)(struct device *dev, const struct device_driver *drv);
    int (*uevent)(const struct device *dev, struct kobj_uevent_env *env);
    int (*probe)(struct device *dev);
    void (*sync_state)(struct device *dev);
    void (*remove)(struct device *dev);
    void (*shutdown)(struct device *dev);
    const struct cpumask *(*irq_get_affinity)(struct device *dev, unsigned int irq_vec);
    int (*online)(struct device *dev);
    int (*offline)(struct device *dev);
    int (*suspend)(struct device *dev, pm_message_t state);
    int (*resume)(struct device *dev);
    int (*num_vf)(struct device *dev);
    int (*dma_configure)(struct device *dev);
    void (*dma_cleanup)(struct device *dev);
    const struct dev_pm_ops *pm;
    bool need_parent_lock;
};

成員

name

匯流排名稱。

dev_name

用於子系統列舉裝置,例如(“foo``u``”,dev->id)。

bus_groups

匯流排的預設屬性。

dev_groups

總線上裝置的預設屬性。

drv_groups

總線上裝置驅動程式的預設屬性。

match

當此匯流排新增新裝置或驅動程式時,可能會多次呼叫此函式。如果給定驅動程式可以處理給定裝置,則應返回正值,否則返回零。如果無法確定驅動程式是否支援該裝置,它也可能返回錯誤程式碼。如果是 -EPROBE_DEFER,它會將裝置排隊進行延遲探測。

uevent

當裝置被新增、移除或發生其他生成 uevent 以新增環境變數的事件時呼叫。

probe

當新裝置或驅動程式新增到此匯流排時呼叫,並回調特定驅動程式的探測函式以初始化匹配的裝置。

sync_state

在所有連結到此裝置的(在 late_initcall 時存在的)狀態跟蹤消費者成功繫結到驅動程式後,呼叫此函式以將裝置狀態同步到軟體狀態。如果裝置沒有消費者,此函式將在 late_initcall_sync 級別呼叫。如果裝置有從未繫結到驅動程式的消費者,此函式將永遠不會被呼叫,直到它們繫結為止。

remove

當裝置從該匯流排移除時呼叫。

shutdown

在關機時呼叫以使裝置靜止。

irq_get_affinity

獲取此總線上裝置的 IRQ 親和性掩碼。

online

將裝置重新上線(在將其下線後)時呼叫。

offline

為了熱插拔而將裝置下線時呼叫。可能失敗。

suspend

當此總線上的裝置要進入睡眠模式時呼叫。

resume

將此總線上的裝置從睡眠模式喚醒時呼叫。

num_vf

呼叫此函式以找出此總線上的裝置支援多少個虛擬功能。

dma_configure

在總線上的裝置上設定 DMA 配置時呼叫。

dma_cleanup

在總線上的裝置上清理 DMA 配置時呼叫。

pm

此匯流排的電源管理操作,回撥特定裝置驅動程式的 pm-ops。

need_parent_lock

當探測或移除此總線上的裝置時,裝置核心應鎖定裝置的父級。

描述

匯流排是處理器和一個或多個裝置之間的通道。對於裝置模型而言,所有裝置都透過匯流排連線,即使是內部的、虛擬的“平臺”匯流排也是如此。匯流排可以相互連線。例如,USB 控制器通常是一個 PCI 裝置。裝置模型表示匯流排和它們控制的裝置之間的實際連線。匯流排由 bus_type 結構表示。它包含名稱、預設屬性、匯流排方法、PM 操作和驅動程式核心的私有資料。

enum bus_notifier_event

已發生的匯流排通知器事件

常量

BUS_NOTIFY_ADD_DEVICE

裝置已新增到此匯流排

BUS_NOTIFY_DEL_DEVICE

裝置即將從此匯流排移除

BUS_NOTIFY_REMOVED_DEVICE

裝置已成功從此匯流排移除

BUS_NOTIFY_BIND_DRIVER

驅動程式即將繫結到此總線上的此裝置

BUS_NOTIFY_BOUND_DRIVER

驅動程式已成功繫結到此總線上的此裝置

BUS_NOTIFY_UNBIND_DRIVER

驅動程式即將從此總線上的此裝置解綁

BUS_NOTIFY_UNBOUND_DRIVER

驅動程式已成功從此總線上的此裝置解綁

BUS_NOTIFY_DRIVER_NOT_BOUND

驅動程式未能繫結到此總線上的此裝置

描述

這些是當特定事件發生時傳遞給匯流排通知器的值。

請注意,匯流排通知器很可能在驅動核心已持有裝置鎖的情況下被呼叫,因此在任何通知器回撥中處理裝置結構時務必小心。

所有匯流排通知器都以目標 struct device * 作為引數呼叫。

struct class

裝置類別

定義:

struct class {
    const char              *name;
    const struct attribute_group    **class_groups;
    const struct attribute_group    **dev_groups;
    int (*dev_uevent)(const struct device *dev, struct kobj_uevent_env *env);
    char *(*devnode)(const struct device *dev, umode_t *mode);
    void (*class_release)(const struct class *class);
    void (*dev_release)(struct device *dev);
    int (*shutdown_pre)(struct device *dev);
    const struct kobj_ns_type_operations *ns_type;
    const void *(*namespace)(const struct device *dev);
    void (*get_ownership)(const struct device *dev, kuid_t *uid, kgid_t *gid);
    const struct dev_pm_ops *pm;
};

成員

name

類別名稱。

class_groups

此類別預設屬性。

dev_groups

屬於此類別裝置的預設屬性。

dev_uevent

當裝置從此類別中新增、移除,或發生其他生成 uevent 以新增環境變數的事件時呼叫。

devnode

提供 devtmpfs 的回撥。

class_release

呼叫此函式以釋放此類別。

dev_release

呼叫此函式以釋放裝置。

shutdown_pre

在驅動程式關機之前,在關機時呼叫。

ns_type

回撥,以便 sysfs 可以確定名稱空間。

namespace

裝置所屬此類別名稱空間。

get_ownership

允許類別指定屬於該類別的裝置的 sysfs 目錄的 uid/gid。通常與裝置的名稱空間繫結。

pm

此類別的預設裝置電源管理操作。

描述

類別是裝置的更高階檢視,它抽象了低階實現細節。驅動程式可能會看到 SCSI 磁碟或 ATA 磁碟,但在類別級別,它們都只是磁碟。類別允許使用者空間根據裝置的功能而非其連線方式或工作方式來使用裝置。

enum probe_type

要嘗試的裝置驅動程式探測型別 裝置驅動程式可以選擇特殊處理其各自的探測例程。這告訴核心要期待什麼以及偏好什麼。

常量

PROBE_DEFAULT_STRATEGY

同步或非同步探測都能良好工作的驅動程式使用。

PROBE_PREFER_ASYNCHRONOUS

對於探測順序對系統啟動不重要的“慢速”裝置,驅動程式可以選擇非同步執行其探測。

PROBE_FORCE_SYNCHRONOUS

使用此項來標記那些需要其探測例程與驅動程式和設備註冊同步執行的驅動程式(-EPROBE_DEFER 處理除外 - 重新探測總是非同步完成)。

描述

請注意,最終目標是讓核心預設使用非同步探測,因此用 PROBE_PREFER_ASYNCHRONOUS 標記驅動程式是一種臨時措施,它允許我們在驗證其餘驅動程式的同時加快啟動過程。

struct device_driver

基本裝置驅動程式結構

定義:

struct device_driver {
    const char              *name;
    const struct bus_type   *bus;
    struct module           *owner;
    const char              *mod_name;
    bool suppress_bind_attrs;
    enum probe_type probe_type;
    const struct of_device_id       *of_match_table;
    const struct acpi_device_id     *acpi_match_table;
    int (*probe) (struct device *dev);
    void (*sync_state)(struct device *dev);
    int (*remove) (struct device *dev);
    void (*shutdown) (struct device *dev);
    int (*suspend) (struct device *dev, pm_message_t state);
    int (*resume) (struct device *dev);
    const struct attribute_group **groups;
    const struct attribute_group **dev_groups;
    const struct dev_pm_ops *pm;
    void (*coredump) (struct device *dev);
    struct driver_private *p;
};

成員

name

裝置驅動程式名稱。

bus

此驅動程式裝置所屬的匯流排。

owner

模組所有者。

mod_name

用於內建模組。

suppress_bind_attrs

透過 sysfs 停用繫結/解綁。

probe_type

要使用的探測型別(同步或非同步)。

of_match_table

開放韌體表。

acpi_match_table

ACPI 匹配表。

probe

呼叫此函式以查詢特定裝置的存在、此驅動程式是否可以與其一起工作,以及將驅動程式繫結到特定裝置。

sync_state

在所有連結到此裝置的(在 late_initcall 時存在的)狀態跟蹤消費者成功繫結到驅動程式後,呼叫此函式以將裝置狀態同步到軟體狀態。如果裝置沒有消費者,此函式將在 late_initcall_sync 級別呼叫。如果裝置有從未繫結到驅動程式的消費者,此函式將永遠不會被呼叫,直到它們繫結為止。

remove

當裝置從系統中移除時呼叫,以從該驅動程式解綁裝置。

shutdown

在關機時呼叫以使裝置靜止。

suspend

將裝置置於睡眠模式時呼叫。通常是低功耗狀態。

resume

將裝置從睡眠模式喚醒時呼叫。

groups

驅動核心自動建立的預設屬性。

dev_groups

一旦裝置例項繫結到驅動程式後附加的額外屬性。

pm

與此驅動程式匹配的裝置的電源管理操作。

coredump

當 sysfs 條目被寫入時呼叫。裝置驅動程式應呼叫 dev_coredump API,從而產生 uevent。

p

驅動核心的私有資料,除了驅動核心之外,任何人不能觸碰。

描述

裝置驅動模型跟蹤系統中所有已知的驅動程式。跟蹤的主要原因是使驅動核心能夠將驅動程式與新裝置匹配。然而,一旦驅動程式成為系統中已知物件,許多其他事情就變得可能。裝置驅動程式可以匯出獨立於任何特定裝置的資訊和配置變數。

裝置驅動程式基礎

void driver_init(void)

初始化驅動程式模型。

引數

void

無引數

描述

呼叫驅動模型初始化函式以初始化其子系統。在 init/main.c 中早期呼叫。

struct device *driver_find_device_by_name(const struct device_driver *drv, const char *name)

用於按特定名稱定位特定裝置的裝置迭代器。

引數

const struct device_driver *drv

我們正在迭代的驅動程式

const char *name

要匹配的裝置名稱

struct device *driver_find_device_by_of_node(const struct device_driver *drv, const struct device_node *np)

用於按 of_node 指標定位特定裝置的裝置迭代器。

引數

const struct device_driver *drv

我們正在迭代的驅動程式

const struct device_node *np

要匹配的 of_node 指標。

struct device *driver_find_device_by_fwnode(struct device_driver *drv, const struct fwnode_handle *fwnode)

用於按 fwnode 指標定位特定裝置的裝置迭代器。

引數

struct device_driver *drv

我們正在迭代的驅動程式

const struct fwnode_handle *fwnode

要匹配的 fwnode 指標。

struct device *driver_find_device_by_devt(const struct device_driver *drv, dev_t devt)

用於按 devt 定位特定裝置的裝置迭代器。

引數

const struct device_driver *drv

我們正在迭代的驅動程式

dev_t devt

要匹配的 devt 指標。

struct device *driver_find_device_by_acpi_dev(const struct device_driver *drv, const struct acpi_device *adev)

用於定位與 ACPI_COMPANION 裝置匹配的特定裝置的裝置迭代器。

引數

const struct device_driver *drv

我們正在迭代的驅動程式

const struct acpi_device *adev

要匹配的 ACPI_COMPANION 裝置。

module_driver

module_driver (__driver, __register, __unregister, ...)

用於在模組初始化/退出中不執行任何特殊操作的驅動程式的輔助宏。這消除了大量樣板程式碼。每個模組只能使用此宏一次,並且呼叫它會替換 module_init()module_exit()

引數

__driver

驅動程式名稱

__register

此驅動程式型別的註冊函式

__unregister

此驅動程式型別的登出函式

...

要傳遞給 __register 和 __unregister 的附加引數。

描述

使用此宏構建用於註冊驅動程式的匯流排特定宏,不要單獨使用它。

builtin_driver

builtin_driver (__driver, __register, ...)

用於在初始化中不執行任何特殊操作且沒有退出的驅動程式的輔助宏。這消除了一些樣板程式碼。每個驅動程式只能使用此宏一次,並且呼叫它會替換 device_initcall(或在某些情況下,舊版的 __initcall)。這旨在與上面 module_driver() 直接並行,但沒有用於內建情況的 __exit 內容。

引數

__driver

驅動程式名稱

__register

此驅動程式型別的註冊函式

...

要傳遞給 __register 的附加引數

描述

使用此宏構建用於註冊驅動程式的匯流排特定宏,不要單獨使用它。

int driver_set_override(struct device *dev, const char **override, const char *s, size_t len)

設定或清除驅動程式覆蓋的輔助函式。

引數

struct device *dev

要更改的裝置

const char **override

要更改的字串地址(例如 device->driver_override);內容將被釋放並儲存新分配的覆蓋。

const char *s

以 NUL 結尾的字串,新的驅動程式名稱以強制匹配,傳入空字串以清除它("""n",後者僅用於 sysfs 介面)。

size_t len

s 的長度

描述

在裝置中設定或清除驅動程式覆蓋的輔助函式,適用於 driver_override 欄位由驅動程式/匯流排程式碼分配的情況。

返回

成功時返回 0,失敗時返回負錯誤程式碼。

int driver_for_each_device(struct device_driver *drv, struct device *start, void *data, device_iter_t fn)

繫結到驅動程式的裝置的迭代器。

引數

struct device_driver *drv

我們正在迭代的驅動程式。

struct device *start

開始的裝置

void *data

要傳遞給回撥的資料。

device_iter_t fn

為每個裝置呼叫的函式。

描述

迭代 drv 的裝置列表,為每個裝置呼叫 fn

struct device *driver_find_device(const struct device_driver *drv, struct device *start, const void *data, device_match_t match)

用於定位特定裝置的裝置迭代器。

引數

const struct device_driver *drv

裝置的驅動程式

struct device *start

開始的裝置

const void *data

要傳遞給匹配函式的資料

device_match_t match

檢查裝置的回撥函式

描述

這類似於上面的 driver_for_each_device() 函式,但它返回一個指向“找到”的裝置的引用,供以後使用,由 match 回撥確定。

如果裝置不匹配,回撥應返回 0;如果匹配,則返回非零值。如果回撥返回非零值,此函式將返回給呼叫者,不再迭代任何其他裝置。

int driver_create_file(const struct device_driver *drv, const struct driver_attribute *attr)

為驅動程式建立 sysfs 檔案。

引數

const struct device_driver *drv

驅動程式。

const struct driver_attribute *attr

驅動程式屬性描述符。

void driver_remove_file(const struct device_driver *drv, const struct driver_attribute *attr)

移除驅動程式的 sysfs 檔案。

引數

const struct device_driver *drv

驅動程式。

const struct driver_attribute *attr

驅動程式屬性描述符。

int driver_register(struct device_driver *drv)

向匯流排註冊驅動程式

引數

struct device_driver *drv

要註冊的驅動程式

描述

我們將大部分工作交給 bus_add_driver() 呼叫,因為我們必須處理的大部分事情都與匯流排結構有關。

void driver_unregister(struct device_driver *drv)

從系統中移除驅動程式。

引數

struct device_driver *drv

驅動程式。

描述

同樣,我們將大部分工作交給匯流排級別呼叫。

等待正在進行的 devlink 移除作業終止

引數

void

無引數

在兩個裝置之間建立連結。

引數

struct device *consumer

連結的消費者端。

struct device *supplier

連結的供應商端。

u32 flags

連結標誌。

返回

成功時,將返回一個 device_link 結構。

錯誤或標誌設定無效時,將返回 NULL。

描述

呼叫者負責將連結建立與執行時 PM 進行適當同步。首先,設定 DL_FLAG_PM_RUNTIME 標誌將使執行時 PM 框架考慮該連結。其次,如果除此以外還設定了 DL_FLAG_RPM_ACTIVE 標誌,則供應商裝置將在連結建立時被迫進入活動元狀態並進行引用計數。如果未設定 DL_FLAG_PM_RUNTIME,則 DL_FLAG_RPM_ACTIVE 將被忽略。

如果在 flags 中設定 DL_FLAG_STATELESS,此函式的呼叫者應直接藉助 device_link_del()device_link_remove() 釋放其返回的連結。

然而,如果未設定該標誌,此函式的呼叫者將完全把連結的管理權交給驅動核心,並且其返回值只能用於檢查連結是否存在。在那種情況下,DL_FLAG_AUTOREMOVE_CONSUMERDL_FLAG_AUTOREMOVE_SUPPLIER 裝置連結標誌可用於向驅動核心指示何時可以安全地刪除連結。即,在 flags 中設定其中一個,表示在分別從其裝置解綁消費者或供應商驅動程式後,此函式的給定呼叫者將不再使用該連結,因此可以在此時刪除該連結。如果它們都沒有設定,連結將一直保持,直到其指向的裝置之一(無論是消費者還是供應商)被登出。

此外,如果 DL_FLAG_STATELESSDL_FLAG_AUTOREMOVE_CONSUMERDL_FLAG_AUTOREMOVE_SUPPLIER 未在 flags 中設定(即正在新增一個持久的受管理裝置連結),則可以使用 DL_FLAG_AUTOPROBE_CONSUMER 標誌來請求驅動核心在成功將驅動程式繫結到供應商裝置後自動探測消費者驅動程式。

同時在 flags 中設定 DL_FLAG_STATELESS 以及 DL_FLAG_AUTOREMOVE_CONSUMERDL_FLAG_AUTOREMOVE_SUPPLIERDL_FLAG_AUTOPROBE_CONSUMER 的任意一個組合是無效的,並且會導致 upfront 返回 NULL。然而,如果在對給定 consumersupplier 對呼叫此函式時,裝置連結已存在,則將返回現有連結,無論其當前型別和狀態如何(連結的標誌可能會被修改)。此函式的呼叫者隨後應將該連結視為剛剛建立的連結,因此(特別是)如果在 flags 中傳遞了 DL_FLAG_STATELESS,則當不再需要該連結時,需要明確釋放它(如上所述)。

建立連結的一個副作用是重新排序 dpm_list 和 devices_kset 列表,透過將消費者裝置和所有依賴於它的裝置移動到這些列表的末尾(對於呼叫此函式時尚未註冊的裝置,則不會發生此情況)。

此函式呼叫時要求供應商裝置已註冊,否則將返回 NULL。但是,消費者裝置無需註冊。

刪除兩個裝置之間的無狀態連結。

引數

struct device_link *link

要刪除的裝置連結。

描述

呼叫者必須確保此函式與執行時 PM 的正確同步。如果連結被多次新增,則需要多次刪除。熱插拔裝置需要注意:它們的連結在移除時會被清除,並且此時不再允許呼叫 device_link_del()

刪除兩個裝置之間的無狀態連結。

引數

void *consumer

連結的消費者端。

struct device *supplier

連結的供應商端。

描述

呼叫者必須確保此函式與執行時 PM 的正確同步。

const char *dev_driver_string(const struct device *dev)

如果可能,返回裝置的驅動程式名稱

引數

const struct device *dev

struct device 以獲取名稱

描述

如果裝置繫結到驅動程式,將返回裝置的驅動程式名稱。如果裝置未繫結到驅動程式,將返回其所連線的匯流排名稱。如果它也未連線到匯流排,將返回一個空字串。

int devm_device_add_group(struct device *dev, const struct attribute_group *grp)

給定一個裝置,建立一個受管理的屬性組

引數

struct device *dev

要為其建立組的裝置

const struct attribute_group *grp

要建立的屬性組

描述

此函式首次建立一個組。如果正在建立的任何屬性檔案已存在,它將明確地發出警告和錯誤。

成功返回0,失敗返回錯誤程式碼。

int device_create_file(struct device *dev, const struct device_attribute *attr)

為裝置建立sysfs屬性檔案。

引數

struct device *dev

裝置。

const struct device_attribute *attr

裝置屬性描述符。

void device_remove_file(struct device *dev, const struct device_attribute *attr)

移除sysfs屬性檔案。

引數

struct device *dev

裝置。

const struct device_attribute *attr

裝置屬性描述符。

bool device_remove_file_self(struct device *dev, const struct device_attribute *attr)

從其自身方法中移除sysfs屬性檔案。

引數

struct device *dev

裝置。

const struct device_attribute *attr

裝置屬性描述符。

描述

詳見kernfs_remove_self()

int device_create_bin_file(struct device *dev, const struct bin_attribute *attr)

為裝置建立sysfs二進位制屬性檔案。

引數

struct device *dev

裝置。

const struct bin_attribute *attr

裝置二進位制屬性描述符。

void device_remove_bin_file(struct device *dev, const struct bin_attribute *attr)

移除sysfs二進位制屬性檔案

引數

struct device *dev

裝置。

const struct bin_attribute *attr

裝置二進位制屬性描述符。

void device_initialize(struct device *dev)

初始化裝置結構。

引數

struct device *dev

裝置。

描述

此函式透過初始化裝置的欄位,為其他層使用裝置做準備。它是device_register()函式的前半部分,如果由該函式呼叫。不過,它也可以單獨呼叫,以便可以使用dev的欄位。特別是,呼叫此函式後,get_device()/put_device()可用於dev的引用計數。

dev中的所有欄位都必須由呼叫者初始化為0,除了那些明確設定為其他值的欄位。最簡單的方法是使用kzalloc()分配包含dev的結構。

注意

呼叫此函式後,請使用put_device()放棄您的引用,而不是直接釋放dev

int dev_set_name(struct device *dev, const char *fmt, ...)

設定裝置名稱

引數

struct device *dev

裝置

const char *fmt

裝置名稱的格式字串

...

可變引數

int device_add(struct device *dev)

將裝置新增到裝置層級結構。

引數

struct device *dev

裝置。

描述

這是device_register()的第二部分,但如果device_initialize()已單獨呼叫,則可以單獨呼叫。

這透過kobject_add()dev新增到kobject層級結構,將其新增到裝置的全域性和兄弟列表,然後將其新增到驅動程式模型的其他相關子系統。

對於任何裝置結構,不要多次呼叫此例程或device_register()。驅動程式模型核心未設計用於處理登出後又恢復的裝置。(除其他外,很難保證對dev先前例項的所有引用都已釋放。)請改為分配和註冊一個新的struct device

經驗法則是:如果device_add()成功,當您想移除裝置時應呼叫device_del()。如果device_add()_未_成功,則_僅_使用put_device()來減少引用計數。

注意

呼叫此函式後,_切勿_直接釋放dev,即使它返回錯誤!請始終使用put_device()放棄您的引用。

int device_register(struct device *dev)

向系統註冊裝置。

引數

struct device *dev

指向裝置結構的指標

描述

這發生在兩個清晰的步驟中——初始化裝置並將其新增到系統。這兩個步驟可以單獨呼叫,但這是最簡單和最常見的方式。也就是說,只有當您在將裝置新增到層級結構之前明確需要使用並引用計數裝置時,才應單獨呼叫這兩個輔助函式。

有關更多資訊,請參閱device_initialize()device_add()的kerneldoc。

注意

呼叫此函式後,_切勿_直接釋放dev,即使它返回錯誤!請始終使用put_device()放棄此函式中初始化的引用。

struct device *get_device(struct device *dev)

增加裝置引用計數。

引數

struct device *dev

裝置。

描述

這只是將呼叫轉發給kobject_get(),但我們確實注意處理傳入NULL指標的情況。

void put_device(struct device *dev)

減少引用計數。

引數

struct device *dev

相關裝置。

void device_del(struct device *dev)

從系統中刪除裝置。

引數

struct device *dev

裝置。

描述

這是設備註銷序列的第一部分。它將裝置從我們此處控制的列表中移除,將其從在device_add()中新增到的其他驅動程式模型子系統中移除,並將其從kobject層級結構中移除。

注意

只有當device_add()也手動呼叫時,才應手動呼叫此函式。

void device_unregister(struct device *dev)

從系統中登出裝置。

引數

struct device *dev

正在消失的裝置。

描述

我們分兩部分執行此操作,就像我們執行device_register()一樣。首先,我們使用device_del()將其從所有子系統中移除,然後透過put_device()減少引用計數。如果那是最終的引用計數,則裝置將透過上面的device_release()進行清理。否則,結構將保留直到對裝置的最終引用被釋放。

int device_for_each_child(struct device *parent, void *data, device_iter_t fn)

裝置子迭代器。

引數

struct device *parent

struct device

void *data

回撥資料。

device_iter_t fn

為每個裝置呼叫的函式。

描述

迭代parent的子裝置,併為每個子裝置呼叫fn,傳入data

我們每次都檢查fn的返回值。如果它返回非0值,我們就會中斷並返回該值。

int device_for_each_child_reverse(struct device *parent, void *data, device_iter_t fn)

按反向順序迭代裝置子項。

引數

struct device *parent

struct device

void *data

回撥資料。

device_iter_t fn

為每個裝置呼叫的函式。

描述

迭代parent的子裝置,併為每個子裝置呼叫fn,傳入data

我們每次都檢查fn的返回值。如果它返回非0值,我們就會中斷並返回該值。

int device_for_each_child_reverse_from(struct device *parent, struct device *from, void *data, device_iter_t fn)

按反向順序迭代裝置子項。

引數

struct device *parent

struct device

struct device *from

子列表中的可選起始點

void *data

回撥資料。

device_iter_t fn

為每個裝置呼叫的函式。

描述

迭代parent的子裝置,從from開始,併為每個子裝置呼叫fn,傳入data。當from為NULL時,此輔助函式與device_for_each_child_reverse()相同。

每次迭代都會檢查fn。如果它返回非0值,迭代將停止,並將該值返回給device_for_each_child_reverse_from()的呼叫者;

struct device *device_find_child(struct device *parent, const void *data, device_match_t match)

用於定位特定裝置的裝置迭代器。

引數

struct device *parent

struct device

const void *data

要傳遞給匹配函式的資料

device_match_t match

檢查裝置的回撥函式

描述

這類似於上面的device_for_each_child()函式,但它返回一個對“找到”裝置的引用,供以後使用,這由match回撥函式決定。

如果裝置不匹配,回撥應返回0;如果匹配,則返回非0值。如果回撥返回非0值並且可以獲取對當前裝置的引用,則此函式將返回給呼叫者,不再迭代其他裝置。

注意

使用後您需要透過 put_device() 釋放引用。

struct device *__root_device_register(const char *name, struct module *owner)

分配並註冊一個根裝置

引數

const char *name

根裝置名稱

struct module *owner

根裝置的擁有者模組,通常是THIS_MODULE

描述

此函式分配一個根裝置並使用device_register()註冊它。要釋放返回的裝置,請使用root_device_unregister()

根裝置是虛擬裝置,允許其他裝置在/sys/devices下分組。使用此函式分配一個根裝置,然後將其用作應出現在/sys/devices/{name}下的任何裝置的父級。

/sys/devices/{name}目錄還將包含一個指向sysfs中owner目錄的“module”符號連結。

成功返回struct device指標,失敗返回ERR_PTR()

注意

您可能希望使用root_device_register()

void root_device_unregister(struct device *dev)

登出並釋放一個根裝置

引數

struct device *dev

正在消失的裝置

描述

此函式登出並清理由root_device_register()建立的裝置。

struct device *device_create(const struct class *class, struct device *parent, dev_t devt, void *drvdata, const char *fmt, ...)

建立一個裝置並將其註冊到sysfs

引數

const struct class *class

指向此裝置應註冊到的struct class的指標

struct device *parent

指向此新裝置的父struct device的指標(如果有)

dev_t devt

要新增的字元裝置的dev_t

void *drvdata

要新增到裝置以供回撥的資料

const char *fmt

裝置名稱字串

...

可變引數

描述

此函式可用於字元裝置類。一個struct device將在sysfs中建立,並註冊到指定的類。

如果dev_t不是0,0,將建立一個“dev”檔案,顯示裝置的dev_t。如果傳入指向父struct device的指標,則新建立的struct device將成為該裝置在sysfs中的子項。struct device的指標將從呼叫中返回。任何可能需要的進一步sysfs檔案都可以使用此指標建立。

成功返回struct device指標,失敗返回ERR_PTR()

struct device *device_create_with_groups(const struct class *class, struct device *parent, dev_t devt, void *drvdata, const struct attribute_group **groups, const char *fmt, ...)

建立一個裝置並將其註冊到sysfs

引數

const struct class *class

指向此裝置應註冊到的struct class的指標

struct device *parent

指向此新裝置的父struct device的指標(如果有)

dev_t devt

要新增的字元裝置的dev_t

void *drvdata

要新增到裝置以供回撥的資料

const struct attribute_group **groups

要建立的以NULL結尾的屬性組列表

const char *fmt

裝置名稱字串

...

可變引數

描述

此函式可用於字元裝置類。一個struct device將在sysfs中建立,並註冊到指定的類。groups引數中指定的額外屬性也將自動建立。

如果dev_t不是0,0,將建立一個“dev”檔案,顯示裝置的dev_t。如果傳入指向父struct device的指標,則新建立的struct device將成為該裝置在sysfs中的子項。struct device的指標將從呼叫中返回。任何可能需要的進一步sysfs檔案都可以使用此指標建立。

成功返回struct device指標,失敗返回ERR_PTR()

void device_destroy(const struct class *class, dev_t devt)

移除使用device_create()建立的裝置

引數

const struct class *class

指向此設備註冊到的struct class的指標

dev_t devt

之前註冊的裝置的dev_t

描述

此呼叫登出並清理透過呼叫device_create()建立的裝置。

int device_rename(struct device *dev, const char *new_name)

重新命名裝置

引數

struct device *dev

指向要重新命名的struct device的指標

const char *new_name

裝置的新名稱

描述

呼叫者有責任在同一裝置的兩次不同device_rename呼叫之間提供互斥,以確保new_name有效且不會與其他裝置衝突。

然而,如果您正在編寫新程式碼,請不要呼叫此函式。Kay Sievers的以下文字提供了一些見解

重新命名裝置在許多層面上都存在競爭條件,符號連結和其他內容無法原子地替換,您會收到一個“移動”uevent,但不容易將該事件與舊裝置和新裝置關聯起來。裝置節點根本沒有重新命名,核心中甚至沒有對此的支援。

同時,在重新命名期間,您的目標名稱可能被其他驅動程式佔用,從而產生衝突。或者在您重新命名後舊名稱立即被佔用——那麼您會在看到“移動”事件之前,就收到相同DEVPATH的事件。這簡直是一團糟,任何新事物都不應該依賴核心裝置重新命名。除此之外,目前除了(驅動核心層面非常簡單的)網路裝置外,它甚至都沒有實現。

在註冊任何內容之前,在驅動程式中想出一個“真實”名稱,或者為使用者空間新增其他屬性以查詢裝置,或者使用udev新增符號連結——但絕不要稍後重新命名核心裝置,這完全是一團糟。我們甚至不想深入研究並嘗試在核心中實現缺失的部分。我們確實有其他驅動程式核心的爛攤子要解決。 :)

注意

鑑於某些子系統(網路和 InfiniBand)使用此函式,並且目前沒有立即更改的計劃,我們不能假定或要求完全不呼叫此函式。

int device_move(struct device *dev, struct device *new_parent, enum dpm_order dpm_order)

將裝置移動到新的父級

引數

struct device *dev

指向要移動的struct device的指標

struct device *new_parent

裝置的新父級(可為NULL)

enum dpm_order dpm_order

如何重新排序dpm_list

int device_change_owner(struct device *dev, kuid_t kuid, kgid_t kgid)

更改現有裝置的擁有者。

引數

struct device *dev

裝置。

kuid_t kuid

新擁有者的kuid

kgid_t kgid

新擁有者的kgid

描述

這會將dev及其對應的sysfs條目的擁有者更改為kuid/kgid。此函式與dev透過驅動核心新增的方式非常相似。

成功返回0,失敗返回錯誤程式碼。

int dev_err_probe(const struct device *dev, int err, const char *fmt, ...)

探測錯誤檢查和日誌輔助函式

引數

const struct device *dev

指向struct device的指標

int err

要測試的錯誤值

const char *fmt

printf風格的格式字串

...

格式字串中指定的引數

描述

此輔助函式實現了探測函式中常見的錯誤檢查模式:根據錯誤值是否為-EPROBE_DEFER列印除錯或錯誤訊息,並向上層傳播錯誤。在-EPROBE_DEFER的情況下,它還會設定延遲探測原因,可以透過讀取devices_deferred debugfs屬性稍後進行檢查。它替換了以下程式碼序列

if (err != -EPROBE_DEFER)
        dev_err(dev, ...);
else
        dev_dbg(dev, ...);
return err;

替換為

return dev_err_probe(dev, err, ...);

在您的探測函式中使用此輔助函式完全沒有問題,即使已知err永遠不會是-EPROBE_DEFER。與普通的dev_err()相比,其優點是錯誤程式碼的標準化格式,它以符號形式發出(即您會得到“EAGAIN”而不是“-35”),並且返回錯誤程式碼允許更緊湊的錯誤路徑。

返回err

int dev_warn_probe(const struct device *dev, int err, const char *fmt, ...)

探測錯誤檢查和日誌輔助函式

引數

const struct device *dev

指向struct device的指標

int err

要測試的錯誤值

const char *fmt

printf風格的格式字串

...

格式字串中指定的引數

描述

此輔助函式實現了探測函式中常見的錯誤檢查模式:根據錯誤值是否為-EPROBE_DEFER列印除錯或警告訊息,並向上層傳播錯誤。在-EPROBE_DEFER的情況下,它還會設定延遲探測原因,可以透過讀取devices_deferred debugfs屬性稍後進行檢查。它替換了以下程式碼序列

if (err != -EPROBE_DEFER)
        dev_warn(dev, ...);
else
        dev_dbg(dev, ...);
return err;

替換為

return dev_warn_probe(dev, err, ...);

在您的探測函式中使用此輔助函式完全沒有問題,即使已知err永遠不會是-EPROBE_DEFER。與普通的dev_warn()相比,其優點是錯誤程式碼的標準化格式,它以符號形式發出(即您會得到“EAGAIN”而不是“-35”),並且返回錯誤程式碼允許更緊湊的錯誤路徑。

返回err

void set_primary_fwnode(struct device *dev, struct fwnode_handle *fwnode)

更改給定裝置的主韌體節點。

引數

struct device *dev

要處理的裝置。

struct fwnode_handle *fwnode

裝置的新主韌體節點。

描述

將裝置的韌體節點指標設定為fwnode,但如果裝置的次級韌體節點存在,則保留它。

有效的fwnode情況有
  • primary --> secondary --> -ENODEV

  • primary --> NULL

  • secondary --> -ENODEV

  • NULL

void set_secondary_fwnode(struct device *dev, struct fwnode_handle *fwnode)

更改給定裝置的次級韌體節點。

引數

struct device *dev

要處理的裝置。

struct fwnode_handle *fwnode

裝置的新次級韌體節點。

描述

如果裝置的主韌體節點存在,則將其次級指標設定為fwnode。否則,將裝置的韌體節點指標設定為fwnode

void device_remove_of_node(struct device *dev)

從裝置中移除of_node

引數

struct device *dev

其裝置樹節點正在被移除的裝置

int device_add_of_node(struct device *dev, struct device_node *of_node)

of_node新增到現有裝置

引數

struct device *dev

其裝置樹節點正在被新增的裝置

struct device_node *of_node

要新增的of_node

返回

成功返回0,失敗返回錯誤程式碼。

void device_set_of_node_from_dev(struct device *dev, const struct device *dev2)

重用另一個裝置的裝置樹節點

引數

struct device *dev

其裝置樹節點正在被設定的裝置

const struct device *dev2

其裝置樹節點正在被重用的裝置

描述

在首先釋放對舊節點持有的任何引用後,對新裝置樹節點進行另一次引用。

void register_syscore_ops(struct syscore_ops *ops)

註冊一組系統核心操作。

引數

struct syscore_ops *ops

要註冊的系統核心操作。

void unregister_syscore_ops(struct syscore_ops *ops)

登出一組系統核心操作。

引數

struct syscore_ops *ops

要登出的系統核心操作。

int syscore_suspend(void)

執行所有已註冊的系統核心掛起回撥。

引數

void

無引數

描述

此函式在單個CPU線上且中斷被停用時執行。

void syscore_resume(void)

執行所有已註冊的系統核心恢復回撥。

引數

void

無引數

描述

此函式在單個CPU線上且中斷被停用時執行。

struct device *class_find_device_by_name(const struct class *class, const char *name)

用於按特定名稱定位特定裝置的裝置迭代器。

引數

const struct class *class

類型別

const char *name

要匹配的裝置名稱

struct device *class_find_device_by_of_node(const struct class *class, const struct device_node *np)

用於查詢匹配of_node的特定裝置的裝置迭代器。

引數

const struct class *class

類型別

const struct device_node *np

要匹配裝置的of_node

struct device *class_find_device_by_fwnode(const struct class *class, const struct fwnode_handle *fwnode)

用於查詢匹配fwnode的特定裝置的裝置迭代器。

引數

const struct class *class

類型別

const struct fwnode_handle *fwnode

要匹配裝置的fwnode

struct device *class_find_device_by_devt(const struct class *class, dev_t devt)

用於查詢匹配裝置型別的特定裝置的裝置迭代器。

引數

const struct class *class

類型別

dev_t devt

要匹配裝置的裝置型別。

struct device *class_find_device_by_acpi_dev(const struct class *class, const struct acpi_device *adev)

用於定位與 ACPI_COMPANION 裝置匹配的特定裝置的裝置迭代器。

引數

const struct class *class

類型別

const struct acpi_device *adev

要匹配的 ACPI_COMPANION 裝置。

struct class *class_create(const char *name)

建立一個struct class結構

引數

const char *name

指向此類名稱字串的指標。

描述

這用於建立一個struct class指標,該指標隨後可在對device_create()的呼叫中使用。

成功返回struct class指標,失敗返回ERR_PTR()

注意,此處建立的指標在完成後應透過呼叫class_destroy()來銷燬。

void class_destroy(const struct class *cls)

銷燬一個struct class結構

引數

const struct class *cls

指向要銷燬的struct class的指標

描述

注意,要銷燬的指標必須是透過呼叫class_create()建立的。

void class_dev_iter_init(struct class_dev_iter *iter, const struct class *class, const struct device *start, const struct device_type *type)

初始化類裝置迭代器

引數

struct class_dev_iter *iter

要初始化的類迭代器

const struct class *class

我們要迭代的類

const struct device *start

開始迭代的裝置(如果有)

const struct device_type *type

要迭代裝置的device_type,對所有裝置為NULL

描述

初始化類迭代器iter,使其迭代class的裝置。如果設定了start,列表迭代將從那裡開始;否則,如果start為NULL,則迭代從列表的開頭開始。

struct device *class_dev_iter_next(struct class_dev_iter *iter)

迭代到下一個裝置

引數

struct class_dev_iter *iter

要繼續的類迭代器

描述

iter前進到下一個裝置並返回它。如果迭代完成,則返回NULL。

返回的裝置已被引用,並且在迭代器前進到下一個裝置或退出之前不會被釋放。呼叫者可以自由地對裝置執行任何操作,包括回撥到類程式碼中。

void class_dev_iter_exit(struct class_dev_iter *iter)

完成迭代

引數

struct class_dev_iter *iter

要完成的類迭代器

描述

完成一次迭代。無論迭代是否執行到最後,在迭代完成後始終呼叫此函式。

int class_for_each_device(const struct class *class, const struct device *start, void *data, device_iter_t fn)

裝置迭代器

引數

const struct class *class

我們正在迭代的類

const struct device *start

列表中開始的裝置(如果有)。

void *data

回撥資料

device_iter_t fn

為每個裝置呼叫的函式

描述

迭代class的裝置列表,併為每個裝置呼叫fn,傳入data。如果設定了start,列表迭代將從那裡開始;否則,如果start為NULL,則迭代從列表的開頭開始。

我們每次都檢查fn的返回值。如果它返回非0值,我們就會中斷並返回該值。

fn可以執行任何操作,包括回撥到類程式碼中。沒有鎖定限制。

struct device *class_find_device(const struct class *class, const struct device *start, const void *data, device_match_t match)

用於查詢特定裝置的裝置迭代器

引數

const struct class *class

我們正在迭代的類

const struct device *start

開始的裝置

const void *data

匹配函式的資料

device_match_t match

檢查裝置的函式

描述

這類似於上面的class_for_each_dev()函式,但它返回一個對“找到”裝置的引用,供以後使用,這由match回撥函式決定。

如果裝置不匹配,回撥應返回 0;如果匹配,則返回非零值。如果回撥返回非零值,此函式將返回給呼叫者,不再迭代任何其他裝置。

注意,使用後您需要使用put_device()釋放引用。

match可以執行任何操作,包括回撥到類程式碼中。沒有鎖定限制。

struct class_compat *class_compat_register(const char *name)

註冊相容性類

引數

const char *name

類的名稱

描述

相容性類旨在作為將一類裝置系列轉換為匯流排裝置時的臨時使用者空間相容性解決方案。

void class_compat_unregister(struct class_compat *cls)

登出相容性類

引數

struct class_compat *cls

要登出的類

建立一個相容性類裝置連結到匯流排裝置

引數

struct class_compat *cls

相容性類

struct device *dev

目標匯流排裝置

移除相容性類裝置連結到匯流排裝置

引數

struct class_compat *cls

相容性類

struct device *dev

目標匯流排裝置

bool class_is_registered(const struct class *class)

判斷當前時刻,一個類是否在驅動核心中註冊。

引數

const struct class *class

要檢查的類

描述

返回一個布林值,表示該類是否在驅動核心中註冊。請注意,該值在呼叫此函式後可能立即改變,因此僅在您“知道”這樣做安全的地方使用它(通常用於確定特定類是否已註冊)。

使用時請謹慎。

struct faux_device

一個“仿冒”裝置

定義:

struct faux_device {
    struct device dev;
};

成員

dev

物件的內部struct device

描述

一個可以建立/銷燬的簡單仿冒裝置。當驅動程式只需要一個裝置來“掛載”某些東西時使用。這可用於下載韌體或其他基本任務。如果裝置完全沒有分配資源,請使用它而不是struct platform_device

struct faux_device_ops

struct faux_device的一組回撥函式

定義:

struct faux_device_ops {
    int (*probe)(struct faux_device *faux_dev);
    void (*remove)(struct faux_device *faux_dev);
};

成員

probe

當驅動核心探測到仿冒裝置,但在裝置完全繫結到內部仿冒匯流排程式碼之前呼叫。如果探測成功,返回0;否則,返回一個負的錯誤碼以阻止探測序列成功。

remove

當仿冒裝置從系統中移除時呼叫

描述

proberemove都是可選的,如果不需要,請設定為NULL。

struct faux_device *faux_device_create_with_groups(const char *name, struct device *parent, const struct faux_device_ops *faux_ops, const struct attribute_group **groups)

建立一個仿冒裝置並將其註冊到驅動核心,然後用一組初始的sysfs屬性填充該裝置。

引數

const char *name

我們要新增的裝置名稱,對於所有仿冒裝置必須是唯一的。

struct device *parent

指向潛在父struct device的指標。如果設定為NULL,裝置將在sysfs中的仿冒裝置樹的“根”下建立。

const struct faux_device_ops *faux_ops

新裝置將回調的struct faux_device_ops,可以為NULL。

const struct attribute_group **groups

當此設備註冊到驅動核心時,將為其建立的 sysfs 屬性集。

描述

建立一個新的 faux 裝置並正確註冊到驅動核心。如果存在,faux_ops 中的回撥函式將在適當的時機,根據裝置的生命週期,使用該裝置供呼叫者進行操作。

請注意,當呼叫此函式時,struct faux_ops 中指定的函式可能在函式返回之前被呼叫,因此請確保在此時間點之前所有內容都已正確初始化。如果探測回撥(如果存在)未成功,則裝置的建立將失敗並返回 NULL。

返回

  • 如果建立裝置時發生錯誤,則為 NULL

  • 指向已註冊到 sysfs 的有效 struct faux_device 的指標

struct faux_device *faux_device_create(const char *name, struct device *parent, const struct faux_device_ops *faux_ops)

建立一個 faux 裝置並註冊到驅動核心

引數

const char *name

我們要新增的裝置名稱,對於所有仿冒裝置必須是唯一的。

struct device *parent

指向潛在父struct device的指標。如果設定為NULL,裝置將在sysfs中的仿冒裝置樹的“根”下建立。

const struct faux_device_ops *faux_ops

新裝置將回調的struct faux_device_ops,可以為NULL。

描述

建立一個新的 faux 裝置並正確註冊到驅動核心。如果存在,faux_ops 中的回撥函式將在適當的時機,根據裝置的生命週期,使用該裝置供呼叫者進行操作。

請注意,當呼叫此函式時,struct faux_ops 中指定的函式可能在函式返回之前被呼叫,因此請確保在此時間點之前所有內容都已正確初始化。

返回

  • 如果建立裝置時發生錯誤,則為 NULL

  • 指向已註冊到 sysfs 的有效 struct faux_device 的指標

void faux_device_destroy(struct faux_device *faux_dev)

銷燬一個 faux 裝置

引數

struct faux_device *faux_dev

要銷燬的 faux 裝置

描述

登出並清理透過呼叫 faux_device_create() 建立的裝置

struct node_access_nodes

訪問類裝置,用於儲存使用者可見的與其他節點的關聯。

定義:

struct node_access_nodes {
    struct device           dev;
    struct list_head        list_node;
    unsigned int            access;
#ifdef CONFIG_HMEM_REPORTING;
    struct access_coordinate        coord;
#endif;
};

成員

dev

此記憶體訪問類的裝置

list_node

節點訪問列表中的列表元素

access

訪問類別等級

coord

異構記憶體效能座標

struct node_cache_info

記憶體節點快取的內部跟蹤

定義:

struct node_cache_info {
    struct device dev;
    struct list_head node;
    struct node_cache_attrs cache_attrs;
};

成員

dev

表示快取級別的裝置

node

用於在節點中跟蹤的列表元素

cache_attrs

此快取級別的屬性

void node_add_cache(unsigned int nid, struct node_cache_attrs *cache_attrs)

向記憶體節點新增快取屬性

引數

unsigned int nid

具有新快取屬性的節點識別符號

struct node_cache_attrs *cache_attrs

正在新增的快取的屬性

void unregister_node(struct node *node)

登出節點裝置

引數

struct node *node

即將移除的節點

描述

登出節點裝置 node。在呼叫此函式之前,節點上的所有裝置都必須已登出。

int register_memory_node_under_compute_node(unsigned int mem_nid, unsigned int cpu_nid, enum access_coordinate_class access)

將記憶體節點與其計算節點關聯起來,以實現給定的訪問類別。

引數

unsigned int mem_nid

記憶體節點號

unsigned int cpu_nid

CPU 節點號

enum access_coordinate_class access

要註冊的訪問類別

描述

用於可能具有獨立記憶體節點和計算節點的平臺。此函式將匯出節點關係,連線哪些記憶體發起節點可以在給定等級的訪問類別中訪問記憶體目標。

int transport_class_register(struct transport_class *tclass)

註冊一個初始傳輸類

引數

struct transport_class *tclass

指向要初始化的傳輸類結構的指標

描述

傳輸類包含一個嵌入式類,用於標識自身。呼叫者應將此結構初始化為零,然後通用類必須已使用實際的傳輸類唯一名稱進行初始化。有一個宏 DECLARE_TRANSPORT_CLASS() 可以完成此操作(已宣告的類仍必須註冊)。

成功返回 0,失敗返回錯誤。

void transport_class_unregister(struct transport_class *tclass)

登出先前已註冊的類

引數

struct transport_class *tclass

要登出的傳輸類

描述

在為傳輸類釋放記憶體之前必須呼叫此函式。

int anon_transport_class_register(struct anon_transport_class *atc)

註冊一個匿名類

引數

struct anon_transport_class *atc

要註冊的匿名傳輸類

描述

匿名傳輸類包含傳輸類和容器。匿名類的概念是它實際上不關聯任何裝置屬性(從而節省了容器儲存)。因此,它只能用於觸發事件。使用 prezero,然後使用 DECLARE_ANON_TRANSPORT_CLASS() 初始化匿名傳輸類儲存。

void anon_transport_class_unregister(struct anon_transport_class *atc)

登出一個匿名類

引數

struct anon_transport_class *atc

指向要登出的匿名傳輸類的指標

描述

在為匿名傳輸類釋放記憶體之前必須呼叫此函式。

void transport_setup_device(struct device *dev)

宣告一個用於傳輸類關聯的新裝置,但尚未使其可見。

引數

struct device *dev

表示正在新增的實體的通用裝置

描述

通常,dev 表示 HBA 系統中的某個元件(可以是 HBA 本身,也可以是跨 HBA 匯流排的遠端裝置)。此例程只是一個觸發點,用於檢視是否有任何傳輸類集希望與新增的裝置關聯。它為類裝置分配儲存並初始化它,但尚未將其新增到系統或為其新增屬性(您可以使用 transport_add_device 來完成此操作)。如果您不需要單獨的設定和新增操作,請使用 transport_register_device(參見 transport_class.h)。

int transport_add_device(struct device *dev)

宣告一個用於傳輸類關聯的新裝置

引數

struct device *dev

表示正在新增的實體的通用裝置

描述

通常,dev 表示 HBA 系統中的某個元件(可以是 HBA 本身,也可以是跨 HBA 匯流排的遠端裝置)。此例程只是一個觸發點,用於將裝置新增到系統併為其註冊屬性。

void transport_configure_device(struct device *dev)

配置一個已設定的裝置

引數

struct device *dev

表示要配置的裝置的通用裝置

描述

配置的目的是在設定過程中提供一個點,以便傳輸類在裝置設定完成後從裝置中提取資訊。這在 SCSI 中使用,因為我們必須有一個設定好的裝置才能開始使用 HBA,但在傳送初始查詢後,我們使用配置來提取裝置引數。裝置無需新增即可配置。

void transport_remove_device(struct device *dev)

移除裝置的可見性

引數

struct device *dev

要移除的通用裝置

描述

此呼叫會移除裝置的可見性(對 sysfs 使用者而言),但不會銷燬它。要完全消除裝置,您還必須呼叫 transport_destroy_device。如果您不需要將移除和銷燬作為單獨的操作進行,請使用 transport_unregister_device()(參見 transport_class.h),它將為您執行這兩個呼叫。

void transport_destroy_device(struct device *dev)

銷燬已移除的裝置

引數

struct device *dev

要從傳輸類中消除的裝置。

描述

此呼叫會觸發消除與傳輸類裝置關聯的儲存。注意:它實際所做的只是放棄對 classdev 的引用。直到最後一個引用變為零,記憶體才會被釋放。另請注意,classdev 保留了對 dev 的引用計數,因此只要傳輸類裝置存在,dev 也會一直存在。

int driver_deferred_probe_check_state(struct device *dev)

檢查延遲探測狀態

引數

struct device *dev

要檢查的裝置

返回

  • 如果 initcalls 已完成且模組已停用,則為 -ENODEV。

  • 如果設定了延遲探測超時並已過期且模組已啟用,則為 -ETIMEDOUT。

  • 在其他情況下為 -EPROBE_DEFER。

描述

驅動程式或子系統可以選擇呼叫此函式,而不是直接返回 -EPROBE_DEFER。

bool device_is_bound(struct device *dev)

檢查裝置是否繫結到驅動程式

引數

struct device *dev

要檢查的裝置

描述

如果傳入的裝置已成功探測並繫結到驅動程式,則返回 true。

此函式必須在持有裝置鎖的情況下呼叫。

int device_bind_driver(struct device *dev)

將驅動程式繫結到一個裝置。

引數

struct device *dev

裝置。

描述

允許手動將驅動程式附加到裝置。呼叫者必須已經設定了 dev->driver

請注意,這不會修改匯流排引用計數。請在呼叫此函式之前驗證其是否已計入。(從驅動程式的 probe() 方法呼叫時無需其他操作。)

此函式必須在持有裝置鎖的情況下呼叫。

呼叫者應優先使用 device_driver_attach()

void wait_for_device_probe(void)

引數

void

無引數

描述

等待裝置探測完成。

int device_attach(struct device *dev)

嘗試將裝置附加到驅動程式。

引數

struct device *dev

裝置。

描述

遍歷總線上的驅動程式列表,併為每對呼叫 driver_probe_device()。如果找到相容對,則中斷並返回。

如果裝置已繫結到驅動程式,則返回 1;如果沒有找到匹配的驅動程式,則返回 0;如果裝置未註冊,則返回 -ENODEV。

當為 USB 介面呼叫時,必須持有 dev->parent 鎖。

int device_driver_attach(const struct device_driver *drv, struct device *dev)

將特定驅動程式附加到特定裝置

引數

const struct device_driver *drv

要附加的驅動程式

struct device *dev

要附加到的裝置

描述

手動將驅動程式附加到裝置。如果需要,將同時獲取 dev 鎖和 dev->parent 鎖。成功返回 0,失敗返回 -ERR。

int driver_attach(const struct device_driver *drv)

嘗試將驅動程式繫結到裝置。

引數

const struct device_driver *drv

驅動程式。

描述

遍歷總線上的裝置列表,並嘗試將驅動程式與每個裝置匹配。如果 driver_probe_device() 返回 0 且 dev->driver 已設定,則表示我們找到了相容對。

void device_release_driver(struct device *dev)

手動將裝置從驅動程式分離。

引數

struct device *dev

裝置。

描述

手動將裝置從驅動程式分離。當為 USB 介面呼叫時,必須持有 dev->parent 鎖。

如果此函式要在持有 dev->parent 鎖的情況下呼叫,請確保裝置的消費者已提前解除繫結,或者可以在 dev->parent 鎖下獲取其鎖。

struct platform_device *platform_device_register_resndata(struct device *parent, const char *name, int id, const struct resource *res, unsigned int num, const void *data, size_t size)

新增一個帶有資源和平臺特定資料的平臺級裝置

引數

struct device *parent

我們正在新增的裝置的父裝置

const char *name

我們正在新增的裝置的基名

int id

例項 ID

const struct resource *res

需要為裝置分配的資源集

unsigned int num

資源數量

const void *data

此平臺裝置的平臺特定資料

size_t size

平臺特定資料的大小

描述

成功返回 struct platform_device 指標,錯誤返回 ERR_PTR()

struct platform_device *platform_device_register_simple(const char *name, int id, const struct resource *res, unsigned int num)

新增一個平臺級裝置及其資源

引數

const char *name

我們正在新增的裝置的基名

int id

例項 ID

const struct resource *res

需要為裝置分配的資源集

unsigned int num

資源數量

描述

此函式建立一個簡單的平臺裝置,它需要最少的資源和記憶體管理。用於釋放裝置分配記憶體的預設釋放函式允許使用此類裝置的驅動程式在不等待裝置最後引用被釋放的情況下解除安裝。

此介面主要用於直接探測硬體的傳統驅動程式。由於此類驅動程式自行建立 sysfs 裝置節點,而不是讓系統基礎設施處理此類裝置列舉任務,因此它們不完全符合 Linux 驅動程式模型。特別是,當此類驅動程式構建為模組時,它們無法“熱插拔”。

成功返回 struct platform_device 指標,錯誤返回 ERR_PTR()

struct platform_device *platform_device_register_data(struct device *parent, const char *name, int id, const void *data, size_t size)

新增一個帶有平臺特定資料的平臺級裝置

引數

struct device *parent

我們正在新增的裝置的父裝置

const char *name

我們正在新增的裝置的基名

int id

例項 ID

const void *data

此平臺裝置的平臺特定資料

size_t size

平臺特定資料的大小

描述

此函式建立一個簡單的平臺裝置,它需要最少的資源和記憶體管理。用於釋放裝置分配記憶體的預設釋放函式允許使用此類裝置的驅動程式在不等待裝置最後引用被釋放的情況下解除安裝。

成功返回 struct platform_device 指標,錯誤返回 ERR_PTR()

struct resource *platform_get_resource(struct platform_device *dev, unsigned int type, unsigned int num)

獲取裝置的資源

引數

struct platform_device *dev

平臺裝置

unsigned int type

資源型別

unsigned int num

資源索引

返回

指向資源的指標,失敗時為 NULL。

void __iomem *devm_platform_get_and_ioremap_resource(struct platform_device *pdev, unsigned int index, struct resource **res)

為平臺裝置呼叫 devm_ioremap_resource() 並獲取資源

引數

struct platform_device *pdev

用於記憶體資源查詢和資源管理的平臺裝置

unsigned int index

資源索引

struct resource **res

可選的輸出引數,用於儲存指向所獲取資源的指標。

返回

指向重新對映記憶體的指標,或失敗時為 ERR_PTR() 編碼的錯誤碼。

void __iomem *devm_platform_ioremap_resource(struct platform_device *pdev, unsigned int index)

為平臺裝置呼叫 devm_ioremap_resource()

引數

struct platform_device *pdev

用於記憶體資源查詢和資源管理的平臺裝置

unsigned int index

資源索引

返回

指向重新對映記憶體的指標,或失敗時為 ERR_PTR() 編碼的錯誤碼。

void __iomem *devm_platform_ioremap_resource_byname(struct platform_device *pdev, const char *name)

為平臺裝置呼叫 devm_ioremap_resource,按名稱檢索資源

引數

struct platform_device *pdev

用於記憶體資源查詢和資源管理的平臺裝置

const char *name

資源名稱

返回

指向重新對映記憶體的指標,或失敗時為 ERR_PTR() 編碼的錯誤碼。

int platform_get_irq_optional(struct platform_device *dev, unsigned int num)

獲取裝置的可選 IRQ

引數

struct platform_device *dev

平臺裝置

unsigned int num

IRQ 號索引

描述

獲取平臺裝置的 IRQ。裝置驅動程式應檢查返回值以獲取錯誤,以免將負整數值傳遞給 request_irq() API。這與 platform_get_irq() 相同,不同之處在於如果無法獲取 IRQ,它不會列印錯誤訊息。

例如

int irq = platform_get_irq_optional(pdev, 0);
if (irq < 0)
        return irq;

返回

成功返回非零 IRQ 號,失敗返回負錯誤號。

int platform_get_irq(struct platform_device *dev, unsigned int num)

獲取裝置的 IRQ

引數

struct platform_device *dev

平臺裝置

unsigned int num

IRQ 號索引

描述

獲取平臺裝置的 IRQ,如果查詢 IRQ 失敗則列印錯誤訊息。裝置驅動程式應檢查返回值以獲取錯誤,以免將負整數值傳遞給 request_irq() API。

例如

int irq = platform_get_irq(pdev, 0);
if (irq < 0)
        return irq;

返回

成功返回非零 IRQ 號,失敗返回負錯誤號。

int platform_irq_count(struct platform_device *dev)

統計平臺裝置使用的 IRQ 數量

引數

struct platform_device *dev

平臺裝置

返回

平臺裝置使用的 IRQ 數量或 EPROBE_DEFER

int devm_platform_get_irqs_affinity(struct platform_device *dev, struct irq_affinity *affd, unsigned int minvec, unsigned int maxvec, int **irqs)

使用中斷親和性描述符為裝置獲取一組 IRQ 的 devm 方法

引數

struct platform_device *dev

平臺裝置指標

struct irq_affinity *affd

親和性描述符

unsigned int minvec

中斷向量的最小計數

unsigned int maxvec

中斷向量的最大計數

int **irqs

IRQ 號的指標持有者

描述

為平臺裝置獲取一組 IRQ,並根據傳入的親和性描述符更新 IRQ 親和性。

返回

成功時返回向量數量,失敗時返回負錯誤號。

struct resource *platform_get_resource_byname(struct platform_device *dev, unsigned int type, const char *name)

按名稱獲取裝置的資源

引數

struct platform_device *dev

平臺裝置

unsigned int type

資源型別

const char *name

資源名稱

int platform_get_irq_byname(struct platform_device *dev, const char *name)

按名稱獲取裝置的 IRQ

引數

struct platform_device *dev

平臺裝置

const char *name

IRQ 名稱

描述

獲取 IRQ,類似於 platform_get_irq(),但按名稱而不是索引。

返回

成功返回非零 IRQ 號,失敗返回負錯誤號。

int platform_get_irq_byname_optional(struct platform_device *dev, const char *name)

按名稱獲取裝置的可選 IRQ

引數

struct platform_device *dev

平臺裝置

const char *name

IRQ 名稱

描述

按名稱獲取可選 IRQ,類似於 platform_get_irq_byname()。不同之處在於,如果無法獲取 IRQ,它不會列印錯誤訊息。

返回

成功返回非零 IRQ 號,失敗返回負錯誤號。

int platform_add_devices(struct platform_device **devs, int num)

新增多個平臺裝置

引數

struct platform_device **devs

要新增的平臺裝置陣列

int num

陣列中平臺裝置的數量

返回

成功返回 0,失敗返回負錯誤號。

void platform_device_put(struct platform_device *pdev)

銷燬平臺裝置

引數

struct platform_device *pdev

要釋放的平臺裝置

描述

釋放與平臺裝置關聯的所有記憶體。此函式_只能_在錯誤情況下從外部呼叫。所有其他用法都是錯誤。

struct platform_device *platform_device_alloc(const char *name, int id)

建立一個平臺裝置

引數

const char *name

我們正在新增的裝置的基名

int id

例項 ID

描述

建立一個平臺裝置物件,該物件可以附加其他物件,並且在釋放時將釋放附加的物件。

int platform_device_add_resources(struct platform_device *pdev, const struct resource *res, unsigned int num)

向平臺裝置新增資源

引數

struct platform_device *pdev

由 platform_device_alloc 分配的平臺裝置,用於新增資源

const struct resource *res

需要為裝置分配的資源集

unsigned int num

資源數量

描述

將資源的副本新增到平臺裝置。與資源關聯的記憶體將在平臺裝置釋放時被釋放。

int platform_device_add_data(struct platform_device *pdev, const void *data, size_t size)

向平臺裝置新增平臺特定資料

引數

struct platform_device *pdev

由 platform_device_alloc 分配的平臺裝置,用於新增資源

const void *data

此平臺裝置的平臺特定資料

size_t size

平臺特定資料的大小

描述

將平臺特定資料的副本新增到平臺裝置的 platform_data 指標。與平臺數據關聯的記憶體將在平臺裝置釋放時被釋放。

int platform_device_add(struct platform_device *pdev)

將平臺裝置新增到裝置層次結構

引數

struct platform_device *pdev

我們正在新增的平臺裝置

描述

這是 platform_device_register() 的第 2 部分,但如果 pdev 是由 platform_device_alloc() 分配的,則可以單獨呼叫。

void platform_device_del(struct platform_device *pdev)

移除一個平臺級裝置

引數

struct platform_device *pdev

我們正在移除的平臺裝置

描述

請注意,此函式還將釋放裝置擁有的所有基於記憶體和埠的資源(dev->resource)。此函式_只能_在錯誤情況下從外部呼叫。所有其他用法都是錯誤。

int platform_device_register(struct platform_device *pdev)

新增一個平臺級裝置

引數

struct platform_device *pdev

我們正在新增的平臺裝置

注意

在呼叫此函式後,_切勿_直接釋放 pdev,即使它返回錯誤也一樣!請始終使用 platform_device_put() 來放棄此函式中初始化的引用。

void platform_device_unregister(struct platform_device *pdev)

登出一個平臺級裝置

引數

struct platform_device *pdev

我們正在登出的平臺裝置

描述

登出分兩步完成。首先,我們釋放所有資源並將其從子系統中移除,然後透過呼叫 platform_device_put() 減少引用計數。

struct platform_device *platform_device_register_full(const struct platform_device_info *pdevinfo)

新增一個帶有資源和平臺特定資料的平臺級裝置

引數

const struct platform_device_info *pdevinfo

用於建立裝置的資料

描述

成功返回 struct platform_device 指標,錯誤返回 ERR_PTR()

int __platform_driver_register(struct platform_driver *drv, struct module *owner)

註冊平臺級裝置的驅動程式

引數

struct platform_driver *drv

平臺驅動程式結構

struct module *owner

所屬模組/驅動程式

void platform_driver_unregister(struct platform_driver *drv)

登出平臺級裝置的驅動程式

引數

struct platform_driver *drv

平臺驅動程式結構

int __platform_driver_probe(struct platform_driver *drv, int (*probe)(struct platform_device*), struct module *module)

註冊非熱插拔裝置的驅動程式

引數

struct platform_driver *drv

平臺驅動程式結構

int (*probe)(struct platform_device *)

驅動程式探測例程,可能來自一個 __init 部分

struct module *module

將成為該驅動程式所有者的模組

描述

當您知道裝置不可熱插拔且已註冊,並且希望在驅動程式繫結到裝置後從記憶體中移除其一次性探查(probe())基礎設施時,請使用此函式而不是 platform_driver_register()。

一個典型的用例是用於整合在片上系統處理器中的控制器驅動程式,其中控制器裝置已作為板級設定的一部分進行配置。

請注意,這與延遲探測不相容。

如果驅動程式註冊並繫結到裝置,則返回零;否則,返回一個負錯誤程式碼,且驅動程式未註冊。

struct platform_device *__platform_create_bundle(struct platform_driver *driver, int (*probe)(struct platform_device*), struct resource *res, unsigned int n_res, const void *data, size_t size, struct module *module)

註冊驅動程式並建立相應的裝置

引數

struct platform_driver *driver

平臺驅動程式結構

int (*probe)(struct platform_device *)

驅動程式探測例程,可能來自一個 __init 部分

struct resource *res

需要為裝置分配的資源集

unsigned int n_res

資源數量

const void *data

此平臺裝置的平臺特定資料

size_t size

平臺特定資料的大小

struct module *module

將成為該驅動程式所有者的模組

描述

在直接探測硬體並註冊單個平臺裝置和相應平臺驅動程式的傳統風格模組中使用此函式。

成功返回 struct platform_device 指標,錯誤返回 ERR_PTR()

int __platform_register_drivers(struct platform_driver *const *drivers, unsigned int count, struct module *owner)

註冊一個平臺驅動程式陣列

引數

struct platform_driver * const *drivers

要註冊的驅動程式陣列

unsigned int count

要註冊的驅動程式數量

struct module *owner

擁有這些驅動程式的模組

描述

註冊由陣列指定的平臺驅動程式。如果註冊驅動程式失敗,所有先前註冊的驅動程式都將被登出。此 API 的呼叫者應使用 platform_unregister_drivers() 以相反的順序登出驅動程式。

返回

成功時返回 0,失敗時返回負錯誤程式碼。

void platform_unregister_drivers(struct platform_driver *const *drivers, unsigned int count)

登出一個平臺驅動程式陣列

引數

struct platform_driver * const *drivers

要登出的驅動程式陣列

unsigned int count

要登出的驅動程式數量

描述

登出由陣列指定的平臺驅動程式。這通常用於補充之前對 platform_register_drivers() 的呼叫。驅動程式將以其註冊的相反順序被登出。

struct device *platform_find_device_by_driver(struct device *start, const struct device_driver *drv)

查詢具有給定驅動程式的平臺裝置。

引數

struct device *start

開始搜尋的裝置。

const struct device_driver *drv

要查詢的裝置驅動程式。

struct device *bus_find_device_by_name(const struct bus_type *bus, struct device *start, const char *name)

用於按特定名稱定位特定裝置的裝置迭代器。

引數

const struct bus_type *bus

匯流排型別

struct device *start

開始的裝置

const char *name

要匹配的裝置名稱

struct device *bus_find_device_by_of_node(const struct bus_type *bus, const struct device_node *np)

用於查詢匹配of_node的特定裝置的裝置迭代器。

引數

const struct bus_type *bus

匯流排型別

const struct device_node *np

要匹配裝置的of_node

struct device *bus_find_device_by_fwnode(const struct bus_type *bus, const struct fwnode_handle *fwnode)

用於查詢匹配fwnode的特定裝置的裝置迭代器。

引數

const struct bus_type *bus

匯流排型別

const struct fwnode_handle *fwnode

要匹配裝置的fwnode

struct device *bus_find_device_by_devt(const struct bus_type *bus, dev_t devt)

用於查詢匹配裝置型別的特定裝置的裝置迭代器。

引數

const struct bus_type *bus

匯流排型別

dev_t devt

要匹配裝置的裝置型別。

struct device *bus_find_next_device(const struct bus_type *bus, struct device *cur)

在給定匯流排中,查詢給定裝置之後的下一個裝置。

引數

const struct bus_type *bus

匯流排型別

struct device *cur

開始搜尋的裝置。

struct device *bus_find_device_by_acpi_dev(const struct bus_type *bus, const struct acpi_device *adev)

用於定位與 ACPI COMPANION 裝置匹配的特定裝置的裝置迭代器。

引數

const struct bus_type *bus

匯流排型別

const struct acpi_device *adev

要匹配的 ACPI COMPANION 裝置。

int bus_for_each_dev(const struct bus_type *bus, struct device *start, void *data, device_iter_t fn)

裝置迭代器。

引數

const struct bus_type *bus

匯流排型別。

struct device *start

開始迭代的裝置。

void *data

回撥資料。

device_iter_t fn

為每個裝置呼叫的函式。

描述

遍歷 bus 的裝置列表,併為每個裝置呼叫 fn,將 data 傳遞給它。如果 start 不為 NULL,則我們從該裝置開始迭代。

我們每次都檢查fn的返回值。如果它返回非0值,我們就會中斷並返回該值。

注意

返回非零值的裝置不會以任何方式保留,其引用計數也不會增加。如果呼叫者需要保留此資料,則應在提供的回撥中自行處理並增加引用計數。

struct device *bus_find_device(const struct bus_type *bus, struct device *start, const void *data, device_match_t match)

用於定位特定裝置的裝置迭代器。

引數

const struct bus_type *bus

匯流排型別

struct device *start

開始的裝置

const void *data

要傳遞給匹配函式的資料

device_match_t match

檢查裝置的回撥函式

描述

這類似於上面的 bus_for_each_dev() 函式,但它返回一個裝置的引用,該裝置由 match 回撥確定為“找到”,以便以後使用。

如果裝置不匹配,回撥應返回 0;如果匹配,則返回非零值。如果回撥返回非零值,此函式將返回給呼叫者,不再迭代任何其他裝置。

int bus_for_each_drv(const struct bus_type *bus, struct device_driver *start, void *data, int (*fn)(struct device_driver*, void*))

驅動程式迭代器

引數

const struct bus_type *bus

正在處理的匯流排。

struct device_driver *start

開始迭代的驅動程式。

void *data

要傳遞給回撥的資料。

int (*fn)(struct device_driver *, void *)

為每個驅動程式呼叫的函式。

描述

這與上面的裝置迭代器幾乎相同。我們遍歷屬於 bus 的每個驅動程式,併為每個驅動程式呼叫 fn。如果 fn 返回非 0 值,我們就會跳出並返回該值。如果 start 不為 NULL,我們將其用作列表的頭部。

注意

我們不返回返回非零值的驅動程式,也不會為該驅動程式保留增加的引用計數。如果呼叫者需要了解該資訊,它必須在回撥中設定。它還必須確保增加引用計數,以避免在返回給呼叫者之前消失。

int bus_rescan_devices(const struct bus_type *bus)

重新掃描總線上的裝置以查詢可能的驅動程式

引數

const struct bus_type *bus

要掃描的匯流排。

描述

此函式將查詢總線上沒有附加驅動程式的裝置,並將其與現有驅動程式進行重新掃描,透過為未繫結裝置呼叫 device_attach() 來檢視是否匹配任何驅動程式。

int device_reprobe(struct device *dev)

移除裝置的驅動程式並探測新的驅動程式

引數

struct device *dev

要重新探測的裝置

描述

此函式將給定裝置的已附加驅動程式(如果有)分離,並重新啟動驅動程式探測過程。它旨在用於裝置生命週期內探測標準發生變化且驅動程式附件應相應變化的情況。

int bus_register(const struct bus_type *bus)

註冊一個驅動核心子系統

引數

const struct bus_type *bus

要註冊的匯流排

描述

一旦我們有了這個,我們就會使用 kobject 基礎設施註冊匯流排,然後註冊它擁有的子系統:屬於該子系統的裝置和驅動程式。

void bus_unregister(const struct bus_type *bus)

從系統中移除匯流排

引數

const struct bus_type *bus

匯流排。

描述

登出子系統和匯流排本身。最後,我們呼叫 bus_put() 來釋放引用計數。

int subsys_system_register(const struct bus_type *subsys, const struct attribute_group **groups)

在 /sys/devices/system/ 註冊子系統

引數

const struct bus_type *subsys

系統子系統

const struct attribute_group **groups

根裝置的預設屬性

描述

所有“系統”子系統都有一個 /sys/devices/system/ 根裝置,其名稱與子系統相同。根裝置可以攜帶子系統範圍的屬性。所有註冊的裝置都位於這個單一的根裝置之下,並以子系統名稱加上一個簡單的列舉數字命名。註冊的裝置沒有顯式命名;只需設定裝置中的“id”即可。

不要將此介面用於任何新事物,它僅為相容不良設計而存在。新子系統應使用普通子系統;並且子系統範圍的屬性應新增到子系統目錄本身,而不是放置在 /sys/devices/system/ 中的某個虛假根裝置。

int subsys_virtual_register(const struct bus_type *subsys, const struct attribute_group **groups)

在 /sys/devices/virtual/ 註冊子系統

引數

const struct bus_type *subsys

虛擬子系統

const struct attribute_group **groups

根裝置的預設屬性

描述

所有“虛擬”子系統都有一個 /sys/devices/system/ 根裝置,其名稱與子系統相同。根裝置可以攜帶子系統範圍的屬性。所有註冊的裝置都位於這個單一的根裝置之下。對裝置命名沒有限制。這適用於需要 sysfs 介面的核心軟體構造。

struct device_driver *driver_find(const char *name, const struct bus_type *bus)

按名稱在總線上定位驅動程式。

引數

const char *name

驅動程式的名稱。

const struct bus_type *bus

要掃描驅動程式的匯流排。

描述

呼叫 kset_find_obj() 遍歷總線上的驅動程式列表,按名稱查詢驅動程式。如果找到則返回驅動程式。

此例程不提供鎖定機制,以防止返回的驅動程式在呼叫者使用時被登出或解除安裝。呼叫者有責任防止這種情況發生。

struct device *bus_get_dev_root(const struct bus_type *bus)

返回匯流排“裝置根”的指標

引數

const struct bus_type *bus

要返回裝置根的匯流排。

描述

如果匯流排有“裝置根”結構,則返回它,並且引用計數已增加。

注意,使用完裝置後,需要呼叫 put_device()

如果裝置根不存在(或匯流排不是有效指標),將返回 NULL。

裝置驅動程式 DMA 管理

void dmam_free_coherent(struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle)

託管的 dma_free_coherent()

引數

struct device *dev

要釋放一致性記憶體的裝置

size_t size

分配的大小

void *vaddr

要釋放記憶體的虛擬地址

dma_addr_t dma_handle

要釋放記憶體的 DMA 控制代碼

描述

託管的 dma_free_coherent()。

void *dmam_alloc_attrs(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)

託管的 dma_alloc_attrs()

引數

struct device *dev

為之分配非一致性記憶體的裝置

size_t size

分配的大小

dma_addr_t *dma_handle

已分配 DMA 控制代碼的輸出引數

gfp_t gfp

分配標誌

unsigned long attrs

DMA_ATTR_* 名稱空間中的標誌。

描述

託管的 dma_alloc_attrs()。使用此函式分配的記憶體將在驅動程式分離時自動釋放。

返回

成功時返回指向已分配記憶體的指標,失敗時返回 NULL。

unsigned int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg, int nents, enum dma_data_direction dir, unsigned long attrs)

為 DMA 對映給定緩衝區

引數

struct device *dev

執行 DMA 操作的裝置

struct scatterlist *sg

描述緩衝區的 sg_table 物件

int nents

要對映的條目數量

enum dma_data_direction dir

DMA 方向

unsigned long attrs

對映操作的可選 DMA 屬性

描述

dev 裝置,透過 sg 引數中具有 nents 段的 scatterlist 描述的緩衝區,對映 dir DMA 操作。

成功時返回已對映條目的數量(可能小於 nents)。任何錯誤都返回零。

應使用 dma_unmap_sg_attrs() 取消對映緩衝區,使用原始的 sg 和原始的 nents(而不是此函式返回的值)。

int dma_map_sgtable(struct device *dev, struct sg_table *sgt, enum dma_data_direction dir, unsigned long attrs)

為 DMA 對映給定緩衝區

引數

struct device *dev

執行 DMA 操作的裝置

struct sg_table *sgt

描述緩衝區的 sg_table 物件

enum dma_data_direction dir

DMA 方向

unsigned long attrs

對映操作的可選 DMA 屬性

描述

dev 裝置,將儲存在給定 sg_table 物件中的 scatterlist 描述的緩衝區對映到 dir DMA 操作。成功後,緩衝區的所有權將轉移到 DMA 域。在 CPU 訪問緩衝區之前,必須呼叫 dma_sync_sgtable_for_cpu() 或 dma_unmap_sgtable() 將緩衝區的所有權移回 CPU 域。

成功返回 0,錯誤返回負錯誤碼。支援以下錯誤碼及其含義:

-EINVAL

無效引數、未對齊訪問或使用中的其他錯誤。重試也不會成功。

-ENOMEM

資源不足(例如記憶體或 IOVA 空間)無法完成對映。如果稍後重試,應該會成功。

-EIO

含義不明的遺留錯誤碼。例如,如果底層呼叫返回 DMA_MAPPING_ERROR,則返回此錯誤碼。

-EREMOTEIO

DMA 裝置無法訪問 sg_table 中指定的 P2PDMA 記憶體。重試也不會成功。

bool dma_need_unmap(struct device *dev)

此裝置是否需要 dma_unmap_* 操作

引數

struct device *dev

要檢查的裝置

描述

如果此函式返回 false,驅動程式可以在完成 I/O 後跳過呼叫 dma_unmap_*。此函式必須在所有可能需要解除對映的對映操作完成後呼叫。

bool dma_can_mmap(struct device *dev)

檢查給定裝置是否支援 dma_mmap_*

引數

struct device *dev

要檢查的裝置

描述

如果 dev 支援 dma_mmap_coherent() 和 dma_mmap_attrs() 將 DMA 分配對映到使用者空間,則返回 true

int dma_mmap_attrs(struct device *dev, struct vm_area_struct *vma, void *cpu_addr, dma_addr_t dma_addr, size_t size, unsigned long attrs)

將一致性 DMA 分配對映到使用者空間

引數

struct device *dev

有效的 struct device 指標,對於 ISA 和 EISA 類裝置為 NULL

struct vm_area_struct *vma

描述請求的使用者對映的 vm_area_struct

void *cpu_addr

從 dma_alloc_attrs 返回的核心 CPU 檢視地址

dma_addr_t dma_addr

從 dma_alloc_attrs 返回的裝置檢視地址

size_t size

dma_alloc_attrs 中最初請求的記憶體大小

unsigned long attrs

dma_alloc_attrs 中請求的對映屬性

描述

將之前透過 dma_alloc_attrs 分配的一致性 DMA 緩衝區對映到使用者空間。在使用者空間對映被釋放之前,驅動程式不得釋放該一致性 DMA 緩衝區。

bool dma_addressing_limited(struct device *dev)

返回裝置地址是否受限

引數

struct device *dev

要檢查的裝置

描述

如果裝置 DMA 掩碼太小而無法定址系統中所有記憶體,則返回 true,否則返回 false。缺少定址位是跳板緩衝的主要原因,但可能不是唯一原因。

裝置驅動程式 PnP 支援

int pnp_register_protocol(struct pnp_protocol *protocol)

將 pnp 協議新增到 pnp 層

引數

struct pnp_protocol *protocol

指向相應的 pnp_protocol 結構的指標

例如協議:ISAPNP, PNPBIOS 等

struct pnp_dev *pnp_request_card_device(struct pnp_card_link *clink, const char *id, struct pnp_dev *from)

在指定的卡下搜尋 PnP 裝置

引數

struct pnp_card_link *clink

指向卡連結的指標,不能為 NULL

const char *id

指向 PnP ID 結構的指標,該結構解釋了查詢裝置的規則

struct pnp_dev *from

開始搜尋的位置。如果為 NULL,則從頭開始。

void pnp_release_card_device(struct pnp_dev *dev)

當驅動程式不再需要該裝置時呼叫此函式

引數

struct pnp_dev *dev

指向 PnP 裝置結構的指標

int pnp_register_card_driver(struct pnp_card_driver *drv)

向 PnP 層註冊 PnP 卡驅動程式

引數

struct pnp_card_driver *drv

指向要註冊的驅動程式的指標

void pnp_unregister_card_driver(struct pnp_card_driver *drv)

從 PnP 層登出 PnP 卡驅動程式

引數

struct pnp_card_driver *drv

指向要登出的驅動程式的指標

struct pnp_id *pnp_add_id(struct pnp_dev *dev, const char *id)

將 EISA ID 新增到指定裝置

引數

struct pnp_dev *dev

指向所需裝置的指標

const char *id

指向 EISA ID 字串的指標

int pnp_start_dev(struct pnp_dev *dev)

PnP 裝置的低階啟動

引數

struct pnp_dev *dev

指向所需裝置的指標

描述

假設資源已經分配

int pnp_stop_dev(struct pnp_dev *dev)

PnP 裝置的低階停用

引數

struct pnp_dev *dev

指向所需裝置的指標

描述

不釋放資源

int pnp_activate_dev(struct pnp_dev *dev)

啟用 PnP 裝置以供使用

引數

struct pnp_dev *dev

指向所需裝置的指標

描述

不驗證或設定資源,因此請謹慎。

int pnp_disable_dev(struct pnp_dev *dev)

停用裝置

引數

struct pnp_dev *dev

指向所需裝置的指標

描述

通知正確的 pnp 協議,以便其他裝置可以使用資源

int pnp_is_active(struct pnp_dev *dev)

根據當前資源確定裝置是否處於活動狀態

引數

struct pnp_dev *dev

指向所需 PnP 裝置的指標

使用者空間 IO 裝置

void uio_event_notify(struct uio_info *info)

觸發中斷事件

引數

struct uio_info *info

UIO 裝置功能

int __uio_register_device(struct module *owner, struct device *parent, struct uio_info *info)

註冊新的使用者空間 IO 裝置

引數

struct module *owner

建立新裝置的模組

struct device *parent

父裝置

struct uio_info *info

UIO 裝置功能

描述

成功返回零,否則返回負錯誤碼。

int __devm_uio_register_device(struct module *owner, struct device *parent, struct uio_info *info)

資源託管的 uio_register_device()

引數

struct module *owner

建立新裝置的模組

struct device *parent

父裝置

struct uio_info *info

UIO 裝置功能

描述

成功返回零,否則返回負錯誤碼。

void uio_unregister_device(struct uio_info *info)

登出工業 IO 裝置

引數

struct uio_info *info

UIO 裝置功能

struct uio_mem

UIO 記憶體區域的描述

定義:

struct uio_mem {
    const char              *name;
    phys_addr_t addr;
    dma_addr_t dma_addr;
    unsigned long           offs;
    resource_size_t size;
    int memtype;
    void __iomem            *internal_addr;
    struct device           *dma_device;
    struct uio_map          *map;
};

成員

name

用於識別的記憶體區域名稱

addr

裝置記憶體地址,四捨五入到頁面大小(使用 phys_addr 是因為 addr 可以是邏輯、虛擬或物理地址,而 phys_addr_t 應該總是足夠大以處理任何地址型別)

dma_addr

由 dma_alloc_coherent 設定的 DMA 控制代碼,僅與 UIO_MEM_DMA_COHERENT 一起使用(addr 應該是與同一 dma_alloc_coherent 呼叫返回的 void *)

offs

頁面內裝置記憶體的偏移量

size

IO 大小(頁面大小的倍數)

memtype

addr 指向的記憶體型別

internal_addr

ioremap 後的 addr 版本,供驅動程式內部使用

dma_device

傳遞給 dma_alloc_coherent 的裝置結構,僅與 UIO_MEM_DMA_COHERENT 一起使用

map

僅供 UIO 核心使用。

struct uio_port

UIO 埠區域的描述

定義:

struct uio_port {
    const char              *name;
    unsigned long           start;
    unsigned long           size;
    int porttype;
    struct uio_portio       *portio;
};

成員

name

用於識別的埠區域名稱

start

埠區域的起始地址

size

埠區域的大小

porttype

埠型別(參見下面的 UIO_PORT_*)

portio

僅供 UIO 核心使用。

struct uio_info

UIO 裝置功能

定義:

struct uio_info {
    struct uio_device       *uio_dev;
    const char              *name;
    const char              *version;
    struct uio_mem          mem[MAX_UIO_MAPS];
    struct uio_port         port[MAX_UIO_PORT_REGIONS];
    long irq;
    unsigned long           irq_flags;
    void *priv;
    irqreturn_t (*handler)(int irq, struct uio_info *dev_info);
    int (*mmap)(struct uio_info *info, struct vm_area_struct *vma);
    int (*open)(struct uio_info *info, struct inode *inode);
    int (*release)(struct uio_info *info, struct inode *inode);
    int (*irqcontrol)(struct uio_info *info, s32 irq_on);
};

成員

uio_dev

此資訊所屬的 UIO 裝置

name

裝置名稱

version

裝置驅動版本

mem

可對映記憶體區域列表,size==0 表示列表結束

port

埠區域列表,size==0 表示列表結束

irq

中斷號或 UIO_IRQ_CUSTOM

irq_flags

request_irq() 的標誌

priv

可選的私有資料

handler

裝置的 irq 處理程式

mmap

此 uio 裝置的 mmap 操作

open

此 uio 裝置的開啟操作

release

此 uio 裝置的釋放操作

irqcontrol

當 0/1 寫入 /dev/uioX 時停用/啟用中斷

uio_register_device

uio_register_device (parent, info)

註冊新的使用者空間 IO 裝置

引數

parent

父裝置

資訊

UIO 裝置功能

描述

成功返回零,否則返回負錯誤碼。

devm_uio_register_device

devm_uio_register_device (parent, info)

資源託管的 uio_register_device()

引數

parent

父裝置

資訊

UIO 裝置功能

描述

成功返回零,否則返回負錯誤碼。