attach(9E) 的语法如下所示:
int attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
恢复系统电源后,每个具有 reg 属性或具有值为 needs-suspend-resume 的 pm-hardware-state 属性的设备都会使用 DDI_RESUME 命令值调用其 attach(9E) 入口点。如果系统关闭异常中止,则即使尚未关闭电源,也会调用每个暂停的驱动程序以进行恢复。因此,attach(9E) 中的恢复代码不能对系统是否已实际断电作出任何假设。
电源管理框架认为组件的电源级别在执行 DDI_RESUME 时未知。根据设备性质,驱动程序编写者有两种选择:
如果驱动程序无需打开组件电源即可确定设备组件的实际电源级别(如通过读取寄存器),则驱动程序应通过调用 pm_power_has_changed(9F) 来通知框架每个组件的电源级别。
如果驱动程序无法确定组件的电源级别,则驱动程序应在首次访问各个组件之前,在内部将每个组件标记为未知并调用 pm_raise_power(9F)。
以下示例给出了使用 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) 接口也可用于恢复处于静止状态的系统。