ReactOS 0.4.15-dev-7788-g1ad9096
fxpowerpolicystatemachine.hpp
Go to the documentation of this file.
1//
2// Copyright (C) Microsoft. All rights reserved.
3//
4#ifndef _FXPOWERPOLICYSTATEMACHINE_H_
5#define _FXPOWERPOLICYSTATEMACHINE_H_
6
8#include "fxpoxinterface.hpp"
9
10// @@SMVERIFY_SPLIT_BEGIN
11//
12// Treat these values as a bit field when comparing for known dropped events in
13// the current state and treat them as values when they known transition events
14// from state to the next.
15//
17 PwrPolInvalid = 0x00000000,
18 PwrPolStart = 0x00000001,
19 PwrPolStop = 0x00000002,
20 PwrPolSx = 0x00000004,
21 PwrPolS0 = 0x00000008,
22 PwrPolPowerDown = 0x00000010,
23 PwrPolPowerUp = 0x00000020,
26 PwrPolWakeArrived = 0x00000100,
27 PwrPolWakeSuccess = 0x00000200,
28 PwrPolWakeFailed = 0x00000400,
29 PwrPolIoPresent = 0x00000800,
36 PwrPolPowerUpFailed = 0x00040000,
42 PwrPolRemove = 0x01000000,
44
45 //
46 // Not a real event, just a value that indicates all of the events which
47 // goto the head of the queue and are always processed, even if the state is
48 // locked. This applies to the power policy owner state machine.
49 //
64
65 //
66 // Not a real event, just a value that indicates all of the events which
67 // goto the head of the queue and are always processed, even if the state is
68 // locked. This applies to the not power policy owner state machine.
69 //
74
75 //
76 // Not a real event, just a value that indicate all of the events which
77 // should not be in the queue, if a similar event is already enqueued.
78 //
80 //
81 // A device could have multiple wake interrupts that could each fire
82 // this event.
83 //
85
86
87 PwrPolNull = 0xFFFFFFFF,
88};
89
90//
91// Bit packed ULONG.
92//
94 struct {
95 //
96 // Indicates whether the state is open to all events
97 //
99
100 //
101 // Bit of events we know we can drop in this state
102 //
105
106 struct {
107 //
108 // Maps to the same bit location as QueueOpen. Since we start
109 // KnownDroppedEvents at the next bit, start our bits by at the next
110 // bit as well.
111 //
113
114 //
115 // These are defined so that we can easily tell in the debugger what
116 // each set bit in KnownDroppedEvents maps to in the FxPowerPolicyEvent
117 // enum
118 //
139};
140
143
145
147};
148
150
151typedef
155 );
156
158 //
159 // Framework internal function to handle the transition into this state
160 //
162
163 //
164 // First state transition out of this state
165 //
167
168 //
169 // Other state transitions out of this state if FirstTargetState is not
170 // matched. This is an array where we expect the final element to be
171 // { PwrPolNull, WdfDevStatePwrPolNull }
172 //
174
175 //
176 // Whether we allow transitions out of this state that are not D state
177 // related events, ie if this is a green dot state, TRUE, if this is a red
178 // dot state, FALSE. D state events (PwrPolPowerUp, PwrPolPowerDown)
179 // are never affected by the queue state and are always processed.
180 //
182
184
186
187typedef
191 );
192
194 //
195 // The current power policy state that this entry applies to
196 //
198
199 //
200 // Framework internal function to handle the transition into this state
201 //
203
204 //
205 // Only state transition out of this state
206 //
208
210
212
214
216
217#if FX_STATE_MACHINE_VERIFY
218#define MAX_PWR_POL_STATE_ENTRY_FN_RETURN_STATES (5)
219
220struct PWR_POL_STATE_ENTRY_FUNCTION_TARGET_STATE {
221 //
222 // Return value from state entry function
223 //
225
226 //
227 // type of device the returning state applies to
228 //
229 FxStateMachineDeviceType DeviceType;
230
231 //
232 // Info about the state transition
233 //
235};
236
237struct PWR_POL_STATE_ENTRY_FN_RETURN_STATE_TABLE {
238 //
239 // array of state transitions caused by state entry function
240 //
241 PWR_POL_STATE_ENTRY_FUNCTION_TARGET_STATE TargetStates[MAX_PWR_POL_STATE_ENTRY_FN_RETURN_STATES];
242};
243
244typedef const PWR_POL_STATE_ENTRY_FN_RETURN_STATE_TABLE* CPPWR_POL_STATE_ENTRY_FN_RETURN_STATE_TABLE;
245#endif // FX_STATE_MACHINE_VERIFY
246
247
248// @@SMVERIFY_SPLIT_END
249
252
253 FxPowerPolicyDefaultTimeout = 5000, // Timeout in milliseconds
254};
255
259};
260
264};
265
268 {
271
273 }
274
276
277 //
278 // Dx state to put the device in when the policy is applied
279 //
281
283
285
287
289
291};
292
293typedef struct _POX_SETTINGS {
305
307
308private:
309 //
310 // This member is used to control whether or not the idle timeout is
311 // determined by the power manager when running on Windows 8 and above.
312 // The value of this member is some combination of the flags defined below.
313 //
315
316 //
317 // Flags for the m_IdleTimeoutStatus member
318 //
319 // IdleTimeoutStatusFrozen - This flag implies that the decision on
320 // whether the power manager determines the idle timeout is "frozen"
321 // and can no longer be changed. The decision is frozen during start
322 // IRP completion processing, just before WDF registers with the
323 // power manager.
324 //
325 // IdleTimeoutSystemManaged - This flag implies that the power manager
326 // determines the idle timeout on Windows 8 and above. If this flag
327 // is not set, the idle timeout specified by the client driver is
328 // used.
329 //
330 // IdleTimeoutPoxSettingsSpecified - This flag implies that the client
331 // driver has already specified the settings that need to be used
332 // when registering with the power framework. This flag is used to
333 // track that the settings are not specified more than once.
334 //
339 };
340
341 //
342 // Result returned by the UpdateIdleTimeoutStatus() method
343 //
345 //
346 // Flags were sucessfully updated
347 //
349
350 //
351 // The flag we were trying to set was already set
352 //
354
355 //
356 // It is too late to set the flag. The flags have already been frozen.
357 // Flags are frozen the first time a device is started.
358 //
360
361 //
362 // Flags are being set by multiple threads in parallel. This is not
363 // supported.
364 //
366 };
367
368 //
369 // This member contains the client driver's settings that will be used when
370 // we register with the power manager on Windows 8 and above.
371 //
373
374private:
378 );
379
380 CfxDevice *
381 GetDevice(
382 VOID
383 );
384
385public:
387 VOID
388 ) : m_IdleTimeoutStatus(0),
390 {
391 }
392
394 VOID
395 )
396 {
397 BYTE * buffer = NULL;
398 ULONG poxSettingsOffset;
399
400 if (NULL != m_PoxSettings) {
401
403
404 //
405 // In the function FxPkgPnp::AssignPowerFrameworkSettings, we had
406 // allocated a buffer which we need to free now. Note that
407 // m_PoxSettings does not necessarily point to the beginning of the
408 // buffer. It points to the POX_SETTINGS structure in the buffer,
409 // which may or may not be in the beginning. If it is not in the
410 // beginning, figure out where the beginning of the buffer is.
411 //
412 if (m_PoxSettings->Component != NULL) {
413 //
414 // The computation below won't overflow because we already
415 // performed this computation successfully using safeint
416 // functions in FxPkgPnp::AssignPowerFrameworkSettings.
417 //
418 poxSettingsOffset =
419 (sizeof(*(m_PoxSettings->Component->IdleStates)) *
421 (sizeof(*(m_PoxSettings->Component)));
422 }
423 else {
424 poxSettingsOffset = 0;
425 }
426
427 //
428 // Move to the beginning of the buffer
429 //
430 buffer = buffer - poxSettingsOffset;
431
432 //
433 // Free the buffer
434 //
436 }
437 }
438
439 static
440 BOOLEAN
442 VOID
443 );
444
448 );
449
450 VOID
453 );
454
455 BOOLEAN
457 VOID
458 );
459
463 __in PPOX_SETTINGS PoxSettings
464 );
465
466 BOOLEAN
468 VOID
469 );
470
473 VOID
474 )
475 {
476 return m_PoxSettings;
477 }
478};
479
482 VOID
483 ) : PolicySettings()
484 {
489 }
490
491 //
492 // TRUE if the device capable of waking from S0
493 //
495
496 //
497 // This member is meaningful only if the WakeFromS0Capable member (above) is
498 // TRUE. The WakeFromS0Capable member indicates whether or not wake-from-S0
499 // is currently enabled. If wake-from-S0 is currently enabled, the
500 // UsbSSCapable member indicates whether the wake-from-S0 support is generic
501 // or USB SS specific. If wake-from-S0 is not enabled, the UsbSSCapable
502 // member is ignored.
503 //
505
506 //
507 // TRUE if we know whether the device supports generic wake or USB SS wake.
508 // This value is initialized to FALSE and remains FALSE until the first time
509 // that the driver specifies S0-idle settings with an idle capability value
510 // of IdleCanWakeFromS0 or IdleUsbSelectiveSuspend. When the driver
511 // specifies one of these idle capabilities, this value is set to TRUE and
512 // remains TRUE for the lifetime of the device.
513 //
515
516 //
517 // TRUE if idle enabled device should be powered up even when idle,
518 // when resuming from Sx
519 //
521
522 //
523 // Member to manage interactions with the power manager for S0-idle support
524 // on Win8 and above
525 //
527};
528
531 VOID
532 ) : PolicySettings()
533 {
536 }
537
538 //
539 // TRUE if the device should arm for wake when one or more children are
540 // armed for wake.
541 //
543
544 //
545 // TRUE if the device should propagate the wake status to its children.
546 //
548};
549
551
553
554public:
556 __in FxPkgPnp* PkgPnp
557 );
558
560 VOID
561 );
562
565 Init(
566 VOID
567 );
568
569 VOID
571 VOID
572 );
573
574 VOID
576 VOID
577 )
578 {
580 }
581
582 VOID
584 VOID
585 )
586 {
588 }
589
590protected:
591 static
594
595public:
598
599
600
601
602
603
606
609
612
614
616
618
620
621 //
622 // Nibble packed structure. Each D state is encoded 4 bits. The S state is
623 // used as the "index" within the ULONG. PowerSystemUnspecified is the
624 // first 4 bits of the first byte, etc. etc. ...
625 //
627
628 //
629 // The number of children who are in the D0 state. If this count is > 0,
630 // then this parent cannot idle out while in S0. Note that each child also
631 // has an explicit call to PowerReference against this device which is used
632 // to control the idle timer for this device.
633 //
635
636 //
637 // The number of children who are currently armed for wake. This count
638 // can be used by the the wake owner to determine whether wake should be
639 // enabled or not for a parent stack if arming for wake depends on
640 // children being armed for wake.
641 //
643
644 //
645 // The status of the last wait wake IRP to complete in the stack
646 //
648
649 //
650 // Dx state to put the device into when an Sx irp arrives and the device is
651 // not armed for wake from Sx. DEVICE_POWER_STATE values are used.
652 //
654
655 //
656 // Track power requests to assert if someone other than this driver sent it
657 // and to determine if this driver has received the requested irp (to catch
658 // someone above completing irp w/o sending to this driver)
659 //
663
664 //
665 // Tracks wake event being dropped
666 //
668
670
671 //
672 // Indicates whether we can cause paging I/O by writing to the registry
673 //
675
676 //
677 // Guard to stop children from powering up while the parent is in Dx or
678 // about to transition into Dx.
679 //
681
682 //
683 // TRUE if our device caused the machine to wake up. Access to this value
684 // is not synchronized between the parent and PDO. The parent sets it to
685 // TRUE upon successful completion of the WW irp and cleared after
686 // EvtDeviceDisarmWakeFromSx. If a PDO's WW IRP is completed within this
687 // window, the PDO's WW IRP will have PoSetSystemWake called on it. It is
688 // acceptable if the PDO's WW IRP completion races with the clearing of the
689 // value and is not set as a source of wake.
690 //
692
693protected:
695
697
699
700};
701
702//
703// This type of union is done so that we can
704// 1) shrink the array element to the smallest size possible
705// 2) keep types within the structure so we can dump it in the debugger
706//
708 struct {
717 } S;
718
720};
721
724 VOID
725 );
726
728 VOID
729 );
730
731 VOID
733 VOID
734 );
735
738 InitUsbSS(
739 VOID
740 );
741
742 VOID
744 VOID
745 )
746 {
748 }
749
750 BOOLEAN
752 VOID
753 )
754 {
755 //
756 // We have 2 potential call sites racing on trying to complete the wait
757 // wake irp. The first is the cancelling call site. The other is the
758 // irp's completion routine. What we want is for the *2nd* (and last)
759 // call site to actually complete the irp. This is why we check to see
760 // if the result of the exchange is that the ownership is already claimed
761 // (and not unclaimed as one might first be led to think).
762 //
765 return TRUE;
766 }
767 else {
768 return FALSE;
769 }
770 }
771
772public:
774
776
778
779 union {
781
782 union {
783 //
784 // These are defined so that we can easily tell in the debugger what
785 // each set bit in m_SingularEventsPresent maps to in the
786 // FxPowerPolicyEvent enum.
787 //
808 };
809};
810
811#endif // _FXPOWERPOLICYSTATEMACHINE_H_
unsigned char BOOLEAN
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedExchange
Definition: armddk.h:54
#define InterlockedDecrement
Definition: armddk.h:52
@ Comment
Definition: asmpp.cpp:34
LONG NTSTATUS
Definition: precomp.h:26
IdleTimeoutStatusUpdateResult UpdateIdleTimeoutStatus(__in IdleTimeoutStatusFlag Flag)
NTSTATUS UseSystemManagedIdleTimeout(__in PFX_DRIVER_GLOBALS DriverGlobals)
PPOX_SETTINGS GetPowerFrameworkSettings(VOID)
static BOOLEAN _SystemManagedIdleTimeoutAvailable(VOID)
Definition: supportkm.cpp:211
BOOLEAN DriverSpecifiedPowerFrameworkSettings(VOID)
NTSTATUS CommitPowerFrameworkSettings(__in PFX_DRIVER_GLOBALS DriverGlobals, __in PPOX_SETTINGS PoxSettings)
VOID FreezeIdleTimeoutManagementStatus(__in PFX_DRIVER_GLOBALS DriverGlobals)
static __inline VOID MxFreePool(__in PVOID Ptr)
Definition: mxmemorykm.h:41
#define __in
Definition: dbghelp.h:35
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
return pList GetDevice()
DriverGlobals
#define EVENT_TRAP_FIELD
Definition: fxpkgpnp.hpp:64
const UCHAR FxPowerPolicyEventQueueDepth
Definition: fxpkgpnp.hpp:35
FxPowerPolicySxWakeSettingsFlags
@ FxPowerPolicySxWakeDeviceEnabledFlag
@ FxPowerPolicySxWakeChildrenArmedFlag
@ PwrPolPowerTimeoutExpired
@ PwrPolWakeInterruptFired
@ PwrPolPowerDownIoStopped
@ PwrPolPowerUpHwStarted
@ PwrPolPriorityEventsMask
@ PwrPolUsbSelectiveSuspendCompleted
@ PwrPolImplicitPowerDown
@ PwrPolDevicePowerNotRequired
@ PwrPolDevicePowerRequired
@ PwrPolImplicitPowerDownFailed
@ PwrPolS0IdlePolicyChanged
@ PowerPolSingularEventMask
@ PwrPolUsbSelectiveSuspendCallback
@ PwrPolNotOwnerPriorityEventsMask
struct _POX_SETTINGS * PPOX_SETTINGS
struct NOT_POWER_POLICY_OWNER_STATE_TABLE * PNOT_POWER_POLICY_OWNER_STATE_TABLE
@ FxPowerPolicyDefaultTimeout
WDF_DEVICE_POWER_POLICY_STATE(* PFN_NOT_POWER_POLICY_OWNER_STATE_ENTRY_FUNCTION)(FxPkgPnp *This)
WDF_DEVICE_POWER_POLICY_STATE(* PFN_POWER_POLICY_STATE_ENTRY_FUNCTION)(FxPkgPnp *This)
const NOT_POWER_POLICY_OWNER_STATE_TABLE * CPNOT_POWER_POLICY_OWNER_STATE_TABLE
struct POWER_POLICY_STATE_TABLE * PPOWER_POLICY_STATE_TABLE
const POWER_POLICY_EVENT_TARGET_STATE * CPPOWER_POLICY_EVENT_TARGET_STATE
struct _POX_SETTINGS POX_SETTINGS
const POWER_POLICY_STATE_TABLE * CPPOWER_POLICY_STATE_TABLE
@ CancelOwnershipUnclaimed
GLuint buffer
Definition: glext.h:5915
DeviceType
Definition: mmdrv.h:42
#define _Must_inspect_result_
Definition: ms_sal.h:558
CALLBACK_FUNCTION MdCallbackFunctionType
Definition: mxgeneralkm.h:35
@ PowerDeviceD3
Definition: ntpoapi.h:52
enum _DEVICE_POWER_STATE DEVICE_POWER_STATE
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
Definition: xml2sdb.h:80
FxPowerPolicyMachineStateHistory m_States
union FxPowerPolicyMachine::@4779::@4781 m_SingularEventsPresentByName
_Must_inspect_result_ NTSTATUS InitUsbSS(VOID)
FxPowerPolicyOwnerSettings * m_Owner
FxPowerPolicyEvent m_Queue[FxPowerPolicyEventQueueDepth]
FxPowerDeviceArmWakeFromSx m_DeviceArmWakeFromSx
FxPowerDeviceWakeFromSxTriggered m_DeviceWakeFromSxTriggered
static MdCallbackFunctionType _PowerStateCallback
FxPowerDeviceArmWakeFromS0 m_DeviceArmWakeFromS0
FxPowerDeviceDisarmWakeFromSx m_DeviceDisarmWakeFromSx
FxPowerDeviceDisarmWakeFromS0 m_DeviceDisarmWakeFromS0
FxPowerDeviceWakeFromS0Triggered m_DeviceWakeFromS0Triggered
IdleTimeoutManagement m_TimeoutMgmt
PFN_NOT_POWER_POLICY_OWNER_STATE_ENTRY_FUNCTION StateFunc
WDF_DEVICE_POWER_POLICY_STATE CurrentTargetState
CPPOWER_POLICY_EVENT_TARGET_STATE TargetStates
WDF_DEVICE_POWER_POLICY_STATE TargetState
POWER_POLICY_EVENT_TARGET_STATE FirstTargetState
PFN_POWER_POLICY_STATE_ENTRY_FUNCTION StateFunc
CPPOWER_POLICY_EVENT_TARGET_STATE OtherTargetStates
DEVICE_POWER_STATE DxState
FxWmiInstanceInternal * WmiInstance
PFN_WDFDEVICE_WDM_PRE_PO_FX_UNREGISTER_DEVICE EvtDeviceWdmPrePoFxUnregisterDevice
PPO_FX_COMPONENT Component
PPO_FX_COMPONENT_ACTIVE_CONDITION_CALLBACK ComponentActiveConditionCallback
PPO_FX_COMPONENT_IDLE_STATE_CALLBACK ComponentIdleStateCallback
PPO_FX_POWER_CONTROL_CALLBACK PowerControlCallback
PFN_WDFDEVICE_WDM_POST_PO_FX_REGISTER_DEVICE EvtDeviceWdmPostPoFxRegisterDevice
PPO_FX_COMPONENT_IDLE_CONDITION_CALLBACK ComponentIdleConditionCallback
ULONG IdleStateCount
Definition: potypes.h:575
char * PSTR
Definition: typedefs.h:51
uint32_t ULONG
Definition: typedefs.h:59
struct FxPowerPolicyMachineStateHistory::@4778 S
USHORT History[FxPowerPolicyEventQueueDepth]
struct FxPwrPolStateInfo::@4776 Bits
struct FxPwrPolStateInfo::@4777 BitsByName
EVT_WDFDEVICE_WDM_PRE_PO_FX_UNREGISTER_DEVICE * PFN_WDFDEVICE_WDM_PRE_PO_FX_UNREGISTER_DEVICE
Definition: wdfdevice.h:1758
EVT_WDFDEVICE_WDM_POST_PO_FX_REGISTER_DEVICE * PFN_WDFDEVICE_WDM_POST_PO_FX_REGISTER_DEVICE
Definition: wdfdevice.h:1743
enum _WDF_DEVICE_POWER_POLICY_STATE WDF_DEVICE_POWER_POLICY_STATE
_Must_inspect_result_ _In_ WDFWMIINSTANCE WmiInstance
Definition: wdfwmi.h:514
PO_FX_COMPONENT_ACTIVE_CONDITION_CALLBACK * PPO_FX_COMPONENT_ACTIVE_CONDITION_CALLBACK
Definition: potypes.h:498
PO_FX_COMPONENT_IDLE_CONDITION_CALLBACK * PPO_FX_COMPONENT_IDLE_CONDITION_CALLBACK
Definition: potypes.h:508
PO_FX_COMPONENT_IDLE_STATE_CALLBACK * PPO_FX_COMPONENT_IDLE_STATE_CALLBACK
Definition: potypes.h:519
PO_FX_POWER_CONTROL_CALLBACK * PPO_FX_POWER_CONTROL_CALLBACK
Definition: potypes.h:552
unsigned char UCHAR
Definition: xmlstorage.h:181
unsigned char BYTE
Definition: xxhash.c:193