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.

561 lines
13 KiB

  1. /***************************************************************************
  2. Copyright (c) 2002 Microsoft Corporation
  3. Module Name:
  4. power.C
  5. Abstract:
  6. Power Routines for Smartcard Driver Utility Library
  7. Environment:
  8. Kernel Mode Only
  9. Notes:
  10. THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  11. KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  12. IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  13. PURPOSE.
  14. Copyright (c) 2001 Microsoft Corporation. All Rights Reserved.
  15. Revision History:
  16. 05/14/2002 : created
  17. Authors:
  18. Randy Aull
  19. ****************************************************************************/
  20. #include "pch.h"
  21. NTSTATUS
  22. ScUtil_Power(
  23. PDEVICE_OBJECT DeviceObject,
  24. PIRP Irp
  25. )
  26. {
  27. NTSTATUS status = STATUS_UNSUCCESSFUL;
  28. PSCUTIL_EXTENSION pExt = *((PSCUTIL_EXTENSION*) DeviceObject->DeviceExtension);
  29. PIO_STACK_LOCATION irpStack;
  30. ASSERT(pExt);
  31. PAGED_CODE();
  32. __try
  33. {
  34. SmartcardDebug(DEBUG_TRACE,
  35. ("Enter: ScUtil_Power\n"));
  36. irpStack = IoGetCurrentIrpStackLocation(Irp);
  37. status = IoAcquireRemoveLock(pExt->RemoveLock,
  38. Irp);
  39. if (!NT_SUCCESS(status)) {
  40. PoStartNextPowerIrp(Irp);
  41. Irp->IoStatus.Status = status;
  42. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  43. __leave;
  44. }
  45. if ((irpStack->MinorFunction != IRP_MN_QUERY_POWER)
  46. && (irpStack->MinorFunction != IRP_MN_SET_POWER) ) {
  47. // We don't handle these irps
  48. PoStartNextPowerIrp(Irp);
  49. IoSkipCurrentIrpStackLocation(Irp);
  50. status = PoCallDriver(pExt->LowerDeviceObject,
  51. Irp);
  52. IoReleaseRemoveLock(pExt->RemoveLock,
  53. Irp);
  54. __leave;
  55. }
  56. switch (irpStack->Parameters.Power.Type) {
  57. case DevicePowerState:
  58. status = ScUtilDevicePower(DeviceObject,
  59. Irp);
  60. break;
  61. case SystemPowerState:
  62. status = ScUtilSystemPower(DeviceObject,
  63. Irp);
  64. break;
  65. default:
  66. break;
  67. }
  68. }
  69. __finally
  70. {
  71. SmartcardDebug(DEBUG_TRACE,
  72. ("Exit: ScUtil_Power (0x%x)\n", status));
  73. }
  74. return status;
  75. }
  76. NTSTATUS
  77. ScUtilDevicePower(
  78. PDEVICE_OBJECT DeviceObject,
  79. PIRP Irp
  80. )
  81. /*++
  82. Routine Description:
  83. Handles Device Power Irps
  84. Arguments:
  85. Return Value:
  86. --*/
  87. {
  88. NTSTATUS status = STATUS_SUCCESS;
  89. PSCUTIL_EXTENSION pExt = *((PSCUTIL_EXTENSION*) DeviceObject->DeviceExtension);
  90. PIO_STACK_LOCATION stack;
  91. BOOLEAN postWaitWake;
  92. POWER_STATE state;
  93. __try
  94. {
  95. SmartcardDebug( DEBUG_TRACE, ("ScUtilDevicePower Enter\n"));
  96. stack = IoGetCurrentIrpStackLocation(Irp);
  97. state.DeviceState = stack->Parameters.Power.State.DeviceState;
  98. switch (stack->MinorFunction) {
  99. case IRP_MN_QUERY_POWER:
  100. //
  101. // Since we can always wait for our irps to complete, so we just always succeed
  102. //
  103. StopIoctls(pExt);
  104. IoReleaseRemoveLock(pExt->RemoveLock,
  105. Irp);
  106. PoStartNextPowerIrp(Irp);
  107. IoSkipCurrentIrpStackLocation(Irp);
  108. status = PoCallDriver(pExt->LowerDeviceObject,
  109. Irp);
  110. break;
  111. case IRP_MN_SET_POWER:
  112. if (state.DeviceState < pExt->PowerState) {
  113. //
  114. // We are coming up!! We must let lower drivers power up before we do
  115. //
  116. SmartcardDebug( DEBUG_TRACE, ("ScUtilDevicePower Coming Up!\n"));
  117. IoMarkIrpPending(Irp);
  118. IoCopyCurrentIrpStackLocationToNext(Irp);
  119. IoSetCompletionRoutine(Irp,
  120. ScUtilDevicePowerUpCompletion,
  121. pExt,
  122. TRUE,
  123. TRUE,
  124. TRUE);
  125. status = PoCallDriver(pExt->LowerDeviceObject,
  126. Irp);
  127. status = STATUS_PENDING;
  128. } else {
  129. //
  130. // We are moving to a lower power state, so we handle it before
  131. // passing it down
  132. //
  133. SmartcardDebug( DEBUG_TRACE, ("ScUtilDevicePower Going Down!\n"));
  134. StopIoctls(pExt);
  135. DecIoCount(pExt);
  136. KeWaitForSingleObject(&pExt->OkToStop,
  137. Executive,
  138. KernelMode,
  139. FALSE,
  140. NULL);
  141. status = pExt->SetPowerState(DeviceObject,
  142. state.DeviceState,
  143. &postWaitWake);
  144. PoSetPowerState(DeviceObject,
  145. DevicePowerState,
  146. state);
  147. pExt->PowerState = state.DeviceState;
  148. PoStartNextPowerIrp(Irp);
  149. IoSkipCurrentIrpStackLocation(Irp);
  150. status = PoCallDriver(pExt->LowerDeviceObject,
  151. Irp);
  152. IoReleaseRemoveLock(pExt->RemoveLock,
  153. Irp);
  154. }
  155. break;
  156. default:
  157. // We shouldn't be here
  158. ASSERT(FALSE);
  159. break;
  160. }
  161. }
  162. __finally
  163. {
  164. SmartcardDebug( DEBUG_TRACE, ("ScUtilDevicePower Exit : 0x%x\n", status ));
  165. }
  166. return status;
  167. }
  168. NTSTATUS
  169. ScUtilSystemPower(
  170. PDEVICE_OBJECT DeviceObject,
  171. PIRP Irp
  172. )
  173. /*++
  174. Routine Description:
  175. Handles system power irps
  176. Arguments:
  177. Return Value:
  178. --*/
  179. {
  180. NTSTATUS status = STATUS_SUCCESS;
  181. PSCUTIL_EXTENSION pExt = *((PSCUTIL_EXTENSION*) DeviceObject->DeviceExtension);
  182. __try
  183. {
  184. SmartcardDebug( DEBUG_TRACE, ("ScUtilSystemPower Enter\n" ));
  185. IoMarkIrpPending(Irp);
  186. IoCopyCurrentIrpStackLocationToNext(Irp);
  187. IoSetCompletionRoutine(Irp,
  188. ScUtilSystemPowerCompletion,
  189. pExt,
  190. TRUE,
  191. TRUE,
  192. TRUE);
  193. status = PoCallDriver(pExt->LowerDeviceObject,
  194. Irp);
  195. status = STATUS_PENDING;
  196. }
  197. __finally
  198. {
  199. SmartcardDebug( DEBUG_TRACE, ("ScUtilSystemPower Exit : 0x%x\n", status ));
  200. }
  201. return status;
  202. }
  203. NTSTATUS
  204. ScUtilSystemPowerCompletion(
  205. PDEVICE_OBJECT DeviceObject,
  206. PIRP Irp,
  207. PVOID Context
  208. )
  209. /*++
  210. Routine Description:
  211. Completion routine called after system power irp has been passed down the stack.
  212. handles mapping system state to device state and requests the device power irp.
  213. Arguments:
  214. Return Value:
  215. --*/
  216. {
  217. NTSTATUS status = STATUS_SUCCESS;
  218. PSCUTIL_EXTENSION pExt = (PSCUTIL_EXTENSION) Context;
  219. PIO_STACK_LOCATION irpStack;
  220. POWER_STATE state;
  221. POWER_STATE systemState;
  222. __try
  223. {
  224. SmartcardDebug( DEBUG_TRACE, ("ScUtilSystemPowerCompletion Enter\n" ));
  225. if (!NT_SUCCESS(Irp->IoStatus.Status)) {
  226. SmartcardDebug( DEBUG_TRACE, ("ScUtilSystemPowerCompletion SIRP failed by lower driver\n" ));
  227. PoStartNextPowerIrp(Irp);
  228. IoCompleteRequest(Irp,
  229. IO_NO_INCREMENT);
  230. status = Irp->IoStatus.Status;
  231. IoReleaseRemoveLock(pExt->RemoveLock,
  232. Irp);
  233. __leave;
  234. }
  235. irpStack = IoGetCurrentIrpStackLocation(Irp);
  236. systemState = irpStack->Parameters.Power.State;
  237. state.DeviceState = pExt->DeviceCapabilities.DeviceState[systemState.SystemState];
  238. if (systemState.DeviceState != PowerSystemWorking) {
  239. // Wait for D IRP completion
  240. status = PoRequestPowerIrp(DeviceObject,
  241. irpStack->MinorFunction,
  242. state,
  243. ScUtilDeviceRequestCompletion,
  244. (PVOID) Irp,
  245. NULL);
  246. if (!NT_SUCCESS(status)) {
  247. PoStartNextPowerIrp(Irp);
  248. Irp->IoStatus.Status = status;
  249. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  250. IoReleaseRemoveLock(pExt->RemoveLock,
  251. Irp);
  252. status = STATUS_PENDING;
  253. __leave;
  254. }
  255. status = STATUS_MORE_PROCESSING_REQUIRED;
  256. } else {
  257. // Don't wait for completion of D irp to speed up resume time
  258. status = PoRequestPowerIrp(DeviceObject,
  259. irpStack->MinorFunction,
  260. state,
  261. NULL,
  262. NULL,
  263. NULL);
  264. if (!NT_SUCCESS(status)) {
  265. Irp->IoStatus.Status = status;
  266. status = STATUS_PENDING;
  267. PoStartNextPowerIrp(Irp);
  268. IoCompleteRequest(Irp, IO_NO_INCREMENT);
  269. } else {
  270. PoStartNextPowerIrp(Irp);
  271. }
  272. IoReleaseRemoveLock(pExt->RemoveLock,
  273. Irp);
  274. }
  275. }
  276. __finally
  277. {
  278. SmartcardDebug( DEBUG_TRACE, ("ScUtilSystemPowerCompletion Exit : 0x%x\n", status ));
  279. }
  280. return status;
  281. }
  282. VOID
  283. ScUtilDeviceRequestCompletion(
  284. PDEVICE_OBJECT DeviceObject,
  285. UCHAR MinorFunction,
  286. POWER_STATE PowerState,
  287. PVOID Context,
  288. PIO_STATUS_BLOCK IoStatus
  289. )
  290. /*++
  291. Routine Description:
  292. Completion routine called after device power irp completes.
  293. Completes the system power irp.
  294. Arguments:
  295. Return Value:
  296. --*/
  297. {
  298. NTSTATUS status = STATUS_SUCCESS;
  299. PSCUTIL_EXTENSION pExt = *((PSCUTIL_EXTENSION*) DeviceObject->DeviceExtension);
  300. PIRP irp;
  301. __try
  302. {
  303. SmartcardDebug( DEBUG_TRACE, ("ScUtilDeviceRequestCompletion Enter\n" ));
  304. irp = (PIRP) Context;
  305. PoStartNextPowerIrp(irp);
  306. irp->IoStatus.Status = IoStatus->Status;
  307. IoCompleteRequest(irp,
  308. IO_NO_INCREMENT);
  309. IoReleaseRemoveLock(pExt->RemoveLock,
  310. irp);
  311. }
  312. __finally
  313. {
  314. SmartcardDebug( DEBUG_TRACE, ("ScUtilDeviceRequestCompletion Exit : 0x%x\n", status ));
  315. }
  316. return;
  317. }
  318. NTSTATUS
  319. ScUtilDevicePowerUpCompletion(
  320. PDEVICE_OBJECT DeviceObject,
  321. PIRP Irp,
  322. PVOID Context
  323. )
  324. /*++
  325. Routine Description:
  326. Completion routine called after device irp for higher power state has been
  327. passed down the stack.
  328. Arguments:
  329. Return Value:
  330. --*/
  331. {
  332. NTSTATUS status = STATUS_SUCCESS;
  333. PSCUTIL_EXTENSION pExt = *((PSCUTIL_EXTENSION*) DeviceObject->DeviceExtension);
  334. PIO_STACK_LOCATION irpStack;
  335. BOOLEAN postWaitWake; // We don't really care about this
  336. __try
  337. {
  338. SmartcardDebug( DEBUG_TRACE, ("ScUtilDevicePowerUpCompletion Enter\n" ));
  339. irpStack = IoGetCurrentIrpStackLocation(Irp);
  340. status = pExt->SetPowerState(DeviceObject,
  341. irpStack->Parameters.Power.State.DeviceState,
  342. &postWaitWake);
  343. pExt->PowerState = irpStack->Parameters.Power.State.DeviceState;
  344. IncIoCount(pExt);
  345. StartIoctls(pExt);
  346. PoSetPowerState(DeviceObject,
  347. DevicePowerState,
  348. irpStack->Parameters.Power.State);
  349. PoStartNextPowerIrp(Irp);
  350. }
  351. __finally
  352. {
  353. IoReleaseRemoveLock(pExt->RemoveLock,
  354. Irp);
  355. SmartcardDebug( DEBUG_TRACE, ("ScUtilDevicePowerUpCompletion Exit : 0x%x\n", status ));
  356. }
  357. return status;
  358. }