编写设备驱动程序

分层驱动程序句柄-目标设备

内核设备使用方必须使用分层驱动程序句柄 (ldi_handle_t) 来通过 LDI 接口访问目标设备。ldi_handle_t 类型仅对 LDI 接口有效。当 LDI 成功打开某个设备时,将分配并返回此句柄。然后,内核设备使用方可使用此句柄通过 LDI 接口访问目标设备。LDI 在关闭设备时会取消分配该句柄。有关示例,请参见LDI 内核接口示例

本节讨论内核设备使用方如何访问目标设备并检索不同类型的信息。要了解内核设备使用方如何打开和关闭目标设备,请参见打开和关闭目标设备。要了解内核设备使用方如何对目标设备执行 readwritestrategyioctl 之类的操作,请参见访问目标设备检索目标设备信息介绍了用于检索目标设备信息(如设备打开类型和设备次要名称)的接口。检索目标设备属性值介绍了用于检索目标设备属性的值和地址的接口。要了解内核设备使用方如何接收来自目标设备的事件通知,请参见接收异步设备事件通知

打开和关闭目标设备

本节介绍用于打开和关闭目标设备的 LDI 内核接口。打开接口采用指向分层驱动程序句柄的指针。打开接口会尝试打开由设备编号、设备 ID 或路径名指定的目标设备。如果打开操作成功,则打开接口将分配并返回可用于访问目标设备的分层驱动程序句柄。关闭接口用于关闭与指定分层驱动程序句柄关联的目标设备,然后释放该分层驱动程序句柄。

ldi_handle_t

用于访问目标设备的分层驱动程序句柄。一种成功打开设备时返回的不透明数据结构。

ldi_open_by_dev(9F)

打开由 dev_t 设备编号参数指定的设备。

ldi_open_by_devid(9F)

打开由 ddi_devid_t 设备 ID 参数指定的设备。另外,还必须指定要打开的次要节点名称。

ldi_open_by_name(9F)

根据路径名打开设备。路径名是内核地址空间中以 NULL 结尾的字符串。路径名必须是以正斜杠字符 (/) 开头的绝对路径。

ldi_close(9F)

关闭使用 ldi_open_by_dev(9F)、ldi_open_by_devid(9F) 或 ldi_open_by_name (9F) 打开的设备。在 ldi_close(9F) 返回之后,已关闭的设备的分层驱动程序句柄不再有效。

访问目标设备

本节介绍用于访问目标设备的 LDI 内核接口。通过这些接口,内核设备使用方可以对由分层驱动程序句柄指定的目标设备执行操作。内核设备使用方可以对目标设备执行 readwritestrategyioctl 之类的操作。

ldi_handle_t

用于访问目标设备的分层驱动程序句柄。属于不透明数据结构。

ldi_read(9F)

将读取请求传递到目标设备的设备入口点。块设备、字符设备和 STREAMS 设备支持此操作。

ldi_aread(9F)

将异步读取请求传递到目标设备的设备入口点。块设备和字符设备支持此操作。

ldi_write(9F)

将写入请求传递到目标设备的设备入口点。块设备、字符设备和 STREAMS 设备支持此操作。

ldi_awrite(9F)

将异步写入请求传递到目标设备的设备入口点。块设备和字符设备支持此操作。

ldi_strategy(9F)

将策略请求传递到目标设备的设备入口点。块设备和字符设备支持此操作。

ldi_dump(9F)

将转储请求传递到目标设备的设备入口点。块设备和字符设备支持此操作。

ldi_poll(9F)

将轮询请求传递到目标设备的设备入口点。块设备、字符设备和 STREAMS 设备支持此操作。

ldi_ioctl(9F)

ioctl 请求传递到目标设备的设备入口点。块设备、字符设备和 STREAMS 设备支持此操作。LDI 支持 STREAMS 链接和 STREAMS ioctl 命令。请参见 ldi_ioctl(9F) 手册页的 "STREAM IOCTLS" 一节。另请参见 streamio(7I) 手册页中的 ioctl 命令。

ldi_devmap(9F)

devmap 请求传递到目标设备的设备入口点。块设备和字符设备支持此操作。

ldi_getmsg(9F)

从流中获取消息块。

ldi_putmsg(9F)

将消息块放在流中。

检索目标设备信息

本节介绍内核设备使用方可用于检索有关指定目标设备的设备信息的 LDI 接口。目标设备由分层驱动程序句柄指定。内核设备使用方可以接收设备编号、设备打开类型、设备 ID、设备次要名称和设备大小之类的信息。

ldi_get_dev(9F)

获取由分层驱动程序句柄指定的目标设备的 dev_t 设备编号。

ldi_get_otyp(9F)

获取用于打开由分层驱动程序句柄指定的目标设备的打开标志。此标志指示目标设备是字符设备还是块设备。

ldi_get_devid(9F)

获取由分层驱动程序句柄指定的目标设备的 ddi_devid_t 设备 ID。使用完设备 ID 后,应使用 ddi_devid_free(9F) 释放 ddi_devid_t

ldi_get_minor_name(9F)

检索包含为目标设备打开的次要节点的名称的缓冲区。使用完次要节点名称后,应使用 kmem_free(9F) 释放该缓冲区。

ldi_get_size(9F)

检索由分层驱动程序句柄指定的目标设备的分区大小。

检索目标设备属性值

本节介绍内核设备使用方可用于检索有关指定目标设备的属性信息的 LDI 接口。目标设备由分层驱动程序句柄指定。内核设备使用方可以接收属性的值和地址,以及确定某属性是否存在。

ldi_prop_exists(9F)

如果由分层驱动程序句柄指定的目标设备的属性存在,则返回 1。如果指定目标设备的属性不存在,则返回 0

ldi_prop_get_int(9F)

搜索与由分层驱动程序句柄指定的目标设备关联的 int 整数属性。如果找到整数属性,则返回属性值。

ldi_prop_get_int64(9F)

搜索与由分层驱动程序句柄指定的目标设备关联的 int64_t 整数属性。如果找到整数属性,则返回属性值。

ldi_prop_lookup_int_array(9F)

检索由分层驱动程序句柄指定的目标设备的 int 整数数组属性值的地址。

ldi_prop_lookup_int64_array(9F)

检索由分层驱动程序句柄指定的目标设备的 int64_t 整数数组属性值的地址。

ldi_prop_lookup_string(9F)

检索由分层驱动程序句柄指定的目标设备的以 null 结尾的字符串属性值的地址。

ldi_prop_lookup_string_array(9F)

检索字符串数组的地址。字符串数组是一个指针数组,指向由分层驱动程序句柄指定的目标设备的以 null 结尾的字符串属性值。

ldi_prop_lookup_byte_array(9F)

检索字节数组的地址。字节数组是由分层驱动程序句柄指定的目标设备的属性值。

接收异步设备事件通知

通过 LDI,内核设备使用方可以注册事件通知以及接收来自目标设备的事件通知。内核设备使用方可以注册发生事件时将会调用的事件处理程序。内核设备使用方必须先打开设备并接收分层驱动程序句柄,然后才能通过 LDI 事件通知接口注册事件通知。

通过 LDI 事件通知接口,内核设备使用方可以指定事件名称以及检索关联的内核事件 cookie。然后,内核设备使用方可以将分层驱动程序句柄 (ldi_handle_t)、cookie (ddi_eventcookie_t) 及事件处理程序传递到 ldi_add_event_handler(9F) 以注册事件通知。成功完成注册后,内核设备使用方会收到一个唯一的 LDI 事件处理程序标识符 (ldi_callback_id_t)。LDI 事件处理程序标识符属于不透明类型,只能用于 LDI 事件通知接口。

LDI 提供了一个框架,以用于注册其他设备生成的事件。LDI 本身并不定义任何事件类型,也不提供用于生成事件的接口。

下面介绍了 LDI 异步事件通知接口:

ldi_callback_id_t

事件处理程序标识符。属于不透明类型。

ldi_get_eventcookie(9F)

检索由分层驱动程序句柄指定的目标设备的事件服务 cookie。

ldi_add_event_handler(9F)

添加由 ldi_callback_id_t 注册标识符指定的回调处理程序。发生由 ddi_eventcookie_t cookie 指定的事件时,将会调用该回调处理程序。

ldi_remove_event_handler(9F)

删除由 ldi_callback_id_t 注册标识符指定的回调处理程序。