Windows电源管理
+ -

IRP_MJ_POWER设备电源管理

2023-11-28 17 0
Windows电源管理相关编程

以下代码摘自TOASTER电源管理IRP_MJ_POWER的注释

The system dispatches different IRP_MJ_POWER IRPs to ToasterDispatchPower for different purposes:

  • To query a driver to determine if the system can change its overall power state to a different power level.
  • To notify a driver of a change in the overall system power state so that the driver can adjust the device power state of its hardware instance to an appropriate level.
  • To respond to system wake-up events.

Most function and filter drivers perform some processing for each power IRP and then pass the IRP down the device stack without completing it. Eventually the power IRP reaches the bus driver, which physically changes the power to the hardware instance and completes the power IRP.

fdo和fido保留相关的信息之后,直接下传给PDO即可。
总线的PDO收到该IRP之后,更改设备的供电并完成IRP.

In general, a driver should not cause noticeable delays while processing power IRPs. If a driver cannot process a power in a short amount of time, it should mark the power IRP as pending, begin to queue any new non-power IRPs (until the driver completes the pending power IRP), and return STATUS_PENDING to the caller.

电源如无法完成时,应挂起IRP,并置IRP状态为STATUS_PENDING,并调用PoStartNextPowerIrp。


Processing power IRPs is a complex procedure which can involve I/O completion routines, power completion routines, and system worker thread work items. The following sequence demonstrates how a power policy owner (the function driver in this case) processes different power IRPs:

The power manager sends a IRP_MN_QUERY_POWER S-IRP (query power system-IRP) with a specific system power state to query the power policy owner if it can change its hardware instance to an appropriate device power state without disrupting work.

1a) -The function driver receives an IRP_MN_QUERY_POWER (query power system-IRP)
     S-IRP.
    -The function driver sets the system to call an I/O completion routine
     because the function driver must process the IRP_MN_QUERY_POWER S-IRP on its
     passage back up the device stack, after the underlying bus driver completes
     it.
    -The function driver passes the IRP_MN_QUERY_POWER S-IRP down the device
     stack.
    -The function driver returns STATUS_PENDING to the caller.

    After the bus driver completes the IRP_MN_QUERY_POWER S-IRP, the system passes
    the IRP back up the device stack and calls the I/O completion routine set
    earlier:

1b) -The I/O completion routine requests that the power manager send a
     IRP_MN_QUERY_POWER D-IRP (query power device-IRP) that corresponds to the
     original pending IRP_MN_QUERY_POWER S-IRP. When the I/O completion routine
     requests the corresponding D-IRP it also sets the system to call a power
     completion routine after the function driver completes the corresponding
     D-IRP.
    -The I/O completion routine returns STATUS_MORE_PROCESSING_REQUIRED to the
     caller.

1c) -The function driver receives the corresponding IRP_MN_QUERY_POWER D-IRP and
     either completes it successfully to indicate that the hardware instance can
     change to an appropriate device power state without data loss, or fails the
     D-IRP to indicate that the hardware instance cannot change its device power
     state without disrupting work.

    The system then calls the power completion routine set to be called earlier
    when the I/O completion requested the corresponding D-IRP:

1d) -The power completion routine copies the status of the corresponding completed
     IRP_MN_QUERY_POWER D-IRP into the original pending IRP_MN_QUERY_POWER S-IRP.
    -The power completion routine then completes the original pending
     IRP_MN_QUERY_POWER S-IRP.
    -The power completion routine returns to the caller.

    If the function driver fails the original IRP_MN_QUERY_POWER S-IRP, then the
    power manager might send another IRP_MN_QUERY_POWER S-IRP to specify a
    different system power state, and the previous sequence repeats.

    However, if the function driver succeeds the original IRP_MN_QUERY_POWER
    S-IRP, then the power manager sends a IRP_MN_SET_POWER S-IRP (set power
    system IRP) with the same system power state as the original
    IRP_MN_QUERY_POWER S-IRP to notify the function driver to change its hardware
    instance to the device power state appropriate for the system power state.

    Alternately, even if the function driver fails the original IRP_MN_QUERY_POWER
    S-IRP, the power manager can still send a IRP_MN_SET_POWER S-IRP to notify the
    function driver that the system is preparing to change its power state. The
    power manager might force a driver to change its hardware instance to a
    specific device power state because a battery or UPS is going offline

----------------------------------------------------------------------------------

2a) -The function driver receives an IRP_MN_SET_POWER (set power system-IRP)
     S-IRP.
    -The function driver sets the system to call an I/O completion routine
     because the function driver must process the IRP_MN_SET_POWER S-IRP on its
     passage back up the device stack, after the underlying bus driver completes
     it.
    -The function driver passes the IRP_MN_SET_POWER S-IRP down the device
     stack.
    -The function driver returns STATUS_PENDING to the caller.

    After the bus driver completes the IRP_MN_SET_POWER S-IRP, the system calls
    the I/O completion routine set earlier:

2b) -The I/O completion routine requests that the power manager send a
     IRP_MN_SET_POWER D-IRP (set power device-IRP) that corresponds to the
     original pending IRP_MN_SET_POWER S-IRP. When the I/O completion routine
     requests the corresponding D-IRP it also sets the system to call a power
     completion routine after the function driver completes the corresponding
     D-IRP.
    -The I/O completion routine returns STATUS_MORE_PROCESSING_REQUIRED to the
     caller.

----------------------------------------------------------------------------------

3)  -The function driver receives the corresponding IRP_MN_SET_POWER D-IRP and
     must determine if it is a power-down D-IRP or a power-up D-IRP.

4)  If the original pending IRP_MN_SET_POWER S-IRP specifies a higher system power
    state than the current system power state then the corresponding
    IRP_MN_SET_POWER D-IRP is a power-up D-IRP. The underlying bus driver must
    process power-up D-IRPs before the function driver because the bus driver must
    supply power to the hardware instance before the function driver can use it.
    However, the function driver cannot process the power-up D-IRP until every
    pending IRP (if any) such as read, write, or device control operations
    complete (in other threads of execution). Note that, however, the function
    driver cannot wait in the thread processing the power-up D-IRP because that
    might cause the system to stop responding.

    Therefore, the function driver marks the power-up D-IRP as pending and sets
    the system to call an I/O completion routine after the bus driver completes
    the power-up D-IRP. Then, the function driver passes the power-up D-IRP down
    the device stack. Next, the function driver returns STATUS_PENDING to the
    caller. At this time, both the original IRP_MN_SET_POWER S-IRP and the
    corresponding power-up D-IRP are pending.

    After the bus driver completes the power-up D-IRP, the system calls the I/O
    completion routine set earlier. Recall, that the function driver must still
    wait until every pending IRP completes. However, because the function driver
    cannot wait in the I/O completion routine for every IRP to complete, the I/O
    completion routine queues a callback for the system worker thread to process
    at IRQL = PASSIVE_LEVEL. Then the I/O completion routine returns
    STATUS_MORE_PROCESSING_REQUIRED to the caller.

    Finally, the system worker thread calls the callback routine at
    IRQL = PASSIVE_LEVEL to finish processing the power-up D-IRP. The callback
    routine can then wait until every pending IRP completes by suspending the
    execution of the system worker thread (which will not cause a system deadlock
    because the system worker thread calls the callback routine at
    IRQL = PASSIVE_LEVEL), and then the callback routine finishes processing the
    power-up D-IRP before it returns to the caller.

----------------------------------------------------------------------------------

5)  Otherwise, if the original pending IRP_MN_SET_POWER S-IRP specifies the same
    system power state as the current system power state, or a lower system power
    state than the current system power state then the corresponding
    IRP_MN_SET_POWER D-IRP is a power-down D-IRP. The function driver must process
    power-down D-IRPs before passing them down the device stack to be processed by
    the underlying bus driver because the function driver must save the hardware
    instance's operating context before the hardware instance is powered-down (or
    powered-off). The context can then be restored later when the hardware
    instance is powered-up.

    Therefore, the function driver queues a callback for the system worker thread
    to process at IRQL = PASSIVE_LEVEL. Then the function routine returns
    STATUS_PENDING to the caller.

    Finally, the system worker thread calls the callback routine at
    IRQL = PASSIVE_LEVEL to finish processing the power-down D-IRP. The callback
    routine can then wait until every pending IRP completes by suspending the
    execution of the system worker thread (which will not cause a system deadlock
    because the system worker thread calls the callback routine at
    IRQL = PASSIVE_LEVEL), and then the callback routine finishes processing the
    power-down D-IRP before it returns to the caller.

Updated Return Value Description:
    ToasterDispatchPower returns STATUS_NO_SUCH_DEVICE if the hardware instance
    represented by DeviceObject has been removed. If the function driver
    immediately processes the power IRP, then ToasterDispatchPower returns
    STATUS_SUCCESS. If the function driver marked the power IRP as pending, then
    ToasterDispatchPower returns STATUS_PENDING.

0 篇笔记 写笔记

PortClass 电源管理
电源管理实现的COM是AdapterPowerMgr,继承于IAdapterPowerManagement和CUnknown,用于电源的管理。class AdapterPowerMgr: public IAdapterPowerManagement, public CUnkn......
WDF即插即用和电源管理支持
WDF的主要设计目标简化即插即用和电源管理的驱动程序支持,在内核模式和用户模式下都能使用即插即用和电源管理。无缝地处理即插即用事件和电源事件,对于系统的可靠性和良好用户体验来说至关重要,但要想正确实现也出奇地复杂。 这种复杂性多数是因为驱动程序必须确定处理每个即插即用或电源管理请求的正确方式。正确......
PortClass电源管理回调函数及调用时机
PortClass电源管理使用IAdapterPowerManagement类实例来回调。class AdapterPowerMgr: public IAdapterPowerManagement, public CUnknown其三个回调函数分别为:PowerChan......
IRP_MJ_POWER设备电源管理
以下代码摘自TOASTER电源管理IRP_MJ_POWER的注释The system dispatches different IRP_MJ_POWER IRPs to ToasterDispatchPower for different purposes:To query a drive......
Inter电源管理技术Intel Speed Shift与Thread Director
Intel Speed ShiftIntel Speed Shift 技术为从Intel 第六代 Core 处理器开始的搭载的。Intel Speed Shift一种动态电压频率切换技术SpeedStep,它可以动态调节处理器的工作频率、电压,这样可以在处理器负载较低的时候降低系统功耗和处理器工......
显示WIN10系统中隐藏的电源和处理器选项
使用如下命令: powercfg /Q >%UserProfile%DesktopPowerPlanSettings.txt powercfg /Qh >%UserProfile%DesktopPowerPlanSettingsHidden.txt这时在电脑的桌面会显示出2......
作者信息
我爱内核
Windows驱动开发,网站开发
好好学习,天天向上。
取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

您的支持,是我们前进的动力!