ReactOS  0.4.15-dev-3440-g915569a
powerpolicystatemachineum.cpp
Go to the documentation of this file.
1 /*++
2 
3 Copyright (c) Microsoft. All rights reserved.
4 
5 Module Name:
6 
7  PowerPolicyStateMachineUM.cpp
8 
9 Abstract:
10 
11 
12 Environment:
13 
14  User mode only
15 
16 Revision History:
17 
18 --*/
19 
20 #include "../pnppriv.hpp"
21 
22 #include "FxUsbIdleInfo.hpp"
23 
24 extern "C" {
25 #if defined(EVENT_TRACING)
26 #include "PowerPolicyStateMachineUM.tmh"
27 #endif
28 }
29 
30 VOID
32  __in FxIrp* Irp
33  )
34 /*++
35 
36 Routine Description:
37  Gets source of wake if OS supports this.
38 
39 Arguments:
40  Irp
41 
42 Return Value:
43  None
44 
45  --*/
46 {
48 
50 
51  if (m_Device->IsPdo()) {
52 
54 
57  "For PDOs, FxPkgPnp::PowerPolicyUpdateSystemWakeSource should NOT "
58  "be a no-op!");
60  }
61 }
62 
63 BOOLEAN
65  __in KIRQL CurrentIrql,
66  __in BOOLEAN CallerSpecifiedProcessingOnDifferentThread
67  )
68 /*++
69 Routine Description:
70 
71  This function returns whether the power policy state machine should process
72  the current event on the same thread or on a different one.
73 
74  This function has been added to work around a bug in the state machines.
75  The idle state machine always calls PowerPolicyProcessEvent with the idle
76  state machine lock held. Some events sent by the idle state machine can
77  cause the power policy state machine to invoke
78  FxPowerIdleMachine::QueryReturnToIdle().
79  FxPowerIdleMachine::QueryReturnToIdle() will try to acquire the idle state
80  machine lock, which is already being held, so it will result in a recursive
81  acquire of the idle state machine lock.
82 
83  The above bug only affects UMDF, but not KMDF. In KMDF, the idle state
84  machine lock is a spinlock. When PowerPolicyProcessEvent is called, it is
85  called with the spinlock held and hence at dispatch level. Note that if
86  called at a non-passive IRQL, PowerPolicyProcessEvent will always queue a
87  work item to process the event at passive IRQL later. Queuing a work item
88  forces processing to happen on a different thread and hence we don't
89  attempt to recursively acquire the spinlock. On the other hand, with UMDF
90  we are always at passive IRQL and hence we process the event on the same
91  thread and run into the recursive acquire problem.
92 
93 
94 
95 
96 
97 
98 
99 
100 Arguments:
101 
102  CurrentIrql - The current IRQL
103 
104  CallerSpecifiedProcessingOnDifferentThread - Whether or not caller of
105  PowerPolicyProcessEvent specified that the event be processed on a
106  different thread.
107 
108 Returns:
109  TRUE if the power policy state machine should process the event on a
110  different thread.
111 
112  FALSE if the power policy state machine should process the event on the
113  same thread
114 
115 --*/
116 {
117  //
118  // For UMDF, we ignore the IRQL and just do what the caller of
119  // PowerPolicyProcessEvent wants.
120  //
121  UNREFERENCED_PARAMETER(CurrentIrql);
122 
123  return CallerSpecifiedProcessingOnDifferentThread;
124 }
125 
127 NTSTATUS
129  VOID
130  )
131 {
132  HRESULT hr;
134  FxDevice* device;
135  IWudfDeviceStack *devStack;
136 
137  device = ((FxPkgPnp*)m_CallbackInfo.IdleContext)->GetDevice();
138  devStack = device->GetDeviceStack();
139 
140  hr = devStack->InitializeUsbSS();
141  if (S_OK == hr) {
143  }
144  else {
145  PUMDF_VERSION_DATA driverVersion = devStack->GetMinDriverVersion();
146  BOOL preserveCompat =
147  devStack->ShouldPreserveIrpCompletionStatusCompatibility();
148 
149  status = CHostFxUtil::NtStatusFromHr(hr,
150  driverVersion->MajorNumber,
151  driverVersion->MinorNumber,
152  preserveCompat);
153  }
154 
155  return status;
156 }
157 
158 VOID
160  VOID
161  )
162 {
163  //
164  // This will be set to TRUE if USBSS completion event gets dropped.
165  //
167 
168  m_Device->GetDeviceStack()->SubmitUsbIdleNotification(
171  this);
172 }
173 
174 VOID
176  VOID
177  )
178 {
179  m_Device->GetDeviceStack()->CancelUsbSS();
180 }
181 
183 VOID
184 FxUsbIdleInfo::_UsbIdleCallback(
186  )
187 {
188  FxPkgPnp* pPkgPnp;
189 
190  pPkgPnp = (FxPkgPnp*) Context;
191 
194  "Entering USB Selective Suspend Idle callback");
195 
197 }
198 
199 
200 VOID
202  VOID
203  )
204 {
206 
209  "USB Selective Suspend Idle callback processing is complete");
210 
211  device->GetDeviceStack()->SignalUsbSSCallbackProcessingComplete();
212 }
213 
CfxDevice * m_Device
Definition: fxobject.hpp:329
__inline CfxDevice * GetDevice(VOID)
Definition: fxpackage.hpp:46
static MdCompletionRoutineType _PowerPolicyUsbSelectiveSuspendCompletionRoutine
Definition: fxpkgpnp.hpp:2805
HRESULT hr
Definition: shlfolder.c:183
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
LONG NTSTATUS
Definition: precomp.h:26
Definition: fxirp.hpp:28
FxPowerPolicyMachine m_PowerPolicyMachine
Definition: fxpkgpnp.hpp:4153
VOID PowerPolicySubmitUsbIdleNotification(VOID)
FxDevice * device
VOID PowerPolicyCancelUsbSS(VOID)
UCHAR KIRQL
Definition: env_spec_w32.h:591
BOOLEAN m_EventDropped
#define FALSE
Definition: types.h:117
_In_ PIRP Irp
Definition: csq.h:116
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
unsigned int BOOL
Definition: ntddk_ex.h:94
Definition: devices.h:37
USB_IDLE_CALLBACK_INFO m_CallbackInfo
unsigned char BOOLEAN
_Must_inspect_result_ NTSTATUS Initialize(VOID)
FxPkgPnp * pPkgPnp
FxPkgPnp * m_PkgPnp
IWudfDeviceStack * GetDeviceStack(VOID)
Definition: fxdeviceum.hpp:435
FxPowerPolicyOwnerSettings * m_Owner
PFX_DRIVER_GLOBALS pFxDriverGlobals
LONG HRESULT
Definition: typedefs.h:79
VOID PowerPolicyProcessEvent(__in FxPowerPolicyEvent Event, __in BOOLEAN ProcessEventOnDifferentThread=FALSE)
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
#define _Must_inspect_result_
Definition: ms_sal.h:558
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
#define TRACINGPNP
Definition: dbgtrace.h:67
#define S_OK
Definition: intsafe.h:52
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
BOOLEAN ShouldProcessPowerPolicyEventOnDifferentThread(__in KIRQL CurrentIrql, __in BOOLEAN CallerSpecifiedProcessingOnDifferentThread)
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
VOID PowerPolicyUpdateSystemWakeSource(__in FxIrp *Irp)
__drv_maxIRQL(PASSIVE_LEVEL) VOID FxUsbIdleInfo
__inline BOOLEAN IsPdo(VOID)
Definition: fxdevice.hpp:1245
#define STATUS_SUCCESS
Definition: shellext.h:65
#define __in
Definition: dbghelp.h:35
static SERVICE_STATUS status
Definition: service.c:31
FxVerifierDbgBreakPoint(pFxDriverGlobals)
Definition: ps.c:97