编写设备驱动程序

prop_op() 入口点

向系统报告设备属性或驱动程序属性通常需要使用 prop_op(9E) 入口点。如果驱动程序无需创建或管理其自己的属性,则 ddi_prop_op(9F) 函数可用于此入口点。

如果在驱动程序的 cb_ops(9S) 结构中定义了 ddi_prop_op(),则 ddi_prop_op(9F) 可用作设备驱动程序的 prop_op(9E) 入口点。ddi_prop_op() 使叶设备可在设备的属性列表中搜索并获取属性值。

如果驱动程序需要维护其值经常更改的属性,则应在 cb_ops() 结构中定义特定于驱动程序的 prop_op 例程,而不是调用 ddi_prop_op()。此方法可避免由于重复使用 ddi_prop_update() 而造成的效率低下。然后,驱动程序应在其软状态结构或驱动程序变量中维护属性值的副本。

prop_op(9E) 入口点向系统报告特定驱动程序属性的值和设备属性的值。在许多情况下,ddi_prop_op(9F) 例程在 cb_ops(9S) 结构中可用作驱动程序的 prop_op() 入口点。ddi_prop_op() 会执行所有必需的处理过程。对于处理设备属性请求时不需要进行特殊处理的驱动程序,ddi_prop_op() 即可满足要求。

但是,有时驱动程序必须提供 prop_op() 入口点。例如,如果驱动程序维护其值经常更改的属性,则针对每次更改使用 ddi_prop_update(9F) 更新属性便不能满足要求。相反,驱动程序应在实例的软状态下维护属性的阴影副本。然后,驱动程序可在值发生变化时更新阴影副本,而无需使用任何 ddi_prop_update() 例程。prop_op() 入口点必须拦截此属性的请求,并使用 ddi_prop_update() 例程之一更新属性的值,然后将请求传递到 ddi_prop_op() 以处理属性请求。

在以下示例中,prop_op() 拦截 temperature 属性的请求。属性发生变化时,驱动程序将更新状态结构中的变量。但是,仅当发出请求时才会更新该属性。然后,驱动程序使用 ddi_prop_op() 处理该属性请求。如果属性请求不特定于某个设备,则驱动程序不会拦截该请求。dev 参数的值等于 DDI_DEV_T_ANY(通配符设备编号)时即是这种情况。


示例 4–1 prop_op() 例程

static int
xx_prop_op(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op,
    int flags, char *name, caddr_t valuep, int *lengthp)
{
        minor_t instance;
        struct xxstate *xsp;
        if (dev != DDI_DEV_T_ANY) {
                return (ddi_prop_op(dev, dip, prop_op, flags, name,
                    valuep, lengthp));
        }

        instance = getminor(dev);
        xsp = ddi_get_soft_state(statep, instance);
        if (xsp == NULL)
                return (DDI_PROP_NOTFOUND);
        if (strcmp(name, "temperature") == 0) {
                ddi_prop_update_int(dev, dip, name, temperature);
        }

        /* other cases */    
}