编写设备驱动程序

设备电源管理接口

支持包含电源可管理组件的设备的设备驱动程序必须创建 pm-components(9P) 属性。该属性向系统指明设备包含电源可管理组件。pm-components 还向系统指明可用的电源级别。通常,驱动程序通过从其 attach(9E) 入口点调用 ddi_prop_update_string_array(9F) 来通知系统。另一种通知系统的方法是使用 driver.conf(4) 文件。有关详细信息,请参见 pm-components(9P) 手册页。

繁忙-空闲状态转换

驱动程序必须始终使框架了解从空闲到繁忙或从繁忙到空闲的设备状态转换。进行这些转换的位置完全特定于设备。繁忙与空闲状态之间的转换取决于设备的性质以及特定组件具备的状态转换特性。例如,SCSI 磁盘目标驱动程序通常导出单个组件,该组件表示 SCSI 目标磁盘驱动器是启动状态还是停止状态。当驱动器有未解决的请求时,该组件将标记为繁忙。完成最后一个排队请求后,该组件将标记为空闲。某些组件创建后从未标记为繁忙。例如,pm-components(9P) 创建的组件就一直处于空闲状态。

pm_busy_component(9F)pm_idle_component(9F) 接口将通知电源管理框架繁忙/空闲状态转换。pm_busy_component(9F) 调用的语法如下所示:

int pm_busy_component(dev_info_t *dip, int component);

pm_busy_component(9F)component 标记为繁忙。当组件为繁忙状态时,不应关闭该组件的电源。如果已关闭组件电源,则将该组件标记为繁忙不会更改电源级别。为此,驱动程序需要调用 pm_raise_power(9F)。对 pm_busy_component(9F) 的调用具有累积性,因此要使组件处于空闲状态,需要调用相应次数的 pm_idle_component(9F)。

pm_idle_component(9F) 例程的语法如下所示:

int pm_idle_component(dev_info_t *dip, int component);

pm_idle_component(9F)component 标记为空闲。可以关闭空闲组件的电源。要使组件处于空闲状态,必须针对 pm_busy_component(9F) 的每次调用调用 pm_idle_component(9F) 一次。

设备能耗状态转换

设备驱动程序可以调用 pm_raise_power(9F) 来请求将组件至少设置为给定的电源级别。使用已关闭电源的组件之前,必须采用这种方式设置电源级别。例如,如果已关闭磁盘电源,则 SCSI 磁盘目标驱动程序的 read(9E) 例程可能需要启动磁盘。pm_raise_power(9F) 函数请求电源管理框架将设备能耗状态转换为较高的电源级别。通常,由框架来降低组件的电源级别。但是,设备驱动程序在分离时应调用 pm_lower_power(9F),以便尽可能地降低未使用设备的能耗。

对于某些设备来说,关闭电源可能会产生风险。例如,某些磁带机在关闭电源时会损坏磁带。同样,某些磁盘驱动器在开关电源过程中的容错能力有限,因为每次开关电源都会导致磁头停放。应使用 no-involuntary-power-cycles(9P) 属性通知系统,设备驱动程序应控制设备的所有关开机循环。此方法可防止在分离设备驱动程序时切断设备电源,除非驱动程序已从其 detach(9E) 入口点调用 pm_lower_power(9F) 关闭设备电源。

驱动程序发现某个操作所需组件的电源级别不够高时,会调用 pm_raise_power(9F) 函数。该接口会使驱动程序将组件的当前电源级别提高到所需级别。该调用还会将依赖于该设备的所有设备恢复到全功率。

如果在不再需要访问某个设备后分离该设备,则将调用 pm_lower_power(9F)。调用 pm_lower_power(9F) 可将每个组件设置为最低电源级别,从而使设备在未使用时尽可能少地消耗电量。必须从 detach() 入口点调用 pm_lower_power() 函数。如果从驱动程序的任何其他部分调用 pm_lower_power() 函数,该函数不会起作用。

调用 pm_power_has_changed(9F) 函数可通知框架有关电源转换的情况。转换可能是由于设备更改了自己的电源级别而导致。转换也可能是由于暂停/恢复等操作而导致。pm_power_has_changed(9F) 的语法与 pm_raise_power(9F) 的语法相同。