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