mirror of
https://github.com/reactos/reactos.git
synced 2025-08-06 13:13:00 +00:00
[WDF] Add Windows Driver Framework files
Takern from Microsoft GitHub repo:
d9c6040fe9
Licensed under MIT
This commit is contained in:
parent
545df81502
commit
8a978a179f
475 changed files with 285099 additions and 0 deletions
496
sdk/lib/drivers/wdf/shared/irphandlers/pnp/pdopower.cpp
Normal file
496
sdk/lib/drivers/wdf/shared/irphandlers/pnp/pdopower.cpp
Normal file
|
@ -0,0 +1,496 @@
|
|||
/*++
|
||||
|
||||
Copyright (c) Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
PdoPower.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
This module implements the Pnp package for Pdo devices.
|
||||
|
||||
Author:
|
||||
|
||||
|
||||
|
||||
|
||||
Environment:
|
||||
|
||||
Both kernel and user mode
|
||||
|
||||
Revision History:
|
||||
|
||||
|
||||
|
||||
--*/
|
||||
|
||||
#include "pnppriv.hpp"
|
||||
|
||||
// Tracing support
|
||||
#if defined(EVENT_TRACING)
|
||||
extern "C" {
|
||||
#include "PdoPower.tmh"
|
||||
}
|
||||
#endif
|
||||
|
||||
_Must_inspect_result_
|
||||
NTSTATUS
|
||||
FxPkgPdo::_DispatchPowerSequence(
|
||||
__inout FxPkgPnp* This,
|
||||
__in FxIrp *Irp
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
report the power sequence for the child
|
||||
|
||||
Arguments:
|
||||
This - the package
|
||||
|
||||
Irp - the request
|
||||
|
||||
Return Value:
|
||||
STATUS_NOT_SUPPORTED
|
||||
|
||||
--*/
|
||||
{
|
||||
return ((FxPkgPdo*) This)->CompletePowerRequest(Irp, STATUS_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
_Must_inspect_result_
|
||||
NTSTATUS
|
||||
FxPkgPdo::_DispatchSetPower(
|
||||
__inout FxPkgPnp* This,
|
||||
__in FxIrp *Irp
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
This method is invoked when a SetPower IRP enters the driver.
|
||||
|
||||
Arguemnts:
|
||||
|
||||
Device - a pointer to the FxDevice
|
||||
|
||||
Irp - a pointer to the FxIrp
|
||||
|
||||
Returns:
|
||||
|
||||
NTSTATUS
|
||||
|
||||
--*/
|
||||
{
|
||||
if (Irp->GetParameterPowerType() == SystemPowerState) {
|
||||
return ((FxPkgPdo*) This)->DispatchSystemSetPower(Irp);
|
||||
}
|
||||
else {
|
||||
return ((FxPkgPdo*) This)->DispatchDeviceSetPower(Irp);
|
||||
}
|
||||
}
|
||||
|
||||
_Must_inspect_result_
|
||||
NTSTATUS
|
||||
FxPkgPdo::DispatchSystemSetPower(
|
||||
__in FxIrp *Irp
|
||||
)
|
||||
{
|
||||
NTSTATUS status;
|
||||
KIRQL irql;
|
||||
MxDeviceObject deviceObject(m_Device->GetDeviceObject());
|
||||
|
||||
status = STATUS_SUCCESS;
|
||||
|
||||
m_SystemPowerState = (BYTE) Irp->GetParameterPowerStateSystemState();
|
||||
deviceObject.SetPowerState(SystemPowerState,
|
||||
Irp->GetParameterPowerState());
|
||||
|
||||
if (IsPowerPolicyOwner()) {
|
||||
if (m_SystemPowerState == PowerSystemWorking) {
|
||||
//
|
||||
// Ideally we would like to complete the S0 irp before we start
|
||||
// processing the event in the state machine so that the D0 irp
|
||||
// comes after the S0 is moving up the stack...
|
||||
//
|
||||
// ... BUT ...
|
||||
//
|
||||
// ... by allowing the S0 irp to go up the stack first, we must then
|
||||
// handle pnp requests from the current power policy state (because
|
||||
// the S0 irp could be the last S irp in the system and when completed,
|
||||
// the pnp lock is released). So, we process the event first so
|
||||
// that we can move into a state where we can handle pnp events in
|
||||
// the power policy state machine.
|
||||
//
|
||||
// We mitigate the situation a little bit by forcing the processing of the
|
||||
// event to occur on the power policy thread rather then in the current
|
||||
// context.
|
||||
//
|
||||
Mx::MxRaiseIrql(DISPATCH_LEVEL, &irql);
|
||||
PowerPolicyProcessEvent(PwrPolS0);
|
||||
Mx::MxLowerIrql(irql);
|
||||
|
||||
return CompletePowerRequest(Irp, STATUS_SUCCESS);
|
||||
}
|
||||
else {
|
||||
//
|
||||
// Power policy state machine will complete the request later
|
||||
//
|
||||
SetPendingSystemPowerIrp(Irp);
|
||||
PowerPolicyProcessEvent(PwrPolSx);
|
||||
return STATUS_PENDING;
|
||||
}
|
||||
}
|
||||
else {
|
||||
//
|
||||
// Since we are not the power policy owner, we just complete all S irps
|
||||
//
|
||||
return CompletePowerRequest(Irp, STATUS_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
_Must_inspect_result_
|
||||
NTSTATUS
|
||||
FxPkgPdo::DispatchDeviceSetPower(
|
||||
__in FxIrp *Irp
|
||||
)
|
||||
{
|
||||
NTSTATUS status;
|
||||
|
||||
status = STATUS_SUCCESS;
|
||||
|
||||
if (IsPowerPolicyOwner()) {
|
||||
if (m_PowerPolicyMachine.m_Owner->m_RequestedPowerUpIrp == FALSE &&
|
||||
m_PowerPolicyMachine.m_Owner->m_RequestedPowerDownIrp == FALSE) {
|
||||
//
|
||||
// A power irp arrived, but we did not request it. ASSERT and log
|
||||
// an error.
|
||||
//
|
||||
DoTraceLevelMessage(
|
||||
GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGPNP,
|
||||
"Received set device power irp 0x%p on WDFDEVICE 0x%p !devobj 0x%p, "
|
||||
"but the irp was not requested by the device (the power policy owner)",
|
||||
Irp->GetIrp(),
|
||||
m_Device->GetHandle(),
|
||||
m_Device->GetDeviceObject());
|
||||
|
||||
ASSERTMSG("Received set device power irp but the irp was not "
|
||||
"requested by the device (the power policy owner)\n",
|
||||
FALSE);
|
||||
}
|
||||
|
||||
//
|
||||
// We are no longer requesting a power irp because we received the one
|
||||
// we requested.
|
||||
//
|
||||
if (m_PowerPolicyMachine.m_Owner->m_RequestedPowerUpIrp) {
|
||||
m_PowerPolicyMachine.m_Owner->m_RequestedPowerUpIrp = FALSE;
|
||||
}
|
||||
else {
|
||||
m_PowerPolicyMachine.m_Owner->m_RequestedPowerDownIrp = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
SetPendingDevicePowerIrp(Irp);
|
||||
|
||||
if (Irp->GetParameterPowerStateDeviceState() == PowerDeviceD0) {
|
||||
PowerProcessEvent(PowerD0);
|
||||
}
|
||||
else {
|
||||
PowerProcessEvent(PowerDx);
|
||||
}
|
||||
|
||||
return STATUS_PENDING;
|
||||
}
|
||||
|
||||
_Must_inspect_result_
|
||||
NTSTATUS
|
||||
FxPkgPdo::_DispatchQueryPower(
|
||||
__inout FxPkgPnp* This,
|
||||
__in FxIrp *Irp
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Dispatches query power for system and device requests
|
||||
|
||||
Arguments:
|
||||
This - the package
|
||||
|
||||
Irp - the query power request
|
||||
|
||||
Return Value:
|
||||
NTSTATUS
|
||||
|
||||
--*/
|
||||
{
|
||||
FxPkgPdo* pThis;
|
||||
NTSTATUS status;
|
||||
|
||||
pThis = ((FxPkgPdo*) This);
|
||||
|
||||
if (Irp->GetParameterPowerType() == SystemPowerState
|
||||
&&
|
||||
This->PowerPolicyIsWakeEnabled()) {
|
||||
|
||||
status = pThis->PowerPolicyHandleSystemQueryPower(
|
||||
Irp->GetParameterPowerStateSystemState()
|
||||
);
|
||||
}
|
||||
else {
|
||||
status = STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
return pThis->CompletePowerRequest(Irp, status);
|
||||
}
|
||||
|
||||
VOID
|
||||
FxPkgPdo::PowerReleasePendingDeviceIrp(
|
||||
__in BOOLEAN IrpMustBePresent
|
||||
)
|
||||
{
|
||||
MdIrp pIrp;
|
||||
|
||||
pIrp = ClearPendingDevicePowerIrp();
|
||||
|
||||
UNREFERENCED_PARAMETER(IrpMustBePresent);
|
||||
ASSERT(IrpMustBePresent == FALSE || pIrp != NULL);
|
||||
|
||||
if (pIrp != NULL) {
|
||||
FxIrp irp(pIrp);
|
||||
|
||||
CompletePowerRequest(&irp, STATUS_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
_Must_inspect_result_
|
||||
NTSTATUS
|
||||
FxPkgPdo::PowerCheckParentOverload(
|
||||
__in BOOLEAN* ParentOn
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This function implements the CheckParent state. Its
|
||||
job is to determine which state we should go to next based on whether
|
||||
the parent is in D0.
|
||||
|
||||
Arguments:
|
||||
none
|
||||
|
||||
Return Value:
|
||||
|
||||
VOID
|
||||
|
||||
--*/
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
return (m_Device->m_ParentDevice->m_PkgPnp)->
|
||||
PowerPolicyCanChildPowerUp(ParentOn);
|
||||
}
|
||||
|
||||
WDF_DEVICE_POWER_STATE
|
||||
FxPkgPdo::PowerCheckDeviceTypeOverload(
|
||||
VOID
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This function implements the Check Type state. This is a PDO.
|
||||
|
||||
Arguments:
|
||||
none
|
||||
|
||||
Return Value:
|
||||
|
||||
new power state
|
||||
|
||||
--*/
|
||||
{
|
||||
return WdfDevStatePowerCheckParentState;
|
||||
}
|
||||
|
||||
WDF_DEVICE_POWER_STATE
|
||||
FxPkgPdo::PowerCheckDeviceTypeNPOverload(
|
||||
VOID
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
This function implements the Check Type state. This is a PDO.
|
||||
|
||||
Arguments:
|
||||
none
|
||||
|
||||
Return Value:
|
||||
|
||||
new power state
|
||||
|
||||
--*/
|
||||
{
|
||||
return WdfDevStatePowerCheckParentStateNP;
|
||||
}
|
||||
|
||||
_Must_inspect_result_
|
||||
NTSTATUS
|
||||
FxPkgPdo::PowerEnableWakeAtBusOverload(
|
||||
VOID
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Arms the device at the bus level for wake. This arming is generic since
|
||||
the bus driver can only configure the device generically. The power policy
|
||||
owner has already armed the device for wake in a device specific fashion
|
||||
when it processed the wake irp (EvtDeviceArmDeviceForWakeFromS0/x if the ppo
|
||||
is a WDF driver).
|
||||
|
||||
Arguments:
|
||||
None
|
||||
|
||||
Return Value:
|
||||
NTSTATUS, !NT_SUCCESS if the arm failed
|
||||
|
||||
--*/
|
||||
{
|
||||
NTSTATUS status;
|
||||
|
||||
//
|
||||
// The EnableWakeAtBus callback should not be called twice in a row without
|
||||
// an intermediate call to the DisableWakeAtBus callback.
|
||||
//
|
||||
ASSERT(m_EnableWakeAtBusInvoked == FALSE);
|
||||
|
||||
status = m_DeviceEnableWakeAtBus.Invoke(
|
||||
m_Device->GetHandle(),
|
||||
(SYSTEM_POWER_STATE) m_SystemPowerState
|
||||
);
|
||||
|
||||
if (NT_SUCCESS(status)) {
|
||||
m_EnableWakeAtBusInvoked = TRUE;
|
||||
PowerNotifyParentChildWakeArmed();
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
VOID
|
||||
FxPkgPdo::PowerDisableWakeAtBusOverload(
|
||||
VOID
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Disarms the device at the bus level for wake. This disarming is generic
|
||||
since the bus driver can only configure the device generically. The power
|
||||
policy owner may have already disarmed the device for wake in a device
|
||||
specific fashion. For a WDF ppo EvtDeviceDisarmDeviceForWakeFromS0/x is
|
||||
called after the bus has disarmed.
|
||||
|
||||
Arguments:
|
||||
None
|
||||
|
||||
Return Value:
|
||||
None
|
||||
|
||||
--*/
|
||||
{
|
||||
if (m_EnableWakeAtBusInvoked) {
|
||||
m_EnableWakeAtBusInvoked = FALSE;
|
||||
PowerNotifyParentChildWakeDisarmed();
|
||||
|
||||
m_DeviceDisableWakeAtBus.Invoke(m_Device->GetHandle());
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
FxPkgPdo::PowerParentPowerDereference(
|
||||
VOID
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Releases the child power reference on the parent device. This allows the
|
||||
parent to enter into an idle capable state. This power reference does not
|
||||
prevent the parent from moving into Dx when the system power state changes.
|
||||
|
||||
Arguments:
|
||||
None
|
||||
|
||||
Return Value:
|
||||
None
|
||||
|
||||
--*/
|
||||
{
|
||||
|
||||
m_Device->m_ParentDevice->m_PkgPnp->PowerPolicyChildPoweredDown();
|
||||
}
|
||||
|
||||
VOID
|
||||
FxPkgPdo::PowerNotifyParentChildWakeArmed(
|
||||
VOID
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Notifies the parent device that the child is armed for wake. This will
|
||||
cause the parent to increment its count of children armed for wake.
|
||||
|
||||
Arguments:
|
||||
None
|
||||
|
||||
Return Value:
|
||||
None
|
||||
|
||||
--*/
|
||||
{
|
||||
FxPowerPolicyOwnerSettings* settings;
|
||||
|
||||
ASSERT(m_Device->m_ParentDevice != NULL);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
settings = m_Device->m_ParentDevice->m_PkgPnp->
|
||||
m_PowerPolicyMachine.m_Owner;
|
||||
if (settings != NULL) {
|
||||
settings->IncrementChildrenArmedForWakeCount();
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
FxPkgPdo::PowerNotifyParentChildWakeDisarmed(
|
||||
VOID
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Notifies the parent device that the child is not armed for wake. This will
|
||||
cause the parent to decrement its count of children armed for wake.
|
||||
|
||||
Arguments:
|
||||
None
|
||||
|
||||
Return Value:
|
||||
None
|
||||
|
||||
--*/
|
||||
{
|
||||
FxPowerPolicyOwnerSettings* settings;
|
||||
|
||||
ASSERT(m_Device->m_ParentDevice != NULL);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
settings = m_Device->m_ParentDevice->m_PkgPnp->
|
||||
m_PowerPolicyMachine.m_Owner;
|
||||
if (settings != NULL) {
|
||||
settings->DecrementChildrenArmedForWakeCount();
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue