ReactOS  0.4.15-dev-3441-g67ad4e7
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,
25  PwrPolPowerUpHwStarted = 0x00000080,
26  PwrPolWakeArrived = 0x00000100,
27  PwrPolWakeSuccess = 0x00000200,
28  PwrPolWakeFailed = 0x00000400,
29  PwrPolIoPresent = 0x00000800,
32  PwrPolSurpriseRemove = 0x00004000,
35  PwrPolPowerDownFailed = 0x00020000,
36  PwrPolPowerUpFailed = 0x00040000,
39  PwrPolPowerUpNotSeen = 0x00200000,
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  //
104  } Bits;
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  //
138  } BitsByName;
139 };
140 
143 
145 
147 };
148 
150 
151 typedef
154  FxPkgPnp* This
155  );
156 
157 typedef struct POWER_POLICY_STATE_TABLE {
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 
187 typedef
190  FxPkgPnp* This
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 
220 struct 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  //
234  PSTR Comment;
235 };
236 
237 struct 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 
244 typedef 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  {
269  WmiInstance = NULL;
271 
273  }
274 
275  ~PolicySettings();
276 
277  //
278  // Dx state to put the device in when the policy is applied
279  //
281 
283 
285 
287 
289 
291 };
292 
293 typedef struct _POX_SETTINGS {
305 
307 
308 private:
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 
374 private:
378  );
379 
380  CfxDevice *
381  GetDevice(
382  VOID
383  );
384 
385 public:
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 
445  NTSTATUS
448  );
449 
450  VOID
453  );
454 
455  BOOLEAN
457  VOID
458  );
459 
460  NTSTATUS
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 
554 public:
556  __in FxPkgPnp* PkgPnp
557  );
558 
560  VOID
561  );
562 
564  NTSTATUS
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 
590 protected:
591  static
594 
595 public:
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 
693 protected:
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 
737  NTSTATUS
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 
772 public:
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_
_Must_inspect_result_ NTSTATUS InitUsbSS(VOID)
FxPowerDeviceWakeFromSxTriggered m_DeviceWakeFromSxTriggered
PPO_FX_COMPONENT_IDLE_STATE_CALLBACK ComponentIdleStateCallback
const POWER_POLICY_STATE_TABLE * CPPOWER_POLICY_STATE_TABLE
FxPowerPolicyEvent m_Queue[FxPowerPolicyEventQueueDepth]
#define TRUE
Definition: types.h:120
PPOX_SETTINGS GetPowerFrameworkSettings(VOID)
WDF_DEVICE_POWER_POLICY_STATE TargetState
FxPowerPolicyMachineStateHistory m_States
static BOOLEAN _SystemManagedIdleTimeoutAvailable(VOID)
Definition: supportkm.cpp:211
LONG NTSTATUS
Definition: precomp.h:26
_In_ ULONG _In_ ULONG State
Definition: potypes.h:516
GLuint buffer
Definition: glext.h:5915
PFN_WDFDEVICE_WDM_POST_PO_FX_REGISTER_DEVICE EvtDeviceWdmPostPoFxRegisterDevice
DriverGlobals
const NOT_POWER_POLICY_OWNER_STATE_TABLE * CPNOT_POWER_POLICY_OWNER_STATE_TABLE
struct _POX_SETTINGS * PPOX_SETTINGS
WDF_DEVICE_POWER_POLICY_STATE(* PFN_NOT_POWER_POLICY_OWNER_STATE_ENTRY_FUNCTION)(FxPkgPnp *This)
struct POWER_POLICY_STATE_TABLE * PPOWER_POLICY_STATE_TABLE
_Must_inspect_result_ _In_ WDFWMIINSTANCE WmiInstance
Definition: wdfwmi.h:514
FxPowerPolicyOwnerSettings(__in FxPkgPnp *PkgPnp)
FxPowerDeviceDisarmWakeFromS0 m_DeviceDisarmWakeFromS0
#define EVENT_TRAP_FIELD
Definition: fxpkgpnp.hpp:64
static __inline VOID MxFreePool(__in PVOID Ptr)
Definition: mxmemorykm.h:41
BOOLEAN DriverSpecifiedPowerFrameworkSettings(VOID)
FxPowerDeviceDisarmWakeFromSx m_DeviceDisarmWakeFromSx
PO_FX_COMPONENT_IDLE_CONDITION_CALLBACK * PPO_FX_COMPONENT_IDLE_CONDITION_CALLBACK
Definition: potypes.h:508
#define FALSE
Definition: types.h:117
PPO_FX_COMPONENT_IDLE_CONDITION_CALLBACK ComponentIdleConditionCallback
long LONG
Definition: pedump.c:60
IdleTimeoutManagement m_TimeoutMgmt
FxPowerPolicySxWakeSettingsFlags
CPPOWER_POLICY_EVENT_TARGET_STATE OtherTargetStates
unsigned char BOOLEAN
PFN_WDFDEVICE_WDM_PRE_PO_FX_UNREGISTER_DEVICE EvtDeviceWdmPrePoFxUnregisterDevice
DeviceType
Definition: mmdrv.h:41
PPO_FX_COMPONENT_ACTIVE_CONDITION_CALLBACK ComponentActiveConditionCallback
enum _DEVICE_POWER_STATE DEVICE_POWER_STATE
PO_FX_POWER_CONTROL_CALLBACK * PPO_FX_POWER_CONTROL_CALLBACK
Definition: potypes.h:552
FxPowerPolicyOwnerSettings * m_Owner
struct FxPwrPolStateInfo::@4539 BitsByName
Definition: xml2sdb.h:79
union FxPowerPolicyMachine::@4541::@4543 m_SingularEventsPresentByName
unsigned char UCHAR
Definition: xmlstorage.h:181
#define InterlockedDecrement
Definition: armddk.h:52
struct NOT_POWER_POLICY_OWNER_STATE_TABLE * PNOT_POWER_POLICY_OWNER_STATE_TABLE
struct FxPowerPolicyMachineStateHistory::@4540 S
FxPowerDeviceWakeFromS0Triggered m_DeviceWakeFromS0Triggered
#define _Must_inspect_result_
Definition: ms_sal.h:558
FxWmiInstanceInternal * WmiInstance
unsigned char BYTE
Definition: xxhash.c:193
#define InterlockedExchange
Definition: armddk.h:54
const UCHAR FxPowerPolicyEventQueueDepth
Definition: fxpkgpnp.hpp:35
USHORT History[FxPowerPolicyEventQueueDepth]
IdleTimeoutStatusUpdateResult UpdateIdleTimeoutStatus(__in IdleTimeoutStatusFlag Flag)
FxPowerDeviceArmWakeFromS0 m_DeviceArmWakeFromS0
#define InterlockedIncrement
Definition: armddk.h:53
PPO_FX_COMPONENT Component
PPO_FX_POWER_CONTROL_CALLBACK PowerControlCallback
unsigned short USHORT
Definition: pedump.c:61
CALLBACK_FUNCTION MdCallbackFunctionType
Definition: mxgeneralkm.h:35
static MdCallbackFunctionType _PowerStateCallback
signed char * PSTR
Definition: retypes.h:7
PFN_NOT_POWER_POLICY_OWNER_STATE_ENTRY_FUNCTION StateFunc
PO_FX_COMPONENT_IDLE_STATE_CALLBACK * PPO_FX_COMPONENT_IDLE_STATE_CALLBACK
Definition: potypes.h:519
EVT_WDFDEVICE_WDM_POST_PO_FX_REGISTER_DEVICE * PFN_WDFDEVICE_WDM_POST_PO_FX_REGISTER_DEVICE
Definition: wdfdevice.h:1743
#define NULL
Definition: types.h:112
DEVICE_POWER_STATE DxState
const POWER_POLICY_EVENT_TARGET_STATE * CPPOWER_POLICY_EVENT_TARGET_STATE
VOID FreezeIdleTimeoutManagementStatus(__in PFX_DRIVER_GLOBALS DriverGlobals)
enum _WDF_DEVICE_POWER_POLICY_STATE WDF_DEVICE_POWER_POLICY_STATE
unsigned int ULONG
Definition: retypes.h:1
PFN_POWER_POLICY_STATE_ENTRY_FUNCTION StateFunc
WDF_DEVICE_POWER_POLICY_STATE(* PFN_POWER_POLICY_STATE_ENTRY_FUNCTION)(FxPkgPnp *This)
NTSTATUS UseSystemManagedIdleTimeout(__in PFX_DRIVER_GLOBALS DriverGlobals)
FxPowerDeviceArmWakeFromSx m_DeviceArmWakeFromSx
_Must_inspect_result_ NTSTATUS Init(VOID)
#define __in
Definition: dbghelp.h:35
EVT_WDFDEVICE_WDM_PRE_PO_FX_UNREGISTER_DEVICE * PFN_WDFDEVICE_WDM_PRE_PO_FX_UNREGISTER_DEVICE
Definition: wdfdevice.h:1758
CPPOWER_POLICY_EVENT_TARGET_STATE TargetStates
ULONG IdleStateCount
Definition: potypes.h:575
PO_FX_COMPONENT_ACTIVE_CONDITION_CALLBACK * PPO_FX_COMPONENT_ACTIVE_CONDITION_CALLBACK
Definition: potypes.h:498
NTSTATUS CommitPowerFrameworkSettings(__in PFX_DRIVER_GLOBALS DriverGlobals, __in PPOX_SETTINGS PoxSettings)
struct FxPwrPolStateInfo::@4538 Bits
WDF_DEVICE_POWER_POLICY_STATE CurrentTargetState
struct _POX_SETTINGS POX_SETTINGS
POWER_POLICY_EVENT_TARGET_STATE FirstTargetState