ReactOS 0.4.16-dev-199-g898cc56
poxinterface.cpp
Go to the documentation of this file.
1/*++
2Copyright (c) Microsoft. All rights reserved.
3
4Module Name:
5
6 PoxInterface.cpp
7
8Abstract:
9
10 This module implements the power-framework-related logic in WDF.
11
12--*/
13
14#include "pnppriv.hpp"
15
16extern "C" {
17#if defined(EVENT_TRACING)
18#include "PoxInterface.tmh"
19#endif
20}
21
23 __in FxPkgPnp* PkgPnp
24 )
25{
32}
33
35 VOID
36 )
37{
40 }
41}
42
45 VOID
46 )
47{
48// NTSTATUS status;
49// FxDevicePwrRequirementMachine * fxDprMachine = NULL;
50
51// ASSERT(NULL == m_DevicePowerRequirementMachine);
52
53// fxDprMachine = new (m_PkgPnp->GetDriverGlobals())
54// FxDevicePwrRequirementMachine(this);
55// if (NULL == fxDprMachine) {
56// status = STATUS_INSUFFICIENT_RESOURCES;
57// DoTraceLevelMessage(
58// m_PkgPnp->GetDriverGlobals(),
59// TRACE_LEVEL_ERROR, TRACINGPNP,
60// "WDFDEVICE 0x%p !devobj 0x%p failed to allocate "
61// "FxDevicePwrRequirementMachine. %!STATUS!.",
62// m_PkgPnp->GetDevice()->GetHandle(),
63// m_PkgPnp->GetDevice()->GetDeviceObject(),
64// status);
65// goto exit;
66// }
67
68// status = fxDprMachine->Initialize(m_PkgPnp->GetDriverGlobals());
69// if (FALSE == NT_SUCCESS(status)) {
70// DoTraceLevelMessage(
71// m_PkgPnp->GetDriverGlobals(),
72// TRACE_LEVEL_ERROR, TRACINGPNP,
73// "WDFDEVICE 0x%p !devobj 0x%p Device Power Requirement State Machine"
74// " Initialize() failed, %!STATUS!",
75// m_PkgPnp->GetDevice()->GetHandle(),
76// m_PkgPnp->GetDevice()->GetDeviceObject(),
77// status);
78// goto exit;
79// }
80
81// status = fxDprMachine->Init(
82// m_PkgPnp,
83// FxDevicePwrRequirementMachine::_ProcessEventInner
84// );
85// if (!NT_SUCCESS(status)) {
86// DoTraceLevelMessage(
87// m_PkgPnp->GetDriverGlobals(),
88// TRACE_LEVEL_ERROR, TRACINGPNP,
89// "WDFDEVICE 0x%p !devobj 0x%p Device Power Requirement State Machine"
90// " Init() failed, %!STATUS!",
91// m_PkgPnp->GetDevice()->GetHandle(),
92// m_PkgPnp->GetDevice()->GetDeviceObject(),
93// status);
94// goto exit;
95// }
96
97// m_DevicePowerRequirementMachine = fxDprMachine;
98
99// status = STATUS_SUCCESS;
100
101// exit:
102// if (FALSE == NT_SUCCESS(status)) {
103// if (NULL != fxDprMachine) {
104// delete fxDprMachine;
105// }
106// }
107// return status;
109 return STATUS_SUCCESS;
110}
111
114 VOID
115 )
116{
117// NTSTATUS status;
118// PPOX_SETTINGS poxSettings = NULL;
119// WDFDEVICE fxDevice = NULL;
120
121
122// if (FALSE == m_PkgPnp->m_PowerPolicyMachine.m_Owner->m_IdleSettings.
123// m_TimeoutMgmt.UsingSystemManagedIdleTimeout()) {
124// //
125// // Driver-managed idle timeout. Nothing to do.
126// //
127// return STATUS_SUCCESS;
128// }
129
130// //
131// // We create the device power requirement state machine only if system-
132// // managed idle timeout is being used.
133// //
134// if (NULL == m_DevicePowerRequirementMachine) {
135// status = CreateDevicePowerRequirementMachine();
136// if (FALSE == NT_SUCCESS(status)) {
137// goto exit;
138// }
139// }
140
141// ASSERT(NULL != m_DevicePowerRequirementMachine);
142
143// //
144// // Register with the power framework
145// //
146// status = PoxRegisterDevice();
147
148// if (FALSE == NT_SUCCESS(status)) {
149// DoTraceLevelMessage(
150// m_PkgPnp->GetDriverGlobals(),
151// TRACE_LEVEL_ERROR, TRACINGPNP,
152// "WDFDEVICE 0x%p !devobj 0x%p FxPox::PoxRegisterDevice failed. "
153// "%!STATUS!.",
154// m_PkgPnp->GetDevice()->GetHandle(),
155// m_PkgPnp->GetDevice()->GetDeviceObject(),
156// status);
157// goto exit;
158// }
159
160// //
161// // At the time of registration, all components are active. When we start the
162// // power framework's device power management (see below), all components are
163// // moved to the idle state by default. Take an extra reference on the
164// // component to prevent this from happening. The power policy state machine
165// // will evaluate the S0-idle policy later and ask us to drop this reference
166// // if the policy requires it.
167// //
168// PoxActivateComponent();
169
170// //
171// // Tell the power framework to start its device power management. This will
172// // drop a reference on the component, but the component will still remain
173// // active because of the extra reference we took above.
174// //
175// PoxStartDevicePowerManagement();
176
177// //
178// // If the client driver has specified power framework settings, retrieve
179// // them.
180// //
181// poxSettings = GetPowerFrameworkSettings();
182
183// //
184// // If the driver wanted to receive the POHANDLE, invoke their callback now
185// //
186// if ((NULL != poxSettings) &&
187// (NULL != poxSettings->EvtDeviceWdmPostPoFxRegisterDevice)) {
188
189// fxDevice = m_PkgPnp->GetDevice()->GetHandle();
190
191// status = poxSettings->EvtDeviceWdmPostPoFxRegisterDevice(
192// fxDevice,
193// m_PoHandle
194// );
195// if (FALSE == NT_SUCCESS(status)) {
196
197// DoTraceLevelMessage(
198// m_PkgPnp->GetDriverGlobals(),
199// TRACE_LEVEL_ERROR, TRACINGPNP,
200// "WDFDEVICE 0x%p !devobj 0x%p. The client driver has failed the "
201// "EvtDeviceWdmPostPoFxRegisterDevice callback with %!STATUS!.",
202// m_PkgPnp->GetDevice()->GetHandle(),
203// m_PkgPnp->GetDevice()->GetDeviceObject(),
204// status);
205
206// //
207// // Notify the driver that the POHANDLE is about to become invalid
208// //
209// if (NULL != poxSettings->EvtDeviceWdmPrePoFxUnregisterDevice) {
210// poxSettings->EvtDeviceWdmPrePoFxUnregisterDevice(
211// fxDevice,
212// m_PoHandle
213// );
214// }
215
216// //
217// // Unregister with the power framework
218// //
219// PoxUnregisterDevice();
220// goto exit;
221// }
222// }
223
224// //
225// // Tell the device power requirement state machine that we have registered
226// // with the power framework
227// //
228// m_DevicePowerRequirementMachine->ProcessEvent(DprEventRegisteredWithPox);
229
230// exit:
231// return status;
233 return STATUS_SUCCESS;
234}
235
236VOID
238 VOID
239 )
240{
241 // PPOX_SETTINGS poxSettings = NULL;
242
243 // if (FALSE == m_PkgPnp->m_PowerPolicyMachine.m_Owner->m_IdleSettings.
244 // m_TimeoutMgmt.UsingSystemManagedIdleTimeout()) {
245 // //
246 // // Driver-managed idle timeout. Nothing to do.
247 // //
248 // return;
249 // }
250
251 // ASSERT(NULL != m_DevicePowerRequirementMachine);
252
253 // //
254 // // If the client driver has specified power framework settings, retrieve
255 // // them.
256 // //
257 // poxSettings = GetPowerFrameworkSettings();
258
259 // //
260 // // Notify the client driver that the POHANDLE is about to become invalid
261 // //
262 // if ((NULL != poxSettings) &&
263 // (NULL != poxSettings->EvtDeviceWdmPrePoFxUnregisterDevice)) {
264
265 // poxSettings->EvtDeviceWdmPrePoFxUnregisterDevice(
266 // m_PkgPnp->GetDevice()->GetHandle(),
267 // m_PoHandle
268 // );
269 // }
270
271 // //
272 // // Unregister with the power framework
273 // //
274 // PoxUnregisterDevice();
275
276 // //
277 // // Tell the device power requirement state machine that we have unregistered
278 // // with the power framework
279 // //
280 // m_DevicePowerRequirementMachine->ProcessEvent(
281 // DprEventUnregisteredWithPox
282 // );
283 // return;
285}
286
287VOID
289 VOID
290 )
291{
292 // if (FALSE == m_PkgPnp->m_PowerPolicyMachine.m_Owner->m_IdleSettings.
293 // m_TimeoutMgmt.UsingSystemManagedIdleTimeout()) {
294 // //
295 // // Driver-managed idle timeout. Nothing to do.
296 // //
297 // return;
298 // }
299
300 // PoxActivateComponent();
301 // return;
303}
304
307 VOID
308 )
309{
310 // BOOLEAN canPowerDown;
311
312 // if (FALSE == m_PkgPnp->m_PowerPolicyMachine.m_Owner->m_IdleSettings.
313 // m_TimeoutMgmt.UsingSystemManagedIdleTimeout()) {
314 // //
315 // // Driver-managed idle timeout. We can power down immediately, without
316 // // waiting for device-power-not-required notification.
317 // //
318 // canPowerDown = TRUE;
319 // } else {
320 // //
321 // // System-managed idle timeout
322 // //
323 // PoxIdleComponent();
324
325 // //
326 // // We must wait for device-power-not-required notification before
327 // // powering down.
328 // //
329 // canPowerDown = FALSE;
330 // }
331
332 // return canPowerDown;
334 return TRUE;
335}
336
337VOID
339 VOID
340 )
341{
342 // ULONGLONG idleTimeoutHint;
343
344 // if (FALSE == m_PkgPnp->m_PowerPolicyMachine.m_Owner->m_IdleSettings.
345 // m_TimeoutMgmt.UsingSystemManagedIdleTimeout()) {
346 // //
347 // // Driver-managed idle timeout. Nothing to do.
348 // //
349 // return;
350 // }
351
352 // if (m_NextIdleTimeoutHint != m_CurrentIdleTimeoutHint) {
353 // m_CurrentIdleTimeoutHint = m_NextIdleTimeoutHint;
354
355 // //
356 // // Convert the idle timeout from milliseconds to 100-nanosecond units
357 // //
358 // idleTimeoutHint = ((ULONGLONG) m_CurrentIdleTimeoutHint) * 10 * 1000;
359 // PoxSetDeviceIdleTimeout(idleTimeoutHint);
360 // }
361
362 // return;
364}
365
366
369 VOID
370 )
371{
372 // KIRQL irql;
373 // BOOLEAN canPowerOff;
374
375 // if (FALSE == m_PkgPnp->m_PowerPolicyMachine.m_Owner->m_IdleSettings.
376 // m_TimeoutMgmt.UsingSystemManagedIdleTimeout()) {
377 // //
378 // // Driver-managed idle timeout. We don't have to take power framework's
379 // // device power requirement into consideration. Just return success.
380 // //
381 // return STATUS_SUCCESS;
382 // }
383
384 // //
385 // // Acquire the lock to ensure that device power requirement doesn't change.
386 // //
387 // m_DevicePowerRequiredLock.Acquire(&irql);
388 // if (FALSE == m_DevicePowerRequired) {
389 // //
390 // // Send an event to the device power requirement state machine to tell
391 // // it that we are about to go to Dx.
392 // //
393 // // We send the event inside a lock in order to handle the race condition
394 // // when the power framework notifies us that device power is required at
395 // // the same time that we are about to go to Dx. By sending the event
396 // // inside the lock, we ensure that the DprEventDeviceGoingToDx event is
397 // // always queued to device power requirement state machine before the
398 // // DprEventPoxRequiresPower.
399 // //
400 // // This allows for a clean design in the device power requirement state
401 // // machine by ensuring that it does not have to handle a non-intuitive
402 // // sequence, i.e. DprEventPoxRequiresPower followed by
403 // // DprEventDeviceGoingToDx. This sequence is non-intuitive because it
404 // // doesn't make sense for a device to go to Dx after it has been
405 // // informed that device power is required. Avoiding this non-intuitive
406 // // sequence via locking enables a clean design for the device power
407 // // requirement state machine.
408 // //
409 // m_DevicePowerRequirementMachine->ProcessEvent(DprEventDeviceGoingToDx);
410 // canPowerOff = TRUE;
411
412 // } else {
413 // canPowerOff = FALSE;
414 // }
415 // m_DevicePowerRequiredLock.Release(irql);
416
417 // return canPowerOff ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
419 return STATUS_SUCCESS;
420}
421
422VOID
424 VOID
425 )
426{
428 // if (FALSE == m_PkgPnp->m_PowerPolicyMachine.m_Owner->m_IdleSettings.
429 // m_TimeoutMgmt.UsingSystemManagedIdleTimeout()) {
430 // //
431 // // Driver-managed idle timeout. Nothing to do.
432 // //
433 // return;
434 // }
435
436 // //
437 // // System-managed idle timeout. Notify the device power requirement state
438 // // machine that we are back in D0.
439 // //
440 // m_DevicePowerRequirementMachine->ProcessEvent(
441 // DprEventDeviceReturnedToD0
442 // );
443 // return;
444}
445
448 VOID
449 )
450{
451 PPOX_SETTINGS poxSettings = NULL;
452
454 // if (m_PkgPnp->m_PowerPolicyMachine.m_Owner->
455 // m_IdleSettings.m_TimeoutMgmt.DriverSpecifiedPowerFrameworkSettings()) {
456
457 // poxSettings = m_PkgPnp->m_PowerPolicyMachine.m_Owner->
458 // m_IdleSettings.m_TimeoutMgmt.GetPowerFrameworkSettings();
459
460 // ASSERT(NULL != poxSettings);
461 // }
462
463 return poxSettings;
464}
465
466VOID
469 )
470{
472 // KIRQL irql;
473
474 // //
475 // // We should not run the state machine from within a power framework
476 // // callback because we might end up reaching a state where we unregister
477 // // with the power framework. Unregistering from a callback leads to a
478 // // deadlock. Therefore, we raise IRQL before queueing an event to the state
479 // // machine. Raising IRQL causes the event processing to be deferred to a
480 // // worker thread.
481 // //
482
483 // //
484 // // This path should only be invoked for kernel mode. For user mode, this
485 // // condition is avoided by reflector guranteeing that it queues a worker
486 // // item to send a Pofx event corresponding to any PoFx callback
487 // //
488 // ASSERT(FX_IS_KERNEL_MODE);
489
490 // Mx::MxRaiseIrql(DISPATCH_LEVEL, &irql);
491 // m_DevicePowerRequirementMachine->ProcessEvent(Event);
492 // Mx::MxLowerIrql(irql);
493}
494
495VOID
497 VOID
498 )
499{
501 // if (FALSE == m_PkgPnp->m_PowerPolicyMachine.m_Owner->m_IdleSettings.
502 // m_TimeoutMgmt.UsingSystemManagedIdleTimeout()) {
503 // //
504 // // Driver-managed idle timeout. Nothing to do.
505 // //
506 // return;
507 // }
508
509 // //
510 // // System-managed idle timeout. Notify the device power requirement state
511 // // machine that device power is required.
512 // //
513 // PowerRequiredCallbackWorker(FALSE /* InvokedFromPoxCallback */);
514 // return;
515}
516
517VOID
519 VOID
520 )
521{
523 // if (FALSE == m_PkgPnp->m_PowerPolicyMachine.m_Owner->m_IdleSettings.
524 // m_TimeoutMgmt.UsingSystemManagedIdleTimeout()) {
525 // //
526 // // Driver-managed idle timeout. Nothing to do.
527 // //
528 // return;
529 // }
530
531 // //
532 // // System-managed idle timeout. Notify the device power requirement state
533 // // machine that device power is not required.
534 // //
535 // PowerNotRequiredCallbackWorker(FALSE /* InvokedFromPoxCallback */);
536 // return;
537}
538
539VOID
541 __in BOOLEAN InvokedFromPoxCallback
542 )
543{
545 // KIRQL irql;
546
547 // //
548 // // Make a note of the fact that device power is required
549 // //
550 // m_DevicePowerRequiredLock.Acquire(&irql);
551 // m_DevicePowerRequired = TRUE;
552 // m_DevicePowerRequiredLock.Release(irql);
553
554 // //
555 // // Send the device-power-required event to the device power requirement
556 // // state machine.
557 // //
558 // if (InvokedFromPoxCallback) {
559 // DprProcessEventFromPoxCallback(DprEventPoxRequiresPower);
560 // } else {
561 // m_DevicePowerRequirementMachine->ProcessEvent(DprEventPoxRequiresPower);
562 // }
563 // return;
564}
565
566VOID
568 __in BOOLEAN InvokedFromPoxCallback
569 )
570{
572 // KIRQL irql;
573
574 // //
575 // // Make a note of the fact that device power is not required
576 // //
577 // m_DevicePowerRequiredLock.Acquire(&irql);
578 // m_DevicePowerRequired = FALSE;
579 // m_DevicePowerRequiredLock.Release(irql);
580
581 // //
582 // // Send the device-power-not-required event to the device power
583 // // requirement state machine.
584 // //
585 // if (InvokedFromPoxCallback) {
586 // DprProcessEventFromPoxCallback(DprEventPoxDoesNotRequirePower);
587 // } else {
588 // m_DevicePowerRequirementMachine->ProcessEvent(
589 // DprEventPoxDoesNotRequirePower
590 // );
591 // }
592 // return;
593}
594
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN DeclareComponentIdle(VOID)
FxDevicePwrRequirementMachine * m_DevicePowerRequirementMachine
VOID SimulateDevicePowerNotRequired(VOID)
FxPkgPnp * PkgPnp(VOID)
VOID DeviceIsPoweredOn(VOID)
FxPoxInterface(__in FxPkgPnp *PkgPnp)
NTSTATUS CreateDevicePowerRequirementMachine(VOID)
struct _POX_SETTINGS * GetPowerFrameworkSettings(VOID)
VOID PowerRequiredCallbackWorker(__in BOOLEAN InvokedFromPoxCallback)
NTSTATUS NotifyDevicePowerDown(VOID)
NTSTATUS InitializeComponents(VOID)
VOID PowerNotRequiredCallbackWorker(__in BOOLEAN InvokedFromPoxCallback)
VOID UninitializeComponents(VOID)
BOOLEAN m_DevicePowerRequired
VOID SimulateDevicePowerRequired(VOID)
VOID DprProcessEventFromPoxCallback(__in FxDevicePwrRequirementEvents Event)
FxPkgPnp * m_PkgPnp
VOID RequestComponentActive(VOID)
ULONG m_CurrentIdleTimeoutHint
VOID UpdateIdleTimeoutHint(VOID)
#define __in
Definition: dbghelp.h:35
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define ROSWDFNOTIMPLEMENTED
Definition: fxglobals.h:52
#define STATUS_SUCCESS
Definition: shellext.h:65