ReactOS  0.4.15-dev-3182-g7b62228
fdopower.cpp
Go to the documentation of this file.
1 /*++
2 
3 Copyright (c) Microsoft Corporation
4 
5 Module Name:
6 
7  FdoPower.cpp
8 
9 Abstract:
10 
11  This module implements the pnp/power package for the driver
12  framework. This, specifically, is the power code.
13 
14 Author:
15 
16 
17 
18 
19 Environment:
20 
21  Both kernel and user mode
22 
23 Revision History:
24 
25 
26 
27 
28 --*/
29 
30 #include "pnppriv.hpp"
31 
32 
33 
34 
35 #if defined(EVENT_TRACING)
36 extern "C" {
37 #include "FdoPower.tmh"
38 }
39 #endif
40 
45  __in FxIrp *Irp
46  )
47 
48 /*++
49 
50 Routine Description:
51 
52  This method is invoked when a Power Irp we don't handle comes into the
53  driver.
54 
55 Arguemnts:
56 
57  This - the package
58 
59  Irp - a pointer to the FxIrp
60 
61 Returns:
62 
63  NTSTATUS
64 
65 --*/
66 {
67  FxPkgFdo* pThis;
69  MdIrp pIrp;
70 
71  pIrp = Irp->GetIrp();
72  pThis = (FxPkgFdo*) This;
73 
74  //
75  // FDOs don't handle this IRP, so simply pass it down.
76  //
77  Irp->StartNextPowerIrp();
78  Irp->CopyCurrentIrpStackLocationToNext();
79 
80  status = Irp->PoCallDriver(pThis->m_Device->GetAttachedDevice());
81 
83  pIrp);
84 
85  return status;
86 }
87 
92  __in FxIrp *Irp
93  )
94 /*++
95 
96 Routine Description:
97 
98  This method is invoked when a SetPower IRP enters the driver.
99 
100 Arguemnts:
101 
102  Device - a pointer to the FxDevice
103 
104  Irp - a pointer to the FxIrp
105 
106 Returns:
107 
108  NTSTATUS
109 
110 --*/
111 
112 {
113  if (Irp->GetParameterPowerType() == SystemPowerState) {
114  return ((FxPkgFdo*) This)->DispatchSystemSetPower(Irp);
115  }
116  else {
117  return ((FxPkgFdo*) This)->DispatchDeviceSetPower(Irp);
118  }
119 }
120 
122 NTSTATUS
125  __in FxIrp *Irp
126  )
127 
128 /*++
129 
130 Routine Description:
131 
132  This method is invoked when a QueryPower IRP enters the driver.
133 
134 Arguemnts:
135 
136  This - The package
137 
138  Irp - a pointer to the FxIrp
139 
140 Returns:
141 
142  NTSTATUS
143 
144 --*/
145 
146 {
147  if (Irp->GetParameterPowerType() == SystemPowerState) {
149  }
150  else {
152  }
153 }
154 
156 NTSTATUS
157 STDCALL
162  )
163 {
164  FxPkgPnp* pPkgPnp;
165  KIRQL irql;
167 
168  pPkgPnp = (FxPkgPnp*) Context;
169 
170  //
171  // Ideally we would like to complete the S0 irp before we start
172  // processing the event in the state machine so that the D0 irp
173  // comes after the S0 is moving up the stack...
174  //
175  // ... BUT ...
176  //
177  // ... by allowing the S0 irp to go up the stack first, we must then
178  // handle pnp requests from the current power policy state (because
179  // the S0 irp could be the last S irp in the system and when completed,
180  // the pnp lock is released). So, we process the event first so
181  // that we can move into a state where we can handle pnp events in
182  // the power policy state machine.
183  //
184  // We mitigate the situation a little bit by forcing the processing of the
185  // event to occur on the power policy thread rather then in the current
186  // context.
187  //
188  Mx::MxRaiseIrql(DISPATCH_LEVEL, &irql);
190  Mx::MxLowerIrql(irql);
191 
193 
194  //
195  // Let the irp continue on its way
196  //
197  if (irp.PendingReturned()) {
199  }
200 
202  OriginalIrp);
203 
204  return irp.GetStatus();
205 }
206 
208 NTSTATUS
209 STDCALL
214  )
215 {
216  FxPkgFdo *pThis;
218 
220 
221  pThis = (FxPkgFdo*) Context;
222 
223  ASSERT(pThis->IsPowerPolicyOwner());
225 
227 
228  //
229  // Power policy will complete the system irp
230  //
232 }
233 
235 NTSTATUS
237  __in FxIrp *Irp
238  )
239 {
242 
243  m_SystemPowerState = (BYTE) Irp->GetParameterPowerStateSystemState();
245  Irp->GetParameterPowerState());
246 
247  if (IsPowerPolicyOwner()) {
248  //
249  // If we are going to S0, we just notify the power policy state machine
250  // and then let the request go (per the fast resume spec). Otherwise,
251  // send the request down and on the way up, send the Dx request.
252  //
254  //
255  // Post the event into the state machine when the irp is going up
256  // the stack. See the comment in _SystemPowerS0Completion for more
257  // detail as to why.
258  //
259  Irp->CopyCurrentIrpStackLocationToNext();
260  Irp->SetCompletionRoutineEx(deviceObject.GetObject(),
262  this);
263 
264  return Irp->PoCallDriver(m_Device->GetAttachedDevice());
265  }
266  else {
267  //
268  // Stash away the irp for the power policy state machine. We will
269  // post the event to the power policy state machine when the S irp
270  // completes back to this driver.
271  //
273 
274  Irp->CopyCurrentIrpStackLocationToNext();
275  Irp->SetCompletionRoutineEx(deviceObject.GetObject(),
277  this);
278 
279  Irp->PoCallDriver(m_Device->GetAttachedDevice());
280 
282  }
283  }
284  else {
285  //
286  // We don't do anything with S irps if we are not the power policy
287  // owner.
288  //
289  // This will release the remove lock as well.
290  //
291  status = _PowerPassDown(this, Irp);
292  }
293 
294  return status;
295 }
296 
298 NTSTATUS
300  __in FxIrp *Irp
301  )
302 
303 {
305 
306  if (IsPowerPolicyOwner()) {
309  //
310  // A power irp arrived, but we did not request it. log and bugcheck
311  //
314  "Received set device power irp 0x%p on WDFDEVICE 0x%p !devobj 0x%p, "
315  "but the irp was not requested by the device (the power policy owner)",
316  Irp->GetIrp(), m_Device->GetHandle(),
318 
320  WDF_POWER_MULTIPLE_PPO, // specific type
321  (ULONG_PTR)m_Device->GetDeviceObject(), //parm 2
322  (ULONG_PTR)Irp->GetIrp()); // parm 3
323 
324  /* NOTREACHED */
325  }
326 
327  //
328  // We are no longer requesting a power irp because we received the one
329  // we requested.
330  //
333  } else {
335  }
336  }
337 
338  //
339  // Determine if we are raising or lowering the device power state.
340  //
341  if (Irp->GetParameterPowerStateDeviceState() == PowerDeviceD0) {
343  }
344  else {
346  }
347 
348  return status;
349 }
350 
352 NTSTATUS
354  __in FxIrp *Irp
355  )
356 {
357  Irp->MarkIrpPending();
358  Irp->CopyCurrentIrpStackLocationToNext();
359  Irp->SetCompletionRoutineEx(m_Device->GetDeviceObject(),
361  this);
362 
363  Irp->PoCallDriver(m_Device->GetAttachedDevice());
364 
365  return STATUS_PENDING;
366 }
367 
369 NTSTATUS
370 STDCALL
375  )
376 {
377  FxPkgFdo* pThis;
379 
381 
382  pThis = (FxPkgFdo*) Context;
383 
384  //
385  // We can safely cache away the device power irp in our fdo package
386  // storage because we know we can only get one device power irp at
387  // a time.
388  //
389  pThis->SetPendingDevicePowerIrp(&irp);
390 
391  //
392  // Kick off the power state machine.
393  //
394  pThis->PowerProcessEvent(PowerD0);
395 
397 }
398 
400 NTSTATUS
402  __in FxIrp *Irp
403  )
404 {
406 
407  //
408  // Kick off the power state machine.
409  //
411 
412  return STATUS_PENDING;
413 }
414 
416 NTSTATUS
418  __in FxIrp *Irp
419  )
420 {
421  if (PowerPolicyIsWakeEnabled()) {
423 
425  Irp->GetParameterPowerStateSystemState()
426  );
427 
428  Irp->SetStatus(status);
429 
430  if (!NT_SUCCESS(status)) {
432  }
433  }
434 
435  //
436  // Passing down the irp because one of the following
437  // a) We don't care b/c we don't control the power policy
438  // b) we are not enabled for arming for wake from Sx
439  // c) we can wake from the queried S state
440  //
441  return _PowerPassDown(this, Irp);
442 }
443 
445 NTSTATUS
447  __in FxIrp *Irp
448  )
449 {
450  //
451  // Either the framework is the power policy owner and we wouldn't be sending
452  // a device query power or we are a subordinate will do what the power
453  // policy owner wants 100% of the time.
454  //
455  Irp->SetStatus(STATUS_SUCCESS);
456 
457  //
458  // This will release the remove lock
459  //
460  return _PowerPassDown(this, Irp);
461 }
462 
463 VOID
465  __in BOOLEAN IrpMustBePresent
466  )
467 {
468  MdIrp pIrp;
469 
471 
472  UNREFERENCED_PARAMETER(IrpMustBePresent);
473  ASSERT(IrpMustBePresent == FALSE || pIrp != NULL);
474 
475  if (pIrp != NULL) {
476  FxIrp irp(pIrp);
477 
479  //
480  // We catch D0 irps on the way up, so complete it
481  //
483  }
484  else {
486 
487  //
488  // We catch Dx irps on the way down, so send it on its way
489  //
490  // This will also release the remove lock
491  //
492  (void) _PowerPassDown(this, &irp);
493  }
494  }
495 }
496 
499  VOID
500  )
501 /*++
502 
503 Routine Description:
504  This function implements the Check Type state. This is FDO code,
505  so the answer is reductionistly simple.
506 
507 Arguments:
508  none
509 
510 Return Value:
511 
512  new power state
513 
514 --*/
515 {
516  return WdfDevStatePowerWaking;
517 }
518 
521  VOID
522  )
523 /*++
524 
525 Routine Description:
526  This function implements the Check Type state. This is FDO code,
527  so the answer is reductionistly simple.
528 
529 Arguments:
530  none
531 
532 Return Value:
533 
534  new power state
535 
536 --*/
537 {
539 }
540 
542 NTSTATUS
544  __out BOOLEAN* ParentOn
545  )
546 /*++
547 
548 Routine Description:
549  This function implements the CheckParent state. Its
550  job is to determine which state we should go to next based on whether
551  the parent is in D0. But since this is the FDO code, we can't know
552  that. So just assume that the PDO will guarantee it.
553 
554 Arguments:
555  none
556 
557 Return Value:
558 
559  new power state
560 
561 --*/
562 {
563  ASSERT(!"This state shouldn't be reachable for an FDO.");
564  *ParentOn = TRUE;
565  return STATUS_SUCCESS;
566 }
567 
568 VOID
570  VOID
571  )
572 /*++
573 
574 Routine Description:
575  This virtual function is a nop for an FDO. PDOs implement this function
576 
577 Arguments:
578  None
579 
580 Return Value:
581  None
582 
583  --*/
584 {
585  DO_NOTHING();
586 }
_Must_inspect_result_ NTSTATUS PowerPolicyHandleSystemQueryPower(__in SYSTEM_POWER_STATE QueryState)
Definition: fxpkgpnp.cpp:3582
POWER_STATE SetPowerState(__in POWER_STATE_TYPE Type, __in POWER_STATE State)
CfxDevice * m_Device
Definition: fxobject.hpp:329
_Must_inspect_result_ NTSTATUS DispatchSystemQueryPower(__in FxIrp *Irp)
Definition: fdopower.cpp:417
static MdCompletionRoutineType _SystemPowerS0Completion
Definition: fxpkgfdo.hpp:461
virtual _Must_inspect_result_ NTSTATUS PowerCheckParentOverload(__out BOOLEAN *ParentOn)
Definition: fdopower.cpp:543
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
virtual VOID PowerReleasePendingDeviceIrp(__in BOOLEAN IrpMustBePresent=TRUE)
Definition: fdopower.cpp:464
MdRemoveLock GetRemoveLock(VOID)
Definition: fxdevicekm.hpp:47
MdDeviceObject __inline GetDeviceObject(VOID)
Definition: fxdevice.hpp:174
BOOLEAN PowerPolicyIsWakeEnabled(VOID)
Definition: fxpkgpnp.cpp:5769
VOID SetStatus(__in NTSTATUS Status)
Definition: fxirpum.cpp:457
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
#define TRUE
Definition: types.h:120
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
WDFDEVICE __inline GetHandle(VOID)
Definition: fxdevice.hpp:237
static MdCompletionRoutineType RaiseDevicePowerCompletion
Definition: fxpkgfdo.hpp:454
LONG NTSTATUS
Definition: precomp.h:26
_Must_inspect_result_ NTSTATUS DispatchDeviceQueryPower(__in FxIrp *Irp)
Definition: fdopower.cpp:446
Definition: fxirp.hpp:28
static _Must_inspect_result_ NTSTATUS _DispatchSetPower(__inout FxPkgPnp *This, __in FxIrp *Irp)
Definition: fdopower.cpp:90
KIRQL irql
Definition: wave.h:1
FxPowerPolicyMachine m_PowerPolicyMachine
Definition: fxpkgpnp.hpp:4153
static _Must_inspect_result_ NTSTATUS _PowerPassDown(__inout FxPkgPnp *This, __in FxIrp *Irp)
Definition: fdopower.cpp:43
FxIrp * pIrp
_Must_inspect_result_ NTSTATUS DispatchDeviceSetPower(__in FxIrp *Irp)
Definition: fdopower.cpp:299
BOOLEAN PendingReturned()
Definition: fxirpum.cpp:429
#define FxVerifierBugCheck(FxDriverGlobals, Error,...)
Definition: fxverifier.h:58
uint32_t ULONG_PTR
Definition: typedefs.h:65
UCHAR KIRQL
Definition: env_spec_w32.h:591
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
MdIrp ClearPendingDevicePowerIrp(VOID)
Definition: fxpkgpnp.hpp:3069
#define FALSE
Definition: types.h:117
_In_ PIRP Irp
Definition: csq.h:116
VOID PowerProcessEvent(__in FxPowerEvent Event, __in BOOLEAN ProcessEventOnDifferentThread=FALSE)
#define __out
Definition: dbghelp.h:62
unsigned char BOOLEAN
VOID StartNextPowerIrp()
Definition: fxirpum.cpp:61
MdDeviceObject __inline GetAttachedDevice(VOID)
Definition: fxdevice.hpp:210
IWudfIrp * MdIrp
Definition: mxum.h:103
virtual WDF_DEVICE_POWER_STATE PowerCheckDeviceTypeOverload(VOID)
Definition: fdopower.cpp:498
FxPkgPnp * pPkgPnp
_Must_inspect_result_ NTSTATUS DispatchSystemSetPower(__in FxIrp *Irp)
Definition: fdopower.cpp:236
FxPowerPolicyOwnerSettings * m_Owner
virtual VOID PowerParentPowerDereference(VOID)
Definition: fdopower.cpp:569
#define STDCALL
Definition: wdf.h:45
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
DEVICE_POWER_STATE GetParameterPowerStateDeviceState()
Definition: fxirpum.cpp:695
VOID PowerPolicyProcessEvent(__in FxPowerPolicyEvent Event, __in BOOLEAN ProcessEventOnDifferentThread=FALSE)
VOID SetPendingDevicePowerIrp(__inout FxIrp *Irp)
Definition: fxpkgpnp.hpp:3050
BOOLEAN IsPowerPolicyOwner(VOID)
Definition: fxpkgpnp.hpp:3612
MdIrp GetPendingSystemPowerIrp(VOID)
Definition: fxpkgpnp.hpp:3105
#define __inout
Definition: dbghelp.h:50
_In_ PTRANSFER_PACKET _In_ ULONG _In_ PIRP OriginalIrp
Definition: classp.h:1757
#define _Must_inspect_result_
Definition: ms_sal.h:558
_Must_inspect_result_ NTSTATUS LowerDevicePower(__in FxIrp *Irp)
Definition: fdopower.cpp:401
VOID MarkIrpPending()
Definition: fxirpum.cpp:415
unsigned char BYTE
Definition: xxhash.c:193
MxDeviceObject deviceObject
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
static FxWdmDeviceExtension * _GetFxWdmExtension(__in MdDeviceObject DeviceObject)
Definition: fxdevicekm.hpp:30
#define TRACINGPNP
Definition: dbgtrace.h:67
static __inline VOID MxReleaseRemoveLock(__in MdRemoveLock RemoveLock, __in PVOID Tag)
Definition: mxgeneralkm.h:278
__inline MdDeviceObject GetObject(VOID)
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
MdIrp GetIrp(VOID)
Definition: fxirpum.cpp:15
static MdCompletionRoutineType _SystemPowerSxCompletion
Definition: fxpkgfdo.hpp:465
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
#define NULL
Definition: types.h:112
NTSTATUS CompletePowerRequest(__inout FxIrp *Irp, __in NTSTATUS Status)
Definition: fxpkgpnp.cpp:5404
VOID SetPendingSystemPowerIrp(__inout FxIrp *Irp)
Definition: fxpkgpnp.hpp:3082
_Must_inspect_result_ NTSTATUS RaiseDevicePower(__in FxIrp *Irp)
Definition: fdopower.cpp:353
BYTE m_SystemPowerState
Definition: fxpkgpnp.hpp:4102
#define ULONG_PTR
Definition: config.h:101
static _Must_inspect_result_ NTSTATUS _DispatchQueryPower(__inout FxPkgPnp *This, __in FxIrp *Irp)
Definition: fdopower.cpp:123
enum _WDF_DEVICE_POWER_STATE WDF_DEVICE_POWER_STATE
#define STATUS_SUCCESS
Definition: shellext.h:65
_In_ SYSTEM_POWER_STATE SystemPowerState
Definition: iotypes.h:7519
virtual WDF_DEVICE_POWER_STATE PowerCheckDeviceTypeNPOverload(VOID)
Definition: fdopower.cpp:520
#define __in
Definition: dbghelp.h:35
static SERVICE_STATUS status
Definition: service.c:31
FxIrp * irp
#define DO_NOTHING()
Definition: mxgeneral.h:32
NTSTATUS GetStatus()
Definition: fxirpum.cpp:466
Definition: ps.c:97