Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

473 lines
10 KiB

  1. /*++
  2. Copyright (c) 1991 - 2002 Microsoft Corporation
  3. Module Name:
  4. ## ## ### ## # ##### ## ##### ##### #### ##### #####
  5. ## ## ### ### # ## ## ## ## ## ## ## # ## ## ## ##
  6. ## ## ## ## #### # ## ## ## ## ## ## ## ## ## ## ##
  7. ####### ## ## # #### ## ## ## ##### ##### ## ## ## ## ##
  8. ## ## ####### # ### ## ## ## ## #### ## ##### #####
  9. ## ## ## ## # ## ## ## ## ## ## ## ## ## # ## ##
  10. ## ## ## ## # # ##### ##### ##### ## ## ## #### ## ##
  11. Abstract:
  12. This module process the callback from
  13. the OS executive.
  14. Author:
  15. Wesley Witt (wesw) 1-Mar-2002
  16. Environment:
  17. Kernel mode only.
  18. Notes:
  19. --*/
  20. #include "internal.h"
  21. void
  22. WdHandlerSetTimeoutValue(
  23. IN PDEVICE_EXTENSION DeviceExtension,
  24. IN ULONG Timeout,
  25. IN BOOLEAN PingTimer
  26. )
  27. /*++
  28. Routine Description:
  29. This function sets the timeout value for the hardware
  30. timer and the software timer. The software timer runs
  31. as a frequency that is 25% of the hardware timer. The
  32. hardware timer's frequency is set at StartDevice time to
  33. the device's reported maximum value, but it can be changed
  34. through the NtSetSystemInformation inmterface.
  35. Arguments:
  36. DeviceExtension - Pointer to the watchdog device extension
  37. Timeout - The requested timeout value expressed in the device
  38. units.
  39. PingTimer - Specifies if the timer should be pinged after
  40. changing the timeout value.
  41. Return Value:
  42. None.
  43. Notes:
  44. --*/
  45. {
  46. DeviceExtension->HardwareTimeout = Timeout;
  47. DeviceExtension->DpcTimeout = ConvertTimeoutToMilliseconds(
  48. WdTable->Units, DeviceExtension->HardwareTimeout >> 2 ) * 10000;
  49. ULONG Control = READ_REGISTER_ULONG( DeviceExtension->ControlRegisterAddress );
  50. SETBITS( Control, WATCHDOG_CONTROL_TRIGGER );
  51. WRITE_REGISTER_ULONG( DeviceExtension->CountRegisterAddress, DeviceExtension->HardwareTimeout );
  52. WRITE_REGISTER_ULONG( DeviceExtension->ControlRegisterAddress, Control );
  53. if (PingTimer) {
  54. PingWatchdogTimer( DeviceExtension, FALSE );
  55. }
  56. }
  57. ULONG
  58. WdHandlerQueryTimeoutValue(
  59. IN PDEVICE_EXTENSION DeviceExtension
  60. )
  61. /*++
  62. Routine Description:
  63. This function queries the hardware for the current
  64. value of the hardware timer. This timer is counting down
  65. to zero and this query returns the real-time value of
  66. the timer.
  67. Arguments:
  68. DeviceExtension - Pointer to the watchdog device extension
  69. Return Value:
  70. The current timeout value.
  71. Notes:
  72. --*/
  73. {
  74. return READ_REGISTER_ULONG( DeviceExtension->CountRegisterAddress );
  75. }
  76. void
  77. WdHandlerResetTimer(
  78. IN PDEVICE_EXTENSION DeviceExtension
  79. )
  80. /*++
  81. Routine Description:
  82. This function resets the timer to it's previously
  83. set maximum value.
  84. Arguments:
  85. DeviceExtension - Pointer to the watchdog device extension
  86. Return Value:
  87. None.
  88. Notes:
  89. --*/
  90. {
  91. ULONG Control = READ_REGISTER_ULONG( DeviceExtension->ControlRegisterAddress );
  92. SETBITS( Control, WATCHDOG_CONTROL_TRIGGER );
  93. WRITE_REGISTER_ULONG( DeviceExtension->ControlRegisterAddress, Control );
  94. PingWatchdogTimer( DeviceExtension, FALSE );
  95. }
  96. void
  97. WdHandlerStopTimer(
  98. IN PDEVICE_EXTENSION DeviceExtension
  99. )
  100. /*++
  101. Routine Description:
  102. This function stops the hardware and software timer.
  103. Arguments:
  104. DeviceExtension - Pointer to the watchdog device extension
  105. Return Value:
  106. None.
  107. Notes:
  108. --*/
  109. {
  110. ULONG Control = READ_REGISTER_ULONG( DeviceExtension->ControlRegisterAddress );
  111. CLEARBITS( Control, WATCHDOG_CONTROL_ENABLE );
  112. WRITE_REGISTER_ULONG( DeviceExtension->ControlRegisterAddress, Control );
  113. KeCancelTimer( &DeviceExtension->Timer );
  114. }
  115. void
  116. WdHandlerStartTimer(
  117. IN PDEVICE_EXTENSION DeviceExtension
  118. )
  119. /*++
  120. Routine Description:
  121. This function starts the hardware and software timer.
  122. Arguments:
  123. DeviceExtension - Pointer to the watchdog device extension
  124. Return Value:
  125. None.
  126. Notes:
  127. --*/
  128. {
  129. ULONG Control = READ_REGISTER_ULONG( DeviceExtension->ControlRegisterAddress );
  130. SETBITS( Control, WATCHDOG_CONTROL_ENABLE );
  131. WRITE_REGISTER_ULONG( DeviceExtension->ControlRegisterAddress, Control );
  132. SETBITS( Control, WATCHDOG_CONTROL_TRIGGER );
  133. WRITE_REGISTER_ULONG( DeviceExtension->ControlRegisterAddress, Control );
  134. PingWatchdogTimer( DeviceExtension, FALSE );
  135. }
  136. void
  137. WdHandlerSetTriggerAction(
  138. IN PDEVICE_EXTENSION DeviceExtension,
  139. IN ULONG TriggerAction
  140. )
  141. /*++
  142. Routine Description:
  143. This function sets the trigger action. The trigger
  144. action specifies what action takes place when the
  145. hardware timer expires. There are 2 possible actions,
  146. restart and reboot.
  147. Arguments:
  148. DeviceExtension - Pointer to the watchdog device extension
  149. TriggerAction - Sets the trigger action
  150. 0 = Restart system
  151. 1 = Reboot system
  152. Return Value:
  153. None.
  154. Notes:
  155. --*/
  156. {
  157. ULONG Control = READ_REGISTER_ULONG( DeviceExtension->ControlRegisterAddress );
  158. if (TriggerAction == 1) {
  159. SETBITS( Control, WATCHDOG_CONTROL_TIMER_MODE );
  160. } else {
  161. CLEARBITS( Control, WATCHDOG_CONTROL_TIMER_MODE );
  162. }
  163. WRITE_REGISTER_ULONG( DeviceExtension->ControlRegisterAddress, Control );
  164. }
  165. ULONG
  166. WdHandlerQueryTriggerAction(
  167. IN PDEVICE_EXTENSION DeviceExtension
  168. )
  169. /*++
  170. Routine Description:
  171. This function queries the current trigger action.
  172. Arguments:
  173. DeviceExtension - Pointer to the watchdog device extension
  174. Return Value:
  175. TriggerAction:
  176. 0 = Restart system
  177. 1 = Reboot system
  178. Notes:
  179. --*/
  180. {
  181. ULONG Control = READ_REGISTER_ULONG( DeviceExtension->ControlRegisterAddress );
  182. if (Control & WATCHDOG_CONTROL_TIMER_MODE) {
  183. return 1;
  184. }
  185. return 0;
  186. }
  187. ULONG
  188. WdHandlerQueryState(
  189. IN PDEVICE_EXTENSION DeviceExtension,
  190. IN BOOLEAN QueryFiredFromDevice
  191. )
  192. /*++
  193. Routine Description:
  194. This function queries the device state from the
  195. hardware timer.
  196. Arguments:
  197. DeviceExtension - Pointer to the watchdog device extension
  198. QueryFiredFromDevice - Specifies whether the fired state
  199. bit should come from the device or from the driver cache.
  200. Return Value:
  201. Device state.
  202. Notes:
  203. --*/
  204. {
  205. ULONG Control = READ_REGISTER_ULONG( DeviceExtension->ControlRegisterAddress );
  206. ULONG StateValue = 0;
  207. if (QueryFiredFromDevice) {
  208. if (Control & WATCHDOG_CONTROL_FIRED) {
  209. SETBITS( StateValue, WDSTATE_FIRED );
  210. }
  211. } else {
  212. if (DeviceExtension->WdState & WDSTATE_FIRED) {
  213. SETBITS( StateValue, WDSTATE_FIRED );
  214. }
  215. }
  216. if ((Control & WATCHDOG_CONTROL_BIOS_JUMPER) == 0) {
  217. SETBITS( StateValue, WDSTATE_HARDWARE_ENABLED );
  218. }
  219. if (Control & WATCHDOG_CONTROL_ENABLE) {
  220. SETBITS( StateValue, WDSTATE_STARTED );
  221. }
  222. SETBITS( StateValue, WDSTATE_HARDWARE_PRESENT );
  223. return StateValue;
  224. }
  225. void
  226. WdHandlerResetFired(
  227. IN PDEVICE_EXTENSION DeviceExtension
  228. )
  229. /*++
  230. Routine Description:
  231. This function resets the hardware fired state bit.
  232. Arguments:
  233. DeviceExtension - Pointer to the watchdog device extension
  234. Return Value:
  235. None.
  236. Notes:
  237. --*/
  238. {
  239. ULONG Control = READ_REGISTER_ULONG( DeviceExtension->ControlRegisterAddress );
  240. SETBITS( Control, WATCHDOG_CONTROL_FIRED );
  241. WRITE_REGISTER_ULONG( DeviceExtension->ControlRegisterAddress, Control );
  242. }
  243. NTSTATUS
  244. WdHandlerFunction(
  245. IN WATCHDOG_HANDLER_ACTION HandlerAction,
  246. IN PVOID Context,
  247. IN OUT PULONG DataValue,
  248. IN BOOLEAN NoLocks
  249. )
  250. /*++
  251. Routine Description:
  252. This routine is the hardware specific interface to the watchdog device.
  253. All hardware interfaces are here are exposed thru the handler function
  254. for use by NtSet/QuerySystemInformation and the other part of the
  255. watchdog driver.
  256. Arguments:
  257. HandlerAction - Enumeration specifying the requested action
  258. Context - Always a device extension pointer
  259. DataValue - Action specific data value
  260. NoLocks - Specifies that no lock are to be held during
  261. the handler function
  262. Return Value:
  263. If we successfully create a device object, STATUS_SUCCESS is
  264. returned. Otherwise, return the appropriate error code.
  265. Notes:
  266. --*/
  267. {
  268. PDEVICE_EXTENSION DeviceExtension = (PDEVICE_EXTENSION) Context;
  269. NTSTATUS Status = STATUS_SUCCESS;
  270. KLOCK_QUEUE_HANDLE LockHandle;
  271. ULONG Timeout;
  272. if (!NoLocks) {
  273. KeAcquireInStackQueuedSpinLock( &DeviceExtension->DeviceLock, &LockHandle );
  274. }
  275. switch (HandlerAction) {
  276. case WdActionSetTimeoutValue:
  277. Timeout = ConvertTimeoutFromMilliseconds( WdTable->Units, *DataValue );
  278. if (Timeout > DeviceExtension->MaxCount || Timeout == 0) {
  279. Status = STATUS_INVALID_PARAMETER_1;
  280. } else {
  281. WdHandlerSetTimeoutValue( DeviceExtension, Timeout, TRUE );
  282. }
  283. break;
  284. case WdActionQueryTimeoutValue:
  285. *DataValue = WdHandlerQueryTimeoutValue( DeviceExtension );
  286. break;
  287. case WdActionResetTimer:
  288. WdHandlerResetTimer( DeviceExtension );
  289. break;
  290. case WdActionStopTimer:
  291. WdHandlerStopTimer( DeviceExtension );
  292. break;
  293. case WdActionStartTimer:
  294. WdHandlerStartTimer( DeviceExtension );
  295. break;
  296. case WdActionSetTriggerAction:
  297. if (*DataValue == 0xbadbadff) {
  298. KeCancelTimer( &DeviceExtension->Timer );
  299. } else {
  300. if (*DataValue > 1) {
  301. Status = STATUS_INVALID_PARAMETER_2;
  302. } else {
  303. WdHandlerSetTriggerAction( DeviceExtension, *DataValue );
  304. }
  305. }
  306. break;
  307. case WdActionQueryTriggerAction:
  308. *DataValue = WdHandlerQueryTriggerAction( DeviceExtension );
  309. break;
  310. case WdActionQueryState:
  311. *DataValue = WdHandlerQueryState( DeviceExtension, FALSE );
  312. break;
  313. default:
  314. Status = STATUS_INVALID_PARAMETER_3;
  315. }
  316. if (!NoLocks) {
  317. KeReleaseInStackQueuedSpinLock( &LockHandle );
  318. }
  319. return Status;
  320. }