ReactOS 0.4.16-dev-338-g34e76ad
fdopower.cpp
Go to the documentation of this file.
1/*++
2
3Copyright (c) Microsoft Corporation
4
5Module Name:
6
7 FdoPower.cpp
8
9Abstract:
10
11 This module implements the pnp/power package for the driver
12 framework. This, specifically, is the power code.
13
14Author:
15
16
17
18
19Environment:
20
21 Both kernel and user mode
22
23Revision History:
24
25
26
27
28--*/
29
30#include "pnppriv.hpp"
31
32
33
34
35#if defined(EVENT_TRACING)
36extern "C" {
37#include "FdoPower.tmh"
38}
39#endif
40
46 )
47
48/*++
49
50Routine Description:
51
52 This method is invoked when a Power Irp we don't handle comes into the
53 driver.
54
55Arguemnts:
56
57 This - the package
58
59 Irp - a pointer to the FxIrp
60
61Returns:
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
93 )
94/*++
95
96Routine Description:
97
98 This method is invoked when a SetPower IRP enters the driver.
99
100Arguemnts:
101
102 Device - a pointer to the FxDevice
103
104 Irp - a pointer to the FxIrp
105
106Returns:
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
125 __in FxIrp *Irp
126 )
127
128/*++
129
130Routine Description:
131
132 This method is invoked when a QueryPower IRP enters the driver.
133
134Arguemnts:
135
136 This - The package
137
138 Irp - a pointer to the FxIrp
139
140Returns:
141
142 NTSTATUS
143
144--*/
145
146{
147 if (Irp->GetParameterPowerType() == SystemPowerState) {
148 return ((FxPkgFdo*) This)->DispatchSystemQueryPower(Irp);
149 }
150 else {
151 return ((FxPkgFdo*) This)->DispatchDeviceQueryPower(Irp);
152 }
153}
154
162 )
163{
165 KIRQL irql;
167
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
203
204 return irp.GetStatus();
205}
206
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
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
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
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
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
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 //
390
391 //
392 // Kick off the power state machine.
393 //
395
397}
398
402 __in FxIrp *Irp
403 )
404{
406
407 //
408 // Kick off the power state machine.
409 //
411
412 return STATUS_PENDING;
413}
414
418 __in FxIrp *Irp
419 )
420{
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
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
463VOID
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
503Routine Description:
504 This function implements the Check Type state. This is FDO code,
505 so the answer is reductionistly simple.
506
507Arguments:
508 none
509
510Return Value:
511
512 new power state
513
514--*/
515{
517}
518
521 VOID
522 )
523/*++
524
525Routine Description:
526 This function implements the Check Type state. This is FDO code,
527 so the answer is reductionistly simple.
528
529Arguments:
530 none
531
532Return Value:
533
534 new power state
535
536--*/
537{
539}
540
544 __out BOOLEAN* ParentOn
545 )
546/*++
547
548Routine 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
554Arguments:
555 none
556
557Return 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
568VOID
570 VOID
571 )
572/*++
573
574Routine Description:
575 This virtual function is a nop for an FDO. PDOs implement this function
576
577Arguments:
578 None
579
580Return Value:
581 None
582
583 --*/
584{
585 DO_NOTHING();
586}
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
WDFDEVICE __inline GetHandle(VOID)
Definition: fxdevice.hpp:237
MdDeviceObject __inline GetAttachedDevice(VOID)
Definition: fxdevice.hpp:210
MdDeviceObject __inline GetDeviceObject(VOID)
Definition: fxdevice.hpp:174
static FxWdmDeviceExtension * _GetFxWdmExtension(__in MdDeviceObject DeviceObject)
Definition: fxdevicekm.hpp:30
MdRemoveLock GetRemoveLock(VOID)
Definition: fxdevicekm.hpp:47
Definition: fxirp.hpp:28
BOOLEAN PendingReturned()
Definition: fxirpum.cpp:429
VOID StartNextPowerIrp()
Definition: fxirpum.cpp:61
VOID MarkIrpPending()
Definition: fxirpum.cpp:415
VOID SetStatus(__in NTSTATUS Status)
Definition: fxirpum.cpp:457
NTSTATUS GetStatus()
Definition: fxirpum.cpp:466
MdIrp GetIrp(VOID)
Definition: fxirpum.cpp:15
DEVICE_POWER_STATE GetParameterPowerStateDeviceState()
Definition: fxirpum.cpp:695
__inline PFX_DRIVER_GLOBALS GetDriverGlobals(VOID)
Definition: fxobject.hpp:734
CfxDevice * m_Device
Definition: fxobject.hpp:329
virtual WDF_DEVICE_POWER_STATE PowerCheckDeviceTypeOverload(VOID)
Definition: fdopower.cpp:498
virtual WDF_DEVICE_POWER_STATE PowerCheckDeviceTypeNPOverload(VOID)
Definition: fdopower.cpp:520
_Must_inspect_result_ NTSTATUS DispatchDeviceQueryPower(__in FxIrp *Irp)
Definition: fdopower.cpp:446
_Must_inspect_result_ NTSTATUS RaiseDevicePower(__in FxIrp *Irp)
Definition: fdopower.cpp:353
virtual VOID PowerReleasePendingDeviceIrp(__in BOOLEAN IrpMustBePresent=TRUE)
Definition: fdopower.cpp:464
_Must_inspect_result_ NTSTATUS DispatchSystemQueryPower(__in FxIrp *Irp)
Definition: fdopower.cpp:417
static _Must_inspect_result_ NTSTATUS _PowerPassDown(__inout FxPkgPnp *This, __in FxIrp *Irp)
Definition: fdopower.cpp:43
_Must_inspect_result_ NTSTATUS DispatchDeviceSetPower(__in FxIrp *Irp)
Definition: fdopower.cpp:299
static _Must_inspect_result_ NTSTATUS _DispatchSetPower(__inout FxPkgPnp *This, __in FxIrp *Irp)
Definition: fdopower.cpp:90
static MdCompletionRoutineType _SystemPowerS0Completion
Definition: fxpkgfdo.hpp:461
static MdCompletionRoutineType _SystemPowerSxCompletion
Definition: fxpkgfdo.hpp:465
virtual _Must_inspect_result_ NTSTATUS PowerCheckParentOverload(__out BOOLEAN *ParentOn)
Definition: fdopower.cpp:543
_Must_inspect_result_ NTSTATUS DispatchSystemSetPower(__in FxIrp *Irp)
Definition: fdopower.cpp:236
virtual VOID PowerParentPowerDereference(VOID)
Definition: fdopower.cpp:569
static MdCompletionRoutineType RaiseDevicePowerCompletion
Definition: fxpkgfdo.hpp:454
static _Must_inspect_result_ NTSTATUS _DispatchQueryPower(__inout FxPkgPnp *This, __in FxIrp *Irp)
Definition: fdopower.cpp:123
_Must_inspect_result_ NTSTATUS LowerDevicePower(__in FxIrp *Irp)
Definition: fdopower.cpp:401
VOID SetPendingDevicePowerIrp(__inout FxIrp *Irp)
Definition: fxpkgpnp.hpp:3050
VOID PowerProcessEvent(__in FxPowerEvent Event, __in BOOLEAN ProcessEventOnDifferentThread=FALSE)
BOOLEAN IsPowerPolicyOwner(VOID)
Definition: fxpkgpnp.hpp:3612
MdIrp ClearPendingDevicePowerIrp(VOID)
Definition: fxpkgpnp.hpp:3069
_Must_inspect_result_ NTSTATUS PowerPolicyHandleSystemQueryPower(__in SYSTEM_POWER_STATE QueryState)
Definition: fxpkgpnp.cpp:3582
BOOLEAN PowerPolicyIsWakeEnabled(VOID)
Definition: fxpkgpnp.cpp:5769
MdIrp GetPendingSystemPowerIrp(VOID)
Definition: fxpkgpnp.hpp:3105
BYTE m_SystemPowerState
Definition: fxpkgpnp.hpp:4102
VOID SetPendingSystemPowerIrp(__inout FxIrp *Irp)
Definition: fxpkgpnp.hpp:3082
NTSTATUS CompletePowerRequest(__inout FxIrp *Irp, __in NTSTATUS Status)
Definition: fxpkgpnp.cpp:5404
FxPowerPolicyMachine m_PowerPolicyMachine
Definition: fxpkgpnp.hpp:4153
VOID PowerPolicyProcessEvent(__in FxPowerPolicyEvent Event, __in BOOLEAN ProcessEventOnDifferentThread=FALSE)
POWER_STATE SetPowerState(__in POWER_STATE_TYPE Type, __in POWER_STATE State)
__inline MdDeviceObject GetObject(VOID)
static __inline VOID MxReleaseRemoveLock(__in MdRemoveLock RemoveLock, __in PVOID Tag)
Definition: mxgeneralkm.h:278
_In_ PTRANSFER_PACKET _In_ ULONG _In_ PIRP OriginalIrp
Definition: classp.h:1757
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_PENDING
Definition: d3dkmdt.h:43
#define __in
Definition: dbghelp.h:35
#define __inout
Definition: dbghelp.h:50
#define __out
Definition: dbghelp.h:62
#define TRACINGPNP
Definition: dbgtrace.h:67
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
KIRQL irql
Definition: wave.h:1
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
DoTraceLevelMessage(pFxDriverGlobals, TRACE_LEVEL_VERBOSE, TRACINGPNP, "Enter, WDFDEVICE %p", Device)
MxDeviceObject deviceObject
FxPkgPnp * pPkgPnp
FxIrp * pIrp
FxIrp * irp
#define FxVerifierBugCheck(FxDriverGlobals, Error,...)
Definition: fxverifier.h:58
#define ASSERT(a)
Definition: mode.c:44
#define DO_NOTHING()
Definition: mxgeneral.h:32
IWudfIrp * MdIrp
Definition: mxum.h:103
#define _Must_inspect_result_
Definition: no_sal2.h:62
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:325
@ PowerSystemWorking
Definition: ntpoapi.h:36
@ PowerDeviceD0
Definition: ntpoapi.h:49
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
#define STATUS_SUCCESS
Definition: shellext.h:65
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
FxPowerPolicyOwnerSettings * m_Owner
Definition: ps.c:97
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define STDCALL
Definition: wdf.h:45
@ WDF_POWER_MULTIPLE_PPO
Definition: wdfbugcodes.h:70
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ PWDFDEVICE_INIT _In_ BOOLEAN IsPowerPolicyOwner
Definition: wdfdevice.h:2966
enum _WDF_DEVICE_POWER_STATE WDF_DEVICE_POWER_STATE
@ WdfDevStatePowerWaking
Definition: wdfdevice.h:181
@ WdfDevStatePowerWakingNP
Definition: wdfdevice.h:182
_In_ SYSTEM_POWER_STATE SystemPowerState
Definition: iotypes.h:7519
unsigned char BYTE
Definition: xxhash.c:193