[WDF] Add Windows Driver Framework files
[reactos.git] / sdk / lib / drivers / wdf / shared / irphandlers / pnp / km / powerpolicystatemachinekm.cpp
diff --git a/sdk/lib/drivers/wdf/shared/irphandlers/pnp/km/powerpolicystatemachinekm.cpp b/sdk/lib/drivers/wdf/shared/irphandlers/pnp/km/powerpolicystatemachinekm.cpp
new file mode 100644 (file)
index 0000000..a1aa32c
--- /dev/null
@@ -0,0 +1,245 @@
+/*++
+
+Copyright (c) Microsoft. All rights reserved.
+
+Module Name:
+
+    PowerPolicyStateMachineKM.cpp
+
+Abstract:
+
+
+Environment:
+
+    Kernel mode only
+
+Revision History:
+
+--*/
+
+#include "..\pnppriv.hpp"
+
+#if FX_IS_KERNEL_MODE
+#include <usbdrivr.h>
+#endif
+
+#include "FxUsbIdleInfo.hpp"
+
+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
+    )
+{
+    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()
+        );
+}
+
+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();
+}
+
+
+