1 /*++ 2 3 Copyright (c) Microsoft. All rights reserved. 4 5 Module Name: 6 7 PowerPolicyStateMachineKM.cpp 8 9 Abstract: 10 11 12 Environment: 13 14 Kernel mode only 15 16 Revision History: 17 18 --*/ 19 20 #include "../pnppriv.hpp" 21 22 #if FX_IS_KERNEL_MODE 23 #include <usbdrivr.h> 24 #endif 25 26 #include "fxusbidleinfo.hpp" 27 28 extern "C" { 29 #if defined(EVENT_TRACING) 30 #include "PowerPolicyStateMachineKM.tmh" 31 #endif 32 } 33 34 VOID 35 FxPkgPnp::PowerPolicyUpdateSystemWakeSource( 36 __in FxIrp* Irp 37 ) 38 /*++ 39 40 Routine Description: 41 Gets source of wake if OS supports this. 42 43 Arguments: 44 Irp 45 46 Return Value: 47 None 48 49 --*/ 50 { 51 // 52 // Check to see if this device caused the machine to wake up 53 // 54 m_PowerPolicyMachine.m_Owner->m_SystemWakeSource = 55 PoGetSystemWake(Irp->GetIrp()); 56 57 if (m_PowerPolicyMachine.m_Owner->m_SystemWakeSource) { 58 DoTraceLevelMessage( 59 GetDriverGlobals(), TRACE_LEVEL_INFORMATION, TRACINGPNP, 60 "WDFDEVICE 0x%p !devobj 0x%p WW !irp 0x%p is a source of " 61 "wake", 62 m_Device->GetHandle(), 63 m_Device->GetDeviceObject(), 64 Irp->GetIrp()); 65 } 66 } 67 68 BOOLEAN 69 FxPkgPnp::ShouldProcessPowerPolicyEventOnDifferentThread( 70 __in KIRQL CurrentIrql, 71 __in BOOLEAN CallerSpecifiedProcessingOnDifferentThread 72 ) 73 /*++ 74 Routine Description: 75 76 This function returns whether the power policy state machine should process 77 the current event on the same thread or on a different one. 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 Arguemnts: 110 111 CurrentIrql - The current IRQL 112 113 CallerSpecifiedProcessingOnDifferentThread - Whether or not caller of 114 PowerPolicyProcessEvent specified that the event be processed on a 115 different thread. 116 117 Returns: 118 TRUE if the power policy state machine should process the event on a 119 different thread. 120 121 FALSE if the power policy state machine should process the event on the 122 same thread 123 124 --*/ 125 { 126 // 127 // For KMDF, we ignore what the caller of PowerPolicyProcessEvent specified 128 // (which should always be FALSE, BTW) and base our decision on the current 129 // IRQL. If we are running at PASSIVE_LEVEL, we process on the same thread 130 // else we queue a work item. 131 // 132 UNREFERENCED_PARAMETER(CallerSpecifiedProcessingOnDifferentThread); 133 134 ASSERT(FALSE == CallerSpecifiedProcessingOnDifferentThread); 135 136 return (CurrentIrql == PASSIVE_LEVEL) ? FALSE : TRUE; 137 } 138 139 _Must_inspect_result_ 140 NTSTATUS 141 FxUsbIdleInfo::Initialize( 142 VOID 143 ) 144 { 145 MdIrp pIrp; 146 MxDeviceObject attachedDevObj; 147 148 attachedDevObj.SetObject(((FxPkgPnp*)m_CallbackInfo.IdleContext)->GetDevice()->GetAttachedDevice()); 149 150 pIrp = FxIrp::AllocateIrp(attachedDevObj.GetStackSize()); 151 152 if (pIrp == NULL) { 153 return STATUS_INSUFFICIENT_RESOURCES; 154 } 155 156 m_IdleIrp.SetIrp(pIrp); 157 158 return STATUS_SUCCESS; 159 } 160 161 VOID 162 FxPkgPnp::PowerPolicySubmitUsbIdleNotification( 163 VOID 164 ) 165 { 166 // FxIrp* usbIdleIrp; 167 168 // // 169 // // This will be set to TRUE if USBSS completion event gets dropped. 170 // // 171 // m_PowerPolicyMachine.m_Owner->m_UsbIdle->m_EventDropped = FALSE; 172 173 // usbIdleIrp = &m_PowerPolicyMachine.m_Owner->m_UsbIdle->m_IdleIrp; 174 175 // usbIdleIrp->Reuse(); 176 177 // usbIdleIrp->SetCompletionRoutineEx( 178 // m_Device->GetDeviceObject(), 179 // _PowerPolicyUsbSelectiveSuspendCompletionRoutine, 180 // this); 181 182 // usbIdleIrp->SetMajorFunction(IRP_MJ_INTERNAL_DEVICE_CONTROL); 183 // usbIdleIrp->SetParameterIoctlCode( 184 // IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION); 185 // usbIdleIrp->SetParameterIoctlInputBufferLength( 186 // sizeof(m_PowerPolicyMachine.m_Owner->m_UsbIdle->m_CallbackInfo)); 187 // usbIdleIrp->SetParameterIoctlType3InputBuffer( 188 // (PVOID) &m_PowerPolicyMachine.m_Owner->m_UsbIdle->m_CallbackInfo); 189 190 // m_PowerPolicyMachine.m_Owner->m_UsbIdle->m_IdleIrp.CallDriver( 191 // m_Device->GetAttachedDevice() 192 // ); 193 ROSWDFNOTIMPLEMENTED; 194 } 195 196 VOID 197 FxPkgPnp::PowerPolicyCancelUsbSS( 198 VOID 199 ) 200 { 201 m_PowerPolicyMachine.m_Owner->m_UsbIdle->m_IdleIrp.Cancel(); 202 } 203 204 __drv_maxIRQL(PASSIVE_LEVEL) 205 VOID 206 FxUsbIdleInfo::_UsbIdleCallback( 207 __in PVOID Context 208 ) 209 { 210 FxPkgPnp* pPkgPnp; 211 FxUsbIdleInfo* pThis; 212 FxCREvent event; 213 214 pPkgPnp = (FxPkgPnp*) Context; 215 216 DoTraceLevelMessage( 217 pPkgPnp->GetDriverGlobals(), TRACE_LEVEL_VERBOSE, TRACINGPNP, 218 "Entering USB Selective Suspend Idle callback"); 219 220 pThis = pPkgPnp->m_PowerPolicyMachine.m_Owner->m_UsbIdle; 221 222 ASSERT(pThis->m_IdleCallbackEvent == NULL); 223 pThis->m_IdleCallbackEvent = event.GetSelfPointer(); 224 225 pPkgPnp->PowerPolicyProcessEvent(PwrPolUsbSelectiveSuspendCallback); 226 227 event.EnterCRAndWaitAndLeave(); 228 pThis->m_IdleCallbackEvent = NULL; 229 230 DoTraceLevelMessage( 231 pPkgPnp->GetDriverGlobals(), TRACE_LEVEL_VERBOSE, TRACINGPNP, 232 "Leaving USB Selective Suspend Idle callback"); 233 } 234 235 236 VOID 237 FxPowerPolicyMachine::UsbSSCallbackProcessingComplete( 238 VOID 239 ) 240 { 241 ASSERT(m_Owner->m_UsbIdle->m_IdleCallbackEvent != NULL); 242 m_Owner->m_UsbIdle->m_IdleCallbackEvent->Set(); 243 } 244 245 246 247