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.

196 lines
4.5 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. power.c
  5. Abstract: NULL filter driver -- boilerplate code
  6. Author:
  7. ervinp
  8. Environment:
  9. Kernel mode
  10. Revision History:
  11. --*/
  12. #include <WDM.H>
  13. #include "filter.h"
  14. NTSTATUS VA_Power(struct DEVICE_EXTENSION *devExt, PIRP irp)
  15. /*++
  16. Routine Description:
  17. Dispatch routine for Power IRPs (MajorFunction == IRP_MJ_Power)
  18. Note: We may or may not have set the DO_POWER_PAGABLE bit
  19. for the filter device object in AddDevice().
  20. Therefore, we don't know whether or not this function
  21. can be called at DISPATCH_LEVEL; so the power-handling
  22. code must be locked.
  23. Arguments:
  24. devExt - device extension for targetted device object
  25. irp - Io Request Packet
  26. Return Value:
  27. NT status code
  28. --*/
  29. {
  30. PIO_STACK_LOCATION irpSp;
  31. NTSTATUS status;
  32. irpSp = IoGetCurrentIrpStackLocation(irp);
  33. DBGOUT(("VA_Power, minorFunc = %d ", (ULONG)irpSp->MinorFunction));
  34. switch (irpSp->MinorFunction){
  35. case IRP_MN_SET_POWER:
  36. switch (irpSp->Parameters.Power.Type) {
  37. case SystemPowerState:
  38. /*
  39. * For system power states, just pass the IRP down.
  40. */
  41. break;
  42. case DevicePowerState:
  43. switch (irpSp->Parameters.Power.State.DeviceState) {
  44. case PowerDeviceD0:
  45. /*
  46. * Resume from APM Suspend
  47. *
  48. * Do nothing here;
  49. * Send down the read IRPs in the completion
  50. * routine for this (the power) IRP.
  51. */
  52. break;
  53. case PowerDeviceD1:
  54. case PowerDeviceD2:
  55. case PowerDeviceD3:
  56. /*
  57. * Suspend
  58. */
  59. if (devExt->state == STATE_STARTED){
  60. devExt->state = STATE_SUSPENDED;
  61. }
  62. break;
  63. }
  64. break;
  65. }
  66. break;
  67. }
  68. /*
  69. * Whether we are completing or relaying this power IRP,
  70. * we must call PoStartNextPowerIrp.
  71. */
  72. PoStartNextPowerIrp(irp);
  73. /*
  74. * Send the IRP down the driver stack,
  75. * using PoCallDriver (not IoCallDriver, as for non-power irps).
  76. */
  77. IoCopyCurrentIrpStackLocationToNext(irp);
  78. IncrementPendingActionCount(devExt);
  79. IoSetCompletionRoutine( irp,
  80. VA_PowerComplete,
  81. (PVOID)devExt, // context
  82. TRUE,
  83. TRUE,
  84. TRUE);
  85. status = PoCallDriver(devExt->physicalDevObj, irp);
  86. return status;
  87. }
  88. NTSTATUS VA_PowerComplete(
  89. IN PDEVICE_OBJECT devObj,
  90. IN PIRP irp,
  91. IN PVOID context)
  92. /*++
  93. Routine Description:
  94. Completion routine for Power IRPs (MajorFunction == IRP_MJ_Power)
  95. Arguments:
  96. devObj - targetted device object
  97. irp - Io Request Packet
  98. context - context value passed to IoSetCompletionRoutine by VA_Power
  99. Return Value:
  100. NT status code
  101. --*/
  102. {
  103. PIO_STACK_LOCATION irpSp;
  104. struct DEVICE_EXTENSION *devExt = (struct DEVICE_EXTENSION *)context;
  105. ASSERT(devExt);
  106. ASSERT(devExt->signature == DEVICE_EXTENSION_SIGNATURE);
  107. irpSp = IoGetCurrentIrpStackLocation(irp);
  108. ASSERT(irpSp->MajorFunction == IRP_MJ_POWER);
  109. if (NT_SUCCESS(irp->IoStatus.Status)){
  110. switch (irpSp->MinorFunction){
  111. case IRP_MN_SET_POWER:
  112. switch (irpSp->Parameters.Power.Type){
  113. case DevicePowerState:
  114. switch (irpSp->Parameters.Power.State.DeviceState){
  115. case PowerDeviceD0:
  116. if (devExt->state == STATE_SUSPENDED){
  117. devExt->state = STATE_STARTED;
  118. }
  119. break;
  120. }
  121. break;
  122. }
  123. break;
  124. }
  125. }
  126. /*
  127. * Decrement the pendingActionCount, which we incremented in VA_Power.
  128. */
  129. DecrementPendingActionCount(devExt);
  130. return STATUS_SUCCESS;
  131. }