reactos/sdk/lib/drivers/wdf/shared/inc/private/common/fxpkgpnp.hpp

4596 lines
108 KiB
C++
Raw Normal View History

/*++
Copyright (c) Microsoft. All rights reserved.
Module Name:
FxPkgPnp.hpp
Abstract:
This module implements the pnp package for the driver frameworks.
Author:
Environment:
Both kernel and user mode
Revision History:
--*/
#ifndef _FXPKGPNP_H_
#define _FXPKGPNP_H_
//
// These are all magical numbers based on inspection. If the queue overflows,
// it is OK to increase these numbers without fear of either dependencies or
// weird side effects.
//
const UCHAR PnpEventQueueDepth = 8;
const UCHAR PowerEventQueueDepth = 8;
const UCHAR FxPowerPolicyEventQueueDepth = 8;
// @@SMVERIFY_SPLIT_BEGIN
//
// DEBUGGED_EVENT is a TRUE value rather then a FALSE value (and having the field
// name be TrapOnEvent) so that the initializer for the entry in the table has
// to explicitly set this value, otherwise, if left out, the compiler will zero
// out the field, which would lead to mistakenly saying the event was debugged
// if DEBUGGED_EVENT is FALSE.
//
// Basically, we are catching folks who update the table but forget to specify
// TRAP_ON_EVENT when they add the new entry.
//
#if FX_SUPER_DBG
#define DEBUGGED_EVENT , TRUE
#define TRAP_ON_EVENT , FALSE
#define DO_EVENT_TRAP(x) if ((x)->EventDebugged == FALSE) { COVERAGE_TRAP(); }
#define EVENT_TRAP_FIELD BOOLEAN EventDebugged;
#else // FX_SUPER_DBG
#define DEBUGGED_EVENT
#define TRAP_ON_EVENT
#define DO_EVENT_TRAP(x) (0)
// intentionally blank
#define EVENT_TRAP_FIELD
#endif // FX_SUPER_DBG
#if FX_STATE_MACHINE_VERIFY
enum FxStateMachineDeviceType {
FxSmDeviceTypeInvalid = 0,
FxSmDeviceTypePnp,
FxSmDeviceTypePnpFdo,
FxSmDeviceTypePnpPdo,
};
#endif // FX_STATE_MACHINE_VERIFY
// @@SMVERIFY_SPLIT_END
#include "fxpnpcallbacks.hpp"
#include "fxeventqueue.hpp"
//
// Bit-flags for tracking which callback is currently executing.
//
enum FxDeviceCallbackFlags {
// Prepare hardware callback is running.
FXDEVICE_CALLBACK_IN_PREPARE_HARDWARE = 0x01,
};
typedef
VOID
(*PFN_POWER_THREAD_ENQUEUE)(
__in PVOID Context,
__in PWORK_QUEUE_ITEM WorkItem
);
//
// workaround overloaded definition (rpc generated headers all define INTERFACE
// to match the class name).
//
#undef INTERFACE
typedef struct _POWER_THREAD_INTERFACE {
//
// generic interface header
//
INTERFACE Interface;
PFN_POWER_THREAD_ENQUEUE PowerThreadEnqueue;
} POWER_THREAD_INTERFACE, *PPOWER_THREAD_INTERFACE;
//
// What follows here is a series of structures that define three state
// machines. The first is the PnP state machine, followed by the
// Power state machine, followed by the Power Policy state machine.
// The first two will be instantiated in every driver. The third will
// be instantiated only in drivers which are the power policy owners
// for their device stacks, which usually amounts to the being the FDO.
//
#include "fxpnpstatemachine.hpp"
#include "fxpowerstatemachine.hpp"
#include "fxpowerpolicystatemachine.hpp"
#include "fxselfmanagediostatemachine.hpp"
//
// Group these here instead of in the individual headers because, for some reason,
// tracewpp.exe, can't handle such an arrangement.
//
// begin_wpp config
// CUSTOM_TYPE(FxPnpEvent, ItemEnum(FxPnpEvent));
// CUSTOM_TYPE(FxPowerEvent, ItemEnum(FxPowerEvent));
// CUSTOM_TYPE(FxPowerPolicyEvent, ItemEnum(FxPowerPolicyEvent));
// CUSTOM_TYPE(FxPowerIdleFlags, ItemEnum(FxPowerIdleFlags));
// CUSTOM_TYPE(FxPowerIdleStates, ItemEnum(FxPowerIdleStates));
// CUSTOM_TYPE(FxPowerIdleEvents, ItemEnum(FxPowerIdleEvents));
// CUSTOM_TYPE(FxDevicePwrRequirementEvents, ItemEnum(FxDevicePwrRequirementEvents));
// CUSTOM_TYPE(FxDevicePwrRequirementStates, ItemEnum(FxDevicePwrRequirementStates));
// CUSTOM_TYPE(FxWakeInterruptEvents, ItemEnum(FxWakeInterruptEvents));
// CUSTOM_TYPE(FxWakeInterruptStates, ItemEnum(FxWakeInterruptStates));
// CUSTOM_TYPE(FxSelfManagedIoEvents, ItemEnum(FxSelfManagedIoEvents));
// CUSTOM_TYPE(FxSelfManagedIoStates, ItemEnum(FxSelfManagedIoStates));
// end_wpp
//
// These are defined in ntddk.h so its wpp custom type should be
// added to a common header along with other public enums. Howeever until that
// is done, define custom type here.
//
// begin_wpp config
// CUSTOM_TYPE(DEVICE_POWER_STATE, ItemEnum(_DEVICE_POWER_STATE));
// CUSTOM_TYPE(SYSTEM_POWER_STATE, ItemEnum(_SYSTEM_POWER_STATE));
// CUSTOM_TYPE(BUS_QUERY_ID_TYPE, ItemEnum(BUS_QUERY_ID_TYPE));
// CUSTOM_TYPE(DEVICE_RELATION_TYPE, ItemEnum(_DEVICE_RELATION_TYPE));
// CUSTOM_TYPE(pwrmn, ItemListByte(IRP_MN_WAIT_WAKE,IRP_MN_POWER_SEQUENCE,IRP_MN_SET_POWER,IRP_MN_QUERY_POWER));
// end_wpp
//
// Information shared between the power and power policy state machines.
//
struct SharedPowerData {
//
// Current wait wake irp in this device object. Access to this field is
// determined by m_WaitWakeOwner.
//
// m_WaitWakeOwner == TRUE, access is guarded by
// FxPowerMachine::m_WaitWakeLock
//
//
// m_WaitWakeOwner == FALSE, access is guarded InterlockedExchange operations
// and the ability to cancel the request is guarded through
// FxPowerPolicyMachine::m_WaitWakeCancelCompletionOwnership
//
// Any devobj can be both the power policy owner and the wait wake owner,
// but usually this dual role would only be for raw PDOs.
//
MdIrp m_WaitWakeIrp;
//
// Indication whether this power machine owns wait wake irps (and calls
// (dis)arm at bus level callbacks and handles cancellation logic.
//
BOOLEAN m_WaitWakeOwner;
//
// If TRUE the watchdog timer should be extended to a very long period of
// time during debugging for a NP power operation.
//
// NOTE: nowhere in the code do we set this value to TRUE. The debugger
// extension !wdfextendwatchdog will set it to TRUE, so the field must
// stay. If moved, the extension must obviously be updated as well.
//
BOOLEAN m_ExtendWatchDogTimer;
};
const UCHAR DeviceWakeStates = PowerSystemHibernate - PowerSystemWorking + 1;
enum SendDeviceRequestAction {
NoRetry = 0,
Retry,
};
enum NotifyResourcesFlags {
NotifyResourcesNoFlags = 0x00,
NotifyResourcesNP = 0x01,
NotifyResourcesSurpriseRemoved = 0x02,
NotifyResourcesForceDisconnect = 0x04,
NotifyResourcesExplicitPowerup = 0x08,
NotifyResourcesExplicitPowerDown = 0x10,
NotifyResourcesDisconnectInactive = 0x20,
NotifyResourcesArmedForWake = 0x40,
};
enum FxPowerDownType {
FxPowerDownTypeExplicit = 0,
FxPowerDownTypeImplicit,
};
typedef
_Must_inspect_result_
NTSTATUS
(*PFN_PNP_POWER_CALLBACK)(
__inout FxPkgPnp* This,
__inout FxIrp* Irp
);
//
// The naming of these values is very important. The following macros rely on
// it:
//
// (state related:)
// SET_PNP_DEVICE_STATE_BIT
// SET_TRI_STATE_FROM_STATE_BITS
// GET_PNP_STATE_BITS_FROM_STRUCT
//
// (caps related:)
// GET_PNP_CAP_BITS_FROM_STRUCT
// SET_PNP_CAP_IF_TRUE
// SET_PNP_CAP_IF_FALSE
// SET_PNP_CAP
//
// They using the naming convention to generically map the field name in
// WDF_DEVICE_PNP_CAPABILITIES and WDF_DEVICE_STATE to the appropriate bit
// values.
//
enum FxPnpStateAndCapValues {
FxPnpStateDisabledFalse = 0x00000000,
FxPnpStateDisabledTrue = 0x00000001,
FxPnpStateDisabledUseDefault = 0x00000002,
FxPnpStateDisabledMask = 0x00000003,
FxPnpStateDontDisplayInUIFalse = 0x00000000,
FxPnpStateDontDisplayInUITrue = 0x00000004,
FxPnpStateDontDisplayInUIUseDefault = 0x00000008,
FxPnpStateDontDisplayInUIMask = 0x0000000C,
FxPnpStateFailedFalse = 0x00000000,
FxPnpStateFailedTrue = 0x00000010,
FxPnpStateFailedUseDefault = 0x00000020,
FxPnpStateFailedMask = 0x00000030,
FxPnpStateNotDisableableFalse = 0x00000000,
FxPnpStateNotDisableableTrue = 0x00000040,
FxPnpStateNotDisableableUseDefault = 0x00000080,
FxPnpStateNotDisableableMask = 0x000000C0,
FxPnpStateRemovedFalse = 0x00000000,
FxPnpStateRemovedTrue = 0x00000100,
FxPnpStateRemovedUseDefault = 0x00000200,
FxPnpStateRemovedMask = 0x00000300,
FxPnpStateResourcesChangedFalse = 0x00000000,
FxPnpStateResourcesChangedTrue = 0x00000400,
FxPnpStateResourcesChangedUseDefault= 0x00000800,
FxPnpStateResourcesChangedMask = 0x00000C00,
FxPnpStateMask = 0x00000FFF,
FxPnpCapLockSupportedFalse = 0x00000000,
FxPnpCapLockSupportedTrue = 0x00001000,
FxPnpCapLockSupportedUseDefault = 0x00002000,
FxPnpCapLockSupportedMask = 0x00003000,
FxPnpCapEjectSupportedFalse = 0x00000000,
FxPnpCapEjectSupportedTrue = 0x00004000,
FxPnpCapEjectSupportedUseDefault = 0x00008000,
FxPnpCapEjectSupportedMask = 0x0000C000,
FxPnpCapRemovableFalse = 0x00000000,
FxPnpCapRemovableTrue = 0x00010000,
FxPnpCapRemovableUseDefault = 0x00020000,
FxPnpCapRemovableMask = 0x00030000,
FxPnpCapDockDeviceFalse = 0x00000000,
FxPnpCapDockDeviceTrue = 0x00040000,
FxPnpCapDockDeviceUseDefault = 0x00080000,
FxPnpCapDockDeviceMask = 0x000C0000,
FxPnpCapUniqueIDFalse = 0x00000000,
FxPnpCapUniqueIDTrue = 0x00100000,
FxPnpCapUniqueIDUseDefault = 0x00200000,
FxPnpCapUniqueIDMask = 0x00300000,
FxPnpCapSilentInstallFalse = 0x00000000,
FxPnpCapSilentInstallTrue = 0x00400000,
FxPnpCapSilentInstallUseDefault = 0x00800000,
FxPnpCapSilentInstallMask = 0x00C00000,
FxPnpCapSurpriseRemovalOKFalse = 0x00000000,
FxPnpCapSurpriseRemovalOKTrue = 0x01000000,
FxPnpCapSurpriseRemovalOKUseDefault = 0x02000000,
FxPnpCapSurpriseRemovalOKMask = 0x03000000,
FxPnpCapHardwareDisabledFalse = 0x00000000,
FxPnpCapHardwareDisabledTrue = 0x04000000,
FxPnpCapHardwareDisabledUseDefault = 0x08000000,
FxPnpCapHardwareDisabledMask = 0x0C000000,
FxPnpCapNoDisplayInUIFalse = 0x00000000,
FxPnpCapNoDisplayInUITrue = 0x10000000,
FxPnpCapNoDisplayInUIUseDefault = 0x20000000,
FxPnpCapNoDisplayInUIMask = 0x30000000,
FxPnpCapMask = 0x3FFFF000,
};
union FxPnpStateAndCaps {
struct {
// States
WDF_TRI_STATE Disabled : 2;
WDF_TRI_STATE DontDisplayInUI : 2;
WDF_TRI_STATE Failed : 2;
WDF_TRI_STATE NotDisableable : 2;
WDF_TRI_STATE Removed : 2;
WDF_TRI_STATE ResourcesChanged : 2;
// Caps
WDF_TRI_STATE LockSupported : 2;
WDF_TRI_STATE EjectSupported : 2;
WDF_TRI_STATE Removable : 2;
WDF_TRI_STATE DockDevice : 2;
WDF_TRI_STATE UniqueID : 2;
WDF_TRI_STATE SilentInstall : 2;
WDF_TRI_STATE SurpriseRemovalOK : 2;
WDF_TRI_STATE HardwareDisabled : 2;
WDF_TRI_STATE NoDisplayInUI : 2;
} ByEnum;
//
// The bottom 3 nibbles (0xFFF) are the pnp state tri state values encoded
// down to 2 bits each.
//
// The remaining portion (0x3FFFF000) are the pnp caps tri state values
// encoded down to 2 bits each as well.
//
LONG Value;
};
//
// The naming of these values is very important. The following macros rely on it:
// GET_POWER_CAP_BITS_FROM_STRUCT
// SET_POWER_CAP
//
// They using the naming convention to generically map the field name in
// WDF_DEVICE_POWER_CAPABILITIES to the appropriate bit values.
//
enum FxPowerCapValues {
FxPowerCapDeviceD1False = 0x0000,
FxPowerCapDeviceD1True = 0x0001,
FxPowerCapDeviceD1UseDefault = 0x0002,
FxPowerCapDeviceD1Mask = 0x0003,
FxPowerCapDeviceD2False = 0x0000,
FxPowerCapDeviceD2True = 0x0004,
FxPowerCapDeviceD2UseDefault = 0x0008,
FxPowerCapDeviceD2Mask = 0x000C,
FxPowerCapWakeFromD0False = 0x0000,
FxPowerCapWakeFromD0True = 0x0010,
FxPowerCapWakeFromD0UseDefault= 0x0020,
FxPowerCapWakeFromD0Mask = 0x0030,
FxPowerCapWakeFromD1False = 0x0000,
FxPowerCapWakeFromD1True = 0x0040,
FxPowerCapWakeFromD1UseDefault= 0x0080,
FxPowerCapWakeFromD1Mask = 0x00C0,
FxPowerCapWakeFromD2False = 0x0000,
FxPowerCapWakeFromD2True = 0x0100,
FxPowerCapWakeFromD2UseDefault= 0x0200,
FxPowerCapWakeFromD2Mask = 0x0300,
FxPowerCapWakeFromD3False = 0x0000,
FxPowerCapWakeFromD3True = 0x0400,
FxPowerCapWakeFromD3UseDefault= 0x0800,
FxPowerCapWakeFromD3Mask = 0x0C00,
};
struct FxPowerCaps {
//
// Encoded with FxPowerCapValues, which encodes the WDF_TRI_STATE values
//
USHORT Caps;
//
// Default value PowerDeviceMaximum, PowerSystemMaximum indicates not to
// set this value.
//
BYTE DeviceWake; // DEVICE_POWER_STATE
BYTE SystemWake; // SYSTEM_POWER_STATE
//
// Each state is encoded in a nibble in a byte
//
ULONG States;
//
// Default values of -1 indicate not to set this value
//
ULONG D1Latency;
ULONG D2Latency;
ULONG D3Latency;
};
enum FxWmiInstanceAction : UINT32 {
AddInstance,
RemoveInstance
};
struct FxEnumerationInfo : public FxStump {
public:
FxEnumerationInfo(
__in PFX_DRIVER_GLOBALS FxDriverGlobals
) : m_ChildListList(FxDriverGlobals)
{
}
NTSTATUS
Initialize(
VOID
)
{
NTSTATUS status;
status = m_PowerStateLock.Initialize();
if (!NT_SUCCESS(status)) {
return status;
}
status = m_ChildListList.Initialize();
if (!NT_SUCCESS(status)) {
return status;
}
return STATUS_SUCCESS;
}
_Acquires_lock_(_Global_critical_region_)
VOID
AcquireParentPowerStateLock(
__in PFX_DRIVER_GLOBALS FxDriverGlobals
)
{
(VOID) m_PowerStateLock.AcquireLock(FxDriverGlobals);
}
_Releases_lock_(_Global_critical_region_)
VOID
ReleaseParentPowerStateLock(
__in PFX_DRIVER_GLOBALS FxDriverGlobals
)
{
m_PowerStateLock.ReleaseLock(FxDriverGlobals);
}
public:
FxWaitLockInternal m_PowerStateLock;
//
// List of FxChildList objects which contain enumerated children
//
FxWaitLockTransactionedList m_ChildListList;
};
class FxPkgPnp : public FxPackage {
friend FxPnpMachine;
friend FxPowerMachine;
friend FxPowerPolicyMachine;
friend FxPowerPolicyOwnerSettings;
friend FxInterrupt;
protected:
FxPkgPnp(
__in PFX_DRIVER_GLOBALS FxDriverGlobals,
__in CfxDevice* Device,
__in WDFTYPE Type
);
~FxPkgPnp();
virtual
BOOLEAN
Dispose(
VOID
);
_Must_inspect_result_
virtual
NTSTATUS
Dispatch(
__in MdIrp Irp
);
virtual
const PFN_PNP_POWER_CALLBACK*
GetDispatchPnp(
VOID
) =0;
virtual
const PFN_PNP_POWER_CALLBACK*
GetDispatchPower(
VOID
) =0;
VOID
DeleteDevice(
VOID
);
VOID
SetInternalFailure(
VOID
);
NTSTATUS
CompletePowerRequest(
__inout FxIrp* Irp,
__in NTSTATUS Status
);
NTSTATUS
CompletePnpRequest(
__inout FxIrp* Irp,
__in NTSTATUS Status
);
PNP_DEVICE_STATE
HandleQueryPnpDeviceState(
__in PNP_DEVICE_STATE PnpDeviceState
);
_Must_inspect_result_
NTSTATUS
HandleQueryBusRelations(
__inout FxIrp* Irp
);
_Must_inspect_result_
NTSTATUS
HandleQueryDeviceRelations(
__inout FxIrp* Irp,
__inout FxRelatedDeviceList* List
);
_Must_inspect_result_
NTSTATUS
HandleQueryInterface(
__inout FxIrp* Irp,
__out PBOOLEAN CompleteRequest
);
_Must_inspect_result_
NTSTATUS
QueryForCapabilities(
VOID
);
VOID
PnpAssignInterruptsSyncIrql(
VOID
);
_Must_inspect_result_
NTSTATUS
PnpMatchResources(
VOID
);
__drv_when(!NT_SUCCESS(return), __drv_arg(ResourcesMatched, _Must_inspect_result_))
NTSTATUS
PnpPrepareHardware(
__out PBOOLEAN ResourcesMatched
);
_Must_inspect_result_
NTSTATUS
PnpPrepareHardwareInternal(
VOID
);
_Must_inspect_result_
NTSTATUS
PnpReleaseHardware(
VOID
);
_Must_inspect_result_
NTSTATUS
PnpEnableInterfacesAndRegisterWmi(
VOID
);
_Must_inspect_result_
static
NTSTATUS
_PnpStartDevice(
__inout FxPkgPnp* This,
__inout FxIrp* Irp
);
_Must_inspect_result_
static
NTSTATUS
_PnpQueryStopDevice(
__inout FxPkgPnp* This,
__inout FxIrp* Irp
);
_Must_inspect_result_
static
NTSTATUS
_PnpCancelStopDevice(
__inout FxPkgPnp* This,
__inout FxIrp* Irp
);
_Must_inspect_result_
static
NTSTATUS
_PnpStopDevice(
__inout FxPkgPnp* This,
__inout FxIrp* Irp
);
_Must_inspect_result_
static
NTSTATUS
_PnpQueryRemoveDevice(
__inout FxPkgPnp* This,
__inout FxIrp* Irp
);
_Must_inspect_result_
static
NTSTATUS
_PnpCancelRemoveDevice(
__inout FxPkgPnp* This,
__inout FxIrp* Irp
);
_Must_inspect_result_
static
NTSTATUS
_PnpRemoveDevice(
__inout FxPkgPnp* This,
__inout FxIrp* Irp
);
_Must_inspect_result_
NTSTATUS
PnpSurpriseRemoval(
__inout FxIrp* Irp
);
NTSTATUS
FilterResourceRequirements(
__in IO_RESOURCE_REQUIREMENTS_LIST **IoList
);
virtual
VOID
PowerReleasePendingDeviceIrp(
BOOLEAN IrpMustBePresent = TRUE
) =0;
VOID
AddInterruptObject(
__in FxInterrupt* Interrupt
);
VOID
RemoveInterruptObject(
__in FxInterrupt* Interrupt
);
VOID
PnpProcessEventInner(
__inout FxPostProcessInfo* Info
);
VOID
PowerProcessEventInner(
__inout FxPostProcessInfo* Info
);
VOID
PowerPolicyProcessEventInner(
__inout FxPostProcessInfo* Info
);
static
VOID
_PnpProcessEventInner(
__inout FxPkgPnp* This,
__inout FxPostProcessInfo* Info,
__in PVOID WorkerContext
);
static
VOID
_PowerProcessEventInner(
__in FxPkgPnp* This,
__in FxPostProcessInfo* Info,
__in PVOID WorkerContext
);
static
VOID
_PowerPolicyProcessEventInner(
__inout FxPkgPnp* This,
__inout FxPostProcessInfo* Info,
__in PVOID WorkerContext
);
VOID
PnpEnterNewState(
__in WDF_DEVICE_PNP_STATE State
);
VOID
PowerEnterNewState(
__in WDF_DEVICE_POWER_STATE State
);
VOID
PowerPolicyEnterNewState(
__in WDF_DEVICE_POWER_POLICY_STATE State
);
VOID
NotPowerPolicyOwnerEnterNewState(
__in WDF_DEVICE_POWER_POLICY_STATE NewState
);
_Must_inspect_result_
static
NTSTATUS
_DispatchWaitWake(
__inout FxPkgPnp* This,
__inout FxIrp* Irp
);
_Must_inspect_result_
NTSTATUS
DispatchWaitWake(
__inout FxIrp* Irp
);
VOID
SaveState(
__in BOOLEAN UseCanSaveState
);
_Must_inspect_result_
static
NTSTATUS
_PnpDeviceUsageNotification(
__inout FxPkgPnp* This,
__inout FxIrp* Irp
);
_Must_inspect_result_
NTSTATUS
PnpDeviceUsageNotification(
__inout FxIrp* Irp
);
LONG
GetPnpStateInternal(
VOID
);
LONG
GetPnpCapsInternal(
VOID
);
static
VOID
_SetPowerCapState(
__in ULONG Index,
__in DEVICE_POWER_STATE State,
__out PULONG Result
);
static
DEVICE_POWER_STATE
_GetPowerCapState(
__in ULONG Index,
__in ULONG State
);
// begin pnp state machine table based callbacks
static
WDF_DEVICE_PNP_STATE
PnpEventCheckForDevicePresence(
__inout FxPkgPnp* This
);
virtual
BOOLEAN
PnpSendStartDeviceDownTheStackOverload(
VOID
) =0;
virtual
WDF_DEVICE_PNP_STATE
PnpEventCheckForDevicePresenceOverload(
VOID
) = 0;
static
WDF_DEVICE_PNP_STATE
PnpEventEjectHardware(
__inout FxPkgPnp* This
);
virtual
WDF_DEVICE_PNP_STATE
PnpEventEjectHardwareOverload(
VOID
) = 0;
static
WDF_DEVICE_PNP_STATE
PnpEventInitStarting(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_PNP_STATE
PnpEventInitSurpriseRemoved(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_PNP_STATE
PnpEventHardwareAvailable(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_PNP_STATE
PnpEventEnableInterfaces(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_PNP_STATE
PnpEventHardwareAvailablePowerPolicyFailed(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_PNP_STATE
PnpEventQueryRemoveAskDriver(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_PNP_STATE
PnpEventQueryRemoveEnsureDeviceAwake(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_PNP_STATE
PnpEventQueryRemovePending(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_PNP_STATE
PnpEventQueryRemoveStaticCheck(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_PNP_STATE
PnpEventQueriedRemoving(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_PNP_STATE
PnpEventQueryStopAskDriver(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_PNP_STATE
PnpEventQueryStopEnsureDeviceAwake(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_PNP_STATE
PnpEventQueryStopPending(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_PNP_STATE
PnpEventQueryStopStaticCheck(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_PNP_STATE
PnpEventQueryCanceled(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_PNP_STATE
PnpEventRemoved(
__inout FxPkgPnp* This
);
virtual
WDF_DEVICE_PNP_STATE
PnpGetPostRemoveState(
VOID
) =0;
static
WDF_DEVICE_PNP_STATE
PnpEventPdoRemoved(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_PNP_STATE
PnpEventRemovedPdoWait(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_PNP_STATE
PnpEventRemovedPdoSurpriseRemoved(
__inout FxPkgPnp* This
);
virtual
WDF_DEVICE_PNP_STATE
PnpEventPdoRemovedOverload(
VOID
) =0;
virtual
WDF_DEVICE_PNP_STATE
PnpEventFdoRemovedOverload(
VOID
) =0;
virtual
VOID
PnpEventSurpriseRemovePendingOverload(
VOID
);
VOID
PnpEventRemovedCommonCode(
VOID
);
static
WDF_DEVICE_PNP_STATE
PnpEventRemovingDisableInterfaces(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_PNP_STATE
PnpEventRestarting(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_PNP_STATE
PnpEventStarted(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_PNP_STATE
PnpEventStartedCancelStop(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_PNP_STATE
PnpEventStartedCancelRemove(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_PNP_STATE
PnpEventStartedRemoving(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_PNP_STATE
PnpEventStartingFromStopped(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_PNP_STATE
PnpEventStopped(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_PNP_STATE
PnpEventStoppedWaitForStartCompletion(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_PNP_STATE
PnpEventStartedStopping(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_PNP_STATE
PnpEventSurpriseRemoved(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_PNP_STATE
PnpEventInitQueryRemove(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_PNP_STATE
PnpEventInitQueryRemoveCanceled(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_PNP_STATE
PnpEventFdoRemoved(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_PNP_STATE
PnpEventQueriedSurpriseRemove(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_PNP_STATE
PnpEventSurpriseRemoveIoStarted(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_PNP_STATE
PnpEventFailedPowerDown(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_PNP_STATE
PnpEventFailedIoStarting(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_PNP_STATE
PnpEventFailedOwnHardware(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_PNP_STATE
PnpEventFailed(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_PNP_STATE
PnpEventFailedPowerPolicyRemoved(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_PNP_STATE
PnpEventFailedSurpriseRemoved(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_PNP_STATE
PnpEventFailedStarted(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_PNP_STATE
PnpEventFailedInit(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_PNP_STATE
PnpEventPdoInitFailed(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_PNP_STATE
PnpEventRestart(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_PNP_STATE
PnpEventRestartReleaseHardware(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_PNP_STATE
PnpEventRestartHardwareAvailable(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_PNP_STATE
PnpEventPdoRestart(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_PNP_STATE
PnpEventRemovedChildrenRemoved(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_PNP_STATE
PnpEventFinal(
__inout FxPkgPnp* This
);
// end pnp state machine table based callbacks
VOID
PnpPowerPolicyStart(
VOID
);
VOID
PnpPowerPolicyStop(
VOID
);
VOID
PnpPowerPolicySurpriseRemove(
VOID
);
VOID
PnpPowerPolicyRemove(
VOID
);
VOID
PnpFinishProcessingIrp(
__in BOOLEAN IrpMustBePresent = TRUE
);
VOID
PnpDisableInterfaces(
VOID
);
virtual
NTSTATUS
SendIrpSynchronously(
FxIrp* Irp
) =0;
// begin power state machine table based callbacks
static
WDF_DEVICE_POWER_STATE
PowerCheckDeviceType(
__inout FxPkgPnp* This
);
virtual
WDF_DEVICE_POWER_STATE
PowerCheckDeviceTypeOverload(
VOID
) =0;
static
WDF_DEVICE_POWER_STATE
PowerCheckDeviceTypeNP(
__inout FxPkgPnp* This
);
virtual
WDF_DEVICE_POWER_STATE
PowerCheckDeviceTypeNPOverload(
VOID
) =0;
static
WDF_DEVICE_POWER_STATE
PowerEnablingWakeAtBus(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerEnablingWakeAtBusNP(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerCheckParentState(
__inout FxPkgPnp* This
);
virtual
NTSTATUS
PowerCheckParentOverload(
BOOLEAN* ParentOn
) =0;
static
WDF_DEVICE_POWER_STATE
PowerCheckParentStateNP(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerDZero(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerD0NP(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerD0BusWakeOwner(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerD0BusWakeOwnerNP(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerD0ArmedForWake(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerD0ArmedForWakeNP(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerGotoImplicitD3DisarmWakeAtBus(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerD0DisarmingWakeAtBus(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerD0DisarmingWakeAtBusNP(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerD0Starting(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerD0StartingConnectInterrupt(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerD0StartingDmaEnable(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerD0StartingStartSelfManagedIo(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerDecideD0State(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerGotoD3Stopped(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerStartingCheckDeviceType(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerStartingChild(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerDxDisablingWakeAtBus(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerDxDisablingWakeAtBusNP(
__inout FxPkgPnp* This
);
virtual
NTSTATUS
PowerEnableWakeAtBusOverload(
VOID
)
{
return STATUS_SUCCESS;
}
virtual
VOID
PowerDisableWakeAtBusOverload(
VOID
)
{
}
virtual
VOID
PowerParentPowerDereference(
VOID
) =0;
static
WDF_DEVICE_POWER_STATE
PowerGotoDNotZero(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerGotoDNotZeroNP(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerGotoDNotZeroIoStopped(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerGotoDNotZeroIoStoppedNP(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerGotoDxNPFailed(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerGotoDxArmedForWake(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerGotoDxArmedForWakeNP(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerDNotZeroNP(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerGotoDxIoStoppedArmedForWake(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerGotoDxIoStoppedArmedForWakeNP(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerCheckParentStateArmedForWake(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerCheckParentStateArmedForWakeNP(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerStartSelfManagedIo(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerStartSelfManagedIoNP(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerStartSelfManagedIoFailed(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerStartSelfManagedIoFailedNP(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerWakePending(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerWakePendingNP(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerWaking(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerWakingNP(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerWakingConnectInterrupt(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerWakingConnectInterruptNP(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerWakingConnectInterruptFailed(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerWakingConnectInterruptFailedNP(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerWakingDmaEnable(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerWakingDmaEnableNP(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerWakingDmaEnableFailed(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerWakingDmaEnableFailedNP(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerReportPowerUpFailedDerefParent(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerReportPowerUpFailed(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerPowerFailedPowerDown(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerReportPowerDownFailed(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerInitialConnectInterruptFailed(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerInitialDmaEnableFailed(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerInitialSelfManagedIoFailed(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerInitialPowerUpFailedDerefParent(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerInitialPowerUpFailed(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerDxSurpriseRemovedPowerDown(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerDxSurpriseRemovedPowerUp(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerDxStoppedDisarmWake(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerDxStoppedDisarmWakeNP(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerGotoDxStoppedDisableInterruptNP(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerGotoDxStopped(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerGotoStopped(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerStoppedCompleteDx(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerDxStoppedDecideDxState(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerDxStoppedArmForWake(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerDxStoppedArmForWakeNP(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerFinalPowerDownFailed(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerD0SurpriseRemoved(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerSurpriseRemoved(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerUpFailedDerefParent(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerUpFailed(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerGotoDxFailed(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerGotoDxStoppedDisableInterrupt(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerUpFailedDerefParentNP(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerUpFailedNP(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerNotifyingD0ExitToWakeInterrupts(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerNotifyingD0EntryToWakeInterrupts(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerNotifyingD0ExitToWakeInterruptsNP(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_STATE
PowerNotifyingD0EntryToWakeInterruptsNP(
__inout FxPkgPnp* This
);
// end power state machine table based callbacks
// begin power policy state machine table based callbacks
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolStarting(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolStartingPoweredUp(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolStartingPoweredUpFailed(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolStartingSucceeded(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolStartingFailed(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolStartingDecideS0Wake(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolStartedIdleCapable(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolIdleCapableDeviceIdle(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolDeviceIdleReturnToActive(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolDeviceIdleSleeping(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolDeviceIdleStopping(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolTimerExpiredNoWake(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolTimerExpiredNoWakeCompletePowerDown(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolWaitingUnarmedQueryIdle(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolS0NoWakePowerUp(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolS0NoWakeCompletePowerUp(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolSystemSleepFromDeviceWaitingUnarmed(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolSystemSleepNeedWake(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolSystemSleepNeedWakeCompletePowerUp(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolSystemSleepPowerRequestFailed(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolCheckPowerPageable(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolSleepingWakeWakeArrived(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolSleepingWakeRevertArmWake(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolSystemAsleepWakeArmed(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolSystemWakeDeviceWakeEnabled(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolSystemWakeDeviceWakeEnabledWakeCanceled(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolSystemWakeDeviceWakeDisarm(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolSystemWakeDeviceWakeTriggeredS0(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolSystemWakeDeviceWokeDisarm(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolSleepingWakeWakeArrivedNP(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolSleepingWakeRevertArmWakeNP(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolSleepingWakePowerDownFailed(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolSleepingWakePowerDownFailedWakeCanceled(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolSystemAsleepWakeArmedNP(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolSystemWakeDeviceWakeEnabledNP(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolSystemWakeDeviceWakeEnabledWakeCanceledNP(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolSystemWakeDeviceWakeDisarmNP(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolSystemWakeDeviceWakeTriggeredS0NP(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolSystemWakeDeviceWokeDisarmNP(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolSystemWakeDeviceWakeCompletePowerUp(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolSleeping(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolSleepingNoWakePowerDown(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolSleepingNoWakeCompletePowerDown(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolSleepingNoWakeDxRequestFailed(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolSleepingWakePowerDown(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolSleepingSendWake(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolSystemAsleepNoWake(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolSystemWakeDeviceWakeDisabled(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolSystemWakeDeviceToD0(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolSystemWakeDeviceToD0CompletePowerUp(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolSystemWakeQueryIdle(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolStartedWakeCapable(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolWakeCapableDeviceIdle(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolWakeCapableUsbSSCompleted(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolTimerExpiredDecideUsbSS(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolTimerExpiredWakeCapablePowerDown(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolTimerExpiredWakeCapableSendWake(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolTimerExpiredWakeCapableUsbSS(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolTimerExpiredWakeCapableWakeArrived(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolTimerExpiredWakeCapableCancelWake(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolTimerExpiredWakeCapableWakeCanceled(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolTimerExpiredWakeCapableCleanup(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolTimerExpiredWakeCapableDxAllocFailed(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolTimerExpiredWakeCapableUndoPowerDown(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolTimerExpiredWakeCompletedPowerDown(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolTimerExpiredWakeCompletedPowerUp(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolTimerExpiredWakeCompletedHardwareStarted(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolWaitingArmedUsbSS(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolWaitingArmedQueryIdle(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolIoPresentArmed(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolIoPresentArmedWakeCanceled(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolS0WakeDisarm(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolS0WakeCompletePowerUp(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolTimerExpiredWakeSucceeded(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolTimerExpiredWakeCompletedDisarm(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolWakeFailedUsbSS(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolTimerExpiredWakeCapablePowerDownFailedCancelWake(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolTimerExpiredWakeCapablePowerDownFailedWakeCanceled(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolTimerExpiredWakeCapablePowerDownFailedUsbSS(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolCancelingWakeForSystemSleep(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolCancelingWakeForSystemSleepWakeCanceled(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolDisarmingWakeForSystemSleepCompletePowerUp(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolPowerUpForSystemSleepFailed(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolWokeFromS0UsbSS(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolWokeFromS0(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolWokeFromS0NotifyDriver(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolStoppingResetDevice(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolStoppingResetDeviceCompletePowerUp(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolStoppingResetDeviceFailed(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolStoppingD0(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolStoppingD0Failed(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolStoppingDisarmWake(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolStoppingDisarmWakeCancelWake(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolStoppingDisarmWakeWakeCanceled(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolStopping(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolStoppingSucceeded(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolStoppingFailed(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolStoppingSendStatus(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolStoppedRemoving(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolRemoved(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolRestarting(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolRestartingFailed(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolStoppingCancelTimer(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolStoppingCancelUsbSS(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolStoppingCancelWake(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolCancelUsbSS(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolStarted(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolStartedCancelTimer(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolStartedWakeCapableCancelTimerForSleep(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolStartedWakeCapableSleepingUsbSS(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolStartedIdleCapableCancelTimerForSleep(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolDeviceD0PowerRequestFailed(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolDevicePowerRequestFailed(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolSleepingPowerDownNotProcessed(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolTimerExpiredWakeCapablePowerDownNotProcessed(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolTimerExpiredNoWakePowerDownNotProcessed(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolTimerExpiredNoWakeUndoPowerDown(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolTimerExpiredNoWakeReturnToActive(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolTimerExpiredNoWakePoweredDownDisableIdleTimer(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolPowerUpForSystemSleepNotSeen(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolWaitingArmedStoppingCancelUsbSS(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolWaitingArmedWakeFailedCancelUsbSS(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolWaitingArmedIoPresentCancelUsbSS(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolWaitingArmedWakeSucceededCancelUsbSS(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolCancelingUsbSSForSystemSleep(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolStoppingD0CancelUsbSS(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolWaitingArmedWakeInterruptFired(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolSystemWakeDeviceWakeInterruptFired(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolSystemWakeDeviceWakeInterruptFiredNP(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
PowerPolTimerExpiredWakeCapableWakeInterruptArrived(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
NotPowerPolOwnerStarting(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
NotPowerPolOwnerStarted(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
NotPowerPolOwnerGotoDx(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
NotPowerPolOwnerGotoDxInDx(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
NotPowerPolOwnerGotoD0(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
NotPowerPolOwnerGotoD0InD0(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
NotPowerPolOwnerStopping(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
NotPowerPolOwnerStoppingSendStatus(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
NotPowerPolOwnerStartingFailed(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
NotPowerPolOwnerStoppingFailed(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
NotPowerPolOwnerStoppingPoweringUp(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
NotPowerPolOwnerStoppingPoweringDown(
__inout FxPkgPnp* This
);
static
WDF_DEVICE_POWER_POLICY_STATE
NotPowerPolOwnerRemoved(
__inout FxPkgPnp* This
);
// end power policy state machine table based callbacks
VOID
PowerGotoDx(
VOID
);
BOOLEAN
PowerGotoDxIoStopped(
VOID
);
BOOLEAN
PowerGotoDxIoStoppedNP(
VOID
);
BOOLEAN
PowerDmaEnableAndScan(
__in BOOLEAN ImplicitPowerUp
);
VOID
PowerCompletePendedWakeIrp(
VOID
);
VOID
PowerCompleteWakeRequestFromWithinMachine(
__in NTSTATUS Status
);
BOOLEAN
PowerMakeWakeRequestNonCancelable(
__in NTSTATUS Status
);
BOOLEAN
PowerIsWakeRequestPresent(
VOID
)
{
//
// We don't acquire the spinlock because when we transition to the state
// which will attempt the arming of the device (at bus level), we will
// gracefully handle the absence of the irp.
//
// On the other side if there is no irp and it is set immediately after
// our check, the event posted by the irp's arrival will transition us
// to the state which will attempt the arming.
//
return m_SharedPower.m_WaitWakeIrp != NULL ? TRUE : FALSE;
}
VOID
PowerSendIdlePowerEvent(
__in FxPowerIdleEvents Event
);
VOID
PowerSendPowerDownEvents(
__in FxPowerDownType Type
);
VOID
PowerSendPowerUpEvents(
VOID
);
VOID
PowerSendPowerDownFailureEvent(
__in FxPowerDownType Type
);
VOID
PowerSendPowerUpFailureEvent(
VOID
);
VOID
PowerSetDevicePowerState(
__in WDF_POWER_DEVICE_STATE State
);
_Must_inspect_result_
BOOLEAN
PowerDmaPowerUp(
VOID
);
BOOLEAN
PowerDmaPowerDown(
VOID
);
VOID
PowerConnectInterruptFailed(
VOID
);
static
MdCancelRoutineType
_PowerWaitWakeCancelRoutine;
VOID
PowerPolicyUpdateSystemWakeSource(
__in FxIrp* Irp
);
static
VOID
_PowerSetSystemWakeSource(
__in FxIrp* Irp
);
static
MdRequestPowerCompleteType
_PowerPolDeviceWaitWakeComplete;
static
MdRequestPowerCompleteType
_PowerPolDevicePowerDownComplete;
static
MdRequestPowerCompleteType
_PowerPolDevicePowerUpComplete;
_Must_inspect_result_
NTSTATUS
PowerPolicySendDevicePowerRequest(
__in DEVICE_POWER_STATE DeviceState,
__in SendDeviceRequestAction Action
);
_Must_inspect_result_
NTSTATUS
PowerPolicySendWaitWakeRequest(
__in SYSTEM_POWER_STATE SystemState
);
VOID
PowerPolicyCompleteSystemPowerIrp(
VOID
);
BOOLEAN
PowerPolicyCancelWaitWake(
VOID
);
VOID
PowerPolicySubmitUsbIdleNotification(
VOID
);
BOOLEAN
PowerPolicyCancelUsbSSIfCapable(
VOID
);
VOID
PowerPolicyCancelUsbSS(
VOID
);
static
MdCompletionRoutineType
_PowerPolicyWaitWakeCompletionRoutine;
static
MdCompletionRoutineType
_PowerPolicyUsbSelectiveSuspendCompletionRoutine;
SYSTEM_POWER_STATE
PowerPolicyGetPendingSystemState(
VOID
)
{
FxIrp irp(m_PendingSystemPowerIrp);
//
// In a FastS4 situation, Parameters.Power.State.SystemState will be
// PowerSystemHibernate, while TargetSystemState will indicate the
// true Sx state the machine is moving into.
//
return (SYSTEM_POWER_STATE)
(irp.GetParameterPowerSystemPowerStateContext()).
TargetSystemState;
}
_Must_inspect_result_
NTSTATUS
PowerPolicyHandleSystemQueryPower(
__in SYSTEM_POWER_STATE QueryState
);
BOOLEAN
PowerPolicyCanWakeFromSystemState(
__in SYSTEM_POWER_STATE SystemState
)
{
return SystemState <= PowerPolicyGetDeviceDeepestSystemWakeState();
}
SYSTEM_POWER_STATE
PowerPolicyGetDeviceDeepestSystemWakeState(
VOID
)
{
return (SYSTEM_POWER_STATE) m_SystemWake;
}
DEVICE_POWER_STATE
PowerPolicyGetDeviceDeepestDeviceWakeState(
__in SYSTEM_POWER_STATE SystemState
);
static
CPPNP_STATE_TABLE
GetPnpTableEntry(
__in WDF_DEVICE_PNP_STATE State
)
{
return &m_WdfPnpStates[WdfDevStateNormalize(State) - WdfDevStatePnpObjectCreated];
}
static
CPPOWER_STATE_TABLE
GetPowerTableEntry(
__in WDF_DEVICE_POWER_STATE State
)
{
return &m_WdfPowerStates[WdfDevStateNormalize(State) - WdfDevStatePowerObjectCreated];
}
static
CPPOWER_POLICY_STATE_TABLE
GetPowerPolicyTableEntry(
__in WDF_DEVICE_POWER_POLICY_STATE State
)
{
return &m_WdfPowerPolicyStates[WdfDevStateNormalize(State) - WdfDevStatePwrPolObjectCreated];
}
#if FX_STATE_MACHINE_VERIFY
static
CPPNP_STATE_ENTRY_FN_RETURN_STATE_TABLE
GetPnpStateEntryFunctionReturnStatesTableEntry(
__in WDF_DEVICE_PNP_STATE State
)
{
return &m_WdfPnpStateEntryFunctionReturnStates[WdfDevStateNormalize(State) - WdfDevStatePnpObjectCreated];
}
static
CPPOWER_STATE_ENTRY_FN_RETURN_STATE_TABLE
GetPowerStateEntryFunctionReturnStatesTableEntry(
__in WDF_DEVICE_POWER_STATE State
)
{
return &m_WdfPowerStateEntryFunctionReturnStates[WdfDevStateNormalize(State) - WdfDevStatePowerObjectCreated];
}
static
CPPWR_POL_STATE_ENTRY_FN_RETURN_STATE_TABLE
GetPwrPolStateEntryFunctionReturnStatesTableEntry(
__in WDF_DEVICE_POWER_POLICY_STATE State
)
{
return &m_WdfPwrPolStateEntryFunctionReturnStates[WdfDevStateNormalize(State) - WdfDevStatePwrPolObjectCreated];
}
VOID
ValidatePnpStateEntryFunctionReturnValue(
WDF_DEVICE_PNP_STATE CurrentState,
WDF_DEVICE_PNP_STATE NewState
);
VOID
ValidatePowerStateEntryFunctionReturnValue(
WDF_DEVICE_POWER_STATE CurrentState,
WDF_DEVICE_POWER_STATE NewState
);
VOID
ValidatePwrPolStateEntryFunctionReturnValue(
WDF_DEVICE_POWER_POLICY_STATE CurrentState,
WDF_DEVICE_POWER_POLICY_STATE NewState
);
#endif //FX_STATE_MACHINE_VERIFY
_Must_inspect_result_
static
CPNOT_POWER_POLICY_OWNER_STATE_TABLE
GetNotPowerPolicyOwnerTableEntry(
__in WDF_DEVICE_POWER_POLICY_STATE State
)
{
ULONG i;
for (i = 0;
m_WdfNotPowerPolicyOwnerStates[i].CurrentTargetState != WdfDevStatePwrPolNull;
i++) {
if (m_WdfNotPowerPolicyOwnerStates[i].CurrentTargetState == State) {
return &m_WdfNotPowerPolicyOwnerStates[i];
}
}
return NULL;
}
static
NTSTATUS
_S0IdleQueryInstance(
__in CfxDevice* Device,
__in FxWmiInstanceInternal* Instance,
__in ULONG OutBufferSize,
__out PVOID OutBuffer,
__out PULONG BufferUsed
);
static
NTSTATUS
_S0IdleSetInstance(
__in CfxDevice* Device,
__in FxWmiInstanceInternal* Instance,
__in ULONG InBufferSize,
__in PVOID InBuffer
);
static
NTSTATUS
_S0IdleSetItem(
__in CfxDevice* Device,
__in FxWmiInstanceInternal* Instance,
__in ULONG DataItemId,
__in ULONG InBufferSize,
__in PVOID InBuffer
);
static
NTSTATUS
_SxWakeQueryInstance(
__in CfxDevice* Device,
__in FxWmiInstanceInternal* Instaace,
__in ULONG OutBufferSize,
__out PVOID OutBuffer,
__out PULONG BufferUsed
);
static
NTSTATUS
_SxWakeSetInstance(
__in CfxDevice* Device,
__in FxWmiInstanceInternal* Instance,
__in ULONG InBufferSize,
__in PVOID InBuffer
);
static
NTSTATUS
_SxWakeSetItem(
__in CfxDevice* Device,
__in FxWmiInstanceInternal* Instance,
__in ULONG DataItemId,
__in ULONG InBufferSize,
__in PVOID InBuffer
);
BOOLEAN
IsPresentPendingPnpIrp(
VOID
)
{
return (m_PendingPnPIrp != NULL) ? TRUE : FALSE;
}
VOID
SetPendingPnpIrp(
__inout FxIrp* Irp,
__in BOOLEAN MarkIrpPending = TRUE
);
VOID
SetPendingPnpIrpStatus(
__in NTSTATUS Status
)
{
FxIrp irp(m_PendingPnPIrp);
ASSERT(m_PendingPnPIrp != NULL);
irp.SetStatus(Status);
}
MdIrp
ClearPendingPnpIrp(
VOID
)
{
MdIrp irp;
irp = m_PendingPnPIrp;
m_PendingPnPIrp = NULL;
return irp;
}
MdIrp
GetPendingPnpIrp(
VOID
)
{
return m_PendingPnPIrp;
}
VOID
SetPendingDevicePowerIrp(
__inout FxIrp* Irp
)
{
ASSERT(m_PendingDevicePowerIrp == NULL);
Irp->MarkIrpPending();
m_PendingDevicePowerIrp = Irp->GetIrp();
if (Irp->GetParameterPowerStateDeviceState() > PowerDeviceD0) {
//
// We are powering down, capture the current power action. We will
// reset it to PowerActionNone once we have powered up.
//
m_SystemPowerAction = (UCHAR) Irp->GetParameterPowerShutdownType();
}
}
MdIrp
ClearPendingDevicePowerIrp(
VOID
)
{
MdIrp irp;
irp = m_PendingDevicePowerIrp;
m_PendingDevicePowerIrp = NULL;
return irp;
}
VOID
SetPendingSystemPowerIrp(
__inout FxIrp* Irp
)
{
ASSERT(m_PendingSystemPowerIrp == NULL);
Irp->MarkIrpPending();
m_PendingSystemPowerIrp = Irp->GetIrp();
}
MdIrp
ClearPendingSystemPowerIrp(
VOID
)
{
MdIrp irp;
irp = m_PendingSystemPowerIrp;
m_PendingSystemPowerIrp = NULL;
return irp;
}
MdIrp
GetPendingSystemPowerIrp(
VOID
)
{
return m_PendingSystemPowerIrp;
}
BOOLEAN
IsDevicePowerUpIrpPending(
VOID
)
{
DEVICE_POWER_STATE state;
FxIrp irp(m_PendingDevicePowerIrp);
if (irp.GetIrp() == NULL) {
return FALSE;
}
state = irp.GetParameterPowerStateDeviceState();
return (state == PowerDeviceD0 ? TRUE : FALSE);
}
BOOLEAN
IsUsageSupported(
__in DEVICE_USAGE_NOTIFICATION_TYPE Usage
)
{
return m_SpecialSupport[((ULONG)Usage)-1];
}
VOID
SetUsageSupport(
__in DEVICE_USAGE_NOTIFICATION_TYPE Usage,
__in BOOLEAN Supported
)
{
m_SpecialSupport[((ULONG) Usage)-1] = Supported;
}
LONG
AdjustUsageCount(
__in DEVICE_USAGE_NOTIFICATION_TYPE Usage,
__in BOOLEAN Add
)
{
if (Add) {
return InterlockedIncrement(&m_SpecialFileCount[((ULONG)Usage)-1]);
}
else {
return InterlockedDecrement(&m_SpecialFileCount[((ULONG)Usage)-1]);
}
}
LONG
GetUsageCount(
// __range(WdfSpecialFilePaging, WdfSpecialFileBoot)
__in __range(1, 4) ULONG Usage
)
{
return m_SpecialFileCount[Usage-1];
}
BOOLEAN
IsInSpecialUse(
VOID
)
{
if (GetUsageCount(WdfSpecialFilePaging) == 0 &&
GetUsageCount(WdfSpecialFileHibernation) == 0 &&
GetUsageCount(WdfSpecialFileDump) == 0 &&
GetUsageCount(WdfSpecialFileBoot) == 0) {
return FALSE;
}
else {
return TRUE;
}
}
static
DEVICE_USAGE_NOTIFICATION_TYPE
_SpecialTypeToUsage(
__in WDF_SPECIAL_FILE_TYPE Type
)
{
switch (Type) {
case WdfSpecialFilePaging: return DeviceUsageTypePaging;
case WdfSpecialFileHibernation: return DeviceUsageTypeHibernation;
case WdfSpecialFileDump: return DeviceUsageTypeDumpFile;
case WdfSpecialFileBoot: return DeviceUsageTypeBoot;
default: ASSERT(FALSE);return DeviceUsageTypePaging;
}
}
static
WDF_SPECIAL_FILE_TYPE
_UsageToSpecialType(
__in DEVICE_USAGE_NOTIFICATION_TYPE Type
)
{
switch (Type) {
case DeviceUsageTypePaging: return WdfSpecialFilePaging;
case DeviceUsageTypeHibernation: return WdfSpecialFileHibernation;
case DeviceUsageTypeDumpFile: return WdfSpecialFileDump;
case DeviceUsageTypeBoot: return WdfSpecialFileBoot;
default: ASSERT(FALSE); return WdfSpecialFilePaging;
}
}
ULONG
SetUsageNotificationFlags(
__in DEVICE_USAGE_NOTIFICATION_TYPE Type,
__in BOOLEAN InPath
);
VOID
RevertUsageNotificationFlags(
__in DEVICE_USAGE_NOTIFICATION_TYPE Type,
__in BOOLEAN InPath,
__in ULONG OldFlags
);
VOID
CommitUsageNotification(
__in DEVICE_USAGE_NOTIFICATION_TYPE Type,
__in ULONG OldFlags
);
_Must_inspect_result_
NTSTATUS
CreatePowerThread(
VOID
);
public:
VOID
PnpProcessEvent(
__in FxPnpEvent Event,
__in BOOLEAN ProcessEventOnDifferentThread = FALSE
);
VOID
PowerProcessEvent(
__in FxPowerEvent Event,
__in BOOLEAN ProcessEventOnDifferentThread = FALSE
);
VOID
PowerPolicyProcessEvent(
__in FxPowerPolicyEvent Event,
__in BOOLEAN ProcessEventOnDifferentThread = FALSE
);
BOOLEAN
ShouldProcessPnpEventOnDifferentThread(
__in KIRQL CurrentIrql,
__in BOOLEAN CallerSpecifiedProcessingOnDifferentThread
);
BOOLEAN
ShouldProcessPowerPolicyEventOnDifferentThread(
__in KIRQL CurrentIrql,
__in BOOLEAN CallerSpecifiedProcessingOnDifferentThread
);
VOID
CleanupStateMachines(
__in BOOLEAN ClenaupPnp
);
VOID
CleanupDeviceFromFailedCreate(
__in MxEvent * WaitEvent
);
_Must_inspect_result_
virtual
NTSTATUS
Initialize(
__in PWDFDEVICE_INIT DeviceInit
);
_Must_inspect_result_
NTSTATUS
PostCreateDeviceInitialize(
VOID
);
virtual
VOID
FinishInitialize(
__inout PWDFDEVICE_INIT DeviceInit
);
VOID
SetSpecialFileSupport(
__in WDF_SPECIAL_FILE_TYPE FileType,
__in BOOLEAN Supported
);
_Must_inspect_result_
NTSTATUS
RegisterCallbacks(
__in PWDF_PNPPOWER_EVENT_CALLBACKS DispatchTable
);
VOID
RegisterPowerPolicyCallbacks(
__in PWDF_POWER_POLICY_EVENT_CALLBACKS Callbacks
);
NTSTATUS
RegisterPowerPolicyWmiInstance(
__in const GUID* Guid,
__in FxWmiInstanceInternalCallbacks* Callbacks,
__out FxWmiInstanceInternal** Instance
);
NTSTATUS
PowerPolicySetS0IdleSettings(
__in PWDF_DEVICE_POWER_POLICY_IDLE_SETTINGS Settings
);
NTSTATUS
AssignPowerFrameworkSettings(
__in PWDF_POWER_FRAMEWORK_SETTINGS PowerFrameworkSettings
);
NTSTATUS
PowerPolicySetSxWakeSettings(
__in PWDF_DEVICE_POWER_POLICY_WAKE_SETTINGS Settings,
__in BOOLEAN ArmForWakeIfChildrenAreArmedForWake,
__in BOOLEAN IndicateChildWakeOnParentWake
);
private:
VOID
DisconnectInterruptNP(
VOID
);
NTSTATUS
UpdateWmiInstanceForS0Idle(
__in FxWmiInstanceAction Action
);
VOID
ReadRegistryS0Idle(
__in PCUNICODE_STRING ValueName,
__out BOOLEAN *Enabled
);
NTSTATUS
UpdateWmiInstanceForSxWake(
__in FxWmiInstanceAction Action
);
VOID
ReadRegistrySxWake(
__in PCUNICODE_STRING ValueName,
__out BOOLEAN *Enabled
);
VOID
WriteStateToRegistry(
__in HANDLE RegKey,
__in PUNICODE_STRING ValueName,
__in ULONG Value
);
NTSTATUS
ReadStateFromRegistry(
_In_ PCUNICODE_STRING ValueName,
_Out_ PULONG Value
);
NTSTATUS
UpdateWmiInstance(
_In_ FxWmiInstanceAction Action,
_In_ BOOLEAN ForS0Idle
);
public:
BOOLEAN
PowerIndicateWaitWakeStatus(
__in NTSTATUS WaitWakeStatus
);
BOOLEAN
PowerPolicyIsWakeEnabled(
VOID
);
ULONG
PowerPolicyGetCurrentWakeReason(
VOID
);
BOOLEAN
__inline
PowerPolicyShouldPropagateWakeStatusToChildren(
VOID
)
{
return m_PowerPolicyMachine.m_Owner->m_WakeSettings.IndicateChildWakeOnParentWake;
}
VOID
ChildRemoved(
VOID
)
{
LONG c;
//
// Called by a child that we are waiting on its removal
//
c = InterlockedDecrement(&m_PendingChildCount);
ASSERT(c >= 0);
if (c == 0) {
PnpProcessEvent(PnpEventChildrenRemovalComplete);
}
}
VOID
PowerPolicySetS0IdleState(
__in BOOLEAN State
);
VOID
PowerPolicySetSxWakeState(
__in BOOLEAN State
);
VOID
SetPowerCaps(
__in PWDF_DEVICE_POWER_CAPABILITIES PowerCapabilities
);
VOID
SetPnpCaps(
__in PWDF_DEVICE_PNP_CAPABILITIES PnpCapabilities
);
VOID
GetPnpState(
__out PWDF_DEVICE_STATE State
);
VOID
SetPnpState(
__in PWDF_DEVICE_STATE State
);
VOID
SetDeviceFailed(
__in WDF_DEVICE_FAILED_ACTION FailedAction
);
VOID
SetChildBusInformation(
__in PPNP_BUS_INFORMATION BusInformation
)
{
RtlCopyMemory(&m_BusInformation,
BusInformation,
sizeof(PNP_BUS_INFORMATION));
}
_Must_inspect_result_
NTSTATUS
HandleQueryBusInformation(
__inout FxIrp* Irp
);
_Must_inspect_result_
NTSTATUS
__inline
PowerReference(
__in BOOLEAN WaitForD0,
__in_opt PVOID Tag = NULL,
__in_opt LONG Line = 0,
__in_opt PSTR File = NULL
)
{
return m_PowerPolicyMachine.m_Owner->m_PowerIdleMachine.PowerReference(WaitForD0, Tag, Line, File);
}
VOID
__inline
PowerDereference(
__in_opt PVOID Tag = NULL,
__in_opt LONG Line = 0,
__in_opt PSTR File = NULL
)
{
m_PowerPolicyMachine.m_Owner->m_PowerIdleMachine.IoDecrement(Tag, Line, File);
}
BOOLEAN
HasPowerThread(
VOID
)
{
return m_HasPowerThread;
}
VOID
QueueToPowerThread(
__in PWORK_QUEUE_ITEM WorkItem
)
{
m_PowerThreadInterface.PowerThreadEnqueue(
m_PowerThreadInterface.Interface.Context,
WorkItem
);
}
_Must_inspect_result_
NTSTATUS
AddUsageDevice(
__in MdDeviceObject DependentDevice
);
VOID
RemoveUsageDevice(
__in MdDeviceObject DependentDevice
);
_Must_inspect_result_
NTSTATUS
AddRemovalDevice(
__in MdDeviceObject DependentDevice
);
VOID
RemoveRemovalDevice(
__in MdDeviceObject DependentDevice
);
VOID
ClearRemovalDevicesList(
VOID
);
_Must_inspect_result_
NTSTATUS
AllocateEnumInfo(
VOID
);
VOID
AddChildList(
__in FxChildList* List
);
VOID
RemoveChildList(
__in FxChildList* List
);
VOID
ChildListNotifyRemove(
__inout PLONG PendingCount
);
_Must_inspect_result_
NTSTATUS
AllocateDmaEnablerList(
VOID
);
VOID
AddDmaEnabler(
__in FxDmaEnabler* Enabler
);
VOID
RemoveDmaEnabler(
__in FxDmaEnabler* Enabler
);
VOID
RevokeDmaEnablerResources(
__in FxDmaEnabler* Enabler
);
VOID
AddQueryInterface(
__in FxQueryInterface* QI,
__in BOOLEAN Lock
);
VOID
QueryForD3ColdInterface(
VOID
);
VOID
DropD3ColdInterface(
VOID
);
BOOLEAN
IsPowerPolicyOwner(
VOID
)
{
return m_PowerPolicyMachine.m_Owner != NULL ? TRUE : FALSE;
}
BOOLEAN
SupportsWakeInterrupt(
VOID
)
{
if (m_WakeInterruptCount > 0) {
return TRUE;
} else {
return FALSE;
}
}
BOOLEAN
IsS0IdleWakeFromS0Enabled(
VOID
)
{
if (IsPowerPolicyOwner()) {
return m_PowerPolicyMachine.m_Owner->m_IdleSettings.WakeFromS0Capable;
}
else {
return FALSE;
}
}
BOOLEAN
IsS0IdleSystemManaged(
VOID
)
{
if (IsPowerPolicyOwner()) {
return m_PowerPolicyMachine.m_Owner->m_IdleSettings.m_TimeoutMgmt.UsingSystemManagedIdleTimeout();
}
else {
return FALSE;
}
}
BOOLEAN
IsS0IdleUsbSSEnabled(
VOID
)
{
if (IsPowerPolicyOwner()) {
return (m_PowerPolicyMachine.m_Owner->m_IdleSettings.WakeFromS0Capable &&
m_PowerPolicyMachine.m_Owner->m_IdleSettings.UsbSSCapable);
}
else {
return FALSE;
}
}
BOOLEAN
IsSxWakeEnabled(
VOID
)
{
if (IsPowerPolicyOwner()) {
return m_PowerPolicyMachine.m_Owner->m_WakeSettings.Enabled;
}
else {
return FALSE;
}
}
_Must_inspect_result_
NTSTATUS
PowerPolicyCanChildPowerUp(
__out PBOOLEAN PowerUp
)
{
*PowerUp = FALSE;
if (IsPowerPolicyOwner()) {
NTSTATUS status;
//
// By referencing the parent (this device) we make sure that if the
// parent is in Dx, we force it back into D0 so that this child can
// be in D0.
//
status = PowerReference(FALSE);
if (!NT_SUCCESS(status)) {
return status;
}
//
// m_EnumInfo is valid because the child device is calling into the
// parent device and if there is a child, there is a m_EnumInfo.
//
m_EnumInfo->AcquireParentPowerStateLock(GetDriverGlobals());
//
// The caller has added a power reference to this device, so this device
// will remain in D0 until that power reference has been removed. This
// count is separate from the power ref count b/c the power ref count
// only controls when the idle timer will fire. This count handles the
// race that can occur after we decide that the parent is idle and act
// on it and the child powers up before this parent actually powers
// down.
//
m_PowerPolicyMachine.m_Owner->m_ChildrenPoweredOnCount++;
*PowerUp = m_PowerPolicyMachine.m_Owner->m_ChildrenCanPowerUp;
m_EnumInfo->ReleaseParentPowerStateLock(GetDriverGlobals());
}
else {
//
// The parent (this device) is not the power policy owner. That
// means we cannot poke the parent to come back to D0 and rely on
// the parent being in D0. Our only recourse is to move into D0 and
// ignore the parent's device power state.
//
// We will only get into this situation if the parent is not the
// power policy owner of the stack. This usually means the parent
// is a filter driver in the parent stack and is creating a virtual
// child. Since the child is assumed virtual, it's D state is not
// tied to real hardware and doesn't really matter.
//
*PowerUp = TRUE;
}
return STATUS_SUCCESS;
}
VOID
PowerPolicyChildPoweredDown(
VOID
)
{
//
// If this parent is the power policy owner of the child's stack, release
// the requirement this device to be in D0 while the child is in D0.
//
if (IsPowerPolicyOwner()) {
//
// Decrement the number of children who are powered on
//
m_EnumInfo->AcquireParentPowerStateLock(GetDriverGlobals());
ASSERT(m_PowerPolicyMachine.m_Owner->m_ChildrenPoweredOnCount > 0);
m_PowerPolicyMachine.m_Owner->m_ChildrenPoweredOnCount--;
m_EnumInfo->ReleaseParentPowerStateLock(GetDriverGlobals());
PowerDereference();
}
}
POWER_ACTION
GetSystemPowerAction(
VOID
)
{
return (POWER_ACTION) m_SystemPowerAction;
}
VOID
ProcessDelayedDeletion(
VOID
);
VOID
SignalDeviceRemovedEvent(
VOID
)
{
m_DeviceRemoveProcessed->Set();
}
virtual
NTSTATUS
FireAndForgetIrp(
FxIrp* Irp
) =0;
FxCmResList *
GetTranslatedResourceList(
VOID
)
{
return m_Resources;
}
FxCmResList *
GetRawResourceList(
VOID
)
{
return m_ResourcesRaw;
}
ULONG
GetInterruptObjectCount(
VOID
)
{
return m_InterruptObjectCount;
}
VOID
AckPendingWakeInterruptOperation(
__in BOOLEAN ProcessPowerEventOnDifferentThread
);
VOID
SendEventToAllWakeInterrupts(
__in enum FxWakeInterruptEvents WakeInterruptEvent
);
private:
VOID
PowerPolicyCheckAssumptions(
VOID
);
VOID
PowerCheckAssumptions(
VOID
);
VOID
PnpCheckAssumptions(
VOID
);
VOID
NotifyResourceobjectsToReleaseResources(
VOID
);
_Must_inspect_result_
NTSTATUS
NotifyResourceObjectsD0(
__in ULONG NotifyFlags
);
NTSTATUS
NotifyResourceObjectsDx(
__in ULONG NotifyFlags
);
BOOLEAN
PnpCheckAndIncrementRestartCount(
VOID
);
BOOLEAN
PnpIncrementRestartCountLogic(
_In_ HANDLE RestartKey,
_In_ BOOLEAN CreatedNewKey
);
VOID
PnpCleanupForRemove(
__in BOOLEAN GracefulRemove
);
virtual
NTSTATUS
ProcessRemoveDeviceOverload(
FxIrp* Irp
) =0;
virtual
VOID
DeleteSymbolicLinkOverload(
BOOLEAN GracefulRemove
) =0;
virtual
VOID
QueryForReenumerationInterface(
VOID
) =0;
virtual
VOID
ReleaseReenumerationInterface(
VOID
) =0;
virtual
NTSTATUS
AskParentToRemoveAndReenumerate(
VOID
) =0;
_Must_inspect_result_
NTSTATUS
CreatePowerThreadIfNeeded(
VOID
);
virtual
NTSTATUS
QueryForPowerThread(
VOID
) =0;
VOID
ReleasePowerThread(
VOID
);
_Must_inspect_result_
NTSTATUS
HandleQueryInterfaceForPowerThread(
__inout FxIrp* Irp,
__out PBOOLEAN CompleteRequest
);
_Must_inspect_result_
NTSTATUS
PnpPowerReferenceSelf(
VOID
);
VOID
PnpPowerDereferenceSelf(
VOID
);
static
VOID
_PowerThreadEnqueue(
__in PVOID Context,
__in PWORK_QUEUE_ITEM WorkItem
)
{
BOOLEAN result;
result = ((FxPkgPnp*) Context)->m_PowerThread->QueueWorkItem(WorkItem);
#if DBG
ASSERT(result);
#else
UNREFERENCED_PARAMETER(result);
#endif
}
static
VOID
STDCALL
_PowerThreadInterfaceReference(
__inout PVOID Context
);
static
VOID
STDCALL
_PowerThreadInterfaceDereference(
__inout PVOID Context
);
BOOLEAN
PowerPolicyCanIdlePowerDown(
__in DEVICE_POWER_STATE DxState
);
VOID
PowerPolicyPostParentToD0ToChildren(
VOID
);
VOID
PowerPolicyChildrenCanPowerUp(
VOID
);
VOID
__inline
PowerPolicyDisarmWakeFromSx(
VOID
);
_Must_inspect_result_
NTSTATUS
PowerPolicyPowerDownForSx(
__in DEVICE_POWER_STATE DxState,
__in SendDeviceRequestAction Action
)
{
//
// The device is powering down because the system is moving into a lower
// power state.
//
// If we have child devices, setup the guard so that they do not power
// up while the parent is in low power. Note that in this case (an Sx
// transition) we do not look at the count of powered up children
// because the power policy owner for the child's stack should not be
// powering up the device once it has processed the Sx irp for its stack.
//
PowerPolicyBlockChildrenPowerUp();
return PowerPolicySendDevicePowerRequest(DxState, Action);
}
VOID
PowerPolicyBlockChildrenPowerUp(
VOID
)
{
if (m_EnumInfo != NULL) {
m_EnumInfo->AcquireParentPowerStateLock(GetDriverGlobals());
//
// Setup a guard so that no children power up until we return to S0.
//
m_PowerPolicyMachine.m_Owner->m_ChildrenCanPowerUp = FALSE;
m_EnumInfo->ReleaseParentPowerStateLock(GetDriverGlobals());
}
}
_Must_inspect_result_
NTSTATUS
PnpPowerReferenceDuringQueryPnp(
VOID
);
public:
_Must_inspect_result_
NTSTATUS
ValidateCmResource(
__inout PCM_PARTIAL_RESOURCE_DESCRIPTOR* CmResourceRaw,
__inout PCM_PARTIAL_RESOURCE_DESCRIPTOR* CmResource
);
_Must_inspect_result_
NTSTATUS
ValidateInterruptResourceCm(
__in PCM_PARTIAL_RESOURCE_DESCRIPTOR CmIntResourceRaw,
__in PCM_PARTIAL_RESOURCE_DESCRIPTOR CmIntResource,
__in PWDF_INTERRUPT_CONFIG Configuration
);
BOOLEAN
IsDefaultReleaseHardwareOrder(
VOID
)
{
#if FX_IS_KERNEL_MODE
return (m_ReleaseHardwareAfterDescendantsOnFailure == WdfReleaseHardwareOrderOnFailureEarly ? TRUE : FALSE);
#else
return FALSE;
#endif
}
BOOLEAN
HasMultipleInterrupts(
VOID
)
{
return (m_InterruptObjectCount > 1 ? TRUE : FALSE);
}
VOID
WakeInterruptCreated(
VOID
)
{
ASSERT(IsPowerPolicyOwner() != FALSE);
++m_WakeInterruptCount;
}
//
// Start of members
//
public:
FxPnpStateAndCaps m_PnpStateAndCaps;
ULONG m_PnpCapsAddress;
ULONG m_PnpCapsUINumber;
FxPowerCaps m_PowerCaps;
BOOLEAN m_Failed;
//
// Track the current device and system power states.
//
// SYSTEM_POWER_STATE
BYTE m_SystemPowerState;
// WDF_POWER_DEVICE_STATE
BYTE m_DevicePowerState;
// WDF_POWER_DEVICE_STATE
BYTE m_DevicePowerStateOld;
//
// List of dependent devices for usage notifications
//
FxRelatedDeviceList* m_UsageDependentDeviceList;
FxRelatedDeviceList* m_RemovalDeviceList;
//
// Collection of FxQueryInterface objects
//
FxWaitLockInternal m_QueryInterfaceLock;
SINGLE_LIST_ENTRY m_QueryInterfaceHead;
FxWaitLockInternal m_DeviceInterfaceLock;
SINGLE_LIST_ENTRY m_DeviceInterfaceHead;
BOOLEAN m_DeviceInterfacesCanBeEnabled;
//
// Indicate the types of special files which are supported.
//
BOOLEAN m_SpecialSupport[WdfSpecialFileMax-1];
//
// Track the number of special file notifications
// (ie. paging file, crash dump file, and hibernate file).
//
LONG m_SpecialFileCount[WdfSpecialFileMax-1];
//
// ULONG and not a BOOLEAN so the driver can match nest calls to
// WdfDeviceSetStaticStopRemove without having to track the count on their
// own.
//
ULONG m_DeviceStopCount;
//
// All 3 state machine engines
//
FxPnpMachine m_PnpMachine;
FxPowerMachine m_PowerMachine;
FxPowerPolicyMachine m_PowerPolicyMachine;
FxSelfManagedIoMachine* m_SelfManagedIoMachine;
//
// Data shared between the power and power policy machines determining how
// we handle wait wake irps.
//
SharedPowerData m_SharedPower;
//
// Interface for managing the difference between D3hot and D3cold.
//
D3COLD_SUPPORT_INTERFACE m_D3ColdInterface;
protected:
//
// Event that is set when processing a remove device is complete
//
MxEvent* m_DeviceRemoveProcessed;
//
// Count of children we need to fully remove when the parent (this package)
// is being removed.
//
LONG m_PendingChildCount;
//
// DEVICE_WAKE_DEPTH - Indicates the lowest D-state that can successfully
// generate a wake signal from a particular S-state. The array is tightly-
// packed, with index 0 corresponding to PowerSystemWorking.
//
BYTE m_DeviceWake[DeviceWakeStates];
// SYSTEM_POWER_STATE
BYTE m_SystemWake;
// WDF_DEVICE_FAILED_ACTION
BYTE m_FailedAction;
//
// Set the event which indicates that the pnp state machine is done outside
// of the state machine so that we can drain any remaining state machine
// events in the removing thread before signaling the event.
//
BYTE m_SetDeviceRemoveProcessed;
//
// Interface to queue a work item to the devnode's power thread. Any device
// in the stack can export the power thread, but it must be the lowest
// device in the stack capable of doing so. This would always be a WDF
// enumerated PDO, but could theoretically be any PDO. If the PDO does
// support this interface, WDF will try to export the interface in a filter
// or FDO.
//
// This export is not publicly defined because this is an internal WDF
// implementation detail where we want to use as few threads as possible,
// but still guarantee that non power pagable devices can operate a passive
// level and not be blocked by paging I/O (which eliminates using work items).
//
POWER_THREAD_INTERFACE m_PowerThreadInterface;
FxEnumerationInfo* m_EnumInfo;
//
// Translated resources
//
FxCmResList* m_Resources;
//
// Raw resources
//
FxCmResList* m_ResourcesRaw;
FxSpinLockTransactionedList* m_DmaEnablerList;
//
// Bus information for any enumerated children
//
PNP_BUS_INFORMATION m_BusInformation;
//
// Number of times we have tried to enumerate children but failed
//
UCHAR m_BusEnumRetries;
//
// The power action corresponding to the system power transition
//
UCHAR m_SystemPowerAction;
//
// TRUE once the entire stack has been queried for the caps
//
BOOLEAN m_CapsQueried;
BOOLEAN m_InternalFailure;
//
// if FALSE, there is no power thread available on the devnode currently
// and a work item should be enqueued. if TRUE, there is a power thread
// and the callback should be enqueued to it.
//
BOOLEAN m_HasPowerThread;
//
// If TRUE, we guarantee that in *all* cases that the ReleaseHardware
// callback for the current device is invoked only after all descendent
// devices have already been removed. We do this by ensuring that
// ReleaseHardware is only ever invoked when there is a PNP IRP such as
// remove, surprise-remove or stop is pending in the device. PNP already
// ensures that it sends us that IRP only after all child devices have
// processed the corresponding IRP in their stacks.
//
// Even if FALSE, in *most* cases, the ReleaseHardware callback of the
// current device should still be invoked only after all descendent devices
// have already been stopped/removed. However, in some failure paths we
// might invoke the ReleaseHardware callback of the current device before
// all descendent devices have been stopped. In these cases, we do not wait
// for the surprise-remove IRP sent as a result of the failure in order to
// invoke ReleaseHardware. Instead, we invoke it proactively.
//
// The default value is FALSE.
//
BOOLEAN m_ReleaseHardwareAfterDescendantsOnFailure;
//
// GUID for querying for a power thread down the stack
//
static const GUID GUID_POWER_THREAD_INTERFACE;
#if (FX_CORE_MODE==FX_CORE_KERNEL_MODE)
//
// Interrupt APIs for Vista and forward
//
PFN_IO_CONNECT_INTERRUPT_EX m_IoConnectInterruptEx;
PFN_IO_DISCONNECT_INTERRUPT_EX m_IoDisconnectInterruptEx;
//
// Interrupt APIs for Windows 8 and forward
//
PFN_IO_REPORT_INTERRUPT_ACTIVE m_IoReportInterruptActive;
PFN_IO_REPORT_INTERRUPT_INACTIVE m_IoReportInterruptInactive;
#endif
private:
//
// For user mode we need to preallocate event since its initialization can
// fail
//
#if (FX_CORE_MODE==FX_CORE_USER_MODE)
FxCREvent m_CleanupEventUm;
MxEvent m_RemoveEventUm;
#endif
ULONG m_InterruptObjectCount;
LIST_ENTRY m_InterruptListHead;
//
// Number of interrupts that are declared to be capable
// of waking from low power
//
ULONG m_WakeInterruptCount;
//
// Count that keeps track of the number of wake interrupt
// machines that have acknowledged back an event queued
// in to them by the device level PnP/Power code
//
ULONG m_WakeInterruptPendingAckCount;
//
// Keeps track of whether the last system wake was due to
// a wake interrupt, so that we can report this device as
// the source of wake to the power manager
//
BOOLEAN m_SystemWokenByWakeInterrupt;
//
// If TRUE, do not disconnect wake interrupts even if there is no
// pended IRP_MN_WAIT_WAKE. This works around a race condition between
// the wake interrupt firing (and the wake ISR running) and the device
// powering down. This flag is set when we are in a wake-enabled device
// powering down path and is cleared when the device is powered up again.
//
BOOLEAN m_WakeInterruptsKeepConnected;
//
// If TRUE, the PNP State has reached PnpEventStarted at least once.
//
BOOLEAN m_AchievedStart;
//
// Non NULL when this device is exporting the power thread interface. This
// would be the lowest device in the stack that supports this interface.
//
FxSystemThread* m_PowerThread;
LONG m_PowerThreadInterfaceReferenceCount;
FxCREvent* m_PowerThreadEvent;
//
// The current pnp state changing irp in the stack that we have pended to
// process in the pnp state machine
//
MdIrp m_PendingPnPIrp;
//
// The current system power irp in the stack that we have pended to process
// in the power state machine
//
MdIrp m_PendingSystemPowerIrp;
//
// The current device power irp in the stack that we have pended to process
// in the power state machine
//
MdIrp m_PendingDevicePowerIrp;
FxPnpStateCallback* m_PnpStateCallbacks;
FxPowerStateCallback* m_PowerStateCallbacks;
FxPowerPolicyStateCallback* m_PowerPolicyStateCallbacks;
static const PNP_STATE_TABLE m_WdfPnpStates[];
static const POWER_STATE_TABLE m_WdfPowerStates[];
static const POWER_POLICY_STATE_TABLE m_WdfPowerPolicyStates[];
static const NOT_POWER_POLICY_OWNER_STATE_TABLE m_WdfNotPowerPolicyOwnerStates[];
static const PNP_EVENT_TARGET_STATE m_PnpInitOtherStates[];
static const PNP_EVENT_TARGET_STATE m_PnpInitStartingOtherStates[];
static const PNP_EVENT_TARGET_STATE m_PnpHardwareAvailableOtherStates[];
static const PNP_EVENT_TARGET_STATE m_PnpQueryStopPendingOtherStates[];
static const PNP_EVENT_TARGET_STATE m_PnpRemovedPdoWaitOtherStates[];
static const PNP_EVENT_TARGET_STATE m_PnpRestartingOtherStates[];
static const PNP_EVENT_TARGET_STATE m_PnpStartedOtherStates[];
static const PNP_EVENT_TARGET_STATE m_PnpQueryRemovePendingOtherStates[];
static const PNP_EVENT_TARGET_STATE m_PnpQueriedRemovingOtherStates[];
static const PNP_EVENT_TARGET_STATE m_PnpInitQueryRemoveOtherStates[];
static const PNP_EVENT_TARGET_STATE m_PnpStoppedOtherStates[];
static const PNP_EVENT_TARGET_STATE m_PnpStoppedWaitForStartCompletionOtherStates[];
static const PNP_EVENT_TARGET_STATE m_PnpStartedStoppingOtherStates[];
static const PNP_EVENT_TARGET_STATE m_PnpStartedStoppingFailedOtherStates[];
static const PNP_EVENT_TARGET_STATE m_PnpEjectFailedOtherStates[];
static const PNP_EVENT_TARGET_STATE m_PnpStartedRemovingOtherStates[];
static const PNP_EVENT_TARGET_STATE m_PnpFailedPowerDownOtherStates[];
static const PNP_EVENT_TARGET_STATE m_PnpFailedIoStartingOtherStates[];
static const PNP_EVENT_TARGET_STATE m_PnpFailedWaitForRemoveOtherStates[];
static const PNP_EVENT_TARGET_STATE m_PnpRestartOtherStates[];
static const PNP_EVENT_TARGET_STATE m_PnpRestartReleaseHardware[];
static const PNP_EVENT_TARGET_STATE m_PnpRestartHardwareAvailableOtherStates[];
static const POWER_EVENT_TARGET_STATE m_PowerD0OtherStates[];
static const POWER_EVENT_TARGET_STATE m_PowerD0NPOtherStates[];
static const POWER_EVENT_TARGET_STATE m_PowerD0BusWakeOwnerOtherStates[];
static const POWER_EVENT_TARGET_STATE m_PowerD0BusWakeOwnerNPOtherStates[];
static const POWER_EVENT_TARGET_STATE m_PowerD0ArmedForWakeOtherStates[];
static const POWER_EVENT_TARGET_STATE m_PowerD0ArmedForWakeNPOtherStates[];
static const POWER_EVENT_TARGET_STATE m_PowerDNotZeroOtherStates[];
static const POWER_EVENT_TARGET_STATE m_PowerDNotZeroNPOtherStates[];
static const POWER_EVENT_TARGET_STATE m_DxArmedForWakeOtherStates[];
static const POWER_EVENT_TARGET_STATE m_DxArmedForWakeNPOtherStates[];
static const POWER_EVENT_TARGET_STATE m_WakePendingOtherStates[];
static const POWER_EVENT_TARGET_STATE m_WakePendingNPOtherStates[];
static const POWER_EVENT_TARGET_STATE m_DxSurpriseRemovedOtherStates[];
static const POWER_EVENT_TARGET_STATE m_PowerStoppedOtherStates[];
static const POWER_EVENT_TARGET_STATE m_PowerDxStoppedOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolObjectCreatedOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolStartingOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolStartedIdleCapableOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolIdleCapableDeviceIdleOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolTimerExpiredNoWakeOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolTimerExpiredNoWakeCompletePowerDownOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolWaitingUnarmedOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolS0NoWakePowerUpOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolS0NoWakeCompletePowerUpOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolSystemSleepNeedWakeOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolSystemSleepNeedWakeCompletePowerUpOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolSystemAsleepWakeArmedOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolSystemAsleepWakeArmedNPOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolSystemWakeDeviceToD0OtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolSystemWakeDeviceToD0CompletePowerUpOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolStartedWakeCapableOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolWakeCapableDeviceIdleOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolTimerExpiredWakeCapablePowerDownOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolTimerExpiredWakeCapableSendWakeOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolTimerExpiredWakeCapableUsbSSOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolWaitingArmedOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolDisarmingWakeForSystemSleepCompletePowerUpOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolCancelingWakeForSystemSleepWakeCanceledOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolWokeFromS0OtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolStoppingResetDeviceOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolStoppingResetDeviceCompletePowerUpOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolStoppingD0OtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolStoppingDisarmWakeOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolStoppingDisarmWakeCancelWakeOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolIoPresentArmedOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolIoPresentArmedWakeCanceledOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolS0WakeCompletePowerUpOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolTimerExpiredWakeCapableWakeSucceededOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolTimerExpiredWakeCapableWakeFailedOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolTimerExpiredWakeCapablePowerDownFailedCancelWakeOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolCancelingWakeForSystemSleepOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolTimerExpiredWakeCapableWakeArrivedOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolTimerExpiredWakeCapableCancelWakeOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolTimerExpiredWakeCompletedPowerDownOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolTimerExpiredWakeCompletedPowerUpOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolSystemWakeDeviceWakeEnabledOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolSystemWakeDeviceWakeEnabledNPOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolSystemWakeDeviceWakeEnabledWakeCanceledOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolSystemWakeDeviceWakeEnabledWakeCanceledNPOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolSleepingWakeWakeArrivedOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolSystemWakeDeviceWakeTriggeredS0OtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolSystemWakeDeviceWakeTriggeredS0NPOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolSystemWakeDeviceWakeCompletePowerUpOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolSleepingNoWakePowerDownOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolSleepingNoWakeCompletePowerDownOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolSleepingWakePowerDownOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolSleepingSendWakeOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolSleepingWakeWakeArrivedNPOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolSleepingWakePowerDownFailedOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolStartedOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolStartedWaitForIdleTimeoutOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolDevicePowerRequestFailedOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolStoppingOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolStoppedOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolRestartingOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolStoppingCancelWakeOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolCancelUsbSSOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolSleepingWakeRevertArmWakeOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolSleepingWakeRevertArmWakeNPOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolRemovedOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolTimerExpiredWakeCapableWakeInterruptArrivedOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolTimerExpiredWakeCapablePowerDownFailedWakeInterruptArrivedOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolWaitingArmedWakeInterruptFiredDuringPowerDownOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_NotPowerPolOwnerObjectCreatedStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_NotPowerPolOwnerStartingStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_NotPowerPolOwnerStartingSucceededStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_NotPowerPolOwnerStartingFailedStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_NotPowerPolOwnerGotoDxStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_NotPowerPolOwnerGotoDxInDxStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_NotPowerPolOwnerDxStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_NotPowerPolOwnerGotoD0States[];
static const POWER_POLICY_EVENT_TARGET_STATE m_NotPowerPolOwnerGotoD0InD0States[];
static const POWER_POLICY_EVENT_TARGET_STATE m_NotPowerPolOwnerStoppedStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_NotPowerPolOwnerStoppingWaitForImplicitPowerDownStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_NotPowerPolOwnerStoppingPoweringUpStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_NotPowerPolOwnerStoppingPoweringDownStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_NotPowerPolOwnerRemovedStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolWaitingArmedWakeInterruptFiredOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolSystemWakeDeviceWakeInterruptFiredOtherStates[];
static const POWER_POLICY_EVENT_TARGET_STATE m_PowerPolSystemWakeDeviceWakeInterruptFiredNPOtherStates[];
#if FX_STATE_MACHINE_VERIFY
//
// Array of possible states that can be returned by state entry functions
//
static const PNP_STATE_ENTRY_FN_RETURN_STATE_TABLE m_WdfPnpStateEntryFunctionReturnStates[];
static const POWER_STATE_ENTRY_FN_RETURN_STATE_TABLE m_WdfPowerStateEntryFunctionReturnStates[];
static const PWR_POL_STATE_ENTRY_FN_RETURN_STATE_TABLE m_WdfPwrPolStateEntryFunctionReturnStates[];
#endif // FX_STATE_MACHINE_VERIFY
//
// Names for registry values in which we will store the beginning of the
// restart time period, the number of restart attempts in that period, and
// if the device successfully started.
//
static const PWCHAR m_RestartStartAchievedName;
static const PWCHAR m_RestartStartTimeName;
static const PWCHAR m_RestartCountName;
//
// Time between successive restarts in which we will attempt to restart a
// stack again. Expressed in seconds.
//
static const ULONG m_RestartTimePeriodMaximum;
//
// Number of times in the restart time period in which we will attempt a
// restart.
//
static const ULONG m_RestartCountMaximum;
//
// Shove the function pointers to the end of the structure so that when
// we dump the structure while debugging, the less pertinent info is at the
// bottom.
//
public:
FxPnpDeviceUsageNotification m_DeviceUsageNotification;
FxPnpDeviceUsageNotificationEx m_DeviceUsageNotificationEx;
FxPnpDeviceRelationsQuery m_DeviceRelationsQuery;
FxPnpDeviceD0Entry m_DeviceD0Entry;
FxPnpDeviceD0EntryPostInterruptsEnabled m_DeviceD0EntryPostInterruptsEnabled;
FxPnpDeviceD0ExitPreInterruptsDisabled m_DeviceD0ExitPreInterruptsDisabled;
FxPnpDeviceD0Exit m_DeviceD0Exit;
FxPnpDevicePrepareHardware m_DevicePrepareHardware;
FxPnpDeviceReleaseHardware m_DeviceReleaseHardware;
FxPnpDeviceQueryStop m_DeviceQueryStop;
FxPnpDeviceQueryRemove m_DeviceQueryRemove;
FxPnpDeviceSurpriseRemoval m_DeviceSurpriseRemoval;
};
__inline
VOID
FxPostProcessInfo::Evaluate(
__inout FxPkgPnp* PkgPnp
)
{
if (m_SetRemovedEvent) {
ASSERT(m_DeleteObject == FALSE && m_Event == NULL && m_FireAndForgetIrp == NULL);
PkgPnp->SignalDeviceRemovedEvent();
return;
}
//
// Process any irp that should be sent down the stack/forgotten.
//
if (m_FireAndForgetIrp != NULL) {
FxIrp irp(m_FireAndForgetIrp);
m_FireAndForgetIrp = NULL;
(void) PkgPnp->FireAndForgetIrp(&irp);
}
if (m_DeleteObject) {
PkgPnp->ProcessDelayedDeletion();
}
if (m_Event != NULL) {
m_Event->Set();
}
}
#endif // _FXPKGPNP_H_