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.

267 lines
6.3 KiB

  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. handlers.c
  5. Abstract:
  6. GPE and Operation Region handlers for the ACPI Embedded Controller Driver
  7. Author:
  8. Bob Moore (Intel)
  9. Environment:
  10. Notes:
  11. Revision History:
  12. --*/
  13. #include "ecp.h"
  14. NTSTATUS
  15. AcpiEcOpRegionCompletion (
  16. IN PDEVICE_OBJECT DeviceObject,
  17. IN PIRP Irp,
  18. IN PVOID Context
  19. )
  20. /*++
  21. Routine Description:
  22. This routine starts or continues servicing the device's work queue
  23. Arguments:
  24. DeviceObject - EC device object
  25. Irp - Completing Irp
  26. Context - Not Used
  27. Return Value:
  28. Status
  29. --*/
  30. {
  31. PACPI_OPREGION_CALLBACK completionHandler;
  32. PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation( Irp );
  33. PVOID completionContext;
  34. //
  35. // Grab the arguments from the irp
  36. //
  37. completionHandler = (PACPI_OPREGION_CALLBACK) irpSp->Parameters.Others.Argument1;
  38. completionContext = (PVOID) irpSp->Parameters.Others.Argument2;
  39. EcPrint(
  40. EC_HANDLER,
  41. ("AcpiEcOpRegionCompletion: Callback: %08lx Context: %08lx\n",
  42. completionHandler, completionContext )
  43. );
  44. //
  45. // What happened?
  46. //
  47. if (!NT_SUCCESS(Irp->IoStatus.Status)) {
  48. EcPrint(
  49. EC_ERROR,
  50. ("AcpiEcOpRegionCompletion: region IO failed: %x\n",
  51. Irp->IoStatus.Status)
  52. );
  53. }
  54. //
  55. // Invoke the AML interpreter's callback
  56. //
  57. (completionHandler)( completionContext );
  58. //
  59. // We are done with this irp and the irp
  60. //
  61. IoFreeIrp( Irp );
  62. //
  63. // Return always return this --- because had to free the irp
  64. //
  65. return STATUS_MORE_PROCESSING_REQUIRED;
  66. }
  67. NTSTATUS
  68. EXPORT
  69. AcpiEcOpRegionHandler (
  70. ULONG AccessType,
  71. PVOID OpRegion,
  72. ULONG Address,
  73. ULONG Size,
  74. PULONG Data,
  75. ULONG_PTR Context,
  76. PACPI_OPREGION_CALLBACK CompletionHandler,
  77. PVOID CompletionContext
  78. )
  79. /*++
  80. Routine Description:
  81. This routine handles requests to service the EC operation region
  82. Arguments:
  83. AccessType - Read or Write data
  84. OpRegion - Operation region object
  85. Address - Address within the EC address space
  86. Size - Number of bytes to transfer
  87. Data - Data buffer to transfer to/from
  88. Context - EcData
  89. CompletionHandler - AMLI handler to call when operation is complete
  90. CompletionContext - Context to pass to the AMLI handler
  91. Return Value:
  92. Status
  93. Notes:
  94. Optimization 1: Queue the IRP directly.
  95. Optimization 2: Queue the context, modify service loop handle it
  96. --*/
  97. {
  98. LARGE_INTEGER startingOffset;
  99. NTSTATUS status;
  100. PECDATA ecData = (PECDATA) Context;
  101. PIO_STACK_LOCATION irpSp;
  102. PIRP irp;
  103. EcPrint(
  104. (EC_HANDLER | EC_OPREGION),
  105. ("AcpiEcOpRegionHandler: %s Addr=%x Data = %x EcData=%x, Irql=%x\n",
  106. (AccessType == ACPI_OPREGION_READ ? "read" : "write"),
  107. Address, *Data, ecData, KeGetCurrentIrql() )
  108. );
  109. //
  110. // Parameter validation will be done in AcpiEcReadWrite
  111. //
  112. //
  113. // Determine where the read will occur
  114. //
  115. startingOffset.LowPart = Address;
  116. startingOffset.HighPart = 0;
  117. //
  118. // Allocate an IRP for ourselves. Since we are going to send this
  119. // irp to ourselves, we know that we only need 1 stack location for it
  120. // However, to make life easier for ourselves, we will allocate a
  121. // second one as well and store some data on it.
  122. //
  123. irp = IoAllocateIrp( 2, FALSE );
  124. if (!irp) {
  125. EcPrint(EC_ERROR, ("AcpiEcOpRegionHandler: Couldn't allocate Irp\n"));
  126. //
  127. // Retun -1 for data
  128. //
  129. RtlFillMemory (Data, Size, 0xff);
  130. CompletionHandler( CompletionContext );
  131. //
  132. // Always return STATUS_PENDING because ACPI interpreter doesn't handle errors.
  133. //
  134. return STATUS_PENDING;
  135. }
  136. //
  137. // Fill in the top location so that we can use it ourselves
  138. //
  139. irpSp = IoGetNextIrpStackLocation( irp );
  140. irpSp->Parameters.Others.Argument1 = (PVOID) CompletionHandler;
  141. irpSp->Parameters.Others.Argument2 = (PVOID) CompletionContext;
  142. IoSetNextIrpStackLocation( irp );
  143. //
  144. // Fill out the irp with the request info
  145. //
  146. irpSp = IoGetNextIrpStackLocation( irp );
  147. irpSp->MajorFunction = (AccessType == ACPI_OPREGION_READ ? IRP_MJ_READ : IRP_MJ_WRITE);
  148. irpSp->Parameters.Read.ByteOffset.HighPart = 0;
  149. irpSp->Parameters.Read.ByteOffset.LowPart = Address;
  150. irpSp->Parameters.Read.Length = Size;
  151. irp->AssociatedIrp.SystemBuffer = Data;
  152. //
  153. // Set a completion routine
  154. //
  155. IoSetCompletionRoutine(
  156. irp,
  157. AcpiEcOpRegionCompletion,
  158. NULL,
  159. TRUE,
  160. TRUE,
  161. TRUE
  162. );
  163. //
  164. // Send to the front-end of the EC driver as a normal I/O request
  165. //
  166. status = IoCallDriver( ecData->DeviceObject, irp);
  167. EcPrint(
  168. EC_HANDLER,
  169. ("AcpiEcOpRegionHandler: Exiting - Data=%08lx Status=%08lx\n",
  170. (UCHAR) *Data, status)
  171. );
  172. return STATUS_PENDING;
  173. //
  174. // Always return STATUS_PENDING since actual status has been returned
  175. // by the calback function.
  176. //
  177. }
  178. BOOLEAN
  179. AcpiEcGpeServiceRoutine (
  180. IN PVOID GpeVectorObject,
  181. IN PVOID ServiceContext
  182. )
  183. /*++
  184. Routine Description:
  185. Routine to service the EC based on a General Purpose Event
  186. Arguments:
  187. GpeVectorObject - Object associated with this GPE
  188. ServiceContext - EcData
  189. Return Value:
  190. TRUE, since we always handle this GPE
  191. --*/
  192. {
  193. PECDATA EcData = (PECDATA) ServiceContext;
  194. EcPrint (EC_HANDLER, ("AcpiEcGpeServiceRoutine: Vobj=%Lx, EcData=%Lx\n",
  195. GpeVectorObject, EcData));
  196. AcpiEcLogAction (EcData, EC_ACTION_INTERRUPT, 0);
  197. AcpiEcServiceDevice (EcData);
  198. return (TRUE);
  199. }