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.

451 lines
10 KiB

  1. //
  2. // This file contains functions that handle Power Management IRPs
  3. //
  4. /*++
  5. Copyright (C) Microsoft Corporation, 1998 - 1998
  6. Module Name:
  7. power.c
  8. Abstract:
  9. This file contains routines that handle ParClass Power Management IRPs.
  10. Revision History :
  11. --*/
  12. #include "pch.h"
  13. NTSTATUS
  14. ParPower (
  15. IN PDEVICE_OBJECT pDeviceObject,
  16. IN PIRP pIrp
  17. )
  18. /*++
  19. Routine Description:
  20. This is the ParClass dispatch routine for all Power Management IRPs.
  21. Arguments:
  22. pDeviceObject - represents a parallel device
  23. pIrp - Power IRP
  24. Return Value:
  25. STATUS_SUCCESS - if successful.
  26. !STATUS_SUCCESS - otherwise.
  27. --*/
  28. {
  29. PDEVICE_EXTENSION Extension = pDeviceObject->DeviceExtension;
  30. //
  31. // determine the type of DeviceObject and forward the call as appropriate
  32. //
  33. if( Extension->IsPdo ) {
  34. return ParPdoPower (Extension, pIrp); // this is a PDO (PODOs never get Power IRPs)
  35. } else {
  36. return ParFdoPower (Extension, pIrp); // this is the ParClass FDO
  37. }
  38. }
  39. NTSTATUS
  40. ParPdoPower (
  41. IN PDEVICE_EXTENSION Extension,
  42. IN PIRP pIrp
  43. )
  44. /*++
  45. Routine Description:
  46. This routine handles all Power IRPs for PDOs.
  47. Arguments:
  48. pDeviceObject - represents a parallel device
  49. pIrp - PNP Irp
  50. Return Value:
  51. STATUS_SUCCESS - if successful.
  52. STATUS_UNSUCCESSFUL - otherwise.
  53. --*/
  54. {
  55. POWER_STATE_TYPE powerType;
  56. POWER_STATE powerState;
  57. PIO_STACK_LOCATION pIrpStack;
  58. NTSTATUS status = STATUS_SUCCESS;
  59. ParDump2(PARPOWER, ("ParPdoPower(...)\n") );
  60. pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
  61. powerType = pIrpStack->Parameters.Power.Type;
  62. powerState = pIrpStack->Parameters.Power.State;
  63. switch (pIrpStack->MinorFunction) {
  64. case IRP_MN_QUERY_POWER:
  65. status = STATUS_SUCCESS;
  66. break;
  67. case IRP_MN_SET_POWER:
  68. ParDump2(PARPOWER, ("PARCLASS-PnP Setting %s state to %d\n",
  69. ((powerType == SystemPowerState) ? "System" : "Device"),
  70. powerState.SystemState) );
  71. switch (powerType) {
  72. case DevicePowerState:
  73. if (Extension->DeviceState < powerState.DeviceState) {
  74. //
  75. // Powering down
  76. //
  77. if (PowerDeviceD0 == Extension->DeviceState) {
  78. //
  79. // Do the power on stuff here.
  80. //
  81. }
  82. } else if (powerState.DeviceState < Extension->DeviceState) {
  83. //
  84. // Powering Up
  85. //
  86. }
  87. PoSetPowerState (Extension->DeviceObject, powerType, powerState);
  88. Extension->DeviceState = powerState.DeviceState;
  89. break;
  90. case SystemPowerState:
  91. status = STATUS_SUCCESS;
  92. break;
  93. }
  94. break;
  95. default:
  96. status = STATUS_NOT_SUPPORTED;
  97. }
  98. pIrp->IoStatus.Status = status;
  99. PoStartNextPowerIrp (pIrp);
  100. IoCompleteRequest (pIrp, IO_NO_INCREMENT);
  101. return (status);
  102. }
  103. NTSTATUS
  104. ParPowerComplete (
  105. IN PDEVICE_OBJECT pDeviceObject,
  106. IN PIRP pIrp,
  107. IN PDEVICE_EXTENSION Extension
  108. )
  109. /*++
  110. Routine Description:
  111. This routine handles all IRP_MJ_POWER IRPs.
  112. Arguments:
  113. pDeviceObject - represents the port device
  114. pIrp - PNP irp
  115. Extension - Device Extension
  116. Return Value:
  117. Status
  118. --*/
  119. {
  120. POWER_STATE_TYPE powerType;
  121. POWER_STATE powerState;
  122. PIO_STACK_LOCATION pIrpStack;
  123. UNREFERENCED_PARAMETER( pDeviceObject );
  124. ParDump2(PARPOWER, ("Enter ParPowerComplete(...)\n") );
  125. pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
  126. powerType = pIrpStack->Parameters.Power.Type;
  127. powerState = pIrpStack->Parameters.Power.State;
  128. switch (pIrpStack->MinorFunction) {
  129. case IRP_MN_QUERY_POWER:
  130. ASSERTMSG ("Invalid power completion minor code: Query Power\n", FALSE);
  131. break;
  132. case IRP_MN_SET_POWER:
  133. ParDump2(PARPOWER, ("PARCLASS-PnP Setting %s state to %d\n",
  134. ((powerType == SystemPowerState) ? "System" : "Device"),
  135. powerState.SystemState) );
  136. switch (powerType) {
  137. case DevicePowerState:
  138. if (Extension->DeviceState < powerState.DeviceState) {
  139. //
  140. // Powering down
  141. //
  142. ASSERTMSG ("Invalid power completion Device Down\n", FALSE);
  143. } else if (powerState.DeviceState < Extension->DeviceState) {
  144. //
  145. // Powering Up
  146. //
  147. if( Extension->IsPdo ) {
  148. // only call for PDOs
  149. PoSetPowerState (Extension->DeviceObject, powerType, powerState);
  150. }
  151. if (PowerDeviceD0 == Extension->DeviceState) {
  152. //
  153. // Do the power on stuff here.
  154. //
  155. }
  156. Extension->DeviceState = powerState.DeviceState;
  157. }
  158. break;
  159. case SystemPowerState:
  160. if (Extension->SystemState < powerState.SystemState) {
  161. //
  162. // Powering down
  163. //
  164. ASSERTMSG ("Invalid power completion System Down\n", FALSE);
  165. } else if (powerState.SystemState < Extension->SystemState) {
  166. //
  167. // Powering Up
  168. //
  169. if (PowerSystemWorking == powerState.SystemState) {
  170. //
  171. // Do the system start up stuff here.
  172. //
  173. powerState.DeviceState = PowerDeviceD0;
  174. PoRequestPowerIrp (Extension->DeviceObject,
  175. IRP_MN_SET_POWER,
  176. powerState,
  177. NULL, // no completion function
  178. NULL, // and no context
  179. NULL);
  180. }
  181. Extension->SystemState = powerState.SystemState;
  182. }
  183. break;
  184. }
  185. break;
  186. default:
  187. ASSERTMSG ("Power Complete: Bad Power State", FALSE);
  188. }
  189. PoStartNextPowerIrp (pIrp);
  190. return STATUS_SUCCESS;
  191. }
  192. NTSTATUS
  193. ParFdoPower (
  194. IN PDEVICE_EXTENSION Extension,
  195. IN PIRP pIrp
  196. )
  197. /*++
  198. Routine Description:
  199. This routine handles all Power IRPs Fdos.
  200. Arguments:
  201. pDeviceObject - represents a parallel device
  202. pIrp - PNP Irp
  203. Return Value:
  204. STATUS_SUCCESS - if successful.
  205. STATUS_UNSUCCESSFUL - otherwise.
  206. --*/
  207. {
  208. POWER_STATE_TYPE powerType;
  209. POWER_STATE powerState;
  210. PIO_STACK_LOCATION pIrpStack;
  211. NTSTATUS status = STATUS_SUCCESS;
  212. BOOLEAN hookit = FALSE;
  213. ParDump2(PARPOWER, ("ParFdoPower(...)\n") );
  214. {
  215. NTSTATUS status = ParAcquireRemoveLock(&Extension->RemoveLock, pIrp);
  216. if (!NT_SUCCESS (status)) {
  217. pIrp->IoStatus.Status = status;
  218. pIrp->IoStatus.Information = 0;
  219. PoStartNextPowerIrp( pIrp );
  220. IoCompleteRequest(pIrp, IO_NO_INCREMENT);
  221. return status;
  222. }
  223. }
  224. pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
  225. powerType = pIrpStack->Parameters.Power.Type;
  226. powerState = pIrpStack->Parameters.Power.State;
  227. switch (pIrpStack->MinorFunction) {
  228. case IRP_MN_QUERY_POWER:
  229. status = STATUS_SUCCESS;
  230. break;
  231. case IRP_MN_SET_POWER:
  232. ParDump2(PARPOWER, ("PARCLASS-PnP Setting %s state to %d\n",
  233. ((powerType == SystemPowerState) ? "System" : "Device"),
  234. powerState.SystemState) );
  235. switch (powerType) {
  236. case DevicePowerState:
  237. if (Extension->DeviceState < powerState.DeviceState) {
  238. //
  239. // Powering down
  240. //
  241. // Don't call - this is an FDO
  242. // PoSetPowerState (Extension->DeviceObject, powerType, powerState);
  243. if (PowerDeviceD0 == Extension->DeviceState) {
  244. //
  245. // Do the power on stuff here.
  246. //
  247. //
  248. // WORKWORK
  249. //
  250. // We must check to see that our children are in a
  251. // consistent power state.
  252. //
  253. }
  254. Extension->DeviceState = powerState.DeviceState;
  255. } else if (powerState.DeviceState < Extension->DeviceState) {
  256. //
  257. // Powering Up
  258. //
  259. hookit = TRUE;
  260. }
  261. break;
  262. case SystemPowerState:
  263. if (Extension->SystemState < powerState.SystemState) {
  264. //
  265. // Powering down
  266. //
  267. if (PowerSystemWorking == Extension->SystemState) {
  268. //
  269. // Do the system shut down stuff here.
  270. //
  271. }
  272. powerState.DeviceState = PowerDeviceD3;
  273. PoRequestPowerIrp (Extension->DeviceObject,
  274. IRP_MN_SET_POWER,
  275. powerState,
  276. NULL, // no completion function
  277. NULL, // and no context
  278. NULL);
  279. Extension->SystemState = powerState.SystemState;
  280. } else if (powerState.SystemState < Extension->SystemState) {
  281. //
  282. // Powering Up
  283. //
  284. hookit = TRUE;
  285. }
  286. break;
  287. }
  288. break;
  289. default:
  290. status = STATUS_NOT_SUPPORTED;
  291. }
  292. IoCopyCurrentIrpStackLocationToNext (pIrp);
  293. if (!NT_SUCCESS (status)) {
  294. pIrp->IoStatus.Status = status;
  295. PoStartNextPowerIrp (pIrp);
  296. IoCompleteRequest (pIrp, IO_NO_INCREMENT);
  297. } else if (hookit) {
  298. IoSetCompletionRoutine(pIrp, ParPowerComplete, Extension, TRUE, TRUE, TRUE);
  299. status = PoCallDriver(Extension->ParentDeviceObject, pIrp);
  300. } else {
  301. PoStartNextPowerIrp (pIrp);
  302. status = PoCallDriver (Extension->ParentDeviceObject, pIrp);
  303. }
  304. ParReleaseRemoveLock(&Extension->RemoveLock, pIrp);
  305. return status;
  306. }