18a978a17SVictor Perevertkin /*++
28a978a17SVictor Perevertkin
38a978a17SVictor Perevertkin Copyright (c) Microsoft Corporation
48a978a17SVictor Perevertkin
58a978a17SVictor Perevertkin Module Name:
68a978a17SVictor Perevertkin
78a978a17SVictor Perevertkin FdoPower.cpp
88a978a17SVictor Perevertkin
98a978a17SVictor Perevertkin Abstract:
108a978a17SVictor Perevertkin
118a978a17SVictor Perevertkin This module implements the pnp/power package for the driver
128a978a17SVictor Perevertkin framework. This, specifically, is the power code.
138a978a17SVictor Perevertkin
148a978a17SVictor Perevertkin Author:
158a978a17SVictor Perevertkin
168a978a17SVictor Perevertkin
178a978a17SVictor Perevertkin
188a978a17SVictor Perevertkin
198a978a17SVictor Perevertkin Environment:
208a978a17SVictor Perevertkin
218a978a17SVictor Perevertkin Both kernel and user mode
228a978a17SVictor Perevertkin
238a978a17SVictor Perevertkin Revision History:
248a978a17SVictor Perevertkin
258a978a17SVictor Perevertkin
268a978a17SVictor Perevertkin
278a978a17SVictor Perevertkin
288a978a17SVictor Perevertkin --*/
298a978a17SVictor Perevertkin
308a978a17SVictor Perevertkin #include "pnppriv.hpp"
318a978a17SVictor Perevertkin
328a978a17SVictor Perevertkin
338a978a17SVictor Perevertkin
348a978a17SVictor Perevertkin
358a978a17SVictor Perevertkin #if defined(EVENT_TRACING)
368a978a17SVictor Perevertkin extern "C" {
378a978a17SVictor Perevertkin #include "FdoPower.tmh"
388a978a17SVictor Perevertkin }
398a978a17SVictor Perevertkin #endif
408a978a17SVictor Perevertkin
418a978a17SVictor Perevertkin _Must_inspect_result_
428a978a17SVictor Perevertkin NTSTATUS
_PowerPassDown(__inout FxPkgPnp * This,__in FxIrp * Irp)438a978a17SVictor Perevertkin FxPkgFdo::_PowerPassDown(
448a978a17SVictor Perevertkin __inout FxPkgPnp* This,
458a978a17SVictor Perevertkin __in FxIrp *Irp
468a978a17SVictor Perevertkin )
478a978a17SVictor Perevertkin
488a978a17SVictor Perevertkin /*++
498a978a17SVictor Perevertkin
508a978a17SVictor Perevertkin Routine Description:
518a978a17SVictor Perevertkin
528a978a17SVictor Perevertkin This method is invoked when a Power Irp we don't handle comes into the
538a978a17SVictor Perevertkin driver.
548a978a17SVictor Perevertkin
558a978a17SVictor Perevertkin Arguemnts:
568a978a17SVictor Perevertkin
578a978a17SVictor Perevertkin This - the package
588a978a17SVictor Perevertkin
598a978a17SVictor Perevertkin Irp - a pointer to the FxIrp
608a978a17SVictor Perevertkin
618a978a17SVictor Perevertkin Returns:
628a978a17SVictor Perevertkin
638a978a17SVictor Perevertkin NTSTATUS
648a978a17SVictor Perevertkin
658a978a17SVictor Perevertkin --*/
668a978a17SVictor Perevertkin {
678a978a17SVictor Perevertkin FxPkgFdo* pThis;
688a978a17SVictor Perevertkin NTSTATUS status;
698a978a17SVictor Perevertkin MdIrp pIrp;
708a978a17SVictor Perevertkin
718a978a17SVictor Perevertkin pIrp = Irp->GetIrp();
728a978a17SVictor Perevertkin pThis = (FxPkgFdo*) This;
738a978a17SVictor Perevertkin
748a978a17SVictor Perevertkin //
758a978a17SVictor Perevertkin // FDOs don't handle this IRP, so simply pass it down.
768a978a17SVictor Perevertkin //
778a978a17SVictor Perevertkin Irp->StartNextPowerIrp();
788a978a17SVictor Perevertkin Irp->CopyCurrentIrpStackLocationToNext();
798a978a17SVictor Perevertkin
808a978a17SVictor Perevertkin status = Irp->PoCallDriver(pThis->m_Device->GetAttachedDevice());
818a978a17SVictor Perevertkin
828a978a17SVictor Perevertkin Mx::MxReleaseRemoveLock(pThis->m_Device->GetRemoveLock(),
838a978a17SVictor Perevertkin pIrp);
848a978a17SVictor Perevertkin
858a978a17SVictor Perevertkin return status;
868a978a17SVictor Perevertkin }
878a978a17SVictor Perevertkin
888a978a17SVictor Perevertkin _Must_inspect_result_
898a978a17SVictor Perevertkin NTSTATUS
_DispatchSetPower(__inout FxPkgPnp * This,__in FxIrp * Irp)908a978a17SVictor Perevertkin FxPkgFdo::_DispatchSetPower(
918a978a17SVictor Perevertkin __inout FxPkgPnp* This,
928a978a17SVictor Perevertkin __in FxIrp *Irp
938a978a17SVictor Perevertkin )
948a978a17SVictor Perevertkin /*++
958a978a17SVictor Perevertkin
968a978a17SVictor Perevertkin Routine Description:
978a978a17SVictor Perevertkin
988a978a17SVictor Perevertkin This method is invoked when a SetPower IRP enters the driver.
998a978a17SVictor Perevertkin
1008a978a17SVictor Perevertkin Arguemnts:
1018a978a17SVictor Perevertkin
1028a978a17SVictor Perevertkin Device - a pointer to the FxDevice
1038a978a17SVictor Perevertkin
1048a978a17SVictor Perevertkin Irp - a pointer to the FxIrp
1058a978a17SVictor Perevertkin
1068a978a17SVictor Perevertkin Returns:
1078a978a17SVictor Perevertkin
1088a978a17SVictor Perevertkin NTSTATUS
1098a978a17SVictor Perevertkin
1108a978a17SVictor Perevertkin --*/
1118a978a17SVictor Perevertkin
1128a978a17SVictor Perevertkin {
1138a978a17SVictor Perevertkin if (Irp->GetParameterPowerType() == SystemPowerState) {
1148a978a17SVictor Perevertkin return ((FxPkgFdo*) This)->DispatchSystemSetPower(Irp);
1158a978a17SVictor Perevertkin }
1168a978a17SVictor Perevertkin else {
1178a978a17SVictor Perevertkin return ((FxPkgFdo*) This)->DispatchDeviceSetPower(Irp);
1188a978a17SVictor Perevertkin }
1198a978a17SVictor Perevertkin }
1208a978a17SVictor Perevertkin
1218a978a17SVictor Perevertkin _Must_inspect_result_
1228a978a17SVictor Perevertkin NTSTATUS
_DispatchQueryPower(__inout FxPkgPnp * This,__in FxIrp * Irp)1238a978a17SVictor Perevertkin FxPkgFdo::_DispatchQueryPower(
1248a978a17SVictor Perevertkin __inout FxPkgPnp* This,
1258a978a17SVictor Perevertkin __in FxIrp *Irp
1268a978a17SVictor Perevertkin )
1278a978a17SVictor Perevertkin
1288a978a17SVictor Perevertkin /*++
1298a978a17SVictor Perevertkin
1308a978a17SVictor Perevertkin Routine Description:
1318a978a17SVictor Perevertkin
1328a978a17SVictor Perevertkin This method is invoked when a QueryPower IRP enters the driver.
1338a978a17SVictor Perevertkin
1348a978a17SVictor Perevertkin Arguemnts:
1358a978a17SVictor Perevertkin
1368a978a17SVictor Perevertkin This - The package
1378a978a17SVictor Perevertkin
1388a978a17SVictor Perevertkin Irp - a pointer to the FxIrp
1398a978a17SVictor Perevertkin
1408a978a17SVictor Perevertkin Returns:
1418a978a17SVictor Perevertkin
1428a978a17SVictor Perevertkin NTSTATUS
1438a978a17SVictor Perevertkin
1448a978a17SVictor Perevertkin --*/
1458a978a17SVictor Perevertkin
1468a978a17SVictor Perevertkin {
1478a978a17SVictor Perevertkin if (Irp->GetParameterPowerType() == SystemPowerState) {
1488a978a17SVictor Perevertkin return ((FxPkgFdo*) This)->DispatchSystemQueryPower(Irp);
1498a978a17SVictor Perevertkin }
1508a978a17SVictor Perevertkin else {
1518a978a17SVictor Perevertkin return ((FxPkgFdo*) This)->DispatchDeviceQueryPower(Irp);
1528a978a17SVictor Perevertkin }
1538a978a17SVictor Perevertkin }
1548a978a17SVictor Perevertkin
1558a978a17SVictor Perevertkin _Must_inspect_result_
1568a978a17SVictor Perevertkin NTSTATUS
157*e55eeb2dSJérôme Gardou STDCALL
_SystemPowerS0Completion(__in MdDeviceObject DeviceObject,__in MdIrp OriginalIrp,__in PVOID Context)1588a978a17SVictor Perevertkin FxPkgFdo::_SystemPowerS0Completion(
1598a978a17SVictor Perevertkin __in MdDeviceObject DeviceObject,
1608a978a17SVictor Perevertkin __in MdIrp OriginalIrp,
1618a978a17SVictor Perevertkin __in PVOID Context
1628a978a17SVictor Perevertkin )
1638a978a17SVictor Perevertkin {
1648a978a17SVictor Perevertkin FxPkgPnp* pPkgPnp;
1658a978a17SVictor Perevertkin KIRQL irql;
1668a978a17SVictor Perevertkin FxIrp irp(OriginalIrp);
1678a978a17SVictor Perevertkin
1688a978a17SVictor Perevertkin pPkgPnp = (FxPkgPnp*) Context;
1698a978a17SVictor Perevertkin
1708a978a17SVictor Perevertkin //
1718a978a17SVictor Perevertkin // Ideally we would like to complete the S0 irp before we start
1728a978a17SVictor Perevertkin // processing the event in the state machine so that the D0 irp
1738a978a17SVictor Perevertkin // comes after the S0 is moving up the stack...
1748a978a17SVictor Perevertkin //
1758a978a17SVictor Perevertkin // ... BUT ...
1768a978a17SVictor Perevertkin //
1778a978a17SVictor Perevertkin // ... by allowing the S0 irp to go up the stack first, we must then
1788a978a17SVictor Perevertkin // handle pnp requests from the current power policy state (because
1798a978a17SVictor Perevertkin // the S0 irp could be the last S irp in the system and when completed,
1808a978a17SVictor Perevertkin // the pnp lock is released). So, we process the event first so
1818a978a17SVictor Perevertkin // that we can move into a state where we can handle pnp events in
1828a978a17SVictor Perevertkin // the power policy state machine.
1838a978a17SVictor Perevertkin //
1848a978a17SVictor Perevertkin // We mitigate the situation a little bit by forcing the processing of the
1858a978a17SVictor Perevertkin // event to occur on the power policy thread rather then in the current
1868a978a17SVictor Perevertkin // context.
1878a978a17SVictor Perevertkin //
1888a978a17SVictor Perevertkin Mx::MxRaiseIrql(DISPATCH_LEVEL, &irql);
1898a978a17SVictor Perevertkin pPkgPnp->PowerPolicyProcessEvent(PwrPolS0);
1908a978a17SVictor Perevertkin Mx::MxLowerIrql(irql);
1918a978a17SVictor Perevertkin
1928a978a17SVictor Perevertkin irp.StartNextPowerIrp();
1938a978a17SVictor Perevertkin
1948a978a17SVictor Perevertkin //
1958a978a17SVictor Perevertkin // Let the irp continue on its way
1968a978a17SVictor Perevertkin //
1978a978a17SVictor Perevertkin if (irp.PendingReturned()) {
1988a978a17SVictor Perevertkin irp.MarkIrpPending();
1998a978a17SVictor Perevertkin }
2008a978a17SVictor Perevertkin
2018a978a17SVictor Perevertkin Mx::MxReleaseRemoveLock((&FxDevice::_GetFxWdmExtension(DeviceObject)->IoRemoveLock),
2028a978a17SVictor Perevertkin OriginalIrp);
2038a978a17SVictor Perevertkin
2048a978a17SVictor Perevertkin return irp.GetStatus();
2058a978a17SVictor Perevertkin }
2068a978a17SVictor Perevertkin
2078a978a17SVictor Perevertkin _Must_inspect_result_
2088a978a17SVictor Perevertkin NTSTATUS
209*e55eeb2dSJérôme Gardou STDCALL
_SystemPowerSxCompletion(__in MdDeviceObject DeviceObject,__in MdIrp OriginalIrp,__in PVOID Context)2108a978a17SVictor Perevertkin FxPkgFdo::_SystemPowerSxCompletion(
2118a978a17SVictor Perevertkin __in MdDeviceObject DeviceObject,
2128a978a17SVictor Perevertkin __in MdIrp OriginalIrp,
2138a978a17SVictor Perevertkin __in PVOID Context
2148a978a17SVictor Perevertkin )
2158a978a17SVictor Perevertkin {
2168a978a17SVictor Perevertkin FxPkgFdo *pThis;
2178a978a17SVictor Perevertkin FxIrp irp(OriginalIrp);
2188a978a17SVictor Perevertkin
2198a978a17SVictor Perevertkin UNREFERENCED_PARAMETER(DeviceObject);
2208a978a17SVictor Perevertkin
2218a978a17SVictor Perevertkin pThis = (FxPkgFdo*) Context;
2228a978a17SVictor Perevertkin
2238a978a17SVictor Perevertkin ASSERT(pThis->IsPowerPolicyOwner());
2248a978a17SVictor Perevertkin ASSERT(OriginalIrp == pThis->GetPendingSystemPowerIrp());
2258a978a17SVictor Perevertkin
2268a978a17SVictor Perevertkin pThis->PowerPolicyProcessEvent(PwrPolSx);
2278a978a17SVictor Perevertkin
2288a978a17SVictor Perevertkin //
2298a978a17SVictor Perevertkin // Power policy will complete the system irp
2308a978a17SVictor Perevertkin //
2318a978a17SVictor Perevertkin return STATUS_MORE_PROCESSING_REQUIRED;
2328a978a17SVictor Perevertkin }
2338a978a17SVictor Perevertkin
2348a978a17SVictor Perevertkin _Must_inspect_result_
2358a978a17SVictor Perevertkin NTSTATUS
DispatchSystemSetPower(__in FxIrp * Irp)2368a978a17SVictor Perevertkin FxPkgFdo::DispatchSystemSetPower(
2378a978a17SVictor Perevertkin __in FxIrp *Irp
2388a978a17SVictor Perevertkin )
2398a978a17SVictor Perevertkin {
2408a978a17SVictor Perevertkin NTSTATUS status;
2418a978a17SVictor Perevertkin MxDeviceObject deviceObject(m_Device->GetDeviceObject());
2428a978a17SVictor Perevertkin
2438a978a17SVictor Perevertkin m_SystemPowerState = (BYTE) Irp->GetParameterPowerStateSystemState();
2448a978a17SVictor Perevertkin deviceObject.SetPowerState(SystemPowerState,
2458a978a17SVictor Perevertkin Irp->GetParameterPowerState());
2468a978a17SVictor Perevertkin
2478a978a17SVictor Perevertkin if (IsPowerPolicyOwner()) {
2488a978a17SVictor Perevertkin //
2498a978a17SVictor Perevertkin // If we are going to S0, we just notify the power policy state machine
2508a978a17SVictor Perevertkin // and then let the request go (per the fast resume spec). Otherwise,
2518a978a17SVictor Perevertkin // send the request down and on the way up, send the Dx request.
2528a978a17SVictor Perevertkin //
2538a978a17SVictor Perevertkin if (m_SystemPowerState == PowerSystemWorking) {
2548a978a17SVictor Perevertkin //
2558a978a17SVictor Perevertkin // Post the event into the state machine when the irp is going up
2568a978a17SVictor Perevertkin // the stack. See the comment in _SystemPowerS0Completion for more
2578a978a17SVictor Perevertkin // detail as to why.
2588a978a17SVictor Perevertkin //
2598a978a17SVictor Perevertkin Irp->CopyCurrentIrpStackLocationToNext();
2608a978a17SVictor Perevertkin Irp->SetCompletionRoutineEx(deviceObject.GetObject(),
2618a978a17SVictor Perevertkin _SystemPowerS0Completion,
2628a978a17SVictor Perevertkin this);
2638a978a17SVictor Perevertkin
2648a978a17SVictor Perevertkin return Irp->PoCallDriver(m_Device->GetAttachedDevice());
2658a978a17SVictor Perevertkin }
2668a978a17SVictor Perevertkin else {
2678a978a17SVictor Perevertkin //
2688a978a17SVictor Perevertkin // Stash away the irp for the power policy state machine. We will
2698a978a17SVictor Perevertkin // post the event to the power policy state machine when the S irp
2708a978a17SVictor Perevertkin // completes back to this driver.
2718a978a17SVictor Perevertkin //
2728a978a17SVictor Perevertkin SetPendingSystemPowerIrp(Irp);
2738a978a17SVictor Perevertkin
2748a978a17SVictor Perevertkin Irp->CopyCurrentIrpStackLocationToNext();
2758a978a17SVictor Perevertkin Irp->SetCompletionRoutineEx(deviceObject.GetObject(),
2768a978a17SVictor Perevertkin _SystemPowerSxCompletion,
2778a978a17SVictor Perevertkin this);
2788a978a17SVictor Perevertkin
2798a978a17SVictor Perevertkin Irp->PoCallDriver(m_Device->GetAttachedDevice());
2808a978a17SVictor Perevertkin
2818a978a17SVictor Perevertkin status = STATUS_PENDING;
2828a978a17SVictor Perevertkin }
2838a978a17SVictor Perevertkin }
2848a978a17SVictor Perevertkin else {
2858a978a17SVictor Perevertkin //
2868a978a17SVictor Perevertkin // We don't do anything with S irps if we are not the power policy
2878a978a17SVictor Perevertkin // owner.
2888a978a17SVictor Perevertkin //
2898a978a17SVictor Perevertkin // This will release the remove lock as well.
2908a978a17SVictor Perevertkin //
2918a978a17SVictor Perevertkin status = _PowerPassDown(this, Irp);
2928a978a17SVictor Perevertkin }
2938a978a17SVictor Perevertkin
2948a978a17SVictor Perevertkin return status;
2958a978a17SVictor Perevertkin }
2968a978a17SVictor Perevertkin
2978a978a17SVictor Perevertkin _Must_inspect_result_
2988a978a17SVictor Perevertkin NTSTATUS
DispatchDeviceSetPower(__in FxIrp * Irp)2998a978a17SVictor Perevertkin FxPkgFdo::DispatchDeviceSetPower(
3008a978a17SVictor Perevertkin __in FxIrp *Irp
3018a978a17SVictor Perevertkin )
3028a978a17SVictor Perevertkin
3038a978a17SVictor Perevertkin {
3048a978a17SVictor Perevertkin NTSTATUS status;
3058a978a17SVictor Perevertkin
3068a978a17SVictor Perevertkin if (IsPowerPolicyOwner()) {
3078a978a17SVictor Perevertkin if (m_PowerPolicyMachine.m_Owner->m_RequestedPowerUpIrp == FALSE &&
3088a978a17SVictor Perevertkin m_PowerPolicyMachine.m_Owner->m_RequestedPowerDownIrp == FALSE) {
3098a978a17SVictor Perevertkin //
3108a978a17SVictor Perevertkin // A power irp arrived, but we did not request it. log and bugcheck
3118a978a17SVictor Perevertkin //
3128a978a17SVictor Perevertkin DoTraceLevelMessage(
3138a978a17SVictor Perevertkin GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGPNP,
3148a978a17SVictor Perevertkin "Received set device power irp 0x%p on WDFDEVICE 0x%p !devobj 0x%p, "
3158a978a17SVictor Perevertkin "but the irp was not requested by the device (the power policy owner)",
3168a978a17SVictor Perevertkin Irp->GetIrp(), m_Device->GetHandle(),
3178a978a17SVictor Perevertkin m_Device->GetDeviceObject());
3188a978a17SVictor Perevertkin
3198a978a17SVictor Perevertkin FxVerifierBugCheck(GetDriverGlobals(), // globals
3208a978a17SVictor Perevertkin WDF_POWER_MULTIPLE_PPO, // specific type
3218a978a17SVictor Perevertkin (ULONG_PTR)m_Device->GetDeviceObject(), //parm 2
3228a978a17SVictor Perevertkin (ULONG_PTR)Irp->GetIrp()); // parm 3
3238a978a17SVictor Perevertkin
3248a978a17SVictor Perevertkin /* NOTREACHED */
3258a978a17SVictor Perevertkin }
3268a978a17SVictor Perevertkin
3278a978a17SVictor Perevertkin //
3288a978a17SVictor Perevertkin // We are no longer requesting a power irp because we received the one
3298a978a17SVictor Perevertkin // we requested.
3308a978a17SVictor Perevertkin //
3318a978a17SVictor Perevertkin if (m_PowerPolicyMachine.m_Owner->m_RequestedPowerUpIrp) {
3328a978a17SVictor Perevertkin m_PowerPolicyMachine.m_Owner->m_RequestedPowerUpIrp = FALSE;
3338a978a17SVictor Perevertkin } else {
3348a978a17SVictor Perevertkin m_PowerPolicyMachine.m_Owner->m_RequestedPowerDownIrp = FALSE;
3358a978a17SVictor Perevertkin }
3368a978a17SVictor Perevertkin }
3378a978a17SVictor Perevertkin
3388a978a17SVictor Perevertkin //
3398a978a17SVictor Perevertkin // Determine if we are raising or lowering the device power state.
3408a978a17SVictor Perevertkin //
3418a978a17SVictor Perevertkin if (Irp->GetParameterPowerStateDeviceState() == PowerDeviceD0) {
3428a978a17SVictor Perevertkin status = RaiseDevicePower(Irp);
3438a978a17SVictor Perevertkin }
3448a978a17SVictor Perevertkin else {
3458a978a17SVictor Perevertkin status = LowerDevicePower(Irp);
3468a978a17SVictor Perevertkin }
3478a978a17SVictor Perevertkin
3488a978a17SVictor Perevertkin return status;
3498a978a17SVictor Perevertkin }
3508a978a17SVictor Perevertkin
3518a978a17SVictor Perevertkin _Must_inspect_result_
3528a978a17SVictor Perevertkin NTSTATUS
RaiseDevicePower(__in FxIrp * Irp)3538a978a17SVictor Perevertkin FxPkgFdo::RaiseDevicePower(
3548a978a17SVictor Perevertkin __in FxIrp *Irp
3558a978a17SVictor Perevertkin )
3568a978a17SVictor Perevertkin {
3578a978a17SVictor Perevertkin Irp->MarkIrpPending();
3588a978a17SVictor Perevertkin Irp->CopyCurrentIrpStackLocationToNext();
3598a978a17SVictor Perevertkin Irp->SetCompletionRoutineEx(m_Device->GetDeviceObject(),
3608a978a17SVictor Perevertkin RaiseDevicePowerCompletion,
3618a978a17SVictor Perevertkin this);
3628a978a17SVictor Perevertkin
3638a978a17SVictor Perevertkin Irp->PoCallDriver(m_Device->GetAttachedDevice());
3648a978a17SVictor Perevertkin
3658a978a17SVictor Perevertkin return STATUS_PENDING;
3668a978a17SVictor Perevertkin }
3678a978a17SVictor Perevertkin
3688a978a17SVictor Perevertkin _Must_inspect_result_
3698a978a17SVictor Perevertkin NTSTATUS
370*e55eeb2dSJérôme Gardou STDCALL
RaiseDevicePowerCompletion(__in MdDeviceObject DeviceObject,__in MdIrp OriginalIrp,__in PVOID Context)3718a978a17SVictor Perevertkin FxPkgFdo::RaiseDevicePowerCompletion(
3728a978a17SVictor Perevertkin __in MdDeviceObject DeviceObject,
3738a978a17SVictor Perevertkin __in MdIrp OriginalIrp,
3748a978a17SVictor Perevertkin __in PVOID Context
3758a978a17SVictor Perevertkin )
3768a978a17SVictor Perevertkin {
3778a978a17SVictor Perevertkin FxPkgFdo* pThis;
3788a978a17SVictor Perevertkin FxIrp irp(OriginalIrp);
3798a978a17SVictor Perevertkin
3808a978a17SVictor Perevertkin UNREFERENCED_PARAMETER(DeviceObject);
3818a978a17SVictor Perevertkin
3828a978a17SVictor Perevertkin pThis = (FxPkgFdo*) Context;
3838a978a17SVictor Perevertkin
3848a978a17SVictor Perevertkin //
3858a978a17SVictor Perevertkin // We can safely cache away the device power irp in our fdo package
3868a978a17SVictor Perevertkin // storage because we know we can only get one device power irp at
3878a978a17SVictor Perevertkin // a time.
3888a978a17SVictor Perevertkin //
3898a978a17SVictor Perevertkin pThis->SetPendingDevicePowerIrp(&irp);
3908a978a17SVictor Perevertkin
3918a978a17SVictor Perevertkin //
3928a978a17SVictor Perevertkin // Kick off the power state machine.
3938a978a17SVictor Perevertkin //
3948a978a17SVictor Perevertkin pThis->PowerProcessEvent(PowerD0);
3958a978a17SVictor Perevertkin
3968a978a17SVictor Perevertkin return STATUS_MORE_PROCESSING_REQUIRED;
3978a978a17SVictor Perevertkin }
3988a978a17SVictor Perevertkin
3998a978a17SVictor Perevertkin _Must_inspect_result_
4008a978a17SVictor Perevertkin NTSTATUS
LowerDevicePower(__in FxIrp * Irp)4018a978a17SVictor Perevertkin FxPkgFdo::LowerDevicePower(
4028a978a17SVictor Perevertkin __in FxIrp *Irp
4038a978a17SVictor Perevertkin )
4048a978a17SVictor Perevertkin {
4058a978a17SVictor Perevertkin SetPendingDevicePowerIrp(Irp);
4068a978a17SVictor Perevertkin
4078a978a17SVictor Perevertkin //
4088a978a17SVictor Perevertkin // Kick off the power state machine.
4098a978a17SVictor Perevertkin //
4108a978a17SVictor Perevertkin PowerProcessEvent(PowerDx);
4118a978a17SVictor Perevertkin
4128a978a17SVictor Perevertkin return STATUS_PENDING;
4138a978a17SVictor Perevertkin }
4148a978a17SVictor Perevertkin
4158a978a17SVictor Perevertkin _Must_inspect_result_
4168a978a17SVictor Perevertkin NTSTATUS
DispatchSystemQueryPower(__in FxIrp * Irp)4178a978a17SVictor Perevertkin FxPkgFdo::DispatchSystemQueryPower(
4188a978a17SVictor Perevertkin __in FxIrp *Irp
4198a978a17SVictor Perevertkin )
4208a978a17SVictor Perevertkin {
4218a978a17SVictor Perevertkin if (PowerPolicyIsWakeEnabled()) {
4228a978a17SVictor Perevertkin NTSTATUS status;
4238a978a17SVictor Perevertkin
4248a978a17SVictor Perevertkin status = PowerPolicyHandleSystemQueryPower(
4258a978a17SVictor Perevertkin Irp->GetParameterPowerStateSystemState()
4268a978a17SVictor Perevertkin );
4278a978a17SVictor Perevertkin
4288a978a17SVictor Perevertkin Irp->SetStatus(status);
4298a978a17SVictor Perevertkin
4308a978a17SVictor Perevertkin if (!NT_SUCCESS(status)) {
4318a978a17SVictor Perevertkin return CompletePowerRequest(Irp, status);
4328a978a17SVictor Perevertkin }
4338a978a17SVictor Perevertkin }
4348a978a17SVictor Perevertkin
4358a978a17SVictor Perevertkin //
4368a978a17SVictor Perevertkin // Passing down the irp because one of the following
4378a978a17SVictor Perevertkin // a) We don't care b/c we don't control the power policy
4388a978a17SVictor Perevertkin // b) we are not enabled for arming for wake from Sx
4398a978a17SVictor Perevertkin // c) we can wake from the queried S state
4408a978a17SVictor Perevertkin //
4418a978a17SVictor Perevertkin return _PowerPassDown(this, Irp);
4428a978a17SVictor Perevertkin }
4438a978a17SVictor Perevertkin
4448a978a17SVictor Perevertkin _Must_inspect_result_
4458a978a17SVictor Perevertkin NTSTATUS
DispatchDeviceQueryPower(__in FxIrp * Irp)4468a978a17SVictor Perevertkin FxPkgFdo::DispatchDeviceQueryPower(
4478a978a17SVictor Perevertkin __in FxIrp *Irp
4488a978a17SVictor Perevertkin )
4498a978a17SVictor Perevertkin {
4508a978a17SVictor Perevertkin //
4518a978a17SVictor Perevertkin // Either the framework is the power policy owner and we wouldn't be sending
4528a978a17SVictor Perevertkin // a device query power or we are a subordinate will do what the power
4538a978a17SVictor Perevertkin // policy owner wants 100% of the time.
4548a978a17SVictor Perevertkin //
4558a978a17SVictor Perevertkin Irp->SetStatus(STATUS_SUCCESS);
4568a978a17SVictor Perevertkin
4578a978a17SVictor Perevertkin //
4588a978a17SVictor Perevertkin // This will release the remove lock
4598a978a17SVictor Perevertkin //
4608a978a17SVictor Perevertkin return _PowerPassDown(this, Irp);
4618a978a17SVictor Perevertkin }
4628a978a17SVictor Perevertkin
4638a978a17SVictor Perevertkin VOID
PowerReleasePendingDeviceIrp(__in BOOLEAN IrpMustBePresent)4648a978a17SVictor Perevertkin FxPkgFdo::PowerReleasePendingDeviceIrp(
4658a978a17SVictor Perevertkin __in BOOLEAN IrpMustBePresent
4668a978a17SVictor Perevertkin )
4678a978a17SVictor Perevertkin {
4688a978a17SVictor Perevertkin MdIrp pIrp;
4698a978a17SVictor Perevertkin
4708a978a17SVictor Perevertkin pIrp = ClearPendingDevicePowerIrp();
4718a978a17SVictor Perevertkin
4728a978a17SVictor Perevertkin UNREFERENCED_PARAMETER(IrpMustBePresent);
4738a978a17SVictor Perevertkin ASSERT(IrpMustBePresent == FALSE || pIrp != NULL);
4748a978a17SVictor Perevertkin
4758a978a17SVictor Perevertkin if (pIrp != NULL) {
4768a978a17SVictor Perevertkin FxIrp irp(pIrp);
4778a978a17SVictor Perevertkin
4788a978a17SVictor Perevertkin if (irp.GetParameterPowerStateDeviceState() == PowerDeviceD0) {
4798a978a17SVictor Perevertkin //
4808a978a17SVictor Perevertkin // We catch D0 irps on the way up, so complete it
4818a978a17SVictor Perevertkin //
4828a978a17SVictor Perevertkin CompletePowerRequest(&irp, STATUS_SUCCESS);
4838a978a17SVictor Perevertkin }
4848a978a17SVictor Perevertkin else {
4858a978a17SVictor Perevertkin irp.SetStatus(STATUS_SUCCESS);
4868a978a17SVictor Perevertkin
4878a978a17SVictor Perevertkin //
4888a978a17SVictor Perevertkin // We catch Dx irps on the way down, so send it on its way
4898a978a17SVictor Perevertkin //
4908a978a17SVictor Perevertkin // This will also release the remove lock
4918a978a17SVictor Perevertkin //
4928a978a17SVictor Perevertkin (void) _PowerPassDown(this, &irp);
4938a978a17SVictor Perevertkin }
4948a978a17SVictor Perevertkin }
4958a978a17SVictor Perevertkin }
4968a978a17SVictor Perevertkin
4978a978a17SVictor Perevertkin WDF_DEVICE_POWER_STATE
PowerCheckDeviceTypeOverload(VOID)4988a978a17SVictor Perevertkin FxPkgFdo::PowerCheckDeviceTypeOverload(
4998a978a17SVictor Perevertkin VOID
5008a978a17SVictor Perevertkin )
5018a978a17SVictor Perevertkin /*++
5028a978a17SVictor Perevertkin
5038a978a17SVictor Perevertkin Routine Description:
5048a978a17SVictor Perevertkin This function implements the Check Type state. This is FDO code,
5058a978a17SVictor Perevertkin so the answer is reductionistly simple.
5068a978a17SVictor Perevertkin
5078a978a17SVictor Perevertkin Arguments:
5088a978a17SVictor Perevertkin none
5098a978a17SVictor Perevertkin
5108a978a17SVictor Perevertkin Return Value:
5118a978a17SVictor Perevertkin
5128a978a17SVictor Perevertkin new power state
5138a978a17SVictor Perevertkin
5148a978a17SVictor Perevertkin --*/
5158a978a17SVictor Perevertkin {
5168a978a17SVictor Perevertkin return WdfDevStatePowerWaking;
5178a978a17SVictor Perevertkin }
5188a978a17SVictor Perevertkin
5198a978a17SVictor Perevertkin WDF_DEVICE_POWER_STATE
PowerCheckDeviceTypeNPOverload(VOID)5208a978a17SVictor Perevertkin FxPkgFdo::PowerCheckDeviceTypeNPOverload(
5218a978a17SVictor Perevertkin VOID
5228a978a17SVictor Perevertkin )
5238a978a17SVictor Perevertkin /*++
5248a978a17SVictor Perevertkin
5258a978a17SVictor Perevertkin Routine Description:
5268a978a17SVictor Perevertkin This function implements the Check Type state. This is FDO code,
5278a978a17SVictor Perevertkin so the answer is reductionistly simple.
5288a978a17SVictor Perevertkin
5298a978a17SVictor Perevertkin Arguments:
5308a978a17SVictor Perevertkin none
5318a978a17SVictor Perevertkin
5328a978a17SVictor Perevertkin Return Value:
5338a978a17SVictor Perevertkin
5348a978a17SVictor Perevertkin new power state
5358a978a17SVictor Perevertkin
5368a978a17SVictor Perevertkin --*/
5378a978a17SVictor Perevertkin {
5388a978a17SVictor Perevertkin return WdfDevStatePowerWakingNP;
5398a978a17SVictor Perevertkin }
5408a978a17SVictor Perevertkin
5418a978a17SVictor Perevertkin _Must_inspect_result_
5428a978a17SVictor Perevertkin NTSTATUS
PowerCheckParentOverload(__out BOOLEAN * ParentOn)5438a978a17SVictor Perevertkin FxPkgFdo::PowerCheckParentOverload(
5448a978a17SVictor Perevertkin __out BOOLEAN* ParentOn
5458a978a17SVictor Perevertkin )
5468a978a17SVictor Perevertkin /*++
5478a978a17SVictor Perevertkin
5488a978a17SVictor Perevertkin Routine Description:
5498a978a17SVictor Perevertkin This function implements the CheckParent state. Its
5508a978a17SVictor Perevertkin job is to determine which state we should go to next based on whether
5518a978a17SVictor Perevertkin the parent is in D0. But since this is the FDO code, we can't know
5528a978a17SVictor Perevertkin that. So just assume that the PDO will guarantee it.
5538a978a17SVictor Perevertkin
5548a978a17SVictor Perevertkin Arguments:
5558a978a17SVictor Perevertkin none
5568a978a17SVictor Perevertkin
5578a978a17SVictor Perevertkin Return Value:
5588a978a17SVictor Perevertkin
5598a978a17SVictor Perevertkin new power state
5608a978a17SVictor Perevertkin
5618a978a17SVictor Perevertkin --*/
5628a978a17SVictor Perevertkin {
5638a978a17SVictor Perevertkin ASSERT(!"This state shouldn't be reachable for an FDO.");
5648a978a17SVictor Perevertkin *ParentOn = TRUE;
5658a978a17SVictor Perevertkin return STATUS_SUCCESS;
5668a978a17SVictor Perevertkin }
5678a978a17SVictor Perevertkin
5688a978a17SVictor Perevertkin VOID
PowerParentPowerDereference(VOID)5698a978a17SVictor Perevertkin FxPkgFdo::PowerParentPowerDereference(
5708a978a17SVictor Perevertkin VOID
5718a978a17SVictor Perevertkin )
5728a978a17SVictor Perevertkin /*++
5738a978a17SVictor Perevertkin
5748a978a17SVictor Perevertkin Routine Description:
5758a978a17SVictor Perevertkin This virtual function is a nop for an FDO. PDOs implement this function
5768a978a17SVictor Perevertkin
5778a978a17SVictor Perevertkin Arguments:
5788a978a17SVictor Perevertkin None
5798a978a17SVictor Perevertkin
5808a978a17SVictor Perevertkin Return Value:
5818a978a17SVictor Perevertkin None
5828a978a17SVictor Perevertkin
5838a978a17SVictor Perevertkin --*/
5848a978a17SVictor Perevertkin {
5858a978a17SVictor Perevertkin DO_NOTHING();
5868a978a17SVictor Perevertkin }
587