[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] Asynchronous power handling.



From: Martin Harvey <Martin.Harvey@xxxxxxxxxx>

XenDisk requires minimal IRP_MN_SET_POWER/IRP_MN_QUERY_POWER interactions.
No IoWorkItems are required as operations perform no significant work.
Power handlers are is limited to tracking state changes and calling 
PoSetPowerState.

Signed-off-by: Martin Harvey <martin.harvey@xxxxxxxxxx>

Refactored
Signed-off-by: Owen Smith <owen.smith@xxxxxxxxx>

---
 src/xendisk/fdo.c | 552 +++++++++------------------------------------
 src/xendisk/pdo.c | 555 +++++++++-------------------------------------
 2 files changed, 209 insertions(+), 898 deletions(-)

diff --git a/src/xendisk/fdo.c b/src/xendisk/fdo.c
index 056e24a..2e5c0de 100644
--- a/src/xendisk/fdo.c
+++ b/src/xendisk/fdo.c
@@ -54,11 +54,6 @@ struct _XENDISK_FDO {
     PDEVICE_OBJECT                  LowerDeviceObject;
     PDEVICE_OBJECT                  PhysicalDeviceObject;
 
-    PXENDISK_THREAD                 SystemPowerThread;
-    PIRP                            SystemPowerIrp;
-    PXENDISK_THREAD                 DevicePowerThread;
-    PIRP                            DevicePowerIrp;
-
     MUTEX                           Mutex;
     ULONG                           References;
 };
@@ -1136,36 +1131,50 @@ fail1:
     return status;
 }
 
-static FORCEINLINE NTSTATUS
-__FdoSetDevicePowerUp(
-    IN  PXENDISK_FDO    Fdo,
-    IN  PIRP            Irp
+__drv_functionClass(IO_COMPLETION_ROUTINE)
+__drv_sameIRQL
+static NTSTATUS
+FdoSetDevicePowerUpComplete(
+    IN  PDEVICE_OBJECT  DeviceObject,
+    IN  PIRP            Irp,
+    IN  PVOID           Context
     )
 {
+    PXENDISK_FDO        Fdo = (PXENDISK_FDO) Context;
     PIO_STACK_LOCATION  StackLocation;
-    DEVICE_POWER_STATE  DeviceState;
-    NTSTATUS            status;
+    POWER_STATE         PowerState;
 
-    StackLocation = IoGetCurrentIrpStackLocation(Irp);
-    DeviceState = StackLocation->Parameters.Power.State.DeviceState;
+    UNREFERENCED_PARAMETER(DeviceObject);
 
-    ASSERT3U(DeviceState, <,  __FdoGetDevicePowerState(Fdo));
+    StackLocation = IoGetCurrentIrpStackLocation(Irp);
+    PowerState = StackLocation->Parameters.Power.State;
 
-    status = FdoForwardIrpSynchronously(Fdo, Irp);
-    if (!NT_SUCCESS(status))
-        goto done;
+    if (Irp->PendingReturned)
+        IoMarkIrpPending(Irp);
 
-    Verbose("%p: %s -> %s\n",
-         Fdo->Dx->DeviceObject,
-         PowerDeviceStateName(__FdoGetDevicePowerState(Fdo)),
-         PowerDeviceStateName(DeviceState));
+    __FdoSetDevicePowerState(Fdo, PowerState.DeviceState);
+    PoSetPowerState(Fdo->Dx->DeviceObject,
+                    DevicePowerState,
+                    PowerState);
 
-    __FdoSetDevicePowerState(Fdo, DeviceState);
+    return STATUS_CONTINUE_COMPLETION;
+}
 
-done:
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+static FORCEINLINE NTSTATUS
+__FdoSetDevicePowerUp(
+    IN  PXENDISK_FDO    Fdo,
+    IN  PIRP            Irp
+    )
+{
+    IoCopyCurrentIrpStackLocationToNext(Irp);
+    IoSetCompletionRoutine(Irp,
+                           FdoSetDevicePowerUpComplete,
+                           Fdo,
+                           TRUE,
+                           TRUE,
+                           TRUE);
 
-    return status;
+    return IoCallDriver(Fdo->LowerDeviceObject, Irp);
 }
 
 static FORCEINLINE NTSTATUS
@@ -1175,27 +1184,21 @@ __FdoSetDevicePowerDown(
     )
 {
     PIO_STACK_LOCATION  StackLocation;
-    DEVICE_POWER_STATE  DeviceState;
-    NTSTATUS            status;
+    POWER_STATE         PowerState;
 
     StackLocation = IoGetCurrentIrpStackLocation(Irp);
-    DeviceState = StackLocation->Parameters.Power.State.DeviceState;
-
-    ASSERT3U(DeviceState, >,  __FdoGetDevicePowerState(Fdo));
-
-    Verbose("%p: %s -> %s\n",
-         Fdo->Dx->DeviceObject,
-         PowerDeviceStateName(__FdoGetDevicePowerState(Fdo)),
-         PowerDeviceStateName(DeviceState));
+    PowerState = StackLocation->Parameters.Power.State;
 
-    __FdoSetDevicePowerState(Fdo, DeviceState);
-
-    status = FdoForwardIrpSynchronously(Fdo, Irp);
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    __FdoSetDevicePowerState(Fdo, PowerState.DeviceState);
+    PoSetPowerState(Fdo->Dx->DeviceObject,
+                    DevicePowerState,
+                    PowerState);
 
-    return status;
+    IoSkipCurrentIrpStackLocation(Irp);
+    return IoCallDriver(Fdo->LowerDeviceObject, Irp);
 }
 
+/* IRQL argnostic code, just mark power states.*/
 static FORCEINLINE NTSTATUS
 __FdoSetDevicePower(
     IN  PXENDISK_FDO    Fdo,
@@ -1216,13 +1219,12 @@ __FdoSetDevicePower(
           PowerActionName(PowerAction));
 
     if (DeviceState == __FdoGetDevicePowerState(Fdo)) {
-        status = FdoForwardIrpSynchronously(Fdo, Irp);
-        IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
+        IoSkipCurrentIrpStackLocation(Irp);
+        status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
         goto done;
     }
 
-    status = (DeviceState < __FdoGetDevicePowerState(Fdo)) ?
+    status = DeviceState < __FdoGetDevicePowerState(Fdo) ?
              __FdoSetDevicePowerUp(Fdo, Irp) :
              __FdoSetDevicePowerDown(Fdo, Irp);
 
@@ -1231,39 +1233,51 @@ done:
           PowerDeviceStateName(DeviceState),
           PowerActionName(PowerAction),
           status);
+
     return status;
 }
 
-static FORCEINLINE NTSTATUS
-__FdoSetSystemPowerUp(
-    IN  PXENDISK_FDO    Fdo,
-    IN  PIRP            Irp
+__drv_functionClass(IO_COMPLETION_ROUTINE)
+__drv_sameIRQL
+static NTSTATUS
+FdoSetSystemPowerUpComplete(
+    IN  PDEVICE_OBJECT  DeviceObject,
+    IN  PIRP            Irp,
+    IN  PVOID           Context
     )
 {
+    PXENDISK_FDO        Fdo = (PXENDISK_FDO) Context;
     PIO_STACK_LOCATION  StackLocation;
     SYSTEM_POWER_STATE  SystemState;
-    NTSTATUS            status;
+
+    UNREFERENCED_PARAMETER(DeviceObject);
 
     StackLocation = IoGetCurrentIrpStackLocation(Irp);
     SystemState = StackLocation->Parameters.Power.State.SystemState;
 
-    ASSERT3U(SystemState, <,  __FdoGetSystemPowerState(Fdo));
-
-    status = FdoForwardIrpSynchronously(Fdo, Irp);
-    if (!NT_SUCCESS(status))
-        goto done;
-
-    Verbose("%p: %s -> %s\n",
-         Fdo->Dx->DeviceObject,
-         PowerSystemStateName(__FdoGetSystemPowerState(Fdo)),
-         PowerSystemStateName(SystemState));
+    if (Irp->PendingReturned)
+        IoMarkIrpPending(Irp);
 
     __FdoSetSystemPowerState(Fdo, SystemState);
 
-done:
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    return STATUS_CONTINUE_COMPLETION;
+}
 
-    return status;
+static FORCEINLINE NTSTATUS
+__FdoSetSystemPowerUp(
+    IN  PXENDISK_FDO    Fdo,
+    IN  PIRP            Irp
+    )
+{
+    IoCopyCurrentIrpStackLocationToNext(Irp);
+    IoSetCompletionRoutine(Irp,
+                           FdoSetSystemPowerUpComplete,
+                           Fdo,
+                           TRUE,
+                           TRUE,
+                           TRUE);
+
+    return IoCallDriver(Fdo->LowerDeviceObject, Irp);
 }
 
 static FORCEINLINE NTSTATUS
@@ -1274,29 +1288,19 @@ __FdoSetSystemPowerDown(
 {
     PIO_STACK_LOCATION  StackLocation;
     SYSTEM_POWER_STATE  SystemState;
-    NTSTATUS            status;
 
     StackLocation = IoGetCurrentIrpStackLocation(Irp);
     SystemState = StackLocation->Parameters.Power.State.SystemState;
 
-    ASSERT3U(SystemState, >,  __FdoGetSystemPowerState(Fdo));
-
-    Verbose("%p: %s -> %s\n",
-         Fdo->Dx->DeviceObject,
-         PowerSystemStateName(__FdoGetSystemPowerState(Fdo)),
-         PowerSystemStateName(SystemState));
-
     __FdoSetSystemPowerState(Fdo, SystemState);
 
-    status = FdoForwardIrpSynchronously(Fdo, Irp);
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return status;
+    IoSkipCurrentIrpStackLocation(Irp);
+    return IoCallDriver(Fdo->LowerDeviceObject, Irp);
 }
 
 static FORCEINLINE NTSTATUS
 __FdoSetSystemPower(
-    IN  PXENDISK_FDO    Fdo,
+    IN  PXENDISK_FDO     Fdo,
     IN  PIRP            Irp
     )
 {
@@ -1314,13 +1318,12 @@ __FdoSetSystemPower(
           PowerActionName(PowerAction));
 
     if (SystemState == __FdoGetSystemPowerState(Fdo)) {
-        status = FdoForwardIrpSynchronously(Fdo, Irp);
-        IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
+        IoSkipCurrentIrpStackLocation(Irp);
+        status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
         goto done;
     }
 
-    status = (SystemState < __FdoGetSystemPowerState(Fdo)) ?
+    status = SystemState < __FdoGetSystemPowerState(Fdo) ?
              __FdoSetSystemPowerUp(Fdo, Irp) :
              __FdoSetSystemPowerDown(Fdo, Irp);
 
@@ -1329,310 +1332,60 @@ done:
           PowerSystemStateName(SystemState),
           PowerActionName(PowerAction),
           status);
-    return status;
-}
-
-static FORCEINLINE NTSTATUS
-__FdoQueryDevicePowerUp(
-    IN  PXENDISK_FDO    Fdo,
-    IN  PIRP            Irp
-    )
-{
-    PIO_STACK_LOCATION  StackLocation;
-    DEVICE_POWER_STATE  DeviceState;
-    NTSTATUS            status;
-
-    StackLocation = IoGetCurrentIrpStackLocation(Irp);
-    DeviceState = StackLocation->Parameters.Power.State.DeviceState;
-
-    ASSERT3U(DeviceState, <,  __FdoGetDevicePowerState(Fdo));
-
-    status = FdoForwardIrpSynchronously(Fdo, Irp);
-
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
 
     return status;
 }
 
-static FORCEINLINE NTSTATUS
-__FdoQueryDevicePowerDown(
-    IN  PXENDISK_FDO    Fdo,
-    IN  PIRP            Irp
-    )
-{
-    PIO_STACK_LOCATION  StackLocation;
-    DEVICE_POWER_STATE  DeviceState;
-    NTSTATUS            status;
-
-    StackLocation = IoGetCurrentIrpStackLocation(Irp);
-    DeviceState = StackLocation->Parameters.Power.State.DeviceState;
-
-    ASSERT3U(DeviceState, >,  __FdoGetDevicePowerState(Fdo));
-
-    status = FdoForwardIrpSynchronously(Fdo, Irp);
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return status;
-}
-
-static FORCEINLINE NTSTATUS
-__FdoQueryDevicePower(
+static NTSTATUS
+FdoDevicePower(
     IN  PXENDISK_FDO    Fdo,
     IN  PIRP            Irp
     )
 {
     PIO_STACK_LOCATION  StackLocation;
-    DEVICE_POWER_STATE  DeviceState;
-    POWER_ACTION        PowerAction;
     NTSTATUS            status;
 
     StackLocation = IoGetCurrentIrpStackLocation(Irp);
-    DeviceState = StackLocation->Parameters.Power.State.DeviceState;
-    PowerAction = StackLocation->Parameters.Power.ShutdownType;
 
-    Trace("====> (%s:%s)\n",
-          PowerDeviceStateName(DeviceState),
-          PowerActionName(PowerAction));
-
-    if (DeviceState == __FdoGetDevicePowerState(Fdo)) {
-        status = FdoForwardIrpSynchronously(Fdo, Irp);
-        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    switch (StackLocation->MinorFunction) {
+    case IRP_MN_SET_POWER:
+        status = __FdoSetDevicePower(Fdo, Irp);
+        break;
 
-        goto done;
+    default:
+        IoSkipCurrentIrpStackLocation(Irp);
+        status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
+        break;
     }
 
-    status = (DeviceState < __FdoGetDevicePowerState(Fdo)) ?
-             __FdoQueryDevicePowerUp(Fdo, Irp) :
-             __FdoQueryDevicePowerDown(Fdo, Irp);
-
-done:
-    Trace("<==== (%s:%s)(%08x)\n",
-          PowerDeviceStateName(DeviceState),
-          PowerActionName(PowerAction),
-          status);
-    return status;
-}
-
-static FORCEINLINE NTSTATUS
-__FdoQuerySystemPowerUp(
-    IN  PXENDISK_FDO     Fdo,
-    IN  PIRP            Irp
-    )
-{
-    PIO_STACK_LOCATION  StackLocation;
-    SYSTEM_POWER_STATE  SystemState;
-    NTSTATUS            status;
-
-    StackLocation = IoGetCurrentIrpStackLocation(Irp);
-    SystemState = StackLocation->Parameters.Power.State.SystemState;
-
-    ASSERT3U(SystemState, <,  __FdoGetSystemPowerState(Fdo));
-
-    status = FdoForwardIrpSynchronously(Fdo, Irp);
-
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
     return status;
 }
 
-static FORCEINLINE NTSTATUS
-__FdoQuerySystemPowerDown(
-    IN  PXENDISK_FDO    Fdo,
-    IN  PIRP            Irp
-    )
-{
-    PIO_STACK_LOCATION  StackLocation;
-    SYSTEM_POWER_STATE  SystemState;
-    NTSTATUS            status;
-
-    StackLocation = IoGetCurrentIrpStackLocation(Irp);
-    SystemState = StackLocation->Parameters.Power.State.SystemState;
-
-    ASSERT3U(SystemState, >,  __FdoGetSystemPowerState(Fdo));
-
-    status = FdoForwardIrpSynchronously(Fdo, Irp);
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return status;
-}
-
-static FORCEINLINE NTSTATUS
-__FdoQuerySystemPower(
+static NTSTATUS
+FdoSystemPower(
     IN  PXENDISK_FDO    Fdo,
     IN  PIRP            Irp
     )
 {
     PIO_STACK_LOCATION  StackLocation;
-    SYSTEM_POWER_STATE  SystemState;
-    POWER_ACTION        PowerAction;
     NTSTATUS            status;
 
     StackLocation = IoGetCurrentIrpStackLocation(Irp);
-    SystemState = StackLocation->Parameters.Power.State.SystemState;
-    PowerAction = StackLocation->Parameters.Power.ShutdownType;
-
-    Trace("====> (%s:%s)\n",
-          PowerSystemStateName(SystemState),
-          PowerActionName(PowerAction));
 
-    if (SystemState == __FdoGetSystemPowerState(Fdo)) {
-        status = FdoForwardIrpSynchronously(Fdo, Irp);
-        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    switch (StackLocation->MinorFunction) {
+    case IRP_MN_SET_POWER:
+        status = __FdoSetSystemPower(Fdo, Irp);
+        break;
 
-        goto done;
+    default:
+        IoSkipCurrentIrpStackLocation(Irp);
+        status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
+        break;
     }
 
-    status = (SystemState < __FdoGetSystemPowerState(Fdo)) ?
-             __FdoQuerySystemPowerUp(Fdo, Irp) :
-             __FdoQuerySystemPowerDown(Fdo, Irp);
-
-done:
-    Trace("<==== (%s:%s)(%08x)\n",
-          PowerSystemStateName(SystemState),
-          PowerActionName(PowerAction),
-          status);
-
     return status;
 }
 
-static NTSTATUS
-FdoDevicePower(
-    IN  PXENDISK_THREAD Self,
-    IN  PVOID           Context
-    )
-{
-    PXENDISK_FDO        Fdo = Context;
-    PKEVENT             Event;
-
-    Event = ThreadGetEvent(Self);
-
-    for (;;) {
-        PIRP                Irp;
-        PIO_STACK_LOCATION  StackLocation;
-        UCHAR               MinorFunction;
-
-        if (Fdo->DevicePowerIrp == NULL) {
-            (VOID) KeWaitForSingleObject(Event,
-                                         Executive,
-                                         KernelMode,
-                                         FALSE,
-                                         NULL);
-            KeClearEvent(Event);
-        }
-
-        if (ThreadIsAlerted(Self))
-            break;
-
-        Irp = Fdo->DevicePowerIrp;
-
-        if (Irp == NULL)
-            continue;
-
-        Fdo->DevicePowerIrp = NULL;
-        KeMemoryBarrier();
-
-        StackLocation = IoGetCurrentIrpStackLocation(Irp);
-        MinorFunction = StackLocation->MinorFunction;
-
-        switch (StackLocation->MinorFunction) {
-        case IRP_MN_SET_POWER:
-            (VOID) __FdoSetDevicePower(Fdo, Irp);
-            break;
-
-        case IRP_MN_QUERY_POWER:
-            (VOID) __FdoQueryDevicePower(Fdo, Irp);
-            break;
-
-        default:
-            ASSERT(FALSE);
-            break;
-        }
-
-        IoReleaseRemoveLock(&Fdo->Dx->RemoveLock, Irp);
-    }
-
-    return STATUS_SUCCESS;
-}
-
-static NTSTATUS
-FdoSystemPower(
-    IN  PXENDISK_THREAD Self,
-    IN  PVOID           Context
-    )
-{
-    PXENDISK_FDO        Fdo = Context;
-    PKEVENT             Event;
-
-    Event = ThreadGetEvent(Self);
-
-    for (;;) {
-        PIRP                Irp;
-        PIO_STACK_LOCATION  StackLocation;
-        UCHAR               MinorFunction;
-
-        if (Fdo->SystemPowerIrp == NULL) {
-            (VOID) KeWaitForSingleObject(Event,
-                                         Executive,
-                                         KernelMode,
-                                         FALSE,
-                                         NULL);
-            KeClearEvent(Event);
-        }
-
-        if (ThreadIsAlerted(Self))
-            break;
-
-        Irp = Fdo->SystemPowerIrp;
-
-        if (Irp == NULL)
-            continue;
-
-        Fdo->SystemPowerIrp = NULL;
-        KeMemoryBarrier();
-
-        StackLocation = IoGetCurrentIrpStackLocation(Irp);
-        MinorFunction = StackLocation->MinorFunction;
-
-        switch (StackLocation->MinorFunction) {
-        case IRP_MN_SET_POWER:
-            (VOID) __FdoSetSystemPower(Fdo, Irp);
-            break;
-
-        case IRP_MN_QUERY_POWER:
-            (VOID) __FdoQuerySystemPower(Fdo, Irp);
-            break;
-
-        default:
-            ASSERT(FALSE);
-            break;
-        }
-
-        IoReleaseRemoveLock(&Fdo->Dx->RemoveLock, Irp);
-    }
-
-    return STATUS_SUCCESS;
-}
-
-__drv_functionClass(IO_COMPLETION_ROUTINE)
-__drv_sameIRQL
-static NTSTATUS
-__FdoDispatchPower(
-    IN  PDEVICE_OBJECT  DeviceObject,
-    IN  PIRP            Irp,
-    IN  PVOID           Context
-    )
-{
-    PXENDISK_FDO        Fdo = Context;
-
-    UNREFERENCED_PARAMETER(DeviceObject);
-
-    if (Irp->PendingReturned)
-        IoMarkIrpPending(Irp);
-
-    IoReleaseRemoveLock(&Fdo->Dx->RemoveLock, Irp);
-    return STATUS_SUCCESS;
-}
-
 static DECLSPEC_NOINLINE NTSTATUS
 FdoDispatchPower(
     IN  PXENDISK_FDO    Fdo,
@@ -1640,90 +1393,27 @@ FdoDispatchPower(
     )
 {
     PIO_STACK_LOCATION  StackLocation;
-    UCHAR               MinorFunction;
     POWER_STATE_TYPE    PowerType;
     NTSTATUS            status;
 
-    status = IoAcquireRemoveLock(&Fdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
     StackLocation = IoGetCurrentIrpStackLocation(Irp);
-    MinorFunction = StackLocation->MinorFunction;
-
-    if (MinorFunction != IRP_MN_QUERY_POWER &&
-        MinorFunction != IRP_MN_SET_POWER) {
-        IoCopyCurrentIrpStackLocationToNext(Irp);
-        IoSetCompletionRoutine(Irp,
-                               __FdoDispatchPower,
-                               Fdo,
-                               TRUE,
-                               TRUE,
-                               TRUE);
-
-        status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
-
-        goto done;
-    }
-
     PowerType = StackLocation->Parameters.Power.Type;
 
-    Trace("====> (%02x:%s)\n",
-          MinorFunction,
-          PowerMinorFunctionName(MinorFunction));
-
     switch (PowerType) {
     case DevicePowerState:
-        IoMarkIrpPending(Irp);
-
-        ASSERT3P(Fdo->DevicePowerIrp, ==, NULL);
-        Fdo->DevicePowerIrp = Irp;
-        KeMemoryBarrier();
-
-        ThreadWake(Fdo->DevicePowerThread);
-
-        status = STATUS_PENDING;
+        status = FdoDevicePower(Fdo, Irp);
         break;
 
     case SystemPowerState:
-        IoMarkIrpPending(Irp);
-
-        ASSERT3P(Fdo->SystemPowerIrp, ==, NULL);
-        Fdo->SystemPowerIrp = Irp;
-        KeMemoryBarrier();
-
-        ThreadWake(Fdo->SystemPowerThread);
-
-        status = STATUS_PENDING;
+        status = FdoSystemPower(Fdo, Irp);
         break;
 
     default:
-        IoCopyCurrentIrpStackLocationToNext(Irp);
-        IoSetCompletionRoutine(Irp,
-                               __FdoDispatchPower,
-                               Fdo,
-                               TRUE,
-                               TRUE,
-                               TRUE);
-
+        IoSkipCurrentIrpStackLocation(Irp);
         status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
         break;
     }
 
-    Trace("<==== (%02x:%s) (%08x)\n",
-          MinorFunction,
-          PowerMinorFunctionName(MinorFunction),
-          status);
-
-done:
-    return status;
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    Irp->IoStatus.Status = status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
     return status;
 }
 
@@ -1864,14 +1554,6 @@ FdoCreate(
     Fdo->PhysicalDeviceObject = PhysicalDeviceObject;
     Fdo->LowerDeviceObject = LowerDeviceObject;
 
-    status = ThreadCreate(FdoSystemPower, Fdo, &Fdo->SystemPowerThread);
-    if (!NT_SUCCESS(status))
-        goto fail4;
-
-    status = ThreadCreate(FdoDevicePower, Fdo, &Fdo->DevicePowerThread);
-    if (!NT_SUCCESS(status))
-        goto fail5;
-
     InitializeMutex(&Fdo->Mutex);
     InitializeListHead(&Dx->ListEntry);
     Fdo->References = 1;
@@ -1889,22 +1571,6 @@ FdoCreate(
 
     return STATUS_SUCCESS;
 
-fail5:
-    Error("fail5\n");
-
-    ThreadAlert(Fdo->SystemPowerThread);
-    ThreadJoin(Fdo->SystemPowerThread);
-    Fdo->SystemPowerThread = NULL;
-
-fail4:
-    Error("fail4\n");
-
-    Fdo->PhysicalDeviceObject = NULL;
-    Fdo->LowerDeviceObject = NULL;
-    Fdo->Dx = NULL;
-
-    IoDetachDevice(LowerDeviceObject);
-
 fail3:
     Error("fail3\n");
 
@@ -1939,14 +1605,6 @@ FdoDestroy(
 
     RtlZeroMemory(&Fdo->Mutex, sizeof (MUTEX));
 
-    ThreadAlert(Fdo->DevicePowerThread);
-    ThreadJoin(Fdo->DevicePowerThread);
-    Fdo->DevicePowerThread = NULL;
-
-    ThreadAlert(Fdo->SystemPowerThread);
-    ThreadJoin(Fdo->SystemPowerThread);
-    Fdo->SystemPowerThread = NULL;
-
     Fdo->LowerDeviceObject = NULL;
     Fdo->PhysicalDeviceObject = NULL;
     Fdo->Dx = NULL;
diff --git a/src/xendisk/pdo.c b/src/xendisk/pdo.c
index 321ecf3..f714efb 100644
--- a/src/xendisk/pdo.c
+++ b/src/xendisk/pdo.c
@@ -60,11 +60,6 @@ struct _XENDISK_PDO {
     PDEVICE_OBJECT              PhysicalDeviceObject;
     CHAR                        Name[MAXNAMELEN];
 
-    PXENDISK_THREAD             SystemPowerThread;
-    PIRP                        SystemPowerIrp;
-    PXENDISK_THREAD             DevicePowerThread;
-    PIRP                        DevicePowerIrp;
-
     PXENDISK_FDO                Fdo;
 
     BOOLEAN                     InterceptTrim;
@@ -1416,37 +1411,50 @@ fail1:
     return status;
 }
 
-static FORCEINLINE NTSTATUS
-__PdoSetDevicePowerUp(
-    IN  PXENDISK_PDO    Pdo,
-    IN  PIRP            Irp
+__drv_functionClass(IO_COMPLETION_ROUTINE)
+__drv_sameIRQL
+static NTSTATUS
+PdoSetDevicePowerUpComplete(
+    IN  PDEVICE_OBJECT  DeviceObject,
+    IN  PIRP            Irp,
+    IN  PVOID           Context
     )
 {
+    PXENDISK_PDO        Pdo = (PXENDISK_PDO) Context;
     PIO_STACK_LOCATION  StackLocation;
-    DEVICE_POWER_STATE  DeviceState;
-    NTSTATUS            status;
+    POWER_STATE         PowerState;
 
-    StackLocation = IoGetCurrentIrpStackLocation(Irp);
-    DeviceState = StackLocation->Parameters.Power.State.DeviceState;
+    UNREFERENCED_PARAMETER(DeviceObject);
 
-    ASSERT3U(DeviceState, <,  __PdoGetDevicePowerState(Pdo));
+    StackLocation = IoGetCurrentIrpStackLocation(Irp);
+    PowerState = StackLocation->Parameters.Power.State;
 
-    status = PdoForwardIrpSynchronously(Pdo, Irp);
-    if (!NT_SUCCESS(status))
-        goto done;
+    if (Irp->PendingReturned)
+        IoMarkIrpPending(Irp);
 
-    Verbose("%s: %s -> %s\n",
-            __PdoGetName(Pdo),
-            PowerDeviceStateName(__PdoGetDevicePowerState(Pdo)),
-            PowerDeviceStateName(DeviceState));
+    __PdoSetDevicePowerState(Pdo, PowerState.DeviceState);
+    PoSetPowerState(Pdo->Dx->DeviceObject,
+                    DevicePowerState,
+                    PowerState);
 
-    __PdoSetDevicePowerState(Pdo, DeviceState);
+    return STATUS_CONTINUE_COMPLETION;
+}
 
-done:
-    Irp->IoStatus.Status = status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+static FORCEINLINE NTSTATUS
+__PdoSetDevicePowerUp(
+    IN  PXENDISK_PDO    Pdo,
+    IN  PIRP            Irp
+    )
+{
+    IoCopyCurrentIrpStackLocationToNext(Irp);
+    IoSetCompletionRoutine(Irp,
+                           PdoSetDevicePowerUpComplete,
+                           Pdo,
+                           TRUE,
+                           TRUE,
+                           TRUE);
 
-    return status;
+    return IoCallDriver(Pdo->LowerDeviceObject, Irp);
 }
 
 static FORCEINLINE NTSTATUS
@@ -1456,25 +1464,18 @@ __PdoSetDevicePowerDown(
     )
 {
     PIO_STACK_LOCATION  StackLocation;
-    DEVICE_POWER_STATE  DeviceState;
-    NTSTATUS            status;
+    POWER_STATE         PowerState;
 
     StackLocation = IoGetCurrentIrpStackLocation(Irp);
-    DeviceState = StackLocation->Parameters.Power.State.DeviceState;
-
-    ASSERT3U(DeviceState, >,  __PdoGetDevicePowerState(Pdo));
-
-    Verbose("%s: %s -> %s\n",
-            __PdoGetName(Pdo),
-            PowerDeviceStateName(__PdoGetDevicePowerState(Pdo)),
-            PowerDeviceStateName(DeviceState));
+    PowerState = StackLocation->Parameters.Power.State;
 
-    __PdoSetDevicePowerState(Pdo, DeviceState);
-
-    status = PdoForwardIrpSynchronously(Pdo, Irp);
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    __PdoSetDevicePowerState(Pdo, PowerState.DeviceState);
+    PoSetPowerState(Pdo->Dx->DeviceObject,
+                    DevicePowerState,
+                    PowerState);
 
-    return status;
+    IoSkipCurrentIrpStackLocation(Irp);
+    return IoCallDriver(Pdo->LowerDeviceObject, Irp);
 }
 
 static FORCEINLINE NTSTATUS
@@ -1497,13 +1498,12 @@ __PdoSetDevicePower(
           PowerActionName(PowerAction));
 
     if (DeviceState == __PdoGetDevicePowerState(Pdo)) {
-        status = PdoForwardIrpSynchronously(Pdo, Irp);
-        IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
+        IoSkipCurrentIrpStackLocation(Irp);
+        status = IoCallDriver(Pdo->LowerDeviceObject, Irp);
         goto done;
     }
 
-    status = (DeviceState < __PdoGetDevicePowerState(Pdo)) ?
+    status = DeviceState < __PdoGetDevicePowerState(Pdo) ?
              __PdoSetDevicePowerUp(Pdo, Irp) :
              __PdoSetDevicePowerDown(Pdo, Irp);
 
@@ -1512,40 +1512,51 @@ done:
           PowerDeviceStateName(DeviceState),
           PowerActionName(PowerAction),
           status);
+
     return status;
 }
 
-static FORCEINLINE NTSTATUS
-__PdoSetSystemPowerUp(
-    IN  PXENDISK_PDO    Pdo,
-    IN  PIRP            Irp
+__drv_functionClass(IO_COMPLETION_ROUTINE)
+__drv_sameIRQL
+static NTSTATUS
+PdoSetSystemPowerUpComplete(
+    IN  PDEVICE_OBJECT  DeviceObject,
+    IN  PIRP            Irp,
+    IN  PVOID           Context
     )
 {
+    PXENDISK_PDO        Pdo = (PXENDISK_PDO) Context;
     PIO_STACK_LOCATION  StackLocation;
     SYSTEM_POWER_STATE  SystemState;
-    NTSTATUS            status;
+
+    UNREFERENCED_PARAMETER(DeviceObject);
 
     StackLocation = IoGetCurrentIrpStackLocation(Irp);
     SystemState = StackLocation->Parameters.Power.State.SystemState;
 
-    ASSERT3U(SystemState, <,  __PdoGetSystemPowerState(Pdo));
-
-    status = PdoForwardIrpSynchronously(Pdo, Irp);
-    if (!NT_SUCCESS(status))
-        goto done;
-
-    Verbose("%s: %s -> %s\n",
-            __PdoGetName(Pdo),
-            PowerSystemStateName(__PdoGetSystemPowerState(Pdo)),
-            PowerSystemStateName(SystemState));
+    if (Irp->PendingReturned)
+        IoMarkIrpPending(Irp);
 
     __PdoSetSystemPowerState(Pdo, SystemState);
 
-done:
-    Irp->IoStatus.Status = status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    return STATUS_CONTINUE_COMPLETION;
+}
 
-    return status;
+static FORCEINLINE NTSTATUS
+__PdoSetSystemPowerUp(
+    IN  PXENDISK_PDO    Pdo,
+    IN  PIRP            Irp
+    )
+{
+    IoCopyCurrentIrpStackLocationToNext(Irp);
+    IoSetCompletionRoutine(Irp,
+                           PdoSetSystemPowerUpComplete,
+                           Pdo,
+                           TRUE,
+                           TRUE,
+                           TRUE);
+
+    return IoCallDriver(Pdo->LowerDeviceObject, Irp);
 }
 
 static FORCEINLINE NTSTATUS
@@ -1556,24 +1567,14 @@ __PdoSetSystemPowerDown(
 {
     PIO_STACK_LOCATION  StackLocation;
     SYSTEM_POWER_STATE  SystemState;
-    NTSTATUS            status;
 
     StackLocation = IoGetCurrentIrpStackLocation(Irp);
     SystemState = StackLocation->Parameters.Power.State.SystemState;
 
-    ASSERT3U(SystemState, >,  __PdoGetSystemPowerState(Pdo));
-
-    Verbose("%s: %s -> %s\n",
-            __PdoGetName(Pdo),
-            PowerSystemStateName(__PdoGetSystemPowerState(Pdo)),
-            PowerSystemStateName(SystemState));
-
     __PdoSetSystemPowerState(Pdo, SystemState);
 
-    status = PdoForwardIrpSynchronously(Pdo, Irp);
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return status;
+    IoSkipCurrentIrpStackLocation(Irp);
+    return IoCallDriver(Pdo->LowerDeviceObject, Irp);
 }
 
 static FORCEINLINE NTSTATUS
@@ -1596,13 +1597,12 @@ __PdoSetSystemPower(
           PowerActionName(PowerAction));
 
     if (SystemState == __PdoGetSystemPowerState(Pdo)) {
-        status = PdoForwardIrpSynchronously(Pdo, Irp);
-        IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
+        IoSkipCurrentIrpStackLocation(Irp);
+        status = IoCallDriver(Pdo->LowerDeviceObject, Irp);
         goto done;
     }
 
-    status = (SystemState < __PdoGetSystemPowerState(Pdo)) ?
+    status = SystemState < __PdoGetSystemPowerState(Pdo) ?
              __PdoSetSystemPowerUp(Pdo, Irp) :
              __PdoSetSystemPowerDown(Pdo, Irp);
 
@@ -1611,403 +1611,88 @@ done:
           PowerSystemStateName(SystemState),
           PowerActionName(PowerAction),
           status);
-    return status;
-}
-
-static FORCEINLINE NTSTATUS
-__PdoQueryDevicePowerUp(
-    IN  PXENDISK_PDO    Pdo,
-    IN  PIRP            Irp
-    )
-{
-    PIO_STACK_LOCATION  StackLocation;
-    DEVICE_POWER_STATE  DeviceState;
-    NTSTATUS            status;
-
-    StackLocation = IoGetCurrentIrpStackLocation(Irp);
-    DeviceState = StackLocation->Parameters.Power.State.DeviceState;
-
-    ASSERT3U(DeviceState, <,  __PdoGetDevicePowerState(Pdo));
-
-    status = PdoForwardIrpSynchronously(Pdo, Irp);
-
-    Irp->IoStatus.Status = status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
 
     return status;
 }
 
-static FORCEINLINE NTSTATUS
-__PdoQueryDevicePowerDown(
+static NTSTATUS
+PdoDevicePower(
     IN  PXENDISK_PDO    Pdo,
     IN  PIRP            Irp
     )
 {
-    PIO_STACK_LOCATION  StackLocation;
-    DEVICE_POWER_STATE  DeviceState;
     NTSTATUS            status;
-
-    StackLocation = IoGetCurrentIrpStackLocation(Irp);
-    DeviceState = StackLocation->Parameters.Power.State.DeviceState;
-
-    ASSERT3U(DeviceState, >,  __PdoGetDevicePowerState(Pdo));
-
-    status = PdoForwardIrpSynchronously(Pdo, Irp);
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return status;
-}
-
-static FORCEINLINE NTSTATUS
-__PdoQueryDevicePower(
-    IN  PXENDISK_PDO    Pdo,
-    IN  PIRP            Irp
-    )
-{
     PIO_STACK_LOCATION  StackLocation;
-    DEVICE_POWER_STATE  DeviceState;
-    POWER_ACTION        PowerAction;
-    NTSTATUS            status;
 
     StackLocation = IoGetCurrentIrpStackLocation(Irp);
-    DeviceState = StackLocation->Parameters.Power.State.DeviceState;
-    PowerAction = StackLocation->Parameters.Power.ShutdownType;
 
-    Trace("====> (%s:%s)\n",
-          PowerDeviceStateName(DeviceState),
-          PowerActionName(PowerAction));
-
-    if (DeviceState == __PdoGetDevicePowerState(Pdo)) {
-        status = PdoForwardIrpSynchronously(Pdo, Irp);
-        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    switch (StackLocation->MinorFunction) {
+    case IRP_MN_SET_POWER:
+        status = __PdoSetDevicePower(Pdo, Irp);
+        break;
 
-        goto done;
+    default:
+        IoSkipCurrentIrpStackLocation(Irp);
+        status = IoCallDriver(Pdo->LowerDeviceObject, Irp);
+        break;
     }
 
-    status = (DeviceState < __PdoGetDevicePowerState(Pdo)) ?
-             __PdoQueryDevicePowerUp(Pdo, Irp) :
-             __PdoQueryDevicePowerDown(Pdo, Irp);
-
-done:
-    Trace("<==== (%s:%s)(%08x)\n",
-          PowerDeviceStateName(DeviceState),
-          PowerActionName(PowerAction),
-          status);
-    return status;
-}
-
-static FORCEINLINE NTSTATUS
-__PdoQuerySystemPowerUp(
-    IN  PXENDISK_PDO     Pdo,
-    IN  PIRP            Irp
-    )
-{
-    PIO_STACK_LOCATION  StackLocation;
-    SYSTEM_POWER_STATE  SystemState;
-    NTSTATUS            status;
-
-    StackLocation = IoGetCurrentIrpStackLocation(Irp);
-    SystemState = StackLocation->Parameters.Power.State.SystemState;
-
-    ASSERT3U(SystemState, <,  __PdoGetSystemPowerState(Pdo));
-
-    status = PdoForwardIrpSynchronously(Pdo, Irp);
-
-    Irp->IoStatus.Status = status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
     return status;
 }
 
-static FORCEINLINE NTSTATUS
-__PdoQuerySystemPowerDown(
+static NTSTATUS
+PdoSystemPower(
     IN  PXENDISK_PDO    Pdo,
     IN  PIRP            Irp
     )
 {
-    PIO_STACK_LOCATION  StackLocation;
-    SYSTEM_POWER_STATE  SystemState;
     NTSTATUS            status;
-
-    StackLocation = IoGetCurrentIrpStackLocation(Irp);
-    SystemState = StackLocation->Parameters.Power.State.SystemState;
-
-    ASSERT3U(SystemState, >,  __PdoGetSystemPowerState(Pdo));
-
-    status = PdoForwardIrpSynchronously(Pdo, Irp);
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return status;
-}
-
-static FORCEINLINE NTSTATUS
-__PdoQuerySystemPower(
-    IN  PXENDISK_PDO    Pdo,
-    IN  PIRP            Irp
-    )
-{
     PIO_STACK_LOCATION  StackLocation;
-    SYSTEM_POWER_STATE  SystemState;
-    POWER_ACTION        PowerAction;
-    NTSTATUS            status;
 
     StackLocation = IoGetCurrentIrpStackLocation(Irp);
-    SystemState = StackLocation->Parameters.Power.State.SystemState;
-    PowerAction = StackLocation->Parameters.Power.ShutdownType;
 
-    Trace("====> (%s:%s)\n",
-          PowerSystemStateName(SystemState),
-          PowerActionName(PowerAction));
-
-    if (SystemState == __PdoGetSystemPowerState(Pdo)) {
-        status = PdoForwardIrpSynchronously(Pdo, Irp);
-        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    switch (StackLocation->MinorFunction) {
+    case IRP_MN_SET_POWER:
+        status = __PdoSetSystemPower(Pdo, Irp);
+        break;
 
-        goto done;
+    default:
+        IoSkipCurrentIrpStackLocation(Irp);
+        status = IoCallDriver(Pdo->LowerDeviceObject, Irp);
+        break;
     }
 
-    status = (SystemState < __PdoGetSystemPowerState(Pdo)) ?
-             __PdoQuerySystemPowerUp(Pdo, Irp) :
-             __PdoQuerySystemPowerDown(Pdo, Irp);
-
-done:
-    Trace("<==== (%s:%s)(%08x)\n",
-          PowerSystemStateName(SystemState),
-          PowerActionName(PowerAction),
-          status);
-
     return status;
 }
 
-static NTSTATUS
-PdoDevicePower(
-    IN  PXENDISK_THREAD Self,
-    IN  PVOID           Context
-    )
-{
-    PXENDISK_PDO        Pdo = Context;
-    PKEVENT             Event;
-
-    Event = ThreadGetEvent(Self);
-
-    for (;;) {
-        PIRP                Irp;
-        PIO_STACK_LOCATION  StackLocation;
-        UCHAR               MinorFunction;
-
-        if (Pdo->DevicePowerIrp == NULL) {
-            (VOID) KeWaitForSingleObject(Event,
-                                         Executive,
-                                         KernelMode,
-                                         FALSE,
-                                         NULL);
-            KeClearEvent(Event);
-        }
-
-        if (ThreadIsAlerted(Self))
-            break;
-
-        Irp = Pdo->DevicePowerIrp;
-
-        if (Irp == NULL)
-            continue;
-
-        Pdo->DevicePowerIrp = NULL;
-        KeMemoryBarrier();
-
-        StackLocation = IoGetCurrentIrpStackLocation(Irp);
-        MinorFunction = StackLocation->MinorFunction;
-
-        switch (StackLocation->MinorFunction) {
-        case IRP_MN_SET_POWER:
-            (VOID) __PdoSetDevicePower(Pdo, Irp);
-            break;
-
-        case IRP_MN_QUERY_POWER:
-            (VOID) __PdoQueryDevicePower(Pdo, Irp);
-            break;
-
-        default:
-            ASSERT(FALSE);
-            break;
-        }
-
-        IoReleaseRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-    }
-
-    return STATUS_SUCCESS;
-}
-
-static NTSTATUS
-PdoSystemPower(
-    IN  PXENDISK_THREAD Self,
-    IN  PVOID           Context
-    )
-{
-    PXENDISK_PDO        Pdo = Context;
-    PKEVENT             Event;
-
-    Event = ThreadGetEvent(Self);
-
-    for (;;) {
-        PIRP                Irp;
-        PIO_STACK_LOCATION  StackLocation;
-        UCHAR               MinorFunction;
-
-        if (Pdo->SystemPowerIrp == NULL) {
-            (VOID) KeWaitForSingleObject(Event,
-                                         Executive,
-                                         KernelMode,
-                                         FALSE,
-                                         NULL);
-            KeClearEvent(Event);
-        }
-
-        if (ThreadIsAlerted(Self))
-            break;
-
-        Irp = Pdo->SystemPowerIrp;
-
-        if (Irp == NULL)
-            continue;
-
-        Pdo->SystemPowerIrp = NULL;
-        KeMemoryBarrier();
-
-        StackLocation = IoGetCurrentIrpStackLocation(Irp);
-        MinorFunction = StackLocation->MinorFunction;
-
-        switch (StackLocation->MinorFunction) {
-        case IRP_MN_SET_POWER:
-            (VOID) __PdoSetSystemPower(Pdo, Irp);
-            break;
-
-        case IRP_MN_QUERY_POWER:
-            (VOID) __PdoQuerySystemPower(Pdo, Irp);
-            break;
-
-        default:
-            ASSERT(FALSE);
-            break;
-        }
-
-        IoReleaseRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-    }
-
-    return STATUS_SUCCESS;
-}
-
-__drv_functionClass(IO_COMPLETION_ROUTINE)
-__drv_sameIRQL
-static NTSTATUS
-__PdoDispatchPower(
-    IN  PDEVICE_OBJECT  DeviceObject,
-    IN  PIRP            Irp,
-    IN  PVOID           Context
-    )
-{
-    PXENDISK_PDO        Pdo = Context;
-
-    UNREFERENCED_PARAMETER(DeviceObject);
-
-    if (Irp->PendingReturned)
-        IoMarkIrpPending(Irp);
-
-    IoReleaseRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-    return STATUS_SUCCESS;
-}
-
 static DECLSPEC_NOINLINE NTSTATUS
 PdoDispatchPower(
-    IN  PXENDISK_PDO    Pdo,
+    IN  PXENDISK_PDO   Pdo,
     IN  PIRP            Irp
     )
 {
     PIO_STACK_LOCATION  StackLocation;
-    UCHAR               MinorFunction;
     POWER_STATE_TYPE    PowerType;
     NTSTATUS            status;
 
-    status = IoAcquireRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
     StackLocation = IoGetCurrentIrpStackLocation(Irp);
-    MinorFunction = StackLocation->MinorFunction;
-
-    if (MinorFunction != IRP_MN_QUERY_POWER &&
-        MinorFunction != IRP_MN_SET_POWER) {
-        IoCopyCurrentIrpStackLocationToNext(Irp);
-        IoSetCompletionRoutine(Irp,
-                               __PdoDispatchPower,
-                               Pdo,
-                               TRUE,
-                               TRUE,
-                               TRUE);
-
-        status = IoCallDriver(Pdo->LowerDeviceObject, Irp);
-
-        goto done;
-    }
-
     PowerType = StackLocation->Parameters.Power.Type;
 
-    Trace("====> (%02x:%s)\n",
-          MinorFunction,
-          PowerMinorFunctionName(MinorFunction));
-
     switch (PowerType) {
     case DevicePowerState:
-        IoMarkIrpPending(Irp);
-
-        ASSERT3P(Pdo->DevicePowerIrp, ==, NULL);
-        Pdo->DevicePowerIrp = Irp;
-        KeMemoryBarrier();
-
-        ThreadWake(Pdo->DevicePowerThread);
-
-        status = STATUS_PENDING;
+        status = PdoDevicePower(Pdo, Irp);
         break;
 
     case SystemPowerState:
-        IoMarkIrpPending(Irp);
-
-        ASSERT3P(Pdo->SystemPowerIrp, ==, NULL);
-        Pdo->SystemPowerIrp = Irp;
-        KeMemoryBarrier();
-
-        ThreadWake(Pdo->SystemPowerThread);
-
-        status = STATUS_PENDING;
+        status = PdoSystemPower(Pdo, Irp);
         break;
 
     default:
-        IoCopyCurrentIrpStackLocationToNext(Irp);
-        IoSetCompletionRoutine(Irp,
-                               __PdoDispatchPower,
-                               Pdo,
-                               TRUE,
-                               TRUE,
-                               TRUE);
-
+        IoSkipCurrentIrpStackLocation(Irp);
         status = IoCallDriver(Pdo->LowerDeviceObject, Irp);
         break;
     }
 
-    Trace("<==== (%02x:%s) (%08x)\n",
-          MinorFunction,
-          PowerMinorFunctionName(MinorFunction),
-          status);
-
-done:
-    return status;
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    Irp->IoStatus.Status = status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
     return status;
 }
 
@@ -2157,14 +1842,6 @@ PdoCreate(
     Pdo->PhysicalDeviceObject = PhysicalDeviceObject;
     Pdo->LowerDeviceObject = LowerDeviceObject;
 
-    status = ThreadCreate(PdoSystemPower, Pdo, &Pdo->SystemPowerThread);
-    if (!NT_SUCCESS(status))
-        goto fail4;
-
-    status = ThreadCreate(PdoDevicePower, Pdo, &Pdo->DevicePowerThread);
-    if (!NT_SUCCESS(status))
-        goto fail5;
-
     __PdoSetName(Pdo, DeviceID, InstanceID);
 
     ParametersKey = DriverGetParametersKey();
@@ -2192,22 +1869,6 @@ PdoCreate(
 
     return STATUS_SUCCESS;
 
-fail5:
-    Error("fail5\n");
-
-    ThreadAlert(Pdo->SystemPowerThread);
-    ThreadJoin(Pdo->SystemPowerThread);
-    Pdo->SystemPowerThread = NULL;
-
-fail4:
-    Error("fail4\n");
-
-    Pdo->PhysicalDeviceObject = NULL;
-    Pdo->LowerDeviceObject = NULL;
-    Pdo->Dx = NULL;
-
-    IoDetachDevice(LowerDeviceObject);
-
 fail3:
     Error("fail3\n");
 
@@ -2246,14 +1907,6 @@ PdoDestroy(
 
     RtlZeroMemory(Pdo->Name, sizeof (Pdo->Name));
 
-    ThreadAlert(Pdo->DevicePowerThread);
-    ThreadJoin(Pdo->DevicePowerThread);
-    Pdo->DevicePowerThread = NULL;
-
-    ThreadAlert(Pdo->SystemPowerThread);
-    ThreadJoin(Pdo->SystemPowerThread);
-    Pdo->SystemPowerThread = NULL;
-
     Pdo->PhysicalDeviceObject = NULL;
     Pdo->LowerDeviceObject = NULL;
     Pdo->Dx = NULL;
-- 
2.41.0.windows.3




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.