1 // 2 // Copyright (C) Microsoft. All rights reserved. 3 // 4 #ifndef _FXSELFMANAGEDIOSTATEMACHINE_H_ 5 #define _FXSELFMANAGEDIOSTATEMACHINE_H_ 6 7 // 8 // This is a magical number based on inspection. If the queue overflows, 9 // it is OK to increase these numbers without fear of either dependencies or 10 // weird side affects. 11 // 12 const UCHAR FxSelfManagedIoEventQueueDepth = 8; 13 14 enum FxSelfManagedIoEvents { 15 SelfManagedIoEventInvalid = 0x00, 16 SelfManagedIoEventStart = 0x01, 17 SelfManagedIoEventCleanup = 0x02, 18 SelfManagedIoEventSuspend = 0x04, 19 SelfManagedIoEventFlush = 0x08, 20 SelfManagedIoEventNull = 0xFF, 21 }; 22 23 enum FxSelfManagedIoStates { 24 FxSelfManagedIoInvalid = 0, 25 FxSelfManagedIoCreated, 26 FxSelfManagedIoInit, 27 FxSelfManagedIoInitFailed, 28 FxSelfManagedIoStarted, 29 FxSelfManagedIoSuspending, 30 FxSelfManagedIoStopped, 31 FxSelfManagedIoRestarting, 32 FxSelfManagedIoFailed, 33 FxSelfManagedIoFlushing, 34 FxSelfManagedIoFlushed, 35 FxSelfManagedIoCleanup, 36 FxSelfManagedIoFinal, 37 FxSelfManagedIoMax, 38 }; 39 40 typedef 41 _Must_inspect_result_ 42 FxSelfManagedIoStates 43 (*PFN_SELF_MANAGED_IO_STATE_ENTRY_FUNCTION)( 44 __in FxSelfManagedIoMachine*, 45 __out PNTSTATUS Status 46 ); 47 48 struct FxSelfManagedIoTargetState { 49 FxSelfManagedIoEvents SelfManagedIoEvent; 50 51 FxSelfManagedIoStates SelfManagedIoState; 52 53 #if FX_SUPER_DBG 54 BOOLEAN EventDebugged; 55 #endif 56 }; 57 58 // 59 // This type of union is done so that we can 60 // 1) shrink the array element to the smallest size possible 61 // 2) keep types within the structure so we can dump it in the debugger 62 // 63 union FxSelfManagedIoMachineEventHistory { 64 struct { 65 FxSelfManagedIoEvents Event1 : 8; 66 FxSelfManagedIoEvents Event2 : 8; 67 FxSelfManagedIoEvents Event3 : 8; 68 FxSelfManagedIoEvents Event4 : 8; 69 FxSelfManagedIoEvents Event5 : 8; 70 FxSelfManagedIoEvents Event6 : 8; 71 FxSelfManagedIoEvents Event7 : 8; 72 FxSelfManagedIoEvents Event8 : 8; 73 } E; 74 75 UCHAR History[FxSelfManagedIoEventQueueDepth]; 76 }; 77 78 // 79 // This type of union is done so that we can 80 // 1) shrink the array element to the smallest size possible 81 // 2) keep types within the structure so we can dump it in the debugger 82 // 83 union FxSelfManagedIoMachineStateHistory { 84 struct { 85 FxSelfManagedIoStates State1 : 8; 86 FxSelfManagedIoStates State2 : 8; 87 FxSelfManagedIoStates State3 : 8; 88 FxSelfManagedIoStates State4 : 8; 89 FxSelfManagedIoStates State5 : 8; 90 FxSelfManagedIoStates State6 : 8; 91 FxSelfManagedIoStates State7 : 8; 92 FxSelfManagedIoStates State8 : 8; 93 } S; 94 95 UCHAR History[FxSelfManagedIoEventQueueDepth]; 96 }; 97 98 struct FxSelfManagedIoStateTable { 99 PFN_SELF_MANAGED_IO_STATE_ENTRY_FUNCTION StateFunc; 100 101 const FxSelfManagedIoTargetState* TargetStates; 102 103 ULONG TargetStatesCount; 104 }; 105 106 class FxSelfManagedIoMachine : public FxStump { 107 108 public: 109 FxSelfManagedIoMachine( 110 __in FxPkgPnp* PkgPnp 111 ); 112 113 static 114 NTSTATUS 115 _CreateAndInit( 116 __deref_out FxSelfManagedIoMachine** SelfManagedIoMachine, 117 __in FxPkgPnp* PkgPnp 118 ); 119 120 121 // 122 // Sets event callbacks 123 // 124 VOID 125 InitializeMachine( 126 __in PWDF_PNPPOWER_EVENT_CALLBACKS Callbacks 127 ); 128 129 _Must_inspect_result_ 130 NTSTATUS Start(VOID)131 Start( 132 VOID 133 ) 134 { 135 return ProcessEvent(SelfManagedIoEventStart); 136 } 137 138 _Must_inspect_result_ 139 NTSTATUS Suspend(VOID)140 Suspend( 141 VOID 142 ) 143 { 144 return ProcessEvent(SelfManagedIoEventSuspend); 145 } 146 147 VOID Flush(VOID)148 Flush( 149 VOID 150 ) 151 { 152 (void) ProcessEvent(SelfManagedIoEventFlush); 153 } 154 155 VOID Cleanup(VOID)156 Cleanup( 157 VOID 158 ) 159 { 160 (void) ProcessEvent(SelfManagedIoEventCleanup); 161 } 162 163 protected: 164 _Must_inspect_result_ 165 NTSTATUS 166 ProcessEvent( 167 __in FxSelfManagedIoEvents Event 168 ); 169 170 static 171 FxSelfManagedIoStates 172 Init( 173 __in FxSelfManagedIoMachine* This, 174 __out PNTSTATUS Status 175 ); 176 177 static 178 FxSelfManagedIoStates 179 Suspending( 180 __in FxSelfManagedIoMachine* This, 181 __out PNTSTATUS Status 182 ); 183 184 static 185 FxSelfManagedIoStates 186 Restarting( 187 __in FxSelfManagedIoMachine* This, 188 __out PNTSTATUS Status 189 ); 190 191 static 192 FxSelfManagedIoStates 193 Flushing( 194 __in FxSelfManagedIoMachine* This, 195 __out PNTSTATUS Status 196 ); 197 198 static 199 FxSelfManagedIoStates 200 Cleanup( 201 __in FxSelfManagedIoMachine* This, 202 __out PNTSTATUS Status 203 ); 204 205 WDFDEVICE 206 GetDeviceHandle( 207 VOID 208 ); 209 210 public: 211 FxPnpDeviceSelfManagedIoCleanup m_DeviceSelfManagedIoCleanup; 212 FxPnpDeviceSelfManagedIoFlush m_DeviceSelfManagedIoFlush; 213 FxPnpDeviceSelfManagedIoInit m_DeviceSelfManagedIoInit; 214 FxPnpDeviceSelfManagedIoSuspend m_DeviceSelfManagedIoSuspend; 215 FxPnpDeviceSelfManagedIoRestart m_DeviceSelfManagedIoRestart; 216 217 protected: 218 FxWaitLockInternal m_StateMachineLock; 219 220 FxPkgPnp* m_PkgPnp; 221 222 // uses FxSelfManagedIoStates values 223 BYTE m_CurrentState; 224 225 UCHAR m_EventHistoryIndex; 226 227 UCHAR m_StateHistoryIndex; 228 229 // extra padded byte is put in here by the compiler 230 231 FxSelfManagedIoMachineEventHistory m_Events; 232 233 FxSelfManagedIoMachineStateHistory m_States; 234 235 static const FxSelfManagedIoStateTable m_StateTable[]; 236 237 static const FxSelfManagedIoTargetState m_CreatedStates[]; 238 static const FxSelfManagedIoTargetState m_InitFailedStates[]; 239 static const FxSelfManagedIoTargetState m_StartedStates[]; 240 static const FxSelfManagedIoTargetState m_StoppedStates[]; 241 static const FxSelfManagedIoTargetState m_FailedStates[]; 242 static const FxSelfManagedIoTargetState m_FlushedStates[]; 243 }; 244 245 #endif // _FXSELFMANAGEDIOSTATEMACHINE_H_ 246