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