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.

340 lines
9.1 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. cmhndlr.c
  5. Abstract:
  6. Control Method Battery handlers
  7. Author:
  8. Bob Moore
  9. Environment:
  10. Kernel mode
  11. Revision History:
  12. --*/
  13. #include "CmBattp.h"
  14. VOID
  15. CmBattPowerCallBack(
  16. IN PVOID CallBackContext,
  17. IN PVOID Argument1,
  18. IN PVOID Argument2
  19. )
  20. /*++
  21. Routine Description:
  22. This routine is called when the system changes power states
  23. Arguments:
  24. CallBackContext - The device extension for the root device
  25. Argument1
  26. --*/
  27. {
  28. PDRIVER_OBJECT CmBattDriver = (PDRIVER_OBJECT) CallBackContext;
  29. ULONG action = PtrToUlong( Argument1 );
  30. ULONG value = PtrToUlong( Argument2 );
  31. BOOLEAN timerCanceled;
  32. PDEVICE_OBJECT CmBattDevice;
  33. PCM_BATT CmBatt;
  34. CmBattPrint (CMBATT_POWER, ("CmBattPowerCallBack: action: %d, value: %d \n", action, value));
  35. //
  36. // We are looking for a PO_CB_SYSTEM_STATE_LOCK
  37. //
  38. if (action != PO_CB_SYSTEM_STATE_LOCK) {
  39. return;
  40. }
  41. switch (value) {
  42. case 0:
  43. CmBattPrint (CMBATT_POWER, ("CmBattPowerCallBack: Delaying Notifications\n"));
  44. //
  45. // Get the head of the DeviceObject list
  46. //
  47. CmBattDevice = CmBattDriver->DeviceObject;
  48. while (CmBattDevice) {
  49. CmBatt = CmBattDevice->DeviceExtension;
  50. //
  51. // Cause all notifications to be delayed.
  52. //
  53. CmBatt->Sleeping = TRUE;
  54. CmBattDevice = CmBattDevice->NextDevice;
  55. }
  56. break;
  57. case 1:
  58. CmBattPrint (CMBATT_POWER, ("CmBattPowerCallBack: Calling CmBattWakeDpc after 10 seconds.\n"));
  59. timerCanceled = KeSetTimer (&CmBattWakeDpcTimerObject,
  60. CmBattWakeDpcDelay,
  61. &CmBattWakeDpcObject);
  62. CmBattPrint (CMBATT_POWER, ("CmBattPowerCallBack: timerCanceled = %d.\n", timerCanceled));
  63. break;
  64. default:
  65. CmBattPrint (CMBATT_POWER, ("CmBattPowerCallBack: unknown argument2 = %08x\n", value));
  66. }
  67. }
  68. VOID
  69. CmBattWakeDpc (
  70. IN PKDPC Dpc,
  71. IN PVOID DeferredContext,
  72. IN PVOID SystemArgument1,
  73. IN PVOID SystemArgument2
  74. )
  75. /*++
  76. Routine Description:
  77. This routine is called X seconds after the system wakes to proces
  78. all delayed battery notifications.
  79. Arguments:
  80. CmBattDriver - Driver object
  81. Return Value:
  82. None
  83. --*/
  84. {
  85. PDRIVER_OBJECT CmBattDriver = (PDRIVER_OBJECT) DeferredContext;
  86. BOOLEAN notifyAll = FALSE;
  87. PDEVICE_OBJECT CmBattDevice;
  88. PCM_BATT CmBatt;
  89. CmBattPrint (CMBATT_TRACE, ("CmBattWakeDpc: Entered.\n"));
  90. //
  91. // Get the head of the DeviceObject list
  92. //
  93. CmBattDevice = CmBattDriver->DeviceObject;
  94. while (CmBattDevice) {
  95. CmBatt = CmBattDevice->DeviceExtension;
  96. //
  97. // We will now process all delayed notifications.
  98. // For effeiciency, we must go through the devices twice:
  99. // first to see if any AC devices have been notified, and
  100. // then to send notifications to all battery devices if necessary.
  101. //
  102. CmBatt->Sleeping = FALSE;
  103. if ((CmBatt->Type == AC_ADAPTER_TYPE) &&
  104. (CmBatt->ActionRequired & CMBATT_AR_NOTIFY)) {
  105. //
  106. // If any AC adapter devices have notified,
  107. // then we need to notify all battery devices
  108. //
  109. CmBattPrint (CMBATT_PNP, ("CmBattWakeDpc: AC adapter notified\n"));
  110. notifyAll = TRUE;
  111. CmBatt->ActionRequired = CMBATT_AR_NO_ACTION;
  112. }
  113. CmBattDevice = CmBattDevice->NextDevice;
  114. }
  115. //
  116. // Get the head of the DeviceObject list
  117. //
  118. CmBattDevice = CmBattDriver->DeviceObject;
  119. // Walk the list
  120. while (CmBattDevice) {
  121. CmBatt = CmBattDevice->DeviceExtension;
  122. if (CmBatt->Type == CM_BATTERY_TYPE) {
  123. CmBattPrint (CMBATT_PNP, ("CmBattWakeDpc: Performing delayed ARs: %01x\n", CmBatt->ActionRequired));
  124. if (CmBatt->ActionRequired & CMBATT_AR_INVALIDATE_CACHE) {
  125. InterlockedExchange (&CmBatt->CacheState, 0);
  126. }
  127. if (CmBatt->ActionRequired & CMBATT_AR_INVALIDATE_TAG) {
  128. CmBatt->Info.Tag = BATTERY_TAG_INVALID;
  129. }
  130. if ((CmBatt->ActionRequired & CMBATT_AR_NOTIFY) || notifyAll) {
  131. BatteryClassStatusNotify (CmBatt->Class);
  132. }
  133. }
  134. CmBattDevice = CmBattDevice->NextDevice;
  135. }
  136. }
  137. VOID
  138. CmBattNotifyHandler (
  139. IN PVOID Context,
  140. IN ULONG NotifyValue
  141. )
  142. /*++
  143. Routine Description:
  144. This routine fields battery device notifications from the ACPI driver.
  145. Arguments:
  146. Return Value:
  147. None
  148. --*/
  149. {
  150. PCM_BATT CmBatt = Context;
  151. PDRIVER_OBJECT CmBatteryDriver;
  152. PDEVICE_OBJECT CmBatteryDevice;
  153. PCM_BATT CmBatteryExtension;
  154. CmBattPrint ((CMBATT_PNP | CMBATT_BIOS), ("CmBattNotifyHandler: CmBatt 0x%08x Type %d Number %d Notify Value: %x\n",
  155. CmBatt, CmBatt->Type, CmBatt->DeviceNumber, NotifyValue));
  156. switch (NotifyValue) {
  157. case BATTERY_DEVICE_CHECK:
  158. //
  159. // A new battery was inserted in the system.
  160. //
  161. CmBatt->ActionRequired |= CMBATT_AR_NOTIFY;
  162. CmBatt->ActionRequired |= CMBATT_AR_INVALIDATE_CACHE;
  163. //
  164. // This notification is only received when a battery is inserted.
  165. // It also occurs after restart from hibernation on some machines.
  166. // Invalidate battery tag.
  167. //
  168. if (CmBatt->Info.Tag != BATTERY_TAG_INVALID) {
  169. CmBattPrint ((CMBATT_ERROR),
  170. ("CmBattNotifyHandler: Received battery #%x insertion, but tag was not invalid.\n",
  171. CmBatt->DeviceNumber));
  172. }
  173. break;
  174. case BATTERY_EJECT:
  175. //
  176. // A battery was removed from the system
  177. //
  178. CmBatt->ActionRequired |= CMBATT_AR_NOTIFY;
  179. //
  180. // Invalidate the battery tag and all cached informaion
  181. // whenever this message is received.
  182. //
  183. CmBatt->ActionRequired |= CMBATT_AR_INVALIDATE_CACHE;
  184. CmBatt->ActionRequired |= CMBATT_AR_INVALIDATE_TAG;
  185. break;
  186. case BATTERY_STATUS_CHANGE: // Status change only
  187. CmBatt->ActionRequired |= CMBATT_AR_NOTIFY;
  188. break;
  189. case BATTERY_INFO_CHANGE: // Info & status change
  190. CmBatt->ActionRequired |= CMBATT_AR_NOTIFY;
  191. CmBatt->ActionRequired |= CMBATT_AR_INVALIDATE_CACHE;
  192. CmBatt->ActionRequired |= CMBATT_AR_INVALIDATE_TAG;
  193. break;
  194. default:
  195. CmBattPrint (CMBATT_PNP, ("CmBattNotifyHandler: Unknown Notify Value: %x\n", NotifyValue));
  196. break;
  197. }
  198. if (CmBatt->Sleeping) {
  199. CmBattPrint (CMBATT_PNP, ("CmBattNotifyHandler: Notification delayed: ARs = %01x\n", CmBatt->ActionRequired));
  200. } else {
  201. CmBattPrint (CMBATT_PNP, ("CmBattNotifyHandler: Performing ARs: %01x\n", CmBatt->ActionRequired));
  202. if (CmBatt->Type == CM_BATTERY_TYPE) {
  203. //
  204. // Invalidate last trip point set on battery.
  205. //
  206. CmBatt->Alarm.Setting = CM_ALARM_INVALID;
  207. if (CmBatt->ActionRequired & CMBATT_AR_INVALIDATE_CACHE) {
  208. InterlockedExchange (&CmBatt->CacheState, 0);
  209. }
  210. if (CmBatt->ActionRequired & CMBATT_AR_INVALIDATE_TAG) {
  211. CmBatt->Info.Tag = BATTERY_TAG_INVALID;
  212. }
  213. if (CmBatt->ActionRequired & CMBATT_AR_NOTIFY) {
  214. CmBatt->ReCheckSta = TRUE;
  215. BatteryClassStatusNotify (CmBatt->Class);
  216. }
  217. } else if ((CmBatt->Type == AC_ADAPTER_TYPE) &&
  218. (CmBatt->ActionRequired & CMBATT_AR_NOTIFY)) {
  219. //
  220. // Get the Driver Object
  221. //
  222. CmBatteryDriver = CmBatt->Fdo->DriverObject;
  223. //
  224. // Get the head of the DeviceObject list
  225. //
  226. CmBatteryDevice = CmBatteryDriver->DeviceObject;
  227. //
  228. // Walk the DeviceObject list to notify the class driver on all batteries
  229. //
  230. while (CmBatteryDevice) {
  231. CmBatteryExtension = CmBatteryDevice->DeviceExtension;
  232. if (CmBatteryExtension->Type == CM_BATTERY_TYPE) {
  233. CmBatteryExtension->ReCheckSta = TRUE;
  234. BatteryClassStatusNotify (CmBatteryExtension->Class);
  235. }
  236. CmBatteryDevice = CmBatteryDevice->NextDevice;
  237. }
  238. }
  239. CmBatt->ActionRequired = CMBATT_AR_NO_ACTION;
  240. }
  241. }