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