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) 接口也可用于恢复处于静止状态的系统。