1*8a978a17SVictor Perevertkin /*++
2*8a978a17SVictor Perevertkin Copyright (c) Microsoft. All rights reserved.
3*8a978a17SVictor Perevertkin
4*8a978a17SVictor Perevertkin Module Name:
5*8a978a17SVictor Perevertkin
6*8a978a17SVictor Perevertkin DevicePwrReq.cpp
7*8a978a17SVictor Perevertkin
8*8a978a17SVictor Perevertkin Abstract:
9*8a978a17SVictor Perevertkin
10*8a978a17SVictor Perevertkin This module implements the device power requirement logic in the framework.
11*8a978a17SVictor Perevertkin
12*8a978a17SVictor Perevertkin --*/
13*8a978a17SVictor Perevertkin
14*8a978a17SVictor Perevertkin #include "pnppriv.hpp"
15*8a978a17SVictor Perevertkin
16*8a978a17SVictor Perevertkin extern "C" {
17*8a978a17SVictor Perevertkin #if defined(EVENT_TRACING)
18*8a978a17SVictor Perevertkin #include "DevicePwrReqStateMachine.tmh"
19*8a978a17SVictor Perevertkin #endif
20*8a978a17SVictor Perevertkin }
21*8a978a17SVictor Perevertkin
22*8a978a17SVictor Perevertkin const FxDevicePwrRequirementTargetState
23*8a978a17SVictor Perevertkin FxDevicePwrRequirementMachine::m_UnregisteredStates[] =
24*8a978a17SVictor Perevertkin {
25*8a978a17SVictor Perevertkin {DprEventRegisteredWithPox, DprDevicePowerRequiredD0 DEBUGGED_EVENT}
26*8a978a17SVictor Perevertkin };
27*8a978a17SVictor Perevertkin
28*8a978a17SVictor Perevertkin const FxDevicePwrRequirementTargetState
29*8a978a17SVictor Perevertkin FxDevicePwrRequirementMachine::m_DevicePowerRequiredD0States[] =
30*8a978a17SVictor Perevertkin {
31*8a978a17SVictor Perevertkin {DprEventPoxDoesNotRequirePower, DprDevicePowerNotRequiredD0 DEBUGGED_EVENT},
32*8a978a17SVictor Perevertkin {DprEventUnregisteredWithPox, DprUnregistered DEBUGGED_EVENT},
33*8a978a17SVictor Perevertkin {DprEventDeviceReturnedToD0, DprDevicePowerRequiredD0 DEBUGGED_EVENT}
34*8a978a17SVictor Perevertkin };
35*8a978a17SVictor Perevertkin
36*8a978a17SVictor Perevertkin const FxDevicePwrRequirementTargetState
37*8a978a17SVictor Perevertkin FxDevicePwrRequirementMachine::m_DevicePowerNotRequiredD0States[] =
38*8a978a17SVictor Perevertkin {
39*8a978a17SVictor Perevertkin {DprEventDeviceGoingToDx, DprDevicePowerNotRequiredDx DEBUGGED_EVENT},
40*8a978a17SVictor Perevertkin {DprEventPoxRequiresPower, DprReportingDevicePowerAvailable DEBUGGED_EVENT},
41*8a978a17SVictor Perevertkin {DprEventUnregisteredWithPox, DprUnregistered TRAP_ON_EVENT}
42*8a978a17SVictor Perevertkin };
43*8a978a17SVictor Perevertkin
44*8a978a17SVictor Perevertkin const FxDevicePwrRequirementTargetState
45*8a978a17SVictor Perevertkin FxDevicePwrRequirementMachine::m_DevicePowerNotRequiredDxStates[] =
46*8a978a17SVictor Perevertkin {
47*8a978a17SVictor Perevertkin {DprEventDeviceReturnedToD0, DprWaitingForDevicePowerRequiredD0 DEBUGGED_EVENT},
48*8a978a17SVictor Perevertkin {DprEventPoxRequiresPower, DprDevicePowerRequiredDx DEBUGGED_EVENT}
49*8a978a17SVictor Perevertkin };
50*8a978a17SVictor Perevertkin
51*8a978a17SVictor Perevertkin const FxDevicePwrRequirementTargetState
52*8a978a17SVictor Perevertkin FxDevicePwrRequirementMachine::m_DevicePowerRequiredDxStates[] =
53*8a978a17SVictor Perevertkin {
54*8a978a17SVictor Perevertkin {DprEventDeviceReturnedToD0, DprReportingDevicePowerAvailable DEBUGGED_EVENT}
55*8a978a17SVictor Perevertkin };
56*8a978a17SVictor Perevertkin
57*8a978a17SVictor Perevertkin const FxDevicePwrRequirementTargetState
58*8a978a17SVictor Perevertkin FxDevicePwrRequirementMachine::m_WaitingForDevicePowerRequiredD0States[] =
59*8a978a17SVictor Perevertkin {
60*8a978a17SVictor Perevertkin {DprEventPoxRequiresPower, DprReportingDevicePowerAvailable DEBUGGED_EVENT},
61*8a978a17SVictor Perevertkin {DprEventDeviceReturnedToD0, DprWaitingForDevicePowerRequiredD0 TRAP_ON_EVENT},
62*8a978a17SVictor Perevertkin {DprEventUnregisteredWithPox, DprUnregistered DEBUGGED_EVENT},
63*8a978a17SVictor Perevertkin };
64*8a978a17SVictor Perevertkin
65*8a978a17SVictor Perevertkin const FxDevicePwrRequirementStateTable
66*8a978a17SVictor Perevertkin FxDevicePwrRequirementMachine::m_StateTable[] =
67*8a978a17SVictor Perevertkin {
68*8a978a17SVictor Perevertkin // DprUnregistered
69*8a978a17SVictor Perevertkin { NULL,
70*8a978a17SVictor Perevertkin FxDevicePwrRequirementMachine::m_UnregisteredStates,
71*8a978a17SVictor Perevertkin ARRAY_SIZE(FxDevicePwrRequirementMachine::m_UnregisteredStates),
72*8a978a17SVictor Perevertkin },
73*8a978a17SVictor Perevertkin
74*8a978a17SVictor Perevertkin // DprDevicePowerRequiredD0
75*8a978a17SVictor Perevertkin { NULL,
76*8a978a17SVictor Perevertkin FxDevicePwrRequirementMachine::m_DevicePowerRequiredD0States,
77*8a978a17SVictor Perevertkin ARRAY_SIZE(FxDevicePwrRequirementMachine::m_DevicePowerRequiredD0States),
78*8a978a17SVictor Perevertkin },
79*8a978a17SVictor Perevertkin
80*8a978a17SVictor Perevertkin // DprDevicePowerNotRequiredD0
81*8a978a17SVictor Perevertkin { FxDevicePwrRequirementMachine::PowerNotRequiredD0,
82*8a978a17SVictor Perevertkin FxDevicePwrRequirementMachine::m_DevicePowerNotRequiredD0States,
83*8a978a17SVictor Perevertkin ARRAY_SIZE(FxDevicePwrRequirementMachine::m_DevicePowerNotRequiredD0States),
84*8a978a17SVictor Perevertkin },
85*8a978a17SVictor Perevertkin
86*8a978a17SVictor Perevertkin // DprDevicePowerNotRequiredDx
87*8a978a17SVictor Perevertkin { NULL,
88*8a978a17SVictor Perevertkin FxDevicePwrRequirementMachine::m_DevicePowerNotRequiredDxStates,
89*8a978a17SVictor Perevertkin ARRAY_SIZE(FxDevicePwrRequirementMachine::m_DevicePowerNotRequiredDxStates),
90*8a978a17SVictor Perevertkin },
91*8a978a17SVictor Perevertkin
92*8a978a17SVictor Perevertkin // DprDevicePowerRequiredDx
93*8a978a17SVictor Perevertkin { FxDevicePwrRequirementMachine::PowerRequiredDx,
94*8a978a17SVictor Perevertkin FxDevicePwrRequirementMachine::m_DevicePowerRequiredDxStates,
95*8a978a17SVictor Perevertkin ARRAY_SIZE(FxDevicePwrRequirementMachine::m_DevicePowerRequiredDxStates),
96*8a978a17SVictor Perevertkin },
97*8a978a17SVictor Perevertkin
98*8a978a17SVictor Perevertkin // DprReportingDevicePowerAvailable
99*8a978a17SVictor Perevertkin { FxDevicePwrRequirementMachine::ReportingDevicePowerAvailable,
100*8a978a17SVictor Perevertkin NULL,
101*8a978a17SVictor Perevertkin 0,
102*8a978a17SVictor Perevertkin },
103*8a978a17SVictor Perevertkin
104*8a978a17SVictor Perevertkin // DprWaitingForDevicePowerRequiredD0
105*8a978a17SVictor Perevertkin { NULL,
106*8a978a17SVictor Perevertkin FxDevicePwrRequirementMachine::m_WaitingForDevicePowerRequiredD0States,
107*8a978a17SVictor Perevertkin ARRAY_SIZE(FxDevicePwrRequirementMachine::m_WaitingForDevicePowerRequiredD0States),
108*8a978a17SVictor Perevertkin },
109*8a978a17SVictor Perevertkin };
110*8a978a17SVictor Perevertkin
FxDevicePwrRequirementMachine(__in FxPoxInterface * PoxInterface)111*8a978a17SVictor Perevertkin FxDevicePwrRequirementMachine::FxDevicePwrRequirementMachine(
112*8a978a17SVictor Perevertkin __in FxPoxInterface * PoxInterface
113*8a978a17SVictor Perevertkin ) : FxThreadedEventQueue(FxDevicePwrRequirementEventQueueDepth)
114*8a978a17SVictor Perevertkin {
115*8a978a17SVictor Perevertkin //
116*8a978a17SVictor Perevertkin // Make sure we can fit the state into a byte
117*8a978a17SVictor Perevertkin //
118*8a978a17SVictor Perevertkin C_ASSERT(DprMax <= 0xFF);
119*8a978a17SVictor Perevertkin
120*8a978a17SVictor Perevertkin m_CurrentState = DprUnregistered;
121*8a978a17SVictor Perevertkin
122*8a978a17SVictor Perevertkin RtlZeroMemory(&m_Queue, sizeof(m_Queue));
123*8a978a17SVictor Perevertkin RtlZeroMemory(&m_States, sizeof(m_States));
124*8a978a17SVictor Perevertkin
125*8a978a17SVictor Perevertkin //
126*8a978a17SVictor Perevertkin // Store the initial state in the state history array
127*8a978a17SVictor Perevertkin //
128*8a978a17SVictor Perevertkin m_States.History[IncrementHistoryIndex()] = m_CurrentState;
129*8a978a17SVictor Perevertkin m_PoxInterface = PoxInterface;
130*8a978a17SVictor Perevertkin }
131*8a978a17SVictor Perevertkin
132*8a978a17SVictor Perevertkin VOID
ProcessEvent(__in FxDevicePwrRequirementEvents Event)133*8a978a17SVictor Perevertkin FxDevicePwrRequirementMachine::ProcessEvent(
134*8a978a17SVictor Perevertkin __in FxDevicePwrRequirementEvents Event
135*8a978a17SVictor Perevertkin )
136*8a978a17SVictor Perevertkin {
137*8a978a17SVictor Perevertkin NTSTATUS status;
138*8a978a17SVictor Perevertkin KIRQL irql;
139*8a978a17SVictor Perevertkin LONGLONG timeout = 0;
140*8a978a17SVictor Perevertkin
141*8a978a17SVictor Perevertkin //
142*8a978a17SVictor Perevertkin // Acquire state machine *queue* lock, raising to DISPATCH_LEVEL
143*8a978a17SVictor Perevertkin //
144*8a978a17SVictor Perevertkin Lock(&irql);
145*8a978a17SVictor Perevertkin
146*8a978a17SVictor Perevertkin if (IsFull()) {
147*8a978a17SVictor Perevertkin //
148*8a978a17SVictor Perevertkin // The queue is full. This should never happen.
149*8a978a17SVictor Perevertkin //
150*8a978a17SVictor Perevertkin Unlock(irql);
151*8a978a17SVictor Perevertkin
152*8a978a17SVictor Perevertkin ASSERTMSG("The device power requirement state machine queue is full\n",
153*8a978a17SVictor Perevertkin FALSE);
154*8a978a17SVictor Perevertkin return;
155*8a978a17SVictor Perevertkin }
156*8a978a17SVictor Perevertkin
157*8a978a17SVictor Perevertkin if (IsClosedLocked()) {
158*8a978a17SVictor Perevertkin //
159*8a978a17SVictor Perevertkin // The queue is closed. This should never happen.
160*8a978a17SVictor Perevertkin //
161*8a978a17SVictor Perevertkin DoTraceLevelMessage(
162*8a978a17SVictor Perevertkin m_PkgPnp->GetDriverGlobals(), TRACE_LEVEL_INFORMATION, TRACINGPNP,
163*8a978a17SVictor Perevertkin "WDFDEVICE 0x%p !devobj 0x%p current device power requirement state"
164*8a978a17SVictor Perevertkin " %!FxDevicePwrRequirementStates! dropping event "
165*8a978a17SVictor Perevertkin "%!FxDevicePwrRequirementEvents! because of a closed queue",
166*8a978a17SVictor Perevertkin m_PoxInterface->m_PkgPnp->GetDevice()->GetHandle(),
167*8a978a17SVictor Perevertkin m_PoxInterface->m_PkgPnp->GetDevice()->GetDeviceObject(),
168*8a978a17SVictor Perevertkin m_CurrentState,
169*8a978a17SVictor Perevertkin Event);
170*8a978a17SVictor Perevertkin
171*8a978a17SVictor Perevertkin Unlock(irql);
172*8a978a17SVictor Perevertkin
173*8a978a17SVictor Perevertkin ASSERTMSG(
174*8a978a17SVictor Perevertkin "The device power requirement state machine queue is closed\n",
175*8a978a17SVictor Perevertkin FALSE
176*8a978a17SVictor Perevertkin );
177*8a978a17SVictor Perevertkin return;
178*8a978a17SVictor Perevertkin }
179*8a978a17SVictor Perevertkin
180*8a978a17SVictor Perevertkin //
181*8a978a17SVictor Perevertkin // Enqueue the event
182*8a978a17SVictor Perevertkin //
183*8a978a17SVictor Perevertkin m_Queue[InsertAtTail()] = Event;
184*8a978a17SVictor Perevertkin
185*8a978a17SVictor Perevertkin //
186*8a978a17SVictor Perevertkin // Drop the state machine *queue* lock
187*8a978a17SVictor Perevertkin //
188*8a978a17SVictor Perevertkin Unlock(irql);
189*8a978a17SVictor Perevertkin
190*8a978a17SVictor Perevertkin //
191*8a978a17SVictor Perevertkin // Now, if we are running at PASSIVE_LEVEL, attempt to run the state machine
192*8a978a17SVictor Perevertkin // on this thread. If we can't do that, then queue a work item.
193*8a978a17SVictor Perevertkin //
194*8a978a17SVictor Perevertkin if (irql == PASSIVE_LEVEL) {
195*8a978a17SVictor Perevertkin //
196*8a978a17SVictor Perevertkin // Try to acquire the state machine lock
197*8a978a17SVictor Perevertkin //
198*8a978a17SVictor Perevertkin status = m_StateMachineLock.AcquireLock(
199*8a978a17SVictor Perevertkin m_PoxInterface->m_PkgPnp->GetDriverGlobals(),
200*8a978a17SVictor Perevertkin &timeout
201*8a978a17SVictor Perevertkin );
202*8a978a17SVictor Perevertkin if (FxWaitLockInternal::IsLockAcquired(status)) {
203*8a978a17SVictor Perevertkin FxPostProcessInfo info;
204*8a978a17SVictor Perevertkin
205*8a978a17SVictor Perevertkin //
206*8a978a17SVictor Perevertkin // We now hold the state machine lock. So call the function that
207*8a978a17SVictor Perevertkin // dispatches the next state.
208*8a978a17SVictor Perevertkin //
209*8a978a17SVictor Perevertkin ProcessEventInner(&info);
210*8a978a17SVictor Perevertkin
211*8a978a17SVictor Perevertkin //
212*8a978a17SVictor Perevertkin // The pnp state machine should be the only one deleting the object
213*8a978a17SVictor Perevertkin //
214*8a978a17SVictor Perevertkin ASSERT(info.m_DeleteObject == FALSE);
215*8a978a17SVictor Perevertkin
216*8a978a17SVictor Perevertkin //
217*8a978a17SVictor Perevertkin // Release the state machine lock
218*8a978a17SVictor Perevertkin //
219*8a978a17SVictor Perevertkin m_StateMachineLock.ReleaseLock(
220*8a978a17SVictor Perevertkin m_PoxInterface->m_PkgPnp->GetDriverGlobals()
221*8a978a17SVictor Perevertkin );
222*8a978a17SVictor Perevertkin
223*8a978a17SVictor Perevertkin info.Evaluate(m_PkgPnp);
224*8a978a17SVictor Perevertkin
225*8a978a17SVictor Perevertkin return;
226*8a978a17SVictor Perevertkin }
227*8a978a17SVictor Perevertkin }
228*8a978a17SVictor Perevertkin
229*8a978a17SVictor Perevertkin //
230*8a978a17SVictor Perevertkin // For one reason or another, we couldn't run the state machine on this
231*8a978a17SVictor Perevertkin // thread. So queue a work item to do it.
232*8a978a17SVictor Perevertkin //
233*8a978a17SVictor Perevertkin QueueToThread();
234*8a978a17SVictor Perevertkin return;
235*8a978a17SVictor Perevertkin }
236*8a978a17SVictor Perevertkin
237*8a978a17SVictor Perevertkin VOID
_ProcessEventInner(__inout FxPkgPnp * PkgPnp,__inout FxPostProcessInfo * Info,__in PVOID WorkerContext)238*8a978a17SVictor Perevertkin FxDevicePwrRequirementMachine::_ProcessEventInner(
239*8a978a17SVictor Perevertkin __inout FxPkgPnp* PkgPnp,
240*8a978a17SVictor Perevertkin __inout FxPostProcessInfo* Info,
241*8a978a17SVictor Perevertkin __in PVOID WorkerContext
242*8a978a17SVictor Perevertkin )
243*8a978a17SVictor Perevertkin {
244*8a978a17SVictor Perevertkin FxDevicePwrRequirementMachine * pThis = NULL;
245*8a978a17SVictor Perevertkin
246*8a978a17SVictor Perevertkin UNREFERENCED_PARAMETER(WorkerContext);
247*8a978a17SVictor Perevertkin
248*8a978a17SVictor Perevertkin pThis = PkgPnp->m_PowerPolicyMachine.m_Owner->
249*8a978a17SVictor Perevertkin m_PoxInterface.m_DevicePowerRequirementMachine;
250*8a978a17SVictor Perevertkin
251*8a978a17SVictor Perevertkin //
252*8a978a17SVictor Perevertkin // Take the state machine lock.
253*8a978a17SVictor Perevertkin //
254*8a978a17SVictor Perevertkin pThis->m_StateMachineLock.AcquireLock(
255*8a978a17SVictor Perevertkin pThis->m_PoxInterface->m_PkgPnp->GetDriverGlobals()
256*8a978a17SVictor Perevertkin );
257*8a978a17SVictor Perevertkin
258*8a978a17SVictor Perevertkin //
259*8a978a17SVictor Perevertkin // Call the function that will actually run the state machine.
260*8a978a17SVictor Perevertkin //
261*8a978a17SVictor Perevertkin pThis->ProcessEventInner(Info);
262*8a978a17SVictor Perevertkin
263*8a978a17SVictor Perevertkin //
264*8a978a17SVictor Perevertkin // We are being called from the work item and m_WorkItemRunning is > 0, so
265*8a978a17SVictor Perevertkin // we cannot be deleted yet.
266*8a978a17SVictor Perevertkin //
267*8a978a17SVictor Perevertkin ASSERT(Info->SomethingToDo() == FALSE);
268*8a978a17SVictor Perevertkin
269*8a978a17SVictor Perevertkin //
270*8a978a17SVictor Perevertkin // Now release the state machine lock
271*8a978a17SVictor Perevertkin //
272*8a978a17SVictor Perevertkin pThis->m_StateMachineLock.ReleaseLock(
273*8a978a17SVictor Perevertkin pThis->m_PoxInterface->m_PkgPnp->GetDriverGlobals()
274*8a978a17SVictor Perevertkin );
275*8a978a17SVictor Perevertkin
276*8a978a17SVictor Perevertkin return;
277*8a978a17SVictor Perevertkin }
278*8a978a17SVictor Perevertkin
279*8a978a17SVictor Perevertkin VOID
ProcessEventInner(__inout FxPostProcessInfo * Info)280*8a978a17SVictor Perevertkin FxDevicePwrRequirementMachine::ProcessEventInner(
281*8a978a17SVictor Perevertkin __inout FxPostProcessInfo* Info
282*8a978a17SVictor Perevertkin )
283*8a978a17SVictor Perevertkin {
284*8a978a17SVictor Perevertkin KIRQL irql;
285*8a978a17SVictor Perevertkin FxDevicePwrRequirementEvents event;
286*8a978a17SVictor Perevertkin const FxDevicePwrRequirementStateTable* entry;
287*8a978a17SVictor Perevertkin FxDevicePwrRequirementStates newState;
288*8a978a17SVictor Perevertkin
289*8a978a17SVictor Perevertkin //
290*8a978a17SVictor Perevertkin // Process as many events as we can
291*8a978a17SVictor Perevertkin //
292*8a978a17SVictor Perevertkin for ( ; ; ) {
293*8a978a17SVictor Perevertkin //
294*8a978a17SVictor Perevertkin // Acquire state machine *queue* lock
295*8a978a17SVictor Perevertkin //
296*8a978a17SVictor Perevertkin Lock(&irql);
297*8a978a17SVictor Perevertkin
298*8a978a17SVictor Perevertkin if (IsEmpty()) {
299*8a978a17SVictor Perevertkin //
300*8a978a17SVictor Perevertkin // The queue is empty.
301*8a978a17SVictor Perevertkin //
302*8a978a17SVictor Perevertkin GetFinishedState(Info);
303*8a978a17SVictor Perevertkin Unlock(irql);
304*8a978a17SVictor Perevertkin return;
305*8a978a17SVictor Perevertkin }
306*8a978a17SVictor Perevertkin
307*8a978a17SVictor Perevertkin //
308*8a978a17SVictor Perevertkin // Get the event from the queue
309*8a978a17SVictor Perevertkin //
310*8a978a17SVictor Perevertkin event = m_Queue[GetHead()];
311*8a978a17SVictor Perevertkin IncrementHead();
312*8a978a17SVictor Perevertkin
313*8a978a17SVictor Perevertkin //
314*8a978a17SVictor Perevertkin // Drop the state machine *queue* lock
315*8a978a17SVictor Perevertkin //
316*8a978a17SVictor Perevertkin Unlock(irql);
317*8a978a17SVictor Perevertkin
318*8a978a17SVictor Perevertkin //
319*8a978a17SVictor Perevertkin // Get the state table entry for the current state
320*8a978a17SVictor Perevertkin //
321*8a978a17SVictor Perevertkin // NOTE: Prefast complains about buffer overflow if (m_CurrentState ==
322*8a978a17SVictor Perevertkin // DprMax), but that should never happen because DprMax is not a real
323*8a978a17SVictor Perevertkin // state. We just use it to represent the maximum value in the enum that
324*8a978a17SVictor Perevertkin // defines the states.
325*8a978a17SVictor Perevertkin //
326*8a978a17SVictor Perevertkin __analysis_assume(m_CurrentState < DprMax);
327*8a978a17SVictor Perevertkin entry = &m_StateTable[m_CurrentState - DprUnregistered];
328*8a978a17SVictor Perevertkin
329*8a978a17SVictor Perevertkin //
330*8a978a17SVictor Perevertkin // Based on the event received, figure out the next state
331*8a978a17SVictor Perevertkin //
332*8a978a17SVictor Perevertkin newState = DprMax;
333*8a978a17SVictor Perevertkin for (ULONG i = 0; i < entry->TargetStatesCount; i++) {
334*8a978a17SVictor Perevertkin if (entry->TargetStates[i].DprEvent == event) {
335*8a978a17SVictor Perevertkin DO_EVENT_TRAP(&entry->TargetStates[i]);
336*8a978a17SVictor Perevertkin newState = entry->TargetStates[i].DprState;
337*8a978a17SVictor Perevertkin break;
338*8a978a17SVictor Perevertkin }
339*8a978a17SVictor Perevertkin }
340*8a978a17SVictor Perevertkin
341*8a978a17SVictor Perevertkin if (newState == DprMax) {
342*8a978a17SVictor Perevertkin //
343*8a978a17SVictor Perevertkin // Unexpected event for this state
344*8a978a17SVictor Perevertkin //
345*8a978a17SVictor Perevertkin DoTraceLevelMessage(
346*8a978a17SVictor Perevertkin m_PoxInterface->PkgPnp()->GetDriverGlobals(),
347*8a978a17SVictor Perevertkin TRACE_LEVEL_INFORMATION,
348*8a978a17SVictor Perevertkin TRACINGPNP,
349*8a978a17SVictor Perevertkin "WDFDEVICE 0x%p !devobj 0x%p device power requirement state "
350*8a978a17SVictor Perevertkin "%!FxDevicePwrRequirementStates! dropping event "
351*8a978a17SVictor Perevertkin "%!FxDevicePwrRequirementEvents!",
352*8a978a17SVictor Perevertkin m_PoxInterface->PkgPnp()->GetDevice()->GetHandle(),
353*8a978a17SVictor Perevertkin m_PoxInterface->PkgPnp()->GetDevice()->GetDeviceObject(),
354*8a978a17SVictor Perevertkin m_CurrentState,
355*8a978a17SVictor Perevertkin event
356*8a978a17SVictor Perevertkin );
357*8a978a17SVictor Perevertkin
358*8a978a17SVictor Perevertkin COVERAGE_TRAP();
359*8a978a17SVictor Perevertkin }
360*8a978a17SVictor Perevertkin
361*8a978a17SVictor Perevertkin while (newState != DprMax) {
362*8a978a17SVictor Perevertkin DoTraceLevelMessage(
363*8a978a17SVictor Perevertkin m_PoxInterface->PkgPnp()->GetDriverGlobals(),
364*8a978a17SVictor Perevertkin TRACE_LEVEL_INFORMATION,
365*8a978a17SVictor Perevertkin TRACINGPNPPOWERSTATES,
366*8a978a17SVictor Perevertkin "WDFDEVICE 0x%p !devobj 0x%p entering device power requirement "
367*8a978a17SVictor Perevertkin "state %!FxDevicePwrRequirementStates! from "
368*8a978a17SVictor Perevertkin "%!FxDevicePwrRequirementStates!",
369*8a978a17SVictor Perevertkin m_PoxInterface->PkgPnp()->GetDevice()->GetHandle(),
370*8a978a17SVictor Perevertkin m_PoxInterface->PkgPnp()->GetDevice()->GetDeviceObject(),
371*8a978a17SVictor Perevertkin newState,
372*8a978a17SVictor Perevertkin m_CurrentState
373*8a978a17SVictor Perevertkin );
374*8a978a17SVictor Perevertkin
375*8a978a17SVictor Perevertkin //
376*8a978a17SVictor Perevertkin // Update the state history array
377*8a978a17SVictor Perevertkin //
378*8a978a17SVictor Perevertkin m_States.History[IncrementHistoryIndex()] = (UCHAR) newState;
379*8a978a17SVictor Perevertkin
380*8a978a17SVictor Perevertkin //
381*8a978a17SVictor Perevertkin // Move to the new state
382*8a978a17SVictor Perevertkin //
383*8a978a17SVictor Perevertkin m_CurrentState = (BYTE) newState;
384*8a978a17SVictor Perevertkin entry = &m_StateTable[m_CurrentState-DprUnregistered];
385*8a978a17SVictor Perevertkin
386*8a978a17SVictor Perevertkin //
387*8a978a17SVictor Perevertkin // Invoke the state entry function (if present) for the new state
388*8a978a17SVictor Perevertkin //
389*8a978a17SVictor Perevertkin if (entry->StateFunc != NULL) {
390*8a978a17SVictor Perevertkin newState = entry->StateFunc(this);
391*8a978a17SVictor Perevertkin }
392*8a978a17SVictor Perevertkin else {
393*8a978a17SVictor Perevertkin newState = DprMax;
394*8a978a17SVictor Perevertkin }
395*8a978a17SVictor Perevertkin }
396*8a978a17SVictor Perevertkin }
397*8a978a17SVictor Perevertkin
398*8a978a17SVictor Perevertkin return;
399*8a978a17SVictor Perevertkin }
400*8a978a17SVictor Perevertkin
401*8a978a17SVictor Perevertkin FxDevicePwrRequirementStates
PowerNotRequiredD0(__in FxDevicePwrRequirementMachine * This)402*8a978a17SVictor Perevertkin FxDevicePwrRequirementMachine::PowerNotRequiredD0(
403*8a978a17SVictor Perevertkin __in FxDevicePwrRequirementMachine* This
404*8a978a17SVictor Perevertkin )
405*8a978a17SVictor Perevertkin {
406*8a978a17SVictor Perevertkin This->m_PoxInterface->PkgPnp()->PowerPolicyProcessEvent(
407*8a978a17SVictor Perevertkin PwrPolDevicePowerNotRequired
408*8a978a17SVictor Perevertkin );
409*8a978a17SVictor Perevertkin return DprMax;
410*8a978a17SVictor Perevertkin }
411*8a978a17SVictor Perevertkin
412*8a978a17SVictor Perevertkin FxDevicePwrRequirementStates
PowerRequiredDx(__in FxDevicePwrRequirementMachine * This)413*8a978a17SVictor Perevertkin FxDevicePwrRequirementMachine::PowerRequiredDx(
414*8a978a17SVictor Perevertkin __in FxDevicePwrRequirementMachine* This
415*8a978a17SVictor Perevertkin )
416*8a978a17SVictor Perevertkin {
417*8a978a17SVictor Perevertkin This->m_PoxInterface->PkgPnp()->PowerPolicyProcessEvent(
418*8a978a17SVictor Perevertkin PwrPolDevicePowerRequired
419*8a978a17SVictor Perevertkin );
420*8a978a17SVictor Perevertkin return DprMax;
421*8a978a17SVictor Perevertkin }
422*8a978a17SVictor Perevertkin
423*8a978a17SVictor Perevertkin FxDevicePwrRequirementStates
ReportingDevicePowerAvailable(__in FxDevicePwrRequirementMachine * This)424*8a978a17SVictor Perevertkin FxDevicePwrRequirementMachine::ReportingDevicePowerAvailable(
425*8a978a17SVictor Perevertkin __in FxDevicePwrRequirementMachine* This
426*8a978a17SVictor Perevertkin )
427*8a978a17SVictor Perevertkin {
428*8a978a17SVictor Perevertkin This->m_PoxInterface->PoxReportDevicePoweredOn();
429*8a978a17SVictor Perevertkin return DprDevicePowerRequiredD0;
430*8a978a17SVictor Perevertkin }
431