2020-09-24 20:51:15 +00:00
|
|
|
/*++
|
|
|
|
|
|
|
|
Copyright (c) Microsoft. All rights reserved.
|
|
|
|
|
|
|
|
Module Name:
|
|
|
|
|
|
|
|
PowerPolicyStateMachineKM.cpp
|
|
|
|
|
|
|
|
Abstract:
|
|
|
|
|
|
|
|
|
|
|
|
Environment:
|
|
|
|
|
|
|
|
Kernel mode only
|
|
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
|
|
--*/
|
|
|
|
|
2020-10-16 03:30:51 +00:00
|
|
|
#include "../pnppriv.hpp"
|
2020-09-24 20:51:15 +00:00
|
|
|
|
|
|
|
#if FX_IS_KERNEL_MODE
|
|
|
|
#include <usbdrivr.h>
|
|
|
|
#endif
|
|
|
|
|
2020-10-16 03:30:51 +00:00
|
|
|
#include "fxusbidleinfo.hpp"
|
2020-09-24 20:51:15 +00:00
|
|
|
|
|
|
|
extern "C" {
|
|
|
|
#if defined(EVENT_TRACING)
|
|
|
|
#include "PowerPolicyStateMachineKM.tmh"
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
FxPkgPnp::PowerPolicyUpdateSystemWakeSource(
|
|
|
|
__in FxIrp* Irp
|
|
|
|
)
|
|
|
|
/*++
|
|
|
|
|
|
|
|
Routine Description:
|
|
|
|
Gets source of wake if OS supports this.
|
|
|
|
|
|
|
|
Arguments:
|
|
|
|
Irp
|
|
|
|
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
//
|
|
|
|
// Check to see if this device caused the machine to wake up
|
|
|
|
//
|
|
|
|
m_PowerPolicyMachine.m_Owner->m_SystemWakeSource =
|
|
|
|
PoGetSystemWake(Irp->GetIrp());
|
|
|
|
|
|
|
|
if (m_PowerPolicyMachine.m_Owner->m_SystemWakeSource) {
|
|
|
|
DoTraceLevelMessage(
|
|
|
|
GetDriverGlobals(), TRACE_LEVEL_INFORMATION, TRACINGPNP,
|
|
|
|
"WDFDEVICE 0x%p !devobj 0x%p WW !irp 0x%p is a source of "
|
|
|
|
"wake",
|
|
|
|
m_Device->GetHandle(),
|
|
|
|
m_Device->GetDeviceObject(),
|
|
|
|
Irp->GetIrp());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOLEAN
|
|
|
|
FxPkgPnp::ShouldProcessPowerPolicyEventOnDifferentThread(
|
|
|
|
__in KIRQL CurrentIrql,
|
|
|
|
__in BOOLEAN CallerSpecifiedProcessingOnDifferentThread
|
|
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
|
|
This function returns whether the power policy state machine should process
|
|
|
|
the current event on the same thread or on a different one.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Arguemnts:
|
|
|
|
|
|
|
|
CurrentIrql - The current IRQL
|
|
|
|
|
|
|
|
CallerSpecifiedProcessingOnDifferentThread - Whether or not caller of
|
|
|
|
PowerPolicyProcessEvent specified that the event be processed on a
|
|
|
|
different thread.
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
TRUE if the power policy state machine should process the event on a
|
|
|
|
different thread.
|
|
|
|
|
|
|
|
FALSE if the power policy state machine should process the event on the
|
|
|
|
same thread
|
|
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
//
|
|
|
|
// For KMDF, we ignore what the caller of PowerPolicyProcessEvent specified
|
|
|
|
// (which should always be FALSE, BTW) and base our decision on the current
|
|
|
|
// IRQL. If we are running at PASSIVE_LEVEL, we process on the same thread
|
|
|
|
// else we queue a work item.
|
|
|
|
//
|
|
|
|
UNREFERENCED_PARAMETER(CallerSpecifiedProcessingOnDifferentThread);
|
|
|
|
|
|
|
|
ASSERT(FALSE == CallerSpecifiedProcessingOnDifferentThread);
|
|
|
|
|
|
|
|
return (CurrentIrql == PASSIVE_LEVEL) ? FALSE : TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
_Must_inspect_result_
|
|
|
|
NTSTATUS
|
|
|
|
FxUsbIdleInfo::Initialize(
|
|
|
|
VOID
|
|
|
|
)
|
|
|
|
{
|
|
|
|
MdIrp pIrp;
|
|
|
|
MxDeviceObject attachedDevObj;
|
|
|
|
|
|
|
|
attachedDevObj.SetObject(((FxPkgPnp*)m_CallbackInfo.IdleContext)->GetDevice()->GetAttachedDevice());
|
|
|
|
|
|
|
|
pIrp = FxIrp::AllocateIrp(attachedDevObj.GetStackSize());
|
|
|
|
|
|
|
|
if (pIrp == NULL) {
|
|
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_IdleIrp.SetIrp(pIrp);
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
FxPkgPnp::PowerPolicySubmitUsbIdleNotification(
|
|
|
|
VOID
|
|
|
|
)
|
|
|
|
{
|
2020-10-16 03:30:51 +00:00
|
|
|
// FxIrp* usbIdleIrp;
|
|
|
|
|
|
|
|
// //
|
|
|
|
// // This will be set to TRUE if USBSS completion event gets dropped.
|
|
|
|
// //
|
|
|
|
// m_PowerPolicyMachine.m_Owner->m_UsbIdle->m_EventDropped = FALSE;
|
|
|
|
|
|
|
|
// usbIdleIrp = &m_PowerPolicyMachine.m_Owner->m_UsbIdle->m_IdleIrp;
|
|
|
|
|
|
|
|
// usbIdleIrp->Reuse();
|
|
|
|
|
|
|
|
// usbIdleIrp->SetCompletionRoutineEx(
|
|
|
|
// m_Device->GetDeviceObject(),
|
|
|
|
// _PowerPolicyUsbSelectiveSuspendCompletionRoutine,
|
|
|
|
// this);
|
|
|
|
|
|
|
|
// usbIdleIrp->SetMajorFunction(IRP_MJ_INTERNAL_DEVICE_CONTROL);
|
|
|
|
// usbIdleIrp->SetParameterIoctlCode(
|
|
|
|
// IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION);
|
|
|
|
// usbIdleIrp->SetParameterIoctlInputBufferLength(
|
|
|
|
// sizeof(m_PowerPolicyMachine.m_Owner->m_UsbIdle->m_CallbackInfo));
|
|
|
|
// usbIdleIrp->SetParameterIoctlType3InputBuffer(
|
|
|
|
// (PVOID) &m_PowerPolicyMachine.m_Owner->m_UsbIdle->m_CallbackInfo);
|
|
|
|
|
|
|
|
// m_PowerPolicyMachine.m_Owner->m_UsbIdle->m_IdleIrp.CallDriver(
|
|
|
|
// m_Device->GetAttachedDevice()
|
|
|
|
// );
|
|
|
|
ROSWDFNOTIMPLEMENTED;
|
2020-09-24 20:51:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
FxPkgPnp::PowerPolicyCancelUsbSS(
|
|
|
|
VOID
|
|
|
|
)
|
|
|
|
{
|
|
|
|
m_PowerPolicyMachine.m_Owner->m_UsbIdle->m_IdleIrp.Cancel();
|
|
|
|
}
|
|
|
|
|
|
|
|
__drv_maxIRQL(PASSIVE_LEVEL)
|
|
|
|
VOID
|
|
|
|
FxUsbIdleInfo::_UsbIdleCallback(
|
|
|
|
__in PVOID Context
|
|
|
|
)
|
|
|
|
{
|
|
|
|
FxPkgPnp* pPkgPnp;
|
|
|
|
FxUsbIdleInfo* pThis;
|
|
|
|
FxCREvent event;
|
|
|
|
|
|
|
|
pPkgPnp = (FxPkgPnp*) Context;
|
|
|
|
|
|
|
|
DoTraceLevelMessage(
|
|
|
|
pPkgPnp->GetDriverGlobals(), TRACE_LEVEL_VERBOSE, TRACINGPNP,
|
|
|
|
"Entering USB Selective Suspend Idle callback");
|
|
|
|
|
|
|
|
pThis = pPkgPnp->m_PowerPolicyMachine.m_Owner->m_UsbIdle;
|
|
|
|
|
|
|
|
ASSERT(pThis->m_IdleCallbackEvent == NULL);
|
|
|
|
pThis->m_IdleCallbackEvent = event.GetSelfPointer();
|
|
|
|
|
|
|
|
pPkgPnp->PowerPolicyProcessEvent(PwrPolUsbSelectiveSuspendCallback);
|
|
|
|
|
|
|
|
event.EnterCRAndWaitAndLeave();
|
|
|
|
pThis->m_IdleCallbackEvent = NULL;
|
|
|
|
|
|
|
|
DoTraceLevelMessage(
|
|
|
|
pPkgPnp->GetDriverGlobals(), TRACE_LEVEL_VERBOSE, TRACINGPNP,
|
|
|
|
"Leaving USB Selective Suspend Idle callback");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VOID
|
|
|
|
FxPowerPolicyMachine::UsbSSCallbackProcessingComplete(
|
|
|
|
VOID
|
|
|
|
)
|
|
|
|
{
|
|
|
|
ASSERT(m_Owner->m_UsbIdle->m_IdleCallbackEvent != NULL);
|
|
|
|
m_Owner->m_UsbIdle->m_IdleCallbackEvent->Set();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|