ReactOS  0.4.15-dev-2961-gecb0c09
selfmanagediostatemachine.cpp
Go to the documentation of this file.
1 /*++
2 Copyright (c) Microsoft. All rights reserved.
3 
4 Module Name:
5 
6  SelfManagedIoStateMachine.cpp
7 
8 Abstract:
9 
10  This module implements the self managed io state machine start / stop logic
11  in the framework.
12 
13 Author:
14 
15 
16 
17 Environment:
18  Both kernel and user mode
19 
20 Revision History:
21 
22 
23 
24 --*/
25 
26 #include "pnppriv.hpp"
27 
28 extern "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 
161  RtlZeroMemory(&m_Events, sizeof(m_Events));
162  RtlZeroMemory(&m_States, sizeof(m_States));
163 
164  //
165  // Make sure we can fit the state into a byte
166  //
167  ASSERT(FxSelfManagedIoMax <= 0xFF);
168 }
169 
170 NTSTATUS
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 
215 VOID
218  )
219 /*++
220 
221 Routine Description:
222  Sets all the function event callbacks.
223 
224 Arguments:
225  Callbacks - list of callbacks to set
226 
227 Return 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 
239 WDFDEVICE
241  VOID
242  )
243 {
244  return m_PkgPnp->GetDevice()->GetHandle();
245 }
246 
248 NTSTATUS
251  )
252 /*++
253 
254 Routine 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 
259 Arguments:
260  Event - The event to feed into the state machine.
261 
262 Return 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 
294  COVERAGE_TRAP();
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 
335 Routine Description:
336  Calls the event callback for initializing self managed io.
337 
338 Arguments:
339  This - instance of the state machine
340 
341  Status - result of the event callback into the driver
342 
343 Return Value:
344  new machine state
345 
346  --*/
347 {
348  *Status = This->m_DeviceSelfManagedIoInit.Invoke(This->GetDeviceHandle());
349 
350  if (NT_SUCCESS(*Status)) {
351  return FxSelfManagedIoStarted;
352  }
353  else {
355  }
356 }
357 
362  )
363 /*++
364 
365 Routine 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 
369 Arguments:
370  This - instance of the state machine
371 
372  Status - result of the event callback into the driver
373 
374 Return Value:
375  new machine state
376 
377  --*/
378 {
379  *Status = This->m_DeviceSelfManagedIoSuspend.Invoke(This->GetDeviceHandle());
380 
381  if (NT_SUCCESS(*Status)) {
382  return FxSelfManagedIoStopped;
383  }
384  else {
385  return FxSelfManagedIoFailed;
386  }
387 }
388 
393  )
394 /*++
395 
396 Routine Description:
397  Invokes the self managed io event callback for restarting self managed io
398  from the stopped state.
399 
400 Arguments:
401  This - instance of the state machine
402 
403  Status - result of the event callback into the driver
404 
405 Return Value:
406  new machine state
407 
408  --*/
409 {
410  *Status = This->m_DeviceSelfManagedIoRestart.Invoke(This->GetDeviceHandle());
411 
412  if (NT_SUCCESS(*Status)) {
413  return FxSelfManagedIoStarted;
414  }
415  else {
416  return FxSelfManagedIoFailed;
417  }
418 }
419 
424  )
425 /*++
426 
427 Routine Description:
428  Calls the self managed io flush routine.
429 
430 Arguments:
431  This - instance of the state machine
432 
433  Status - result of the event callback into the driver
434 
435 Return Value:
436  FxSelfManagedIoFlushed
437 
438  --*/
439 {
441  This->m_DeviceSelfManagedIoFlush.Invoke(This->GetDeviceHandle());
442  return FxSelfManagedIoFlushed;
443 }
444 
449  )
450 /*++
451 
452 Routine Description:
453  Calls the self managed io cleanup routine.
454 
455 Arguments:
456  This - instance of the state machine
457 
458  Status - result of the event callback into the driver
459 
460 Return Value:
461  FxSelfManagedIoFinal
462 
463  --*/
464 {
466 
467  This->m_DeviceSelfManagedIoCleanup.Invoke(This->GetDeviceHandle());
468  return FxSelfManagedIoFinal;
469 }
static const FxSelfManagedIoTargetState m_CreatedStates[]
* PNTSTATUS
Definition: strlen.c:14
#define TRAP_ON_EVENT
Definition: fxpkgpnp.hpp:60
PFN_WDF_DEVICE_SELF_MANAGED_IO_RESTART m_Method
static FxSelfManagedIoStates Flushing(__in FxSelfManagedIoMachine *This, __out PNTSTATUS Status)
__inline CfxDevice * GetDevice(VOID)
Definition: fxpackage.hpp:46
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
MdDeviceObject __inline GetDeviceObject(VOID)
Definition: fxdevice.hpp:174
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
WDFDEVICE __inline GetHandle(VOID)
Definition: fxdevice.hpp:237
CHECK_RETURN_IF_USER_MODE NTSTATUS Initialize()
Definition: fxwaitlock.hpp:235
LONG NTSTATUS
Definition: precomp.h:26
FxPnpDeviceSelfManagedIoFlush m_DeviceSelfManagedIoFlush
static const FxSelfManagedIoTargetState m_StartedStates[]
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
FxPnpDeviceSelfManagedIoCleanup m_DeviceSelfManagedIoCleanup
VOID InitializeMachine(__in PWDF_PNPPOWER_EVENT_CALLBACKS Callbacks)
FxSelfManagedIoMachine(__in FxPkgPnp *PkgPnp)
static const FxSelfManagedIoStateTable m_StateTable[]
static const FxSelfManagedIoTargetState m_FailedStates[]
#define DO_EVENT_TRAP(x)
Definition: fxpkgpnp.hpp:61
#define __out
Definition: dbghelp.h:62
static FxSelfManagedIoStates Suspending(__in FxSelfManagedIoMachine *This, __out PNTSTATUS Status)
#define COVERAGE_TRAP()
Definition: fxmacros.hpp:246
PFN_WDF_DEVICE_SELF_MANAGED_IO_INIT m_Method
static FxSelfManagedIoStates Init(__in FxSelfManagedIoMachine *This, __out PNTSTATUS Status)
FxPnpDeviceSelfManagedIoInit m_DeviceSelfManagedIoInit
static const FxSelfManagedIoTargetState m_FlushedStates[]
Status
Definition: gdiplustypes.h:24
UCHAR History[FxSelfManagedIoEventQueueDepth]
#define ASSERT(a)
Definition: mode.c:44
const struct winhelp_callbacks Callbacks
Definition: callback.c:161
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
unsigned char UCHAR
Definition: xmlstorage.h:181
uint32_t entry
Definition: isohybrid.c:63
#define DEBUGGED_EVENT
Definition: fxpkgpnp.hpp:59
#define _Must_inspect_result_
Definition: ms_sal.h:558
unsigned char BYTE
Definition: xxhash.c:193
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
_Must_inspect_result_ NTSTATUS ProcessEvent(__in FxSelfManagedIoEvents Event)
#define TRACINGPNP
Definition: dbgtrace.h:67
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
UCHAR History[FxSelfManagedIoEventQueueDepth]
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
#define ARRAY_SIZE(a)
Definition: main.h:24
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
PFN_WDF_DEVICE_SELF_MANAGED_IO_FLUSH m_Method
#define NULL
Definition: types.h:112
FxPnpDeviceSelfManagedIoRestart m_DeviceSelfManagedIoRestart
FxPnpDeviceSelfManagedIoSuspend m_DeviceSelfManagedIoSuspend
FxSelfManagedIoMachineEventHistory m_Events
PFN_WDF_DEVICE_SELF_MANAGED_IO_SUSPEND m_Method
PFN_WDF_DEVICE_SELF_MANAGED_IO_CLEANUP m_Method
static FxSelfManagedIoStates Restarting(__in FxSelfManagedIoMachine *This, __out PNTSTATUS Status)
#define __deref_out
Definition: dbghelp.h:26
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define STATUS_SUCCESS
Definition: shellext.h:65
FxSelfManagedIoMachineStateHistory m_States
static const FxSelfManagedIoTargetState m_InitFailedStates[]
static const FxSelfManagedIoTargetState m_StoppedStates[]
#define __in
Definition: dbghelp.h:35
static SERVICE_STATUS status
Definition: service.c:31
static NTSTATUS _CreateAndInit(__deref_out FxSelfManagedIoMachine **SelfManagedIoMachine, __in FxPkgPnp *PkgPnp)
Definition: ps.c:97