设备驱动程序基础设施

基本设备驱动程序模型结构

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 设备功能

描述

成功返回零,否则返回负错误码。