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.

258 lines
6.9 KiB

  1. /***************************************************************************
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. Dot4Usb.sys - Lower Filter Driver for Dot4.sys for USB connected
  5. IEEE 1284.4 devices.
  6. File Name:
  7. Power.c
  8. Abstract:
  9. Power management functions
  10. Environment:
  11. Kernel mode only
  12. Notes:
  13. THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  14. KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  15. IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  16. PURPOSE.
  17. Copyright (c) 2000 Microsoft Corporation. All Rights Reserved.
  18. Revision History:
  19. 01/18/2000 : created
  20. ToDo in this file:
  21. - code cleanup and documentation
  22. - code review
  23. Author(s):
  24. Joby Lafky (JobyL)
  25. Doug Fritz (DFritz)
  26. ****************************************************************************/
  27. #include "pch.h"
  28. VOID
  29. SetPowerIrpCompletion(IN PDEVICE_OBJECT DeviceObject,
  30. IN UCHAR MinorFunction,
  31. IN POWER_STATE PowerState,
  32. IN PVOID Context,
  33. IN PIO_STATUS_BLOCK IoStatus);
  34. NTSTATUS
  35. PowerD0Completion(IN PDEVICE_OBJECT DeviceObject,
  36. IN PIRP Irp,
  37. IN PVOID Context);
  38. NTSTATUS
  39. DispatchPower(
  40. IN PDEVICE_OBJECT DevObj,
  41. IN PIRP Irp
  42. )
  43. {
  44. PDEVICE_EXTENSION devExt = DevObj->DeviceExtension;
  45. PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation( Irp );
  46. NTSTATUS status;
  47. POWER_STATE powerState;
  48. POWER_STATE newState;
  49. POWER_STATE oldState;
  50. BOOLEAN passRequest = TRUE;
  51. TR_VERBOSE(("DispatchPower, MinorFunction = %x", (ULONG)irpSp->MinorFunction));
  52. //
  53. // Acquire RemoveLock to prevent us from being Removed
  54. //
  55. status = IoAcquireRemoveLock( &devExt->RemoveLock, Irp );
  56. if( !NT_SUCCESS(status) )
  57. {
  58. // couldn't aquire RemoveLock - we're in the process of being removed - abort
  59. PoStartNextPowerIrp( Irp );
  60. Irp->IoStatus.Status = status;
  61. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  62. return status;
  63. }
  64. powerState = irpSp->Parameters.Power.State;
  65. switch (irpSp->MinorFunction)
  66. {
  67. case IRP_MN_SET_POWER:
  68. switch(irpSp->Parameters.Power.Type)
  69. {
  70. case SystemPowerState:
  71. // save the current system state
  72. devExt->SystemPowerState = powerState.SystemState;
  73. // map the new system state to a new device state
  74. if(powerState.SystemState != PowerSystemWorking)
  75. {
  76. newState.DeviceState = PowerDeviceD3;
  77. }
  78. else
  79. {
  80. newState.DeviceState = PowerDeviceD0;
  81. }
  82. if(devExt->DevicePowerState != newState.DeviceState)
  83. {
  84. // save the current power Irp for sending down later
  85. devExt->CurrentPowerIrp = Irp;
  86. // send a power Irp to set new device state
  87. status = PoRequestPowerIrp(devExt->Pdo,
  88. IRP_MN_SET_POWER,
  89. newState,
  90. SetPowerIrpCompletion,
  91. (PVOID) devExt,
  92. NULL);
  93. // this will get passed down in the completion routine
  94. passRequest = FALSE;
  95. }
  96. break;
  97. case DevicePowerState:
  98. // Update the current device state.
  99. oldState.DeviceState = devExt->DevicePowerState;
  100. devExt->DevicePowerState = powerState.DeviceState;
  101. // powering up
  102. if(oldState.DeviceState > PowerDeviceD0 &&
  103. powerState.DeviceState == PowerDeviceD0)
  104. {
  105. // we need to know when this completes and our device is at the proper state
  106. IoCopyCurrentIrpStackLocationToNext(Irp);
  107. IoSetCompletionRoutine(Irp,
  108. PowerD0Completion,
  109. devExt,
  110. TRUE,
  111. TRUE,
  112. TRUE);
  113. status = PoCallDriver(devExt->LowerDevObj, Irp);
  114. // we already passed this one down
  115. passRequest = FALSE;
  116. }
  117. else
  118. {
  119. // powering down, jsut set a flag and pass the request down
  120. if(devExt->PnpState == STATE_STARTED)
  121. {
  122. devExt->PnpState = STATE_SUSPENDED;
  123. }
  124. passRequest = TRUE;
  125. }
  126. break;
  127. }
  128. }
  129. if(passRequest)
  130. {
  131. //
  132. // Send the IRP down the driver stack,
  133. //
  134. IoCopyCurrentIrpStackLocationToNext( Irp );
  135. PoStartNextPowerIrp(Irp);
  136. // release lock
  137. IoReleaseRemoveLock( &devExt->RemoveLock, Irp );
  138. status = PoCallDriver( devExt->LowerDevObj, Irp );
  139. }
  140. return status;
  141. }
  142. VOID
  143. SetPowerIrpCompletion(IN PDEVICE_OBJECT DeviceObject,
  144. IN UCHAR MinorFunction,
  145. IN POWER_STATE PowerState,
  146. IN PVOID Context,
  147. IN PIO_STATUS_BLOCK IoStatus)
  148. {
  149. PDEVICE_EXTENSION devExt;
  150. PIRP irp;
  151. NTSTATUS ntStatus;
  152. UNREFERENCED_PARAMETER( DeviceObject );
  153. UNREFERENCED_PARAMETER( MinorFunction );
  154. UNREFERENCED_PARAMETER( PowerState );
  155. UNREFERENCED_PARAMETER( IoStatus );
  156. devExt = (PDEVICE_EXTENSION) Context;
  157. // get the current power irp
  158. irp = devExt->CurrentPowerIrp;
  159. devExt->CurrentPowerIrp = NULL;
  160. // the requested DevicePowerState Irp has completed, so send the system power Irp down
  161. PoStartNextPowerIrp(irp);
  162. IoCopyCurrentIrpStackLocationToNext(irp);
  163. // mark the Irp pending
  164. IoMarkIrpPending(irp);
  165. // release the lock
  166. IoReleaseRemoveLock( &devExt->RemoveLock, irp );
  167. ntStatus = PoCallDriver(devExt->LowerDevObj, irp);
  168. }
  169. NTSTATUS
  170. PowerD0Completion(IN PDEVICE_OBJECT DeviceObject,
  171. IN PIRP Irp,
  172. IN PVOID Context)
  173. {
  174. PDEVICE_EXTENSION devExt;
  175. NTSTATUS ntStatus;
  176. UNREFERENCED_PARAMETER( DeviceObject );
  177. devExt = (PDEVICE_EXTENSION) Context;
  178. // the device is powered up, set out state
  179. if(devExt->PnpState == STATE_SUSPENDED)
  180. {
  181. devExt->PnpState = STATE_STARTED;
  182. }
  183. ntStatus = Irp->IoStatus.Status;
  184. // release the lock
  185. IoReleaseRemoveLock( &devExt->RemoveLock, Irp );
  186. PoStartNextPowerIrp(Irp);
  187. return ntStatus;
  188. }