ReactOS  0.4.15-dev-2703-g05fb0f1
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
161  )
162 {
163  FxPkgPnp* pPkgPnp;
164  KIRQL irql;
166 
167  pPkgPnp = (FxPkgPnp*) Context;
168 
169  //
170  // Ideally we would like to complete the S0 irp before we start
171  // processing the event in the state machine so that the D0 irp
172  // comes after the S0 is moving up the stack...
173  //
174  // ... BUT ...
175  //
176  // ... by allowing the S0 irp to go up the stack first, we must then
177  // handle pnp requests from the current power policy state (because
178  // the S0 irp could be the last S irp in the system and when completed,
179  // the pnp lock is released). So, we process the event first so
180  // that we can move into a state where we can handle pnp events in
181  // the power policy state machine.
182  //
183  // We mitigate the situation a little bit by forcing the processing of the
184  // event to occur on the power policy thread rather then in the current
185  // context.
186  //
187  Mx::MxRaiseIrql(DISPATCH_LEVEL, &irql);
189  Mx::MxLowerIrql(irql);
190 
192 
193  //
194  // Let the irp continue on its way
195  //
196  if (irp.PendingReturned()) {
198  }
199 
201  OriginalIrp);
202 
203  return irp.GetStatus();
204 }
205 
207 NTSTATUS
212  )
213 {
214  FxPkgFdo *pThis;
216 
218 
219  pThis = (FxPkgFdo*) Context;
220 
221  ASSERT(pThis->IsPowerPolicyOwner());
223 
225 
226  //
227  // Power policy will complete the system irp
228  //
230 }
231 
233 NTSTATUS
235  __in FxIrp *Irp
236  )
237 {
240 
241  m_SystemPowerState = (BYTE) Irp->GetParameterPowerStateSystemState();
243  Irp->GetParameterPowerState());
244 
245  if (IsPowerPolicyOwner()) {
246  //
247  // If we are going to S0, we just notify the power policy state machine
248  // and then let the request go (per the fast resume spec). Otherwise,
249  // send the request down and on the way up, send the Dx request.
250  //
252  //
253  // Post the event into the state machine when the irp is going up
254  // the stack. See the comment in _SystemPowerS0Completion for more
255  // detail as to why.
256  //
257  Irp->CopyCurrentIrpStackLocationToNext();
258  Irp->SetCompletionRoutineEx(deviceObject.GetObject(),
260  this);
261 
262  return Irp->PoCallDriver(m_Device->GetAttachedDevice());
263  }
264  else {
265  //
266  // Stash away the irp for the power policy state machine. We will
267  // post the event to the power policy state machine when the S irp
268  // completes back to this driver.
269  //
271 
272  Irp->CopyCurrentIrpStackLocationToNext();
273  Irp->SetCompletionRoutineEx(deviceObject.GetObject(),
275  this);
276 
277  Irp->PoCallDriver(m_Device->GetAttachedDevice());
278 
280  }
281  }
282  else {
283  //
284  // We don't do anything with S irps if we are not the power policy
285  // owner.
286  //
287  // This will release the remove lock as well.
288  //
289  status = _PowerPassDown(this, Irp);
290  }
291 
292  return status;
293 }
294 
296 NTSTATUS
298  __in FxIrp *Irp
299  )
300 
301 {
303 
304  if (IsPowerPolicyOwner()) {
307  //
308  // A power irp arrived, but we did not request it. log and bugcheck
309  //
312  "Received set device power irp 0x%p on WDFDEVICE 0x%p !devobj 0x%p, "
313  "but the irp was not requested by the device (the power policy owner)",
314  Irp->GetIrp(), m_Device->GetHandle(),
316 
318  WDF_POWER_MULTIPLE_PPO, // specific type
319  (ULONG_PTR)m_Device->GetDeviceObject(), //parm 2
320  (ULONG_PTR)Irp->GetIrp()); // parm 3
321 
322  /* NOTREACHED */
323  }
324 
325  //
326  // We are no longer requesting a power irp because we received the one
327  // we requested.
328  //
331  } else {
333  }
334  }
335 
336  //
337  // Determine if we are raising or lowering the device power state.
338  //
339  if (Irp->GetParameterPowerStateDeviceState() == PowerDeviceD0) {
341  }
342  else {
344  }
345 
346  return status;
347 }
348 
350 NTSTATUS
352  __in FxIrp *Irp
353  )
354 {
355  Irp->MarkIrpPending();
356  Irp->CopyCurrentIrpStackLocationToNext();
357  Irp->SetCompletionRoutineEx(m_Device->GetDeviceObject(),
359  this);
360 
361  Irp->PoCallDriver(m_Device->GetAttachedDevice());
362 
363  return STATUS_PENDING;
364 }
365 
367 NTSTATUS
372  )
373 {
374  FxPkgFdo* pThis;
376 
378 
379  pThis = (FxPkgFdo*) Context;
380 
381  //
382  // We can safely cache away the device power irp in our fdo package
383  // storage because we know we can only get one device power irp at
384  // a time.
385  //
386  pThis->SetPendingDevicePowerIrp(&irp);
387 
388  //
389  // Kick off the power state machine.
390  //
391  pThis->PowerProcessEvent(PowerD0);
392 
394 }
395 
397 NTSTATUS
399  __in FxIrp *Irp
400  )
401 {
403 
404  //
405  // Kick off the power state machine.
406  //
408 
409  return STATUS_PENDING;
410 }
411 
413 NTSTATUS
415  __in FxIrp *Irp
416  )
417 {
418  if (PowerPolicyIsWakeEnabled()) {
420 
422  Irp->GetParameterPowerStateSystemState()
423  );
424 
425  Irp->SetStatus(status);
426 
427  if (!NT_SUCCESS(status)) {
429  }
430  }
431 
432  //
433  // Passing down the irp because one of the following
434  // a) We don't care b/c we don't control the power policy
435  // b) we are not enabled for arming for wake from Sx
436  // c) we can wake from the queried S state
437  //
438  return _PowerPassDown(this, Irp);
439 }
440 
442 NTSTATUS
444  __in FxIrp *Irp
445  )
446 {
447  //
448  // Either the framework is the power policy owner and we wouldn't be sending
449  // a device query power or we are a subordinate will do what the power
450  // policy owner wants 100% of the time.
451  //
452  Irp->SetStatus(STATUS_SUCCESS);
453 
454  //
455  // This will release the remove lock
456  //
457  return _PowerPassDown(this, Irp);
458 }
459 
460 VOID
462  __in BOOLEAN IrpMustBePresent
463  )
464 {
465  MdIrp pIrp;
466 
468 
469  UNREFERENCED_PARAMETER(IrpMustBePresent);
470  ASSERT(IrpMustBePresent == FALSE || pIrp != NULL);
471 
472  if (pIrp != NULL) {
473  FxIrp irp(pIrp);
474 
476  //
477  // We catch D0 irps on the way up, so complete it
478  //
480  }
481  else {
483 
484  //
485  // We catch Dx irps on the way down, so send it on its way
486  //
487  // This will also release the remove lock
488  //
489  (void) _PowerPassDown(this, &irp);
490  }
491  }
492 }
493 
496  VOID
497  )
498 /*++
499 
500 Routine Description:
501  This function implements the Check Type state. This is FDO code,
502  so the answer is reductionistly simple.
503 
504 Arguments:
505  none
506 
507 Return Value:
508 
509  new power state
510 
511 --*/
512 {
513  return WdfDevStatePowerWaking;
514 }
515 
518  VOID
519  )
520 /*++
521 
522 Routine Description:
523  This function implements the Check Type state. This is FDO code,
524  so the answer is reductionistly simple.
525 
526 Arguments:
527  none
528 
529 Return Value:
530 
531  new power state
532 
533 --*/
534 {
536 }
537 
539 NTSTATUS
541  __out BOOLEAN* ParentOn
542  )
543 /*++
544 
545 Routine Description:
546  This function implements the CheckParent state. Its
547  job is to determine which state we should go to next based on whether
548  the parent is in D0. But since this is the FDO code, we can't know
549  that. So just assume that the PDO will guarantee it.
550 
551 Arguments:
552  none
553 
554 Return Value:
555 
556  new power state
557 
558 --*/
559 {
560  ASSERT(!"This state shouldn't be reachable for an FDO.");
561  *ParentOn = TRUE;
562  return STATUS_SUCCESS;
563 }
564 
565 VOID
567  VOID
568  )
569 /*++
570 
571 Routine Description:
572  This virtual function is a nop for an FDO. PDOs implement this function
573 
574 Arguments:
575  None
576 
577 Return Value:
578  None
579 
580  --*/
581 {
582  DO_NOTHING();
583 }
_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:414
virtual _Must_inspect_result_ NTSTATUS PowerCheckParentOverload(__out BOOLEAN *ParentOn)
Definition: fdopower.cpp:540
#define _Must_inspect_result_
Definition: no_sal2.h:62
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:461
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
LONG NTSTATUS
Definition: precomp.h:26
_Must_inspect_result_ NTSTATUS DispatchDeviceQueryPower(__in FxIrp *Irp)
Definition: fdopower.cpp:443
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 MdCompletionRoutineType _SystemPowerSxCompletion
Definition: fxpkgfdo.hpp:465
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:297
BOOLEAN PendingReturned()
Definition: fxirpum.cpp:429
#define FxVerifierBugCheck(FxDriverGlobals, Error,...)
Definition: fxverifier.h:58
uint32_t ULONG_PTR
Definition: typedefs.h:65
static MdCompletionRoutineType RaiseDevicePowerCompletion
Definition: fxpkgfdo.hpp:454
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:495
FxPkgPnp * pPkgPnp
_Must_inspect_result_ NTSTATUS DispatchSystemSetPower(__in FxIrp *Irp)
Definition: fdopower.cpp:234
FxPowerPolicyOwnerSettings * m_Owner
virtual VOID PowerParentPowerDereference(VOID)
Definition: fdopower.cpp:566
#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
static MdCompletionRoutineType _SystemPowerS0Completion
Definition: fxpkgfdo.hpp:461
#define __inout
Definition: dbghelp.h:50
_In_ PTRANSFER_PACKET _In_ ULONG _In_ PIRP OriginalIrp
Definition: classp.h:1757
_Must_inspect_result_ NTSTATUS LowerDevicePower(__in FxIrp *Irp)
Definition: fdopower.cpp:398
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
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:351
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:517
#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