Source code of Windows XP (NT5)
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.

415 lines
8.7 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. bus.c
  5. Abstract:
  6. This module contains the bus dispatcher for the ACPI driver, NT version
  7. Author:
  8. Stephane Plante (splante)
  9. Environment:
  10. NT Kernel Model Driver only
  11. --*/
  12. #include "pch.h"
  13. #ifdef ALLOC_PRAGMA
  14. #pragma alloc_text(PAGE, ACPIInternalDeviceClockIrpStartDevice)
  15. #pragma alloc_text(PAGE, ACPIInternalDeviceQueryCapabilities)
  16. #pragma alloc_text(PAGE, ACPIInternalDeviceQueryDeviceRelations)
  17. #endif
  18. NTSTATUS
  19. ACPIInternalDeviceClockIrpStartDevice(
  20. IN PDEVICE_OBJECT DeviceObject,
  21. IN PIRP Irp
  22. )
  23. /*++
  24. Routine Description:
  25. This function is called to start the Real-Time Clock in the system. This
  26. is similar to starting all the other devices in the system, except that
  27. in this case, we send a WAIT_WAKE irp to the device
  28. Arguments:
  29. DeviceObject - The real-time clock object
  30. Irp - The start request
  31. Return Value:
  32. NTSTATUS
  33. --*/
  34. {
  35. NTSTATUS status;
  36. PAGED_CODE();
  37. //
  38. // Start the device
  39. //
  40. status = ACPIInitStartDevice(
  41. DeviceObject,
  42. NULL,
  43. ACPIInternalDeviceClockIrpStartDeviceCompletion,
  44. Irp,
  45. Irp
  46. );
  47. if (NT_SUCCESS(status)) {
  48. return STATUS_PENDING;
  49. } else {
  50. return status;
  51. }
  52. }
  53. VOID
  54. ACPIInternalDeviceClockIrpStartDeviceCompletion(
  55. IN PDEVICE_EXTENSION DeviceExtension,
  56. IN PVOID Context,
  57. IN NTSTATUS Status
  58. )
  59. /*++
  60. Routine Description:
  61. This is the callback routine that is invoked when we have finished
  62. programming the resources
  63. Arguments:
  64. DeviceExtension - Extension of the device that was started
  65. Context - The Irp
  66. Status - The Result
  67. Return Value:
  68. None
  69. --*/
  70. {
  71. KIRQL oldIrql;
  72. IO_STATUS_BLOCK ioStatus;
  73. PIRP irp = (PIRP) Context;
  74. POWER_STATE state;
  75. irp->IoStatus.Status = Status;
  76. if (NT_SUCCESS(Status)) {
  77. //
  78. // Remember that the device is started
  79. //
  80. DeviceExtension->DeviceState = Started;
  81. //
  82. // If the device doesn't support Wakeup, then we don't have to
  83. // anything else here
  84. //
  85. if ( !(DeviceExtension->Flags & DEV_CAP_WAKE) ) {
  86. goto ACPIInternalDeviceClockIrpStartDeviceCompletionExit;
  87. }
  88. //
  89. // Make sure that we are holding the power lock
  90. //
  91. KeAcquireSpinLock( &AcpiPowerLock, &oldIrql );
  92. //
  93. // Remember the maximum state that the clock can wake the system
  94. //
  95. state.SystemState = DeviceExtension->PowerInfo.SystemWakeLevel;
  96. //
  97. // Done with the lock
  98. //
  99. KeReleaseSpinLock( &AcpiPowerLock, oldIrql );
  100. //
  101. // Initialize the IO_STATUS_BLOCK that we will use to start the wait
  102. // wake loop
  103. //
  104. ioStatus.Status = STATUS_SUCCESS;
  105. ioStatus.Information = 0;
  106. //
  107. // Start the wait wake loop
  108. //
  109. Status = ACPIInternalWaitWakeLoop(
  110. DeviceExtension->DeviceObject,
  111. IRP_MN_WAIT_WAKE,
  112. state,
  113. NULL,
  114. &ioStatus
  115. );
  116. if (!NT_SUCCESS(Status)) {
  117. irp->IoStatus.Status = Status;
  118. goto ACPIInternalDeviceClockIrpStartDeviceCompletionExit;
  119. }
  120. }
  121. ACPIInternalDeviceClockIrpStartDeviceCompletionExit:
  122. //
  123. // Complete the irp
  124. //
  125. IoCompleteRequest( irp, IO_NO_INCREMENT );
  126. }
  127. NTSTATUS
  128. ACPIInternalDeviceQueryCapabilities(
  129. IN PDEVICE_OBJECT DeviceObject,
  130. IN PIRP Irp
  131. )
  132. /*++
  133. Routine Description:
  134. This routine is the dispatch point for the IRP_MN_QUERY_CAPABILITIES requests sent
  135. to the PDO
  136. Arguments:
  137. DeviceObject - Pointer to the device object we received the request for
  138. Irp - Pointer to the request
  139. Return Value:
  140. NTSTATUS
  141. --*/
  142. {
  143. NTSTATUS status = STATUS_SUCCESS;
  144. PDEVICE_CAPABILITIES capabilities;
  145. PDEVICE_EXTENSION deviceExtension = ACPIInternalGetDeviceExtension(DeviceObject);
  146. PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation( Irp );
  147. PAGED_CODE();
  148. //
  149. // Grab a pointer to the capabilities
  150. //
  151. capabilities = irpStack->Parameters.DeviceCapabilities.Capabilities;
  152. #ifndef HANDLE_BOGUS_CAPS
  153. if (capabilities->Version < 1) {
  154. //
  155. // do not touch irp!
  156. //
  157. status = Irp->IoStatus.Status;
  158. goto ACPIInternalDeviceQueryCapabilitiesExit;
  159. }
  160. #endif
  161. //
  162. // Set the current flags for the capabilities
  163. //
  164. capabilities->UniqueID = (deviceExtension->InstanceID == NULL ?
  165. FALSE : TRUE);
  166. capabilities->RawDeviceOK = (deviceExtension->Flags & DEV_CAP_RAW) ?
  167. TRUE : FALSE;
  168. capabilities->SilentInstall = TRUE;
  169. //
  170. // Do the power capabilities
  171. //
  172. status = ACPISystemPowerQueryDeviceCapabilities(
  173. deviceExtension,
  174. capabilities
  175. );
  176. if (!NT_SUCCESS(status)) {
  177. ACPIDevPrint( (
  178. ACPI_PRINT_CRITICAL,
  179. deviceExtension,
  180. " - Could query device capabilities - %08lx",
  181. status
  182. ) );
  183. goto ACPIInternalDeviceQueryCapabilitiesExit;
  184. }
  185. ACPIInternalDeviceQueryCapabilitiesExit:
  186. //
  187. // Done...
  188. //
  189. Irp->IoStatus.Status = status;
  190. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  191. return status;
  192. }
  193. NTSTATUS
  194. ACPIInternalDeviceQueryDeviceRelations(
  195. IN PDEVICE_OBJECT DeviceObject,
  196. IN PIRP Irp
  197. )
  198. /*++
  199. Routine Description:
  200. This routine is the dispatch point for the IRP_MN_QUERY_DEVICE_RELATION
  201. PNP minor function
  202. Arguments:
  203. DeviceObject - The object that we care about
  204. Irp - The request in question
  205. Return Value:
  206. NTSTATUS
  207. --*/
  208. {
  209. NTSTATUS status ;
  210. PDEVICE_EXTENSION deviceExtension = ACPIInternalGetDeviceExtension(DeviceObject);
  211. PDEVICE_RELATIONS deviceRelations = NULL;
  212. PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation( Irp );
  213. UCHAR minorFunction = irpStack->MinorFunction;
  214. PAGED_CODE();
  215. switch(irpStack->Parameters.QueryDeviceRelations.Type) {
  216. case TargetDeviceRelation:
  217. status = ACPIBusIrpQueryTargetRelation(
  218. DeviceObject,
  219. Irp,
  220. &deviceRelations
  221. );
  222. break ;
  223. default:
  224. status = STATUS_NOT_SUPPORTED;
  225. ACPIDevPrint( (
  226. ACPI_PRINT_IRP,
  227. deviceExtension,
  228. "(0x%08lx): %s - Unhandled Type %d\n",
  229. Irp,
  230. ACPIDebugGetIrpText(IRP_MJ_PNP, minorFunction),
  231. irpStack->Parameters.QueryDeviceRelations.Type
  232. ) );
  233. break ;
  234. }
  235. //
  236. // If we succeeds, then we can always write to the irp
  237. //
  238. if (NT_SUCCESS(status)) {
  239. Irp->IoStatus.Status = status;
  240. Irp->IoStatus.Information = (ULONG_PTR) deviceRelations;
  241. } else if (status != STATUS_NOT_SUPPORTED) {
  242. //
  243. // If we haven't succeed the irp, then we can also fail it
  244. //
  245. Irp->IoStatus.Status = status;
  246. Irp->IoStatus.Information = (ULONG_PTR) NULL;
  247. } else {
  248. //
  249. // Grab our status from what is already present
  250. //
  251. status = Irp->IoStatus.Status;
  252. }
  253. //
  254. // Done with the irp
  255. //
  256. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  257. //
  258. // Done
  259. //
  260. ACPIDevPrint( (
  261. ACPI_PRINT_IRP,
  262. deviceExtension,
  263. "(0x%08lx): %s = 0x%08lx\n",
  264. Irp,
  265. ACPIDebugGetIrpText(IRP_MJ_PNP, minorFunction),
  266. status
  267. ) );
  268. return status;
  269. }
  270. NTSTATUS
  271. ACPIInternalWaitWakeLoop(
  272. IN PDEVICE_OBJECT DeviceObject,
  273. IN UCHAR MinorFunction,
  274. IN POWER_STATE PowerState,
  275. IN PVOID Context,
  276. IN PIO_STATUS_BLOCK IoStatus
  277. )
  278. /*++
  279. Routine Description:
  280. This routine is called after the WAIT_WAKE on the RTC has been completed
  281. Arguments:
  282. DeviceObject - The RTC PDO
  283. MinorFunction - IRP_MN_WAIT_WAKE
  284. PowerState - The Sleep state that it could wake from
  285. Context - NOT USED
  286. IoStatus - The status of the request
  287. Return Value:
  288. NTSTATUS
  289. --*/
  290. {
  291. if (!NT_SUCCESS(IoStatus->Status)) {
  292. return IoStatus->Status;
  293. }
  294. //
  295. // In this case, we just cause the same thing to happen again
  296. //
  297. PoRequestPowerIrp(
  298. DeviceObject,
  299. MinorFunction,
  300. PowerState,
  301. ACPIInternalWaitWakeLoop,
  302. Context,
  303. NULL
  304. );
  305. //
  306. // Done
  307. //
  308. return STATUS_SUCCESS;
  309. }