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