1 /*++ 2 3 Copyright (c) Microsoft. All rights reserved. 4 5 Module Name: 6 7 FxWatchDog.hpp 8 9 Abstract: 10 11 This module implements the watchdog utility class for the power and power 12 policy state machines 13 14 Author: 15 16 17 18 Environment: 19 20 Both kernel and user mode 21 22 Revision History: 23 24 --*/ 25 26 #ifndef __FX_WATCHDOG__ 27 #define __FX_WATCHDOG__ 28 29 struct FxWatchdog { FxWatchdogFxWatchdog30 FxWatchdog( 31 __in FxPkgPnp* PkgPnp 32 ) 33 { 34 m_PkgPnp = PkgPnp; 35 } 36 37 VOID StartTimerFxWatchdog38 StartTimer( 39 __in ULONG State 40 ) 41 { 42 LARGE_INTEGER time; 43 NTSTATUS status; 44 45 if (State & WdfDevStateNP) { 46 // 47 // This is a non-pageable state. So we set the timer watchdog. 48 // If it fires, it means that the driver stalled, probably due 49 // to a page fault, which means that the whole machine is wedged. 50 // We will then attempt to put the failure in the trace log 51 // and bring the machine down, hopefully getting the reason we 52 // stopped responding into the crashdump. (This will probably only work 53 // if the machine is hibernating.) 54 // 55 // If the state function returns, then we'll cancel the timer 56 // and no love will be lost. 57 // 58 status = m_Timer.Initialize(this, _WatchdogDpc, 0); 59 60 // 61 // This code is not used in UM. Hence we can assert and assume that 62 // timer start will always be successful. 63 // 64 WDF_VERIFY_KM_ONLY_CODE(); 65 66 FX_ASSERT_AND_ASSUME_FOR_PREFAST(NT_SUCCESS(status)); 67 68 m_CallingThread = Mx::MxGetCurrentThread(); 69 70 if (m_PkgPnp->m_SharedPower.m_ExtendWatchDogTimer) { 71 // 72 // 24 hours: 73 // 60 = to minutes 74 // 60 = to hours 75 // 24 = number of hours 76 // 77 time.QuadPart = WDF_REL_TIMEOUT_IN_SEC(60 * 60 * 24); 78 } 79 else { 80 // 81 // 10 minutes from now (same as the Vista timeout) 82 // 83 time.QuadPart = WDF_REL_TIMEOUT_IN_SEC(60 * 10); 84 } 85 86 m_Timer.Start(time); 87 } 88 } 89 90 VOID CancelTimerFxWatchdog91 CancelTimer( 92 __in ULONG State 93 ) 94 { 95 if (State & WdfDevStateNP) { 96 // 97 // The state was successfully handled without the timer expiring. 98 // We don't care about the return code in this case. 99 // 100 (void) m_Timer.Stop(); 101 } 102 } 103 104 static 105 MdDeferredRoutineType 106 _WatchdogDpc; 107 108 MxTimer m_Timer; 109 110 FxPkgPnp* m_PkgPnp; 111 112 MxThread m_CallingThread; 113 }; 114 115 #endif // __FX_WATCHDOG__ 116 117