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.

474 lines
10 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. power.c
  5. Abstract:
  6. Sample DDK driver - the power management related processing.
  7. Environment:
  8. Kernel mode
  9. Revision History:
  10. 25-July-1997 :
  11. - Created by moving SD_DispatchPower from sample.c
  12. 18-Sept-1998 :
  13. - used again for the PCI legacy project...
  14. 25-April-2002 :
  15. - re-used once more for testing IoCreateDeviceSecure
  16. --*/
  17. #include "wdmsectest.h"
  18. typedef struct _FDO_POWER_CONTEXT {
  19. POWER_STATE_TYPE newPowerType;
  20. POWER_STATE newPowerState;
  21. } FDO_POWER_CONTEXT, *PFDO_POWER_CONTEXT;
  22. NTSTATUS
  23. SD_PassDownToNextPowerDriver (
  24. IN PDEVICE_OBJECT DeviceObject,
  25. IN OUT PIRP Irp
  26. ) ;
  27. NTSTATUS
  28. SD_QueryPowerState (
  29. IN PDEVICE_OBJECT DeviceObject,
  30. IN OUT PIRP Irp
  31. ) ;
  32. NTSTATUS
  33. SD_SetPowerState (
  34. IN PDEVICE_OBJECT DeviceObject,
  35. IN OUT PIRP Irp
  36. ) ;
  37. NTSTATUS
  38. SD_PowerCompletionRoutine (
  39. IN PDEVICE_OBJECT DeviceObject,
  40. IN PIRP Irp,
  41. IN PVOID Context
  42. ) ;
  43. NTSTATUS
  44. SD_DispatchPower (
  45. IN PDEVICE_OBJECT DeviceObject,
  46. IN PIRP Irp
  47. )
  48. /*++
  49. Routine Description:
  50. The power dispatch routine.
  51. As this is a POWER irp, and therefore a special irp, special power irp
  52. handling is required.
  53. Arguments:
  54. DeviceObject - pointer to a device object.
  55. Irp - pointer to an I/O Request Packet.
  56. Return Value:
  57. NT status code
  58. --*/
  59. {
  60. PIO_STACK_LOCATION stack;
  61. PSD_FDO_DATA fdoData;
  62. NTSTATUS status;
  63. LONG requestCount;
  64. stack = IoGetCurrentIrpStackLocation(Irp);
  65. fdoData = (PSD_FDO_DATA) DeviceObject->DeviceExtension;
  66. SD_KdPrint(2, ("FDO 0x%xn (PDO 0x%x): ",
  67. fdoData->Self,
  68. fdoData->PDO)
  69. );
  70. //
  71. // This IRP was sent to the function driver.
  72. // The behavior is similar with the one of SD_Pass
  73. //
  74. //
  75. // This IRP was sent to the function driver.
  76. // We don't queue power Irps, we'll only check if the
  77. // device was removed, otherwise we'll send it to the next lower
  78. // driver.
  79. //
  80. requestCount = SD_IoIncrement (fdoData);
  81. if (fdoData->IsRemoved) {
  82. requestCount = SD_IoDecrement(fdoData);
  83. status = STATUS_DELETE_PENDING;
  84. PoStartNextPowerIrp (Irp);
  85. Irp->IoStatus.Information = 0;
  86. Irp->IoStatus.Status = status;
  87. IoCompleteRequest (Irp, IO_NO_INCREMENT);
  88. } else {
  89. //
  90. // We always need to start the next power irp with PoStartNextPowerIrp
  91. //
  92. switch (stack->MinorFunction) {
  93. case IRP_MN_WAIT_WAKE :
  94. SD_KdPrint(2,( "IRP_MN_WAIT_WAKE\n"));
  95. status = SD_PassDownToNextPowerDriver(DeviceObject, Irp);
  96. break;
  97. case IRP_MN_POWER_SEQUENCE :
  98. SD_KdPrint(2,( "IRP_MN_POWER_SEQUENCE\n"));
  99. status = SD_PassDownToNextPowerDriver(DeviceObject, Irp);
  100. break;
  101. case IRP_MN_QUERY_POWER :
  102. SD_KdPrint(2, ("IRP_MN_QUERY_POWER\n"));
  103. status = SD_QueryPowerState(DeviceObject, Irp);
  104. break;
  105. case IRP_MN_SET_POWER :
  106. SD_KdPrint(2, ("IRP_MN_SET_POWER\n"));
  107. status = SD_SetPowerState(DeviceObject, Irp);
  108. break;
  109. default:
  110. //
  111. // Pass it down
  112. //
  113. SD_KdPrint(2, ("IRP_MN_0x%x\n", stack->MinorFunction));
  114. status = SD_PassDownToNextPowerDriver(DeviceObject, Irp);
  115. break;
  116. }
  117. requestCount = SD_IoDecrement(fdoData);
  118. }
  119. return status;
  120. }
  121. NTSTATUS
  122. SD_PassDownToNextPowerDriver (
  123. IN PDEVICE_OBJECT DeviceObject,
  124. IN OUT PIRP Irp
  125. )
  126. /*++
  127. Routine Description:
  128. Passes the Irp to the next device in the attchement chain
  129. Arguments:
  130. DeviceObject - pointer to a device object.
  131. Irp - pointer to an I/O Request Packet.
  132. Return Value:
  133. NT status code
  134. --*/
  135. {
  136. NTSTATUS status;
  137. PSD_FDO_DATA fdoData;
  138. IoCopyCurrentIrpStackLocationToNext(Irp);
  139. PoStartNextPowerIrp(Irp);
  140. fdoData = (PSD_FDO_DATA)DeviceObject->DeviceExtension;
  141. status = PoCallDriver(fdoData->NextLowerDriver, Irp);
  142. if (!NT_SUCCESS(status)) {
  143. SD_KdPrint(0,( "Lower driver fails a power irp\n"));
  144. }
  145. return status;
  146. }
  147. NTSTATUS
  148. SD_QueryPowerState (
  149. IN PDEVICE_OBJECT DeviceObject,
  150. IN OUT PIRP Irp
  151. )
  152. /*++
  153. Routine Description:
  154. Completes the power Irp with STATUS_SUCCESS
  155. Arguments:
  156. DeviceObject - pointer to a device object.
  157. Irp - pointer to an I/O Request Packet.
  158. Return Value:
  159. NT status code
  160. --*/
  161. {
  162. Irp->IoStatus.Status = STATUS_SUCCESS;
  163. PoStartNextPowerIrp(Irp);
  164. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  165. //
  166. // Do not send this Irp down.
  167. // BUGBUG : Is this correct ?
  168. //
  169. return STATUS_SUCCESS;
  170. }
  171. NTSTATUS
  172. SD_SetPowerState (
  173. IN PDEVICE_OBJECT DeviceObject,
  174. IN OUT PIRP Irp
  175. )
  176. /*++
  177. Routine Description:
  178. Processes IRP_MN_SET_POWER.
  179. Arguments:
  180. DeviceObject - pointer to a device object.
  181. Irp - pointer to an I/O Request Packet.
  182. Return Value:
  183. NT status code
  184. --*/
  185. {
  186. NTSTATUS status = STATUS_SUCCESS;
  187. PSD_FDO_DATA fdoData;
  188. PIO_STACK_LOCATION stack;
  189. PFDO_POWER_CONTEXT context;
  190. BOOLEAN passItDown;
  191. fdoData = DeviceObject->DeviceExtension;
  192. stack = IoGetCurrentIrpStackLocation (Irp);
  193. context = ExAllocatePool (NonPagedPool, sizeof(FDO_POWER_CONTEXT));
  194. if (context == NULL) {
  195. status = STATUS_NO_MEMORY;
  196. } else {
  197. RtlZeroMemory (context, sizeof(FDO_POWER_CONTEXT));
  198. stack = IoGetCurrentIrpStackLocation (Irp);
  199. context->newPowerType = stack->Parameters.Power.Type;
  200. context->newPowerState = stack->Parameters.Power.State;
  201. passItDown = TRUE;
  202. if (stack->Parameters.Power.Type == SystemPowerState) {
  203. if (fdoData->SystemPowerState ==
  204. stack->Parameters.Power.State.SystemState) {
  205. //
  206. // We are already in the given state
  207. //
  208. passItDown = FALSE;
  209. }
  210. } else if (stack->Parameters.Power.Type == DevicePowerState) {
  211. if (fdoData->DevicePowerState !=
  212. stack->Parameters.Power.State.DeviceState) {
  213. if (fdoData->DevicePowerState == PowerDeviceD0) {
  214. //
  215. // getting out of D0 state, better call PoSetPowerState now
  216. //
  217. PoSetPowerState (
  218. DeviceObject,
  219. DevicePowerState,
  220. stack->Parameters.Power.State
  221. );
  222. }
  223. } else {
  224. //
  225. // We are already in the given state
  226. //
  227. passItDown = FALSE;
  228. }
  229. } else {
  230. ASSERT (FALSE);
  231. status = STATUS_NOT_IMPLEMENTED;
  232. }
  233. }
  234. if (NT_SUCCESS(status) && passItDown) {
  235. IoCopyCurrentIrpStackLocationToNext (Irp);
  236. IoSetCompletionRoutine(Irp,
  237. SD_PowerCompletionRoutine,
  238. context,
  239. TRUE,
  240. TRUE,
  241. TRUE);
  242. return PoCallDriver (fdoData->NextLowerDriver, Irp);
  243. } else {
  244. Irp->IoStatus.Information = 0;
  245. Irp->IoStatus.Status = status;
  246. PoStartNextPowerIrp (Irp);
  247. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  248. //
  249. // Free the memory now
  250. //
  251. if (context) {
  252. ExFreePool (context);
  253. }
  254. return status;
  255. }
  256. }
  257. NTSTATUS
  258. SD_PowerCompletionRoutine (
  259. IN PDEVICE_OBJECT DeviceObject,
  260. IN PIRP Irp,
  261. IN PVOID Context
  262. )
  263. /*++
  264. Routine Description:
  265. The completion routine for IRP_MN)SET_POWER.
  266. Arguments:
  267. DeviceObject - pointer to a device object.
  268. Irp - pointer to an I/O Request Packet.
  269. Context - a pointer to a structure that contains the new power type and
  270. new power state.
  271. Return Value:
  272. NT status code
  273. --*/
  274. {
  275. PFDO_POWER_CONTEXT context = Context;
  276. BOOLEAN callPoSetPowerState;
  277. PSD_FDO_DATA fdoData;
  278. fdoData = DeviceObject->DeviceExtension;
  279. if (NT_SUCCESS(Irp->IoStatus.Status)) {
  280. callPoSetPowerState = TRUE;
  281. if (context->newPowerType == SystemPowerState) {
  282. fdoData->SystemPowerState = context->newPowerState.SystemState;
  283. SD_KdPrint (1, ("New Fdo system power state 0x%x\n",
  284. fdoData->SystemPowerState));
  285. } else if (context->newPowerType == DevicePowerState) {
  286. if (fdoData->DevicePowerState == PowerDeviceD0) {
  287. //
  288. // PoSetPowerState is called before we get out of D0
  289. //
  290. callPoSetPowerState = FALSE;
  291. }
  292. fdoData->DevicePowerState = context->newPowerState.DeviceState;
  293. SD_KdPrint (1, ("New Fdo device power state 0x%x\n",
  294. fdoData->DevicePowerState));
  295. }
  296. if (callPoSetPowerState) {
  297. PoSetPowerState (
  298. DeviceObject,
  299. context->newPowerType,
  300. context->newPowerState
  301. );
  302. }
  303. }
  304. PoStartNextPowerIrp (Irp);
  305. //
  306. // We can happily free the heap here
  307. //
  308. ExFreePool(context);
  309. return Irp->IoStatus.Status;
  310. }