编写适用于 Oracle® Solaris 11.2 的设备驱动程序

退出打印视图

更新时间: 2014 年 9 月
 
 

回调接口

驱动程序必须使用以下接口来注册回调支持。

表 8-1  回调支持接口
接口
数据结构
说明
ddi_cb_register()
ddi_cb_flags_tddi_cb_handle_t
注册回调处理程序函数,以接收特定类型的操作。
ddi_cb_unregister()
ddi_cb_handle_t
取消注册回调处理程序函数。
(*ddi_cb_func_t)()
ddi_cb_action_t
接收回调操作以及与要处理的各操作相关的特定参数。

注册回调处理程序函数

使用 ddi_cb_register(9F) 函数为驱动程序注册回调处理程序函数。

int
ddi_cb_register (dev_info_t *dip, ddi_cb_flags_t cbflags,
                 ddi_cb_func_t cbfunc, void *arg1, void *arg2,
                 ddi_cb_handle_t *ret_hdlp);

驱动程序仅可注册一个回调函数。这是用于处理所有独立回调操作的回调函数。cbflags 参数确定驱动程序应在发生哪些类型的操作时接收这些操作。cbfunc() 例程将在驱动程序应处理相关操作时调用。在每次执行 cbfunc() 例程时,驱动程序都会指定应发送给其本身的两个专用参数(arg1arg2)。

cbflags() 参数属于枚举类型,指定驱动程序支持哪些操作。

typedef enum {
        DDI_CB_FLAG_INTR
} ddi_cb_flags_t;

为了注册对中断资源管理操作的支持,驱动程序必须注册处理程序,并包含 DDI_CB_FLAG_INTR 标志。回调处理程序成功注册后,将通过 ret_hdlp 参数返回一个不透明的句柄。驱动程序使用完回调处理程序之后,驱动程序可使用 ret_hdlp 参数取消注册此回调处理程序。

在驱动程序的 attach(9F) 入口点中注册回调处理程序。在驱动程序的软状态中保存不透明的句柄。在驱动程序的 detach(9F) 入口点中取消注册回调处理程序。

取消注册回调处理程序函数

使用 ddi_cb_unregister(9F) 函数为驱动程序取消注册回调处理程序函数。

int
ddi_cb_unregister (ddi_cb_handle_t hdl);

在驱动程序的 detach(9F) 入口点中执行此调用。在此调用之后,驱动程序将不再接收回调操作。

驱动程序也会失去因拥有注册的回调处理函数而从系统中获得的其他所有支持。例如,此前为驱动程序提供的某些中断向量会在取消注册其回调处理函数后立即收回。成功返回之前,ddi_cb_unregister() 函数会通知驱动程序由于系统支持缺失所导致的任何最终操作。

回调处理程序函数

使用注册的回调处理函数来接收回调操作,接收特定于要处理的各操作的参数。

typedef int (*ddi_cb_func_t)(dev_info_t *dip, ddi_cb_action_t cbaction,
                             void *cbarg, void *arg1, void *arg2);

cbaction 参数指定驱动程序接收到的回调要处理哪种操作。

typedef enum {
        DDI_CB_INTR_ADD,
        DDI_CB_INTR_REMOVE
} ddi_cb_action_t;

DDI_CB_INTR_ADD 操作表示驱动程序中断可用数量增加。DDI_CB_INTR_REMOVE 操作表示驱动程序中断可用数量减少。将 cbarg 参数的类型强制转换为 int,以确定添加或删除的中断数量。cbarg 值表示可用中断数量的变化。

例如,获得可用中断数量的变化:

count = (int)(uintptr_t)cbarg;

如果 cbactionDDI_CB_INT _ADD,则应添加 cbarg 数量的中断向量。如果 cbactionDDI_CB_INTR_REMOVE,则应释放 cbarg 数量的中断向量。

有关 arg1arg2 的说明, 请参见 ddi_cb_register(9F)

回调处理函数必须能够在函数注册的整个时间段内正确执行。回调函数不能依赖任何可能会在回调函数成功取消注册之前销毁的数据结构。

    回调处理函数必须返回以下值之一:

  • DDI_SUCCESS(如果正确处理了操作)

  • DDI_FAILURE(如果遇到内部错误)

  • DDI_ENOTSUP(如果接收到无法识别的操作)