ReactOS 0.4.15-dev-8102-g108db8f
devicepwrreqstatemachine.cpp
Go to the documentation of this file.
1/*++
2Copyright (c) Microsoft. All rights reserved.
3
4Module Name:
5
6 DevicePwrReq.cpp
7
8Abstract:
9
10 This module implements the device power requirement logic in the framework.
11
12--*/
13
14#include "pnppriv.hpp"
15
16extern "C" {
17#if defined(EVENT_TRACING)
18#include "DevicePwrReqStateMachine.tmh"
19#endif
20}
21
24{
26};
27
30{
34};
35
38{
42};
43
46{
49};
50
53{
55};
56
59{
63};
64
67{
68 // DprUnregistered
69 { NULL,
72 },
73
74 // DprDevicePowerRequiredD0
75 { NULL,
78 },
79
80 // DprDevicePowerNotRequiredD0
84 },
85
86 // DprDevicePowerNotRequiredDx
87 { NULL,
90 },
91
92 // DprDevicePowerRequiredDx
96 },
97
98 // DprReportingDevicePowerAvailable
100 NULL,
101 0,
102 },
103
104 // DprWaitingForDevicePowerRequiredD0
105 { NULL,
108 },
109};
110
112 __in FxPoxInterface * PoxInterface
114{
115 //
116 // Make sure we can fit the state into a byte
117 //
118 C_ASSERT(DprMax <= 0xFF);
119
121
122 RtlZeroMemory(&m_Queue, sizeof(m_Queue));
124
125 //
126 // Store the initial state in the state history array
127 //
129 m_PoxInterface = PoxInterface;
130}
131
132VOID
135 )
136{
138 KIRQL irql;
139 LONGLONG timeout = 0;
140
141 //
142 // Acquire state machine *queue* lock, raising to DISPATCH_LEVEL
143 //
144 Lock(&irql);
145
146 if (IsFull()) {
147 //
148 // The queue is full. This should never happen.
149 //
150 Unlock(irql);
151
152 ASSERTMSG("The device power requirement state machine queue is full\n",
153 FALSE);
154 return;
155 }
156
157 if (IsClosedLocked()) {
158 //
159 // The queue is closed. This should never happen.
160 //
163 "WDFDEVICE 0x%p !devobj 0x%p current device power requirement state"
164 " %!FxDevicePwrRequirementStates! dropping event "
165 "%!FxDevicePwrRequirementEvents! because of a closed queue",
169 Event);
170
171 Unlock(irql);
172
173 ASSERTMSG(
174 "The device power requirement state machine queue is closed\n",
175 FALSE
176 );
177 return;
178 }
179
180 //
181 // Enqueue the event
182 //
184
185 //
186 // Drop the state machine *queue* lock
187 //
188 Unlock(irql);
189
190 //
191 // Now, if we are running at PASSIVE_LEVEL, attempt to run the state machine
192 // on this thread. If we can't do that, then queue a work item.
193 //
194 if (irql == PASSIVE_LEVEL) {
195 //
196 // Try to acquire the state machine lock
197 //
198 status = m_StateMachineLock.AcquireLock(
200 &timeout
201 );
202 if (FxWaitLockInternal::IsLockAcquired(status)) {
204
205 //
206 // We now hold the state machine lock. So call the function that
207 // dispatches the next state.
208 //
210
211 //
212 // The pnp state machine should be the only one deleting the object
213 //
214 ASSERT(info.m_DeleteObject == FALSE);
215
216 //
217 // Release the state machine lock
218 //
219 m_StateMachineLock.ReleaseLock(
221 );
222
223 info.Evaluate(m_PkgPnp);
224
225 return;
226 }
227 }
228
229 //
230 // For one reason or another, we couldn't run the state machine on this
231 // thread. So queue a work item to do it.
232 //
234 return;
235}
236
237VOID
239 __inout FxPkgPnp* PkgPnp,
241 __in PVOID WorkerContext
242 )
243{
245
246 UNREFERENCED_PARAMETER(WorkerContext);
247
248 pThis = PkgPnp->m_PowerPolicyMachine.m_Owner->
250
251 //
252 // Take the state machine lock.
253 //
254 pThis->m_StateMachineLock.AcquireLock(
256 );
257
258 //
259 // Call the function that will actually run the state machine.
260 //
261 pThis->ProcessEventInner(Info);
262
263 //
264 // We are being called from the work item and m_WorkItemRunning is > 0, so
265 // we cannot be deleted yet.
266 //
267 ASSERT(Info->SomethingToDo() == FALSE);
268
269 //
270 // Now release the state machine lock
271 //
272 pThis->m_StateMachineLock.ReleaseLock(
274 );
275
276 return;
277}
278
279VOID
282 )
283{
284 KIRQL irql;
288
289 //
290 // Process as many events as we can
291 //
292 for ( ; ; ) {
293 //
294 // Acquire state machine *queue* lock
295 //
296 Lock(&irql);
297
298 if (IsEmpty()) {
299 //
300 // The queue is empty.
301 //
303 Unlock(irql);
304 return;
305 }
306
307 //
308 // Get the event from the queue
309 //
310 event = m_Queue[GetHead()];
312
313 //
314 // Drop the state machine *queue* lock
315 //
316 Unlock(irql);
317
318 //
319 // Get the state table entry for the current state
320 //
321 // NOTE: Prefast complains about buffer overflow if (m_CurrentState ==
322 // DprMax), but that should never happen because DprMax is not a real
323 // state. We just use it to represent the maximum value in the enum that
324 // defines the states.
325 //
328
329 //
330 // Based on the event received, figure out the next state
331 //
332 newState = DprMax;
333 for (ULONG i = 0; i < entry->TargetStatesCount; i++) {
334 if (entry->TargetStates[i].DprEvent == event) {
335 DO_EVENT_TRAP(&entry->TargetStates[i]);
336 newState = entry->TargetStates[i].DprState;
337 break;
338 }
339 }
340
341 if (newState == DprMax) {
342 //
343 // Unexpected event for this state
344 //
349 "WDFDEVICE 0x%p !devobj 0x%p device power requirement state "
350 "%!FxDevicePwrRequirementStates! dropping event "
351 "%!FxDevicePwrRequirementEvents!",
355 event
356 );
357
359 }
360
361 while (newState != DprMax) {
366 "WDFDEVICE 0x%p !devobj 0x%p entering device power requirement "
367 "state %!FxDevicePwrRequirementStates! from "
368 "%!FxDevicePwrRequirementStates!",
371 newState,
373 );
374
375 //
376 // Update the state history array
377 //
379
380 //
381 // Move to the new state
382 //
383 m_CurrentState = (BYTE) newState;
385
386 //
387 // Invoke the state entry function (if present) for the new state
388 //
389 if (entry->StateFunc != NULL) {
390 newState = entry->StateFunc(this);
391 }
392 else {
393 newState = DprMax;
394 }
395 }
396 }
397
398 return;
399}
400
404 )
405{
406 This->m_PoxInterface->PkgPnp()->PowerPolicyProcessEvent(
408 );
409 return DprMax;
410}
411
415 )
416{
417 This->m_PoxInterface->PkgPnp()->PowerPolicyProcessEvent(
419 );
420 return DprMax;
421}
422
426 )
427{
428 This->m_PoxInterface->PoxReportDevicePoweredOn();
430}
LONG NTSTATUS
Definition: precomp.h:26
#define ARRAY_SIZE(A)
Definition: main.h:33
WDFDEVICE __inline GetHandle(VOID)
Definition: fxdevice.hpp:237
MdDeviceObject __inline GetDeviceObject(VOID)
Definition: fxdevice.hpp:174
static FxDevicePwrRequirementStates PowerRequiredDx(__in FxDevicePwrRequirementMachine *This)
FxDevicePwrRequirementMachineStateHistory m_States
static const FxDevicePwrRequirementTargetState m_UnregisteredStates[]
static const FxDevicePwrRequirementTargetState m_DevicePowerRequiredD0States[]
static FxDevicePwrRequirementStates PowerNotRequiredD0(__in FxDevicePwrRequirementMachine *This)
static FxDevicePwrRequirementStates ReportingDevicePowerAvailable(__in FxDevicePwrRequirementMachine *This)
FxDevicePwrRequirementMachine(__in FxPoxInterface *PoxInterface)
static const FxDevicePwrRequirementTargetState m_DevicePowerNotRequiredDxStates[]
static const FxDevicePwrRequirementTargetState m_DevicePowerRequiredDxStates[]
static const FxDevicePwrRequirementTargetState m_WaitingForDevicePowerRequiredD0States[]
FxDevicePwrRequirementEvents m_Queue[FxDevicePwrRequirementEventQueueDepth]
static VOID _ProcessEventInner(__inout FxPkgPnp *PkgPnp, __inout FxPostProcessInfo *Info, __in PVOID WorkerContext)
VOID ProcessEvent(__in FxDevicePwrRequirementEvents Event)
VOID ProcessEventInner(__inout FxPostProcessInfo *Info)
static const FxDevicePwrRequirementTargetState m_DevicePowerNotRequiredD0States[]
static const FxDevicePwrRequirementStateTable m_StateTable[]
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
__inline CfxDevice * GetDevice(VOID)
Definition: fxpackage.hpp:46
FxDevicePwrRequirementMachine * m_DevicePowerRequirementMachine
FxPkgPnp * PkgPnp(VOID)
FxPkgPnp * m_PkgPnp
#define __in
Definition: dbghelp.h:35
#define __inout
Definition: dbghelp.h:50
#define TRACINGPNPPOWERSTATES
Definition: dbgtrace.h:69
#define TRACINGPNP
Definition: dbgtrace.h:67
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
@ IsEmpty
Definition: atl_ax.c:995
KIRQL irql
Definition: wave.h:1
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
UCHAR KIRQL
Definition: env_spec_w32.h:591
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
@ DprDevicePowerRequiredD0
@ DprDevicePowerNotRequiredD0
@ DprDevicePowerNotRequiredDx
@ DprWaitingForDevicePowerRequiredD0
@ DprDevicePowerRequiredDx
@ DprReportingDevicePowerAvailable
@ DprEventDeviceReturnedToD0
@ DprEventPoxDoesNotRequirePower
@ DprEventRegisteredWithPox
@ DprEventUnregisteredWithPox
@ DprEventPoxRequiresPower
const UCHAR FxDevicePwrRequirementEventQueueDepth
#define COVERAGE_TRAP()
Definition: fxmacros.hpp:246
#define DO_EVENT_TRAP(x)
Definition: fxpkgpnp.hpp:61
#define DEBUGGED_EVENT
Definition: fxpkgpnp.hpp:59
#define TRAP_ON_EVENT
Definition: fxpkgpnp.hpp:60
@ PwrPolDevicePowerNotRequired
@ PwrPolDevicePowerRequired
struct _cl_event * event
Definition: glext.h:7739
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define C_ASSERT(e)
Definition: intsafe.h:73
uint32_t entry
Definition: isohybrid.c:63
#define ASSERT(a)
Definition: mode.c:44
#define __analysis_assume(expr)
Definition: ms_sal.h:2893
#define ASSERTMSG(msg, exp)
Definition: nt_native.h:431
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
@ Unlock
Definition: ntsecapi.h:294
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
VOID IncrementHead(VOID)
UCHAR IncrementHistoryIndex(VOID)
UCHAR InsertAtTail(VOID)
FxPkgPnp * m_PkgPnp
FxWaitLockInternal m_StateMachineLock
BOOLEAN IsClosedLocked(VOID)
UCHAR GetHead(VOID)
VOID GetFinishedState(__inout FxPostProcessInfo *Info)
BOOLEAN IsFull(VOID)
Definition: ps.c:97
Definition: dhcpd.h:245
int64_t LONGLONG
Definition: typedefs.h:68
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG
Definition: typedefs.h:59
UCHAR History[FxDevicePwrRequirementEventQueueDepth]
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:690
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:127
unsigned char UCHAR
Definition: xmlstorage.h:181
unsigned char BYTE
Definition: xxhash.c:193