ReactOS 0.4.15-dev-7953-g1f49173
selfmanagediostatemachine.cpp
Go to the documentation of this file.
1/*++
2Copyright (c) Microsoft. All rights reserved.
3
4Module Name:
5
6 SelfManagedIoStateMachine.cpp
7
8Abstract:
9
10 This module implements the self managed io state machine start / stop logic
11 in the framework.
12
13Author:
14
15
16
17Environment:
18 Both kernel and user mode
19
20Revision History:
21
22
23
24--*/
25
26#include "pnppriv.hpp"
27
28extern "C" {
29#if defined(EVENT_TRACING)
30#include "SelfManagedIoStateMachine.tmh"
31#endif
32}
33
34// * - We can get a restart from the created state if a PDO is newly enumerated
35// but was disabled on a previous enumeration. Treat restart as an init
36// in this case.
38{
42};
43
45{
48};
49
51{
53};
54
56{
60};
61
63{
66};
67
69{
73};
74
76{
77 // FxSelfManagedIoCreated
78 { NULL,
81 },
82
83 // FxSelfManagedIoInit
85 NULL,
86 0,
87 },
88
89 // FxSelfManagedIoInitFailed
90 { NULL,
93 },
94
95 // FxSelfManagedIoStarted
96 { NULL,
99 },
100
101 // FxSelfManagedIoSuspending
103 NULL,
104 0,
105 },
106
107 // FxSelfManagedIoStopped
108 { NULL,
111 },
112
113 // FxSelfManagedIoRestarting
115 NULL,
116 0,
117 },
118
119 // FxSelfManagedIoFailed
120 { NULL,
123 },
124
125 // FxSelfManagedIoFlushing
127 NULL,
128 0,
129 },
130
131 // FxSelfManagedIoFlushed
132 { NULL,
135 },
136
137 // FxSelfManagedIoCleanup
139 NULL,
140 0,
141 },
142
143 // FxSelfManagedIoFinal
144 { NULL,
145 NULL,
146 0,
147 },
148};
149
151 __in FxPkgPnp* PkgPnp
152 )
153{
154 m_PkgPnp = PkgPnp;
155
158
160
163
164 //
165 // Make sure we can fit the state into a byte
166 //
167 ASSERT(FxSelfManagedIoMax <= 0xFF);
168}
169
172 __deref_out FxSelfManagedIoMachine** SelfManagedIoMachine,
173 __in FxPkgPnp* PkgPnp
174 )
175{
177 FxSelfManagedIoMachine * selfManagedIoMachine;
178
179 *SelfManagedIoMachine = NULL;
180
181 selfManagedIoMachine = new (PkgPnp->GetDriverGlobals()) FxSelfManagedIoMachine(
182 PkgPnp
183 );
184
185 if (selfManagedIoMachine == NULL) {
187 PkgPnp->GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGPNP,
188 "Self managed I/O state machine allocation failed for "
189 "WDFDEVICE 0x%p",
190 PkgPnp->GetDevice()->GetHandle());
191
193 }
194
195 status = selfManagedIoMachine->m_StateMachineLock.Initialize();
196 if (!NT_SUCCESS(status)) {
198 PkgPnp->GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGPNP,
199 "Self managed I/O state machine lock initialization failed for "
200 "WDFDEVICE 0x%p, %!STATUS!",
201 PkgPnp->GetDevice()->GetHandle(),
202 status);
203
204 delete selfManagedIoMachine;
205
206 return status;
207 }
208
209 *SelfManagedIoMachine = selfManagedIoMachine;
210
211 return status;
212}
213
214
215VOID
218 )
219/*++
220
221Routine Description:
222 Sets all the function event callbacks.
223
224Arguments:
225 Callbacks - list of callbacks to set
226
227Return Value:
228 None
229
230 --*/
231{
232 m_DeviceSelfManagedIoCleanup.m_Method = Callbacks->EvtDeviceSelfManagedIoCleanup;
233 m_DeviceSelfManagedIoFlush.m_Method = Callbacks->EvtDeviceSelfManagedIoFlush;
234 m_DeviceSelfManagedIoInit.m_Method = Callbacks->EvtDeviceSelfManagedIoInit;
235 m_DeviceSelfManagedIoSuspend.m_Method = Callbacks->EvtDeviceSelfManagedIoSuspend;
236 m_DeviceSelfManagedIoRestart.m_Method = Callbacks->EvtDeviceSelfManagedIoRestart;
237}
238
239WDFDEVICE
241 VOID
242 )
243{
244 return m_PkgPnp->GetDevice()->GetHandle();
245}
246
251 )
252/*++
253
254Routine Description:
255 Processes an event and runs it through the state machine. Unlike other
256 state machines in the framework, this one acquires lock in the event
257 processing function rather then relying on the caller to do so.
258
259Arguments:
260 Event - The event to feed into the state machine.
261
262Return Value:
263 result of the event
264
265 --*/
266{
268 FxSelfManagedIoStates newState;
270
272
275 (sizeof(m_Events.History)/sizeof(m_Events.History[0]));
276
278 newState = FxSelfManagedIoMax;
279
280 for (ULONG i = 0; i < entry->TargetStatesCount; i++) {
281 if (entry->TargetStates[i].SelfManagedIoEvent == Event) {
282 DO_EVENT_TRAP(&entry->TargetStates[i]);
283 newState = entry->TargetStates[i].SelfManagedIoState;
284 break;
285 }
286 }
287
288 if (newState == FxSelfManagedIoMax) {
289 //
290 // We always can handle io increment/decrement from any state, but we
291 // should not be dropping any other events from this state.
292 //
293
295 }
296
298
299 while (newState != FxSelfManagedIoMax) {
302 "WDFDEVICE 0x%p !devobj 0x%p entering self managed io state "
303 "%!FxSelfManagedIoStates! from %!FxSelfManagedIoStates!",
306 newState, m_CurrentState);
307
310 (sizeof(m_States.History)/sizeof(m_States.History[0]));
311
312 m_CurrentState = (BYTE) newState;
314
315 if (entry->StateFunc != NULL) {
316 newState = entry->StateFunc(this, &status);
317 }
318 else {
319 newState = FxSelfManagedIoMax;
320 }
321 }
322
324
325 return status;
326}
327
332 )
333/*++
334
335Routine Description:
336 Calls the event callback for initializing self managed io.
337
338Arguments:
339 This - instance of the state machine
340
341 Status - result of the event callback into the driver
342
343Return Value:
344 new machine state
345
346 --*/
347{
348 *Status = This->m_DeviceSelfManagedIoInit.Invoke(This->GetDeviceHandle());
349
350 if (NT_SUCCESS(*Status)) {
352 }
353 else {
355 }
356}
357
362 )
363/*++
364
365Routine Description:
366 Invokes the self managed io suspend event callback. Upon failure goes to
367 the failed state and awaits teardown of the stack.
368
369Arguments:
370 This - instance of the state machine
371
372 Status - result of the event callback into the driver
373
374Return Value:
375 new machine state
376
377 --*/
378{
379 *Status = This->m_DeviceSelfManagedIoSuspend.Invoke(This->GetDeviceHandle());
380
381 if (NT_SUCCESS(*Status)) {
383 }
384 else {
386 }
387}
388
393 )
394/*++
395
396Routine Description:
397 Invokes the self managed io event callback for restarting self managed io
398 from the stopped state.
399
400Arguments:
401 This - instance of the state machine
402
403 Status - result of the event callback into the driver
404
405Return Value:
406 new machine state
407
408 --*/
409{
410 *Status = This->m_DeviceSelfManagedIoRestart.Invoke(This->GetDeviceHandle());
411
412 if (NT_SUCCESS(*Status)) {
414 }
415 else {
417 }
418}
419
424 )
425/*++
426
427Routine Description:
428 Calls the self managed io flush routine.
429
430Arguments:
431 This - instance of the state machine
432
433 Status - result of the event callback into the driver
434
435Return Value:
436 FxSelfManagedIoFlushed
437
438 --*/
439{
441 This->m_DeviceSelfManagedIoFlush.Invoke(This->GetDeviceHandle());
443}
444
449 )
450/*++
451
452Routine Description:
453 Calls the self managed io cleanup routine.
454
455Arguments:
456 This - instance of the state machine
457
458 Status - result of the event callback into the driver
459
460Return Value:
461 FxSelfManagedIoFinal
462
463 --*/
464{
466
467 This->m_DeviceSelfManagedIoCleanup.Invoke(This->GetDeviceHandle());
469}
LONG NTSTATUS
Definition: precomp.h:26
#define ARRAY_SIZE(A)
Definition: main.h:33
const struct winhelp_callbacks Callbacks
Definition: callback.c:161
WDFDEVICE __inline GetHandle(VOID)
Definition: fxdevice.hpp:237
MdDeviceObject __inline GetDeviceObject(VOID)
Definition: fxdevice.hpp:174
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
__inline CfxDevice * GetDevice(VOID)
Definition: fxpackage.hpp:46
PFN_WDF_DEVICE_SELF_MANAGED_IO_CLEANUP m_Method
PFN_WDF_DEVICE_SELF_MANAGED_IO_FLUSH m_Method
PFN_WDF_DEVICE_SELF_MANAGED_IO_INIT m_Method
PFN_WDF_DEVICE_SELF_MANAGED_IO_RESTART m_Method
PFN_WDF_DEVICE_SELF_MANAGED_IO_SUSPEND m_Method
static const FxSelfManagedIoTargetState m_StartedStates[]
static FxSelfManagedIoStates Suspending(__in FxSelfManagedIoMachine *This, __out PNTSTATUS Status)
static const FxSelfManagedIoTargetState m_InitFailedStates[]
FxSelfManagedIoMachineStateHistory m_States
static FxSelfManagedIoStates Flushing(__in FxSelfManagedIoMachine *This, __out PNTSTATUS Status)
FxPnpDeviceSelfManagedIoInit m_DeviceSelfManagedIoInit
VOID InitializeMachine(__in PWDF_PNPPOWER_EVENT_CALLBACKS Callbacks)
FxPnpDeviceSelfManagedIoCleanup m_DeviceSelfManagedIoCleanup
static NTSTATUS _CreateAndInit(__deref_out FxSelfManagedIoMachine **SelfManagedIoMachine, __in FxPkgPnp *PkgPnp)
_Must_inspect_result_ NTSTATUS ProcessEvent(__in FxSelfManagedIoEvents Event)
static const FxSelfManagedIoTargetState m_StoppedStates[]
FxPnpDeviceSelfManagedIoFlush m_DeviceSelfManagedIoFlush
FxSelfManagedIoMachine(__in FxPkgPnp *PkgPnp)
FxSelfManagedIoMachineEventHistory m_Events
static const FxSelfManagedIoTargetState m_FailedStates[]
static const FxSelfManagedIoStateTable m_StateTable[]
static FxSelfManagedIoStates Restarting(__in FxSelfManagedIoMachine *This, __out PNTSTATUS Status)
static const FxSelfManagedIoTargetState m_CreatedStates[]
FxPnpDeviceSelfManagedIoSuspend m_DeviceSelfManagedIoSuspend
static const FxSelfManagedIoTargetState m_FlushedStates[]
static FxSelfManagedIoStates Init(__in FxSelfManagedIoMachine *This, __out PNTSTATUS Status)
FxPnpDeviceSelfManagedIoRestart m_DeviceSelfManagedIoRestart
CHECK_RETURN_IF_USER_MODE NTSTATUS Initialize()
Definition: fxwaitlock.hpp:235
#define __in
Definition: dbghelp.h:35
#define __deref_out
Definition: dbghelp.h:26
#define __out
Definition: dbghelp.h:62
#define TRACINGPNP
Definition: dbgtrace.h:67
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define COVERAGE_TRAP()
Definition: fxmacros.hpp:246
#define DO_EVENT_TRAP(x)
Definition: fxpkgpnp.hpp:61
#define DEBUGGED_EVENT
Definition: fxpkgpnp.hpp:59
#define TRAP_ON_EVENT
Definition: fxpkgpnp.hpp:60
Status
Definition: gdiplustypes.h:25
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
uint32_t entry
Definition: isohybrid.c:63
#define ASSERT(a)
Definition: mode.c:44
* PNTSTATUS
Definition: strlen.c:14
#define _Must_inspect_result_
Definition: ms_sal.h:558
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define STATUS_SUCCESS
Definition: shellext.h:65
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
Definition: ps.c:97
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
UCHAR History[FxSelfManagedIoEventQueueDepth]
UCHAR History[FxSelfManagedIoEventQueueDepth]
unsigned char UCHAR
Definition: xmlstorage.h:181
unsigned char BYTE
Definition: xxhash.c:193