编写设备驱动程序

attach() 入口点

attach(9E) 的语法如下所示:

int attach(dev_info_t *dip, ddi_attach_cmd_t cmd);

恢复系统电源后,每个具有 reg 属性或具有值为 needs-suspend-resumepm-hardware-state 属性的设备都会使用 DDI_RESUME 命令值调用其 attach(9E) 入口点。如果系统关闭异常中止,则即使尚未关闭电源,也会调用每个暂停的驱动程序以进行恢复。因此,attach(9E) 中的恢复代码不能对系统是否已实际断电作出任何假设。

电源管理框架认为组件的电源级别在执行 DDI_RESUME 时未知。根据设备性质,驱动程序编写者有两种选择:

以下示例给出了使用 DDI_RESUME 命令的 attach(9E) 例程。


示例 12–7 实现 DDI_RESUME 的 attach(9E) 例程

int
xxattach(devinfo_t *dip, ddi_attach_cmd_t cmd)
{
    struct xxstate *xsp;
    int    instance;

    instance = ddi_get_instance(dip);
    xsp = ddi_get_soft_state(statep, instance);

    switch (cmd) {
    case DDI_ATTACH:
    /* ... */
    case DDI_RESUME:
        mutex_enter(&xsp->mu);
        if (xsp->xx_pm_state_saved) {
            /*
             * Restore device register contents from
             * xsp->xx_device_state
             */
        }
       /*
        * This section is optional and only needed if the
        * driver maintains a running timeout
        */
        xsp->xx_timeout_id = timeout( /* ... */ );

        xsp->xx_suspended = 0;        /* allow new operations */
        cv_broadcast(&xsp->xx_suspend_cv);
       /* If it is possible to determine in a device-specific 
        * way what the power levels of components are without 
        * powering the components up,
        * then the following code is recommended
        */
        for (i = 0; i < num_components; i++) {
            xsp->xx_power_level[i] = xx_get_power_level(dip, i);
            if (xsp->xx_power_level[i] != XX_LEVEL_UNKNOWN)
                (void) pm_power_has_changed(dip, i, 
                    xsp->xx_power_level[i]);
        }
        mutex_exit(&xsp->mu);
        return(DDI_SUCCESS);
    default:
        return(DDI_FAILURE);
    }
}


注 –

detach(9E)attach(9E) 接口也可用于恢复处于静止状态的系统。