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.

264 lines
6.1 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. acpintfy.c
  5. Abstract:
  6. This modules contains code to deal with notifying interested parties
  7. of events
  8. Author:
  9. Jason Clark
  10. Ken Reneris
  11. Environment:
  12. NT Kernel Model Driver only
  13. Some changes are required to work in win9x model
  14. --*/
  15. #include "pch.h"
  16. //
  17. // For handler installation
  18. //
  19. KSPIN_LOCK NotifyHandlerLock;
  20. NTSTATUS
  21. ACPIRegisterForDeviceNotifications (
  22. IN PDEVICE_OBJECT DeviceObject,
  23. IN PDEVICE_NOTIFY_CALLBACK DeviceNotify,
  24. IN PVOID Context
  25. )
  26. /*++
  27. Routine Description:
  28. Registers the DeviceNotify function as the function to receive device notify
  29. callbacks
  30. Arguments:
  31. DeviceObject - The device object to register a notification handler for
  32. DeviceNotify - The handle for device specific notifications
  33. Return Value
  34. Returns status
  35. --*/
  36. {
  37. PACPI_POWER_INFO node;
  38. PVOID previous;
  39. KIRQL oldIrql;
  40. NTSTATUS status;
  41. //
  42. // Find the Node associated with this device object (or DevNode)
  43. // Note: that for NT, the context field is the DeviceExtension of the
  44. // DeviceObject, since this is what is stored within the ACPI Name Space
  45. // object
  46. //
  47. node = OSPowerFindPowerInfoByContext( DeviceObject );
  48. if (node == NULL) {
  49. return STATUS_NO_SUCH_DEVICE;
  50. }
  51. //
  52. // Apply the handler
  53. //
  54. KeAcquireSpinLock (&NotifyHandlerLock, &oldIrql);
  55. if (node->DeviceNotifyHandler != NULL) {
  56. //
  57. // A handler already present
  58. //
  59. status = STATUS_UNSUCCESSFUL;
  60. } else {
  61. node->DeviceNotifyHandler = DeviceNotify;
  62. node->HandlerContext = Context;
  63. status = STATUS_SUCCESS;
  64. }
  65. KeReleaseSpinLock (&NotifyHandlerLock, oldIrql);
  66. return status;
  67. }
  68. VOID
  69. ACPIUnregisterForDeviceNotifications (
  70. IN PDEVICE_OBJECT DeviceObject,
  71. IN PDEVICE_NOTIFY_CALLBACK DeviceNotify
  72. )
  73. /*++
  74. Routine Description:
  75. Disconnects a handler from device notify event.
  76. Arguments:
  77. DeviceObject - The device object to register a notification handler for
  78. DeviceNotify - The handle for device specific notifications
  79. Return Value
  80. None
  81. --*/
  82. {
  83. PACPI_POWER_INFO node;
  84. PVOID previous;
  85. KIRQL oldIrql;
  86. NTSTATUS status;
  87. //
  88. // Find the Node associated with this device object (or DevNode)
  89. // Note: that for NT, the context field is the DeviceExtension of the
  90. // DeviceObject, since this is what is stored within the ACPI Name Space
  91. // object
  92. //
  93. node = OSPowerFindPowerInfoByContext( DeviceObject );
  94. if (node == NULL) {
  95. ASSERTMSG("ACPIUnregisterForDeviceNotifications failed. "\
  96. "Can't find ACPI_POWER_INFO for DeviceObject", FALSE);
  97. return;
  98. }
  99. //
  100. // Attempt to remove the handler/context from the node
  101. //
  102. KeAcquireSpinLock (&NotifyHandlerLock, &oldIrql);
  103. if (node->DeviceNotifyHandler != DeviceNotify) {
  104. //
  105. // Handler does not match
  106. //
  107. ASSERTMSG("ACPIUnregisterForDeviceNotifications failed. "\
  108. "Handler doesn't match.", FALSE);
  109. } else {
  110. node->DeviceNotifyHandler = NULL;
  111. node->HandlerContext = NULL;
  112. }
  113. KeReleaseSpinLock (&NotifyHandlerLock, oldIrql);
  114. return;
  115. }
  116. NTSTATUS EXPORT
  117. NotifyHandler (
  118. ULONG dwEventType,
  119. ULONG dwEventData,
  120. PNSOBJ pnsObj,
  121. ULONG dwParam,
  122. PFNAA CompletionCallback,
  123. PVOID CallbackContext
  124. )
  125. /*++
  126. Routine Description:
  127. The master ACPI notify handler.
  128. The design philosophy here is that ACPI should process all notify requests
  129. that *ONLY* it can handle, namely, DeviceCheck, DeviceEject, and DeviceWake,
  130. and let *all* other notifies get handled by the driver associated with the
  131. object. The other driver will also get told about the ACPI handled events,
  132. but that is only as an FYI, the driver shouldn't do anything...
  133. Arguments:
  134. dwEventType - The type of event that occured (this is EVTYPE_NOTIFY)
  135. dwEventData - The event code
  136. pnsObj - The name space object that was notified
  137. dwParam - The event code
  138. Return Value
  139. NTSTATUS
  140. --*/
  141. {
  142. PACPI_POWER_INFO node;
  143. KIRQL oldIrql;
  144. PDEVICE_NOTIFY_CALLBACK notifyHandler;
  145. PVOID notifyHandlerContext;
  146. ASSERT (dwEventType == EVTYPE_NOTIFY);
  147. ACPIPrint( (
  148. ACPI_PRINT_DPC,
  149. "ACPINotifyHandler: Notify on %x value %x, object type %x\n",
  150. pnsObj,
  151. dwEventData,
  152. NSGETOBJTYPE(pnsObj)
  153. ) );
  154. //
  155. // Any events which must be handled by ACPI and is common to all device
  156. // object types is handled here
  157. //
  158. switch (dwEventData) {
  159. case OPEVENT_DEVICE_ENUM:
  160. OSNotifyDeviceEnum( pnsObj );
  161. break;
  162. case OPEVENT_DEVICE_CHECK:
  163. OSNotifyDeviceCheck( pnsObj );
  164. break;
  165. case OPEVENT_DEVICE_WAKE:
  166. OSNotifyDeviceWake( pnsObj );
  167. break;
  168. case OPEVENT_DEVICE_EJECT:
  169. OSNotifyDeviceEject( pnsObj );
  170. break;
  171. }
  172. //
  173. // Look for handle for this node and dispatch it
  174. //
  175. node = OSPowerFindPowerInfo(pnsObj);
  176. if (node) {
  177. //
  178. // Get handler address/context with mutex
  179. //
  180. KeAcquireSpinLock (&NotifyHandlerLock, &oldIrql);
  181. notifyHandler = node->DeviceNotifyHandler;
  182. notifyHandlerContext = node->HandlerContext;
  183. KeReleaseSpinLock (&NotifyHandlerLock, oldIrql);
  184. //
  185. // If we got something, dispatch it
  186. //
  187. if (notifyHandler) {
  188. notifyHandler (notifyHandlerContext, dwEventData);
  189. }
  190. }
  191. return (STATUS_SUCCESS);
  192. }