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.

390 lines
9.2 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. processor.c
  5. Abstract:
  6. Processor support
  7. Author:
  8. Stephane Plante (splante)
  9. Environment:
  10. NT Kernel Model Driver only
  11. Revision History:
  12. Adapted for processors from buttons - JakeO (3-28-2000)
  13. --*/
  14. #include "pch.h"
  15. #include "..\shared\acpictl.h"
  16. #ifdef ALLOC_PRAGMA
  17. #pragma alloc_text(PAGE, ACPIButtonStartDevice)
  18. #endif
  19. //
  20. // Spinlock to protect the processor list
  21. //
  22. KSPIN_LOCK AcpiProcessorLock;
  23. //
  24. // List entry to store the thermal requests on
  25. //
  26. LIST_ENTRY AcpiProcessorList;
  27. VOID
  28. ACPIProcessorCancelRequest(
  29. IN PDEVICE_OBJECT DeviceObject,
  30. IN PIRP Irp
  31. )
  32. /*++
  33. Routine Description:
  34. This routine cancels an outstanding processor request
  35. Arguments:
  36. DeviceObject - the device which as a request being cancelled
  37. Irp - the cancelling irp
  38. Return Value:
  39. None
  40. --*/
  41. {
  42. KIRQL oldIrql;
  43. PDEVICE_EXTENSION deviceExtension = ACPIInternalGetDeviceExtension(DeviceObject);
  44. //
  45. // We no longer need the cancel lock
  46. //
  47. IoReleaseCancelSpinLock( Irp->CancelIrql );
  48. //
  49. // We do however need the processor queue lock
  50. //
  51. KeAcquireSpinLock( &AcpiProcessorLock, &oldIrql );
  52. //
  53. // Remove the irp from the list that it is on
  54. //
  55. RemoveEntryList( &(Irp->Tail.Overlay.ListEntry) );
  56. //
  57. // Complete the irp now
  58. //
  59. Irp->IoStatus.Status = STATUS_CANCELLED;
  60. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  61. }
  62. BOOLEAN
  63. ACPIProcessorCompletePendingIrps(
  64. IN PDEVICE_OBJECT DeviceObject,
  65. IN ULONG ProcessorEvent
  66. )
  67. /*++
  68. Routine Description:
  69. This routine completes any pending processor irp sent to the specified
  70. device object with the knowledge of which processor events have occured
  71. The respective's processor's spinlock is held during this call
  72. Arguments:
  73. DeviceObject - the target processor object
  74. ProcessorEvent - the processor event that occured
  75. Return Value:
  76. TRUE if we completed an irp, FALSE, otherwise
  77. --*/
  78. {
  79. BOOLEAN handledRequest = FALSE;
  80. KIRQL oldIrql;
  81. LIST_ENTRY doneList;
  82. PDEVICE_OBJECT targetObject;
  83. PIO_STACK_LOCATION irpSp;
  84. PIRP irp;
  85. PLIST_ENTRY listEntry;
  86. PULONG resultBuffer;
  87. //
  88. // Initialize the list that will hold the requests that we need to
  89. // complete
  90. //
  91. InitializeListHead( &doneList );
  92. //
  93. // Acquire the thermal lock so that we can pend these requests
  94. //
  95. KeAcquireSpinLock( &AcpiProcessorLock, &oldIrql );
  96. //
  97. // Walk the list of pending irps to see which ones match this extension
  98. //
  99. listEntry = AcpiProcessorList.Flink;
  100. while (listEntry != &AcpiProcessorList) {
  101. //
  102. // Grab the irp from the list entry and update the next list entry
  103. // that we will look at
  104. //
  105. irp = CONTAINING_RECORD( listEntry, IRP, Tail.Overlay.ListEntry );
  106. listEntry = listEntry->Flink;
  107. //
  108. // We need the current irp stack location
  109. //
  110. irpSp = IoGetCurrentIrpStackLocation( irp );
  111. //
  112. // what is the target object for this irp?
  113. //
  114. targetObject = irpSp->DeviceObject;
  115. //
  116. // Is this an irp that we care about? IE: does the does target mage
  117. // the ones specified in this function
  118. //
  119. if (targetObject != DeviceObject) {
  120. continue;
  121. }
  122. //
  123. // At this point, we need to set the cancel routine to NULL because
  124. // we are going to take care of this irp and we don't want it cancelled
  125. // underneath us
  126. //
  127. if (IoSetCancelRoutine(irp, NULL) == NULL) {
  128. //
  129. // Cancel routine is active. stop processing this irp and move on
  130. //
  131. continue;
  132. }
  133. //
  134. // set the data to return in the irp
  135. //
  136. resultBuffer = (PULONG) irp->AssociatedIrp.SystemBuffer;
  137. *resultBuffer = ProcessorEvent;
  138. irp->IoStatus.Status = STATUS_SUCCESS;
  139. irp->IoStatus.Information = sizeof(ULONG);
  140. //
  141. // Remove the entry from the list
  142. //
  143. RemoveEntryList( &(irp->Tail.Overlay.ListEntry) );
  144. //
  145. // Insert the list onto the next queue, so that we know how to
  146. // complete it later on
  147. //
  148. InsertTailList( &doneList, &(irp->Tail.Overlay.ListEntry) );
  149. }
  150. //
  151. // At this point, droup our processor lock
  152. //
  153. KeReleaseSpinLock( &AcpiProcessorLock, oldIrql );
  154. //
  155. // Walk the list of irps to be completed
  156. //
  157. listEntry = doneList.Flink;
  158. while (listEntry != &doneList) {
  159. //
  160. // Grab the irp from the list entry, update the next list entry
  161. // that we will look at, and complete the request
  162. //
  163. irp = CONTAINING_RECORD( listEntry, IRP, Tail.Overlay.ListEntry );
  164. listEntry = listEntry->Flink;
  165. RemoveEntryList( &(irp->Tail.Overlay.ListEntry) );
  166. //
  167. // Complete the request and remember that we handled a request
  168. //
  169. IoCompleteRequest( irp, IO_NO_INCREMENT );
  170. handledRequest = TRUE;
  171. }
  172. //
  173. // Return wether or not we handled a request
  174. //
  175. return handledRequest;
  176. }
  177. NTSTATUS
  178. ACPIProcessorDeviceControl (
  179. IN PDEVICE_OBJECT DeviceObject,
  180. IN PIRP Irp
  181. )
  182. /*++
  183. Routine Description:
  184. Fixed processor device IOCTL handler
  185. Arguments:
  186. DeviceObject - fixed feature processor device object
  187. Irp - the ioctl request
  188. Return Value:
  189. Status
  190. --*/
  191. {
  192. KIRQL oldIrql;
  193. NTSTATUS status;
  194. PDEVICE_EXTENSION deviceExtension = ACPIInternalGetDeviceExtension(DeviceObject);
  195. PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp);
  196. PULONG resultBuffer;
  197. OBJDATA data;
  198. //
  199. // Do not allow user mode IRPs in this routine
  200. //
  201. if (Irp->RequestorMode != KernelMode) {
  202. return ACPIDispatchIrpInvalid( DeviceObject, Irp );
  203. }
  204. resultBuffer = (PULONG) Irp->AssociatedIrp.SystemBuffer;
  205. switch (irpSp->Parameters.DeviceIoControl.IoControlCode) {
  206. case IOCTL_GET_PROCESSOR_OBJ_INFO:
  207. if (irpSp->Parameters.DeviceIoControl.OutputBufferLength <
  208. sizeof(IOCTL_GET_PROCESSOR_OBJ_INFO)) {
  209. Irp->IoStatus.Status = status = STATUS_INFO_LENGTH_MISMATCH;
  210. Irp->IoStatus.Information = 0;
  211. } else {
  212. status = AMLIEvalNameSpaceObject(deviceExtension->AcpiObject,
  213. &data,
  214. 0,
  215. NULL);
  216. if (NT_SUCCESS(status)) {
  217. ASSERT (data.dwDataType == OBJTYPE_PROCESSOR);
  218. ASSERT (data.pbDataBuff != NULL);
  219. (*(PPROCESSOR_OBJECT_INFO)resultBuffer).PhysicalID =
  220. ((PROCESSOROBJ *)data.pbDataBuff)->bApicID;
  221. (*(PPROCESSOR_OBJECT_INFO)resultBuffer).PBlkAddress =
  222. ((PROCESSOROBJ *)data.pbDataBuff)->dwPBlk;
  223. (*(PPROCESSOR_OBJECT_INFO)resultBuffer).PBlkLength =
  224. (UCHAR)((PROCESSOROBJ *)data.pbDataBuff)->dwPBlkLen;
  225. AMLIFreeDataBuffs(&data, 1);
  226. status = STATUS_SUCCESS;
  227. Irp->IoStatus.Information = sizeof(PROCESSOR_OBJECT_INFO);
  228. }
  229. Irp->IoStatus.Status = status;
  230. }
  231. IoCompleteRequest (Irp, IO_NO_INCREMENT);
  232. break;
  233. case IOCTL_ACPI_ASYNC_EVAL_METHOD:
  234. //
  235. // Handle this elsewhere
  236. //
  237. status = ACPIIoctlAsyncEvalControlMethod(
  238. DeviceObject,
  239. Irp,
  240. irpSp
  241. );
  242. break;
  243. case IOCTL_ACPI_EVAL_METHOD:
  244. //
  245. // Handle this elsewhere
  246. //
  247. status = ACPIIoctlEvalControlMethod(
  248. DeviceObject,
  249. Irp,
  250. irpSp
  251. );
  252. break;
  253. default:
  254. status = STATUS_NOT_SUPPORTED;
  255. Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
  256. IoCompleteRequest (Irp, IO_NO_INCREMENT);
  257. break;
  258. }
  259. return status;
  260. }
  261. NTSTATUS
  262. ACPIProcessorStartDevice (
  263. IN PDEVICE_OBJECT DeviceObject,
  264. IN PIRP Irp
  265. )
  266. /*++
  267. Routine Description:
  268. Start device function for the fixed feature power and sleep device
  269. Arguments:
  270. DeviceObject - fixed feature processor device object
  271. Irp - the start request
  272. Return Value:
  273. Status
  274. --*/
  275. {
  276. NTSTATUS Status;
  277. Status = ACPIInternalSetDeviceInterface (
  278. DeviceObject,
  279. (LPGUID) &GUID_DEVICE_PROCESSOR
  280. );
  281. Irp->IoStatus.Status = Status;
  282. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  283. return Status;
  284. }