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

[RFC PATCH 1/3] [XenFilt] Asynchronous power handling



From: Martin Harvey <Martin.Harvey@xxxxxxxxxx>

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

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

Refactored and limited to XenFilt changes

Signed-off-by: Owen Smith <owen.smith@xxxxxxxxx>
---
 src/xenfilt/fdo.c | 498 +++++++++++----------------------------------
 src/xenfilt/pdo.c | 503 +++++++++++-----------------------------------
 2 files changed, 242 insertions(+), 759 deletions(-)

diff --git a/src/xenfilt/fdo.c b/src/xenfilt/fdo.c
index 78228de..08cf5a7 100644
--- a/src/xenfilt/fdo.c
+++ b/src/xenfilt/fdo.c
@@ -60,11 +60,6 @@ struct _XENFILT_FDO {
     PDEVICE_OBJECT                  PhysicalDeviceObject;
     CHAR                            Name[MAXNAMELEN];
 
-    PXENFILT_THREAD                 SystemPowerThread;
-    PIRP                            SystemPowerIrp;
-    PXENFILT_THREAD                 DevicePowerThread;
-    PIRP                            DevicePowerIrp;
-
     MUTEX                           Mutex;
     LIST_ENTRY                      List;
     ULONG                           References;
@@ -1078,76 +1073,87 @@ fail1:
     return status;
 }
 
+__drv_functionClass(IO_COMPLETION_ROUTINE)
+__drv_sameIRQL
 static NTSTATUS
-FdoSetDevicePowerUp(
-    IN  PXENFILT_FDO    Fdo,
-    IN  PIRP            Irp
+FdoSetDevicePowerUpComplete(
+    IN  PDEVICE_OBJECT  DeviceObject,
+    IN  PIRP            Irp,
+    IN  PVOID           Context
     )
 {
+    PXENFILT_FDO        Fdo = (PXENFILT_FDO)Context;
     PIO_STACK_LOCATION  StackLocation;
-    DEVICE_POWER_STATE  DeviceState;
     POWER_STATE         PowerState;
-    NTSTATUS            status;
+
+    UNREFERENCED_PARAMETER(DeviceObject);
 
     StackLocation = IoGetCurrentIrpStackLocation(Irp);
-    DeviceState = StackLocation->Parameters.Power.State.DeviceState;
+    PowerState = StackLocation->Parameters.Power.State;
 
-    ASSERT3U(DeviceState, <,  __FdoGetDevicePowerState(Fdo));
+    ASSERT3U(PowerState.DeviceState, <,  __FdoGetDevicePowerState(Fdo));
 
-    status = FdoForwardIrpSynchronously(Fdo, Irp);
-    if (!NT_SUCCESS(status))
-        goto done;
+    if (Irp->PendingReturned)
+        IoMarkIrpPending(Irp);
 
     Trace("%s: %s -> %s\n",
           __FdoGetName(Fdo),
           DevicePowerStateName(__FdoGetDevicePowerState(Fdo)),
-          DevicePowerStateName(DeviceState));
+          DevicePowerStateName(PowerState.DeviceState));
 
-    PowerState.DeviceState = DeviceState;
     PoSetPowerState(Fdo->Dx->DeviceObject,
                     DevicePowerState,
                     PowerState);
 
-    __FdoSetDevicePowerState(Fdo, DeviceState);
+    __FdoSetDevicePowerState(Fdo, PowerState.DeviceState);
 
-done:
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    return STATUS_CONTINUE_COMPLETION;
+}
 
-    return status;
+static FORCEINLINE NTSTATUS
+__FdoSetDevicePowerUp(
+    IN  PXENFILT_FDO    Fdo,
+    IN  PIRP            Irp
+    )
+{
+    IoCopyCurrentIrpStackLocationToNext(Irp);
+    IoSetCompletionRoutine(Irp,
+                           FdoSetDevicePowerUpComplete,
+                           Fdo,
+                           TRUE,
+                           TRUE,
+                           TRUE);
+
+    return IoCallDriver(Fdo->LowerDeviceObject, Irp);
 }
 
 static NTSTATUS
-FdoSetDevicePowerDown(
+__FdoSetDevicePowerDown(
     IN  PXENFILT_FDO    Fdo,
     IN  PIRP            Irp
     )
 {
     PIO_STACK_LOCATION  StackLocation;
-    DEVICE_POWER_STATE  DeviceState;
     POWER_STATE         PowerState;
-    NTSTATUS            status;
 
     StackLocation = IoGetCurrentIrpStackLocation(Irp);
-    DeviceState = StackLocation->Parameters.Power.State.DeviceState;
+    PowerState = StackLocation->Parameters.Power.State;
 
-    ASSERT3U(DeviceState, >,  __FdoGetDevicePowerState(Fdo));
+    ASSERT3U(PowerState.DeviceState, >,  __FdoGetDevicePowerState(Fdo));
 
     Trace("%s: %s -> %s\n",
           __FdoGetName(Fdo),
           DevicePowerStateName(__FdoGetDevicePowerState(Fdo)),
-          DevicePowerStateName(DeviceState));
+          DevicePowerStateName(PowerState.DeviceState));
 
-    PowerState.DeviceState = DeviceState;
     PoSetPowerState(Fdo->Dx->DeviceObject,
                     DevicePowerState,
                     PowerState);
 
-    __FdoSetDevicePowerState(Fdo, DeviceState);
+    __FdoSetDevicePowerState(Fdo, PowerState.DeviceState);
 
-    status = FdoForwardIrpSynchronously(Fdo, Irp);
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return status;
+    IoSkipCurrentIrpStackLocation(Irp);
+    return IoCallDriver(Fdo->LowerDeviceObject, Irp);
 }
 
 static NTSTATUS
@@ -1171,15 +1177,15 @@ 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)) ?
-             FdoSetDevicePowerUp(Fdo, Irp) :
-             FdoSetDevicePowerDown(Fdo, Irp);
+             __FdoSetDevicePowerUp(Fdo, Irp) :
+             __FdoSetDevicePowerDown(Fdo, Irp);
 
 done:
     Trace("%s: <==== (%s:%s)(%08x)\n",
@@ -1190,52 +1196,55 @@ done:
     return status;
 }
 
-static NTSTATUS
-FdoSetSystemPowerUp(
+static FORCEINLINE NTSTATUS
+__FdoDispatchDevicePower(
     IN  PXENFILT_FDO    Fdo,
     IN  PIRP            Irp
     )
 {
     PIO_STACK_LOCATION  StackLocation;
-    SYSTEM_POWER_STATE  SystemState;
+    UCHAR               MinorFunction;
     NTSTATUS            status;
 
     StackLocation = IoGetCurrentIrpStackLocation(Irp);
-    SystemState = StackLocation->Parameters.Power.State.SystemState;
-
-    ASSERT3U(SystemState, <,  __FdoGetSystemPowerState(Fdo));
-
-    status = FdoForwardIrpSynchronously(Fdo, Irp);
-    if (!NT_SUCCESS(status))
-        goto done;
-
-    Trace("%s: %s -> %s\n",
-          __FdoGetName(Fdo),
-          SystemPowerStateName(__FdoGetSystemPowerState(Fdo)),
-          SystemPowerStateName(SystemState));
+    MinorFunction = StackLocation->MinorFunction;
 
-    __FdoSetSystemPowerState(Fdo, SystemState);
+    switch (MinorFunction) {
+    case IRP_MN_SET_POWER:
+        status = FdoSetDevicePower(Fdo, Irp);
+        break;
 
-done:
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    default:
+        IoSkipCurrentIrpStackLocation(Irp);
+        status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
+        break;
+    }
 
     return status;
 }
 
+__drv_functionClass(IO_COMPLETION_ROUTINE)
+__drv_sameIRQL
 static NTSTATUS
-FdoSetSystemPowerDown(
-    IN  PXENFILT_FDO     Fdo,
-    IN  PIRP            Irp
+FdoSetSystemPowerUpComplete(
+    IN  PDEVICE_OBJECT  DeviceObject,
+    IN  PIRP            Irp,
+    IN  PVOID           Context
     )
 {
+    PXENFILT_FDO        Fdo = (PXENFILT_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));
+    ASSERT3U(SystemState, <,  __FdoGetSystemPowerState(Fdo));
+
+    if (Irp->PendingReturned)
+        IoMarkIrpPending(Irp);
 
     Trace("%s: %s -> %s\n",
           __FdoGetName(Fdo),
@@ -1244,180 +1253,52 @@ FdoSetSystemPowerDown(
 
     __FdoSetSystemPowerState(Fdo, SystemState);
 
-    status = FdoForwardIrpSynchronously(Fdo, Irp);
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return status;
-}
-
-static NTSTATUS
-FdoSetSystemPower(
-    IN  PXENFILT_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:%s)\n",
-          __FdoGetName(Fdo),
-          SystemPowerStateName(SystemState), 
-          PowerActionName(PowerAction));
-
-    if (SystemState == __FdoGetSystemPowerState(Fdo)) {
-        status = FdoForwardIrpSynchronously(Fdo, Irp);
-        IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-        goto done;
-    }
-
-    status = (SystemState < __FdoGetSystemPowerState(Fdo)) ?
-             FdoSetSystemPowerUp(Fdo, Irp) :
-             FdoSetSystemPowerDown(Fdo, Irp);
-
-done:
-    Trace("%s: <==== (%s:%s)(%08x)\n",
-          __FdoGetName(Fdo),
-          SystemPowerStateName(SystemState), 
-          PowerActionName(PowerAction),
-          status);
-    return status;
-}
-
-static NTSTATUS
-FdoQueryDevicePowerUp(
-    IN  PXENFILT_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;
+    return STATUS_CONTINUE_COMPLETION;
 }
 
-static NTSTATUS
-FdoQueryDevicePowerDown(
-    IN  PXENFILT_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 NTSTATUS
-FdoQueryDevicePower(
+static FORCEINLINE NTSTATUS
+__FdoSetSystemPowerUp(
     IN  PXENFILT_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:%s)\n",
-          __FdoGetName(Fdo),
-          DevicePowerStateName(DeviceState), 
-          PowerActionName(PowerAction));
-
-    if (DeviceState == __FdoGetDevicePowerState(Fdo)) {
-        status = FdoForwardIrpSynchronously(Fdo, Irp);
-        IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-        goto done;
-    }
-
-    status = (DeviceState < __FdoGetDevicePowerState(Fdo)) ?
-             FdoQueryDevicePowerUp(Fdo, Irp) :
-             FdoQueryDevicePowerDown(Fdo, Irp);
-
-done:
-    Trace("%s: <==== (%s:%s)(%08x)\n",
-          __FdoGetName(Fdo),
-          DevicePowerStateName(DeviceState), 
-          PowerActionName(PowerAction),
-          status);
-    return status;
-}
-
-static NTSTATUS
-FdoQuerySystemPowerUp(
-    IN  PXENFILT_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;
+    IoCopyCurrentIrpStackLocationToNext(Irp);
+    IoSetCompletionRoutine(Irp,
+                           FdoSetSystemPowerUpComplete,
+                           Fdo,
+                           TRUE,
+                           TRUE,
+                           TRUE);
+    return IoCallDriver(Fdo->LowerDeviceObject, Irp);
 }
 
-static NTSTATUS
-FdoQuerySystemPowerDown(
+static FORCEINLINE NTSTATUS
+__FdoSetSystemPowerDown(
     IN  PXENFILT_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);
+    Trace("%s: %s -> %s\n",
+          __FdoGetName(Fdo),
+          SystemPowerStateName(__FdoGetSystemPowerState(Fdo)),
+          SystemPowerStateName(SystemState));
 
-    return status;
+    __FdoSetSystemPowerState(Fdo, SystemState);
+
+    IoSkipCurrentIrpStackLocation(Irp);
+    return IoCallDriver(Fdo->LowerDeviceObject, Irp);
 }
 
 static NTSTATUS
-FdoQuerySystemPower(
+FdoSetSystemPower(
     IN  PXENFILT_FDO    Fdo,
     IN  PIRP            Irp
     )
@@ -1437,15 +1318,15 @@ FdoQuerySystemPower(
           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)) ?
-             FdoQuerySystemPowerUp(Fdo, Irp) :
-             FdoQuerySystemPowerDown(Fdo, Irp);
+             __FdoSetSystemPowerUp(Fdo, Irp) :
+             __FdoSetSystemPowerDown(Fdo, Irp);
 
 done:
     Trace("%s: <==== (%s:%s)(%08x)\n",
@@ -1453,126 +1334,34 @@ done:
           SystemPowerStateName(SystemState), 
           PowerActionName(PowerAction),
           status);
-
     return status;
 }
 
-static NTSTATUS
-FdoDevicePower(
-    IN  PXENFILT_THREAD Self,
-    IN  PVOID           Context
-    )
-{
-    PXENFILT_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  PXENFILT_THREAD Self,
-    IN  PVOID           Context
+static FORCEINLINE NTSTATUS
+__FdoDispatchSystemPower(
+    IN  PXENFILT_FDO    Fdo,
+    IN  PIRP            Irp
     )
 {
-    PXENFILT_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;
+    PIO_STACK_LOCATION  StackLocation;
+    UCHAR               MinorFunction;
+    NTSTATUS            status;
 
-        case IRP_MN_QUERY_POWER:
-            (VOID) FdoQuerySystemPower(Fdo, Irp);
-            break;
+    StackLocation = IoGetCurrentIrpStackLocation(Irp);
+    MinorFunction = StackLocation->MinorFunction;
 
-        default:
-            ASSERT(FALSE);
-            break;
-        }
+    switch (MinorFunction) {
+    case IRP_MN_SET_POWER:
+        status = FdoSetSystemPower(Fdo, Irp);
+        break;
 
-        IoReleaseRemoveLock(&Fdo->Dx->RemoveLock, Irp);
+    default:
+        IoSkipCurrentIrpStackLocation(Irp);
+        status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
+        break;
     }
 
-    return STATUS_SUCCESS;
+    return status;
 }
 
 static NTSTATUS
@@ -1593,8 +1382,7 @@ FdoDispatchPower(
     StackLocation = IoGetCurrentIrpStackLocation(Irp);
     MinorFunction = StackLocation->MinorFunction;
 
-    if (MinorFunction != IRP_MN_QUERY_POWER &&
-        MinorFunction != IRP_MN_SET_POWER) {
+    if (MinorFunction != IRP_MN_SET_POWER) {
         IoSkipCurrentIrpStackLocation(Irp);
 
         status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
@@ -1612,27 +1400,13 @@ FdoDispatchPower(
 
     switch (PowerType) {
     case DevicePowerState:
-        IoMarkIrpPending(Irp);
-
-        ASSERT3P(Fdo->DevicePowerIrp, ==, NULL);
-        Fdo->DevicePowerIrp = Irp;
-        KeMemoryBarrier();
-
-        ThreadWake(Fdo->DevicePowerThread);
-
-        status = STATUS_PENDING;
+        status = __FdoDispatchDevicePower(Fdo, Irp);
+        IoReleaseRemoveLock(&Fdo->Dx->RemoveLock, Irp);
         break;
 
     case SystemPowerState:
-        IoMarkIrpPending(Irp);
-
-        ASSERT3P(Fdo->SystemPowerIrp, ==, NULL);
-        Fdo->SystemPowerIrp = Irp;
-        KeMemoryBarrier();
-
-        ThreadWake(Fdo->SystemPowerThread);
-
-        status = STATUS_PENDING;
+        status = __FdoDispatchSystemPower(Fdo, Irp);
+        IoReleaseRemoveLock(&Fdo->Dx->RemoveLock, Irp);
         break;
 
     default:
@@ -1776,21 +1550,13 @@ FdoCreate(
     Fdo->LowerDeviceObject = LowerDeviceObject;
     Fdo->Type = Type;
 
-    status = ThreadCreate(FdoSystemPower, Fdo, &Fdo->SystemPowerThread);
-    if (!NT_SUCCESS(status))
-        goto fail4;
-
-    status = ThreadCreate(FdoDevicePower, Fdo, &Fdo->DevicePowerThread);
-    if (!NT_SUCCESS(status))
-        goto fail5;
-
     status = __FdoSetDeviceID(Fdo);
     if (!NT_SUCCESS(status))
-        goto fail6;
+        goto fail4;
 
     status = __FdoSetInstanceID(Fdo);
     if (!NT_SUCCESS(status))
-        goto fail7;
+        goto fail5;
 
     __FdoSetName(Fdo);
 
@@ -1815,24 +1581,10 @@ FdoCreate(
 
     return STATUS_SUCCESS;
 
-fail7:
-    Error("fail7\n");
-
-    __FdoClearDeviceID(Fdo);
-
-fail6:
-    Error("fail6\n");
-
-    ThreadAlert(Fdo->DevicePowerThread);
-    ThreadJoin(Fdo->DevicePowerThread);
-    Fdo->DevicePowerThread = NULL;
-
 fail5:
     Error("fail5\n");
 
-    ThreadAlert(Fdo->SystemPowerThread);
-    ThreadJoin(Fdo->SystemPowerThread);
-    Fdo->SystemPowerThread = NULL;
+    __FdoClearDeviceID(Fdo);
 
 fail4:
     Error("fail4\n");
@@ -1892,14 +1644,6 @@ FdoDestroy(
     __FdoClearInstanceID(Fdo);
     __FdoClearDeviceID(Fdo);
 
-    ThreadAlert(Fdo->DevicePowerThread);
-    ThreadJoin(Fdo->DevicePowerThread);
-    Fdo->DevicePowerThread = NULL;
-
-    ThreadAlert(Fdo->SystemPowerThread);
-    ThreadJoin(Fdo->SystemPowerThread);
-    Fdo->SystemPowerThread = NULL;
-
     Fdo->Type = XENFILT_EMULATED_OBJECT_TYPE_UNKNOWN;
     Fdo->LowerDeviceObject = NULL;
     Fdo->PhysicalDeviceObject = NULL;
diff --git a/src/xenfilt/pdo.c b/src/xenfilt/pdo.c
index be84996..3ce30a8 100644
--- a/src/xenfilt/pdo.c
+++ b/src/xenfilt/pdo.c
@@ -57,11 +57,6 @@ struct _XENFILT_PDO {
     PDEVICE_OBJECT                  PhysicalDeviceObject;
     CHAR                            Name[MAXNAMELEN];
 
-    PXENFILT_THREAD                 SystemPowerThread;
-    PIRP                            SystemPowerIrp;
-    PXENFILT_THREAD                 DevicePowerThread;
-    PIRP                            DevicePowerIrp;
-
     PXENFILT_FDO                    Fdo;
     BOOLEAN                         Missing;
     const CHAR                      *Reason;
@@ -1187,77 +1182,86 @@ fail1:
     return status;
 }
 
+__drv_functionClass(IO_COMPLETION_ROUTINE)
+__drv_sameIRQL
 static NTSTATUS
-PdoSetDevicePowerUp(
-    IN  PXENFILT_PDO    Pdo,
-    IN  PIRP            Irp
+PdoSetDevicePowerUpComplete(
+    IN  PDEVICE_OBJECT  DeviceObject,
+    IN  PIRP            Irp,
+    IN  PVOID           Context
     )
 {
+    PXENFILT_PDO        Pdo = (PXENFILT_PDO)Context;
     PIO_STACK_LOCATION  StackLocation;
-    DEVICE_POWER_STATE  DeviceState;
     POWER_STATE         PowerState;
-    NTSTATUS            status;
+
+    UNREFERENCED_PARAMETER(DeviceObject);
 
     StackLocation = IoGetCurrentIrpStackLocation(Irp);
-    DeviceState = StackLocation->Parameters.Power.State.DeviceState;
+    PowerState = StackLocation->Parameters.Power.State;
 
-    ASSERT3U(DeviceState, <,  __PdoGetDevicePowerState(Pdo));
+    ASSERT3U(PowerState.DeviceState, <,  __PdoGetDevicePowerState(Pdo));
 
-    status = PdoForwardIrpSynchronously(Pdo, Irp);
-    if (!NT_SUCCESS(status))
-        goto done;
+    if (Irp->PendingReturned)
+        IoMarkIrpPending(Irp);
 
     Trace("%s: %s -> %s\n",
           __PdoGetName(Pdo),
           DevicePowerStateName(__PdoGetDevicePowerState(Pdo)),
-          DevicePowerStateName(DeviceState));
+          DevicePowerStateName(PowerState.DeviceState));
 
-    PowerState.DeviceState = DeviceState;
     PoSetPowerState(__PdoGetDeviceObject(Pdo),
                     DevicePowerState,
                     PowerState);
 
-    __PdoSetDevicePowerState(Pdo, DeviceState);
+    __PdoSetDevicePowerState(Pdo, PowerState.DeviceState);
 
-done:
-    Irp->IoStatus.Status = status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    return STATUS_CONTINUE_COMPLETION;
+}
 
-    return status;
+static FORCEINLINE NTSTATUS
+__PdoSetDevicePowerUp(
+    IN  PXENFILT_PDO    Pdo,
+    IN  PIRP            Irp
+    )
+{
+    IoCopyCurrentIrpStackLocationToNext(Irp);
+    IoSetCompletionRoutine(Irp,
+                           PdoSetDevicePowerUpComplete,
+                           Pdo,
+                           TRUE,
+                           TRUE,
+                           TRUE);
+    return IoCallDriver(Pdo->LowerDeviceObject, Irp);
 }
 
 static NTSTATUS
-PdoSetDevicePowerDown(
+__PdoSetDevicePowerDown(
     IN  PXENFILT_PDO    Pdo,
     IN  PIRP            Irp
     )
 {
     PIO_STACK_LOCATION  StackLocation;
-    DEVICE_POWER_STATE  DeviceState;
     POWER_STATE         PowerState;
-    NTSTATUS            status;
 
     StackLocation = IoGetCurrentIrpStackLocation(Irp);
-    DeviceState = StackLocation->Parameters.Power.State.DeviceState;
+    PowerState = StackLocation->Parameters.Power.State;
 
-    ASSERT3U(DeviceState, >,  __PdoGetDevicePowerState(Pdo));
+    ASSERT3U(PowerState.DeviceState, >,  __PdoGetDevicePowerState(Pdo));
 
     Trace("%s: %s -> %s\n",
           __PdoGetName(Pdo),
           DevicePowerStateName(__PdoGetDevicePowerState(Pdo)),
-          DevicePowerStateName(DeviceState));
+          DevicePowerStateName(PowerState.DeviceState));
 
-    PowerState.DeviceState = DeviceState;
     PoSetPowerState(__PdoGetDeviceObject(Pdo),
                     DevicePowerState,
                     PowerState);
 
-    __PdoSetDevicePowerState(Pdo, DeviceState);
+    __PdoSetDevicePowerState(Pdo, PowerState.DeviceState);
 
-    status = PdoForwardIrpSynchronously(Pdo, Irp);
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return status;
+    IoSkipCurrentIrpStackLocation(Irp);
+    return IoCallDriver(Pdo->LowerDeviceObject, Irp);
 }
 
 static NTSTATUS
@@ -1281,15 +1285,15 @@ 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)) ?
-             PdoSetDevicePowerUp(Pdo, Irp) :
-             PdoSetDevicePowerDown(Pdo, Irp);
+             __PdoSetDevicePowerUp(Pdo, Irp) :
+             __PdoSetDevicePowerDown(Pdo, Irp);
 
 done:
     Trace("%s: <==== (%s:%s)(%08x)\n",
@@ -1300,53 +1304,55 @@ done:
     return status;
 }
 
-static NTSTATUS
-PdoSetSystemPowerUp(
+static FORCEINLINE NTSTATUS
+__PdoDispatchDevicePower(
     IN  PXENFILT_PDO    Pdo,
     IN  PIRP            Irp
     )
 {
     PIO_STACK_LOCATION  StackLocation;
-    SYSTEM_POWER_STATE  SystemState;
+    UCHAR               MinorFunction;
     NTSTATUS            status;
 
     StackLocation = IoGetCurrentIrpStackLocation(Irp);
-    SystemState = StackLocation->Parameters.Power.State.SystemState;
-
-    ASSERT3U(SystemState, <,  __PdoGetSystemPowerState(Pdo));
-
-    status = PdoForwardIrpSynchronously(Pdo, Irp);
-    if (!NT_SUCCESS(status))
-        goto done;
-
-    Trace("%s: %s -> %s\n",
-          __PdoGetName(Pdo),
-          SystemPowerStateName(__PdoGetSystemPowerState(Pdo)),
-          SystemPowerStateName(SystemState));
+    MinorFunction = StackLocation->MinorFunction;
 
-    __PdoSetSystemPowerState(Pdo, SystemState);
+    switch (MinorFunction) {
+    case IRP_MN_SET_POWER:
+        status = PdoSetDevicePower(Pdo, Irp);
+        break;
 
-done:
-    Irp->IoStatus.Status = status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    default:
+        IoSkipCurrentIrpStackLocation(Irp);
+        status = IoCallDriver(Pdo->LowerDeviceObject, Irp);
+        break;
+    }
 
     return status;
 }
 
+__drv_functionClass(IO_COMPLETION_ROUTINE)
+__drv_sameIRQL
 static NTSTATUS
-PdoSetSystemPowerDown(
-    IN  PXENFILT_PDO     Pdo,
-    IN  PIRP            Irp
+PdoSetSystemPowerUpComplete(
+    IN  PDEVICE_OBJECT  DeviceObject,
+    IN  PIRP            Irp,
+    IN  PVOID           Context
     )
 {
+    PXENFILT_PDO        Pdo = (PXENFILT_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));
+    ASSERT3U(SystemState, <,  __PdoGetSystemPowerState(Pdo));
+
+    if (Irp->PendingReturned)
+        IoMarkIrpPending(Irp);
 
     Trace("%s: %s -> %s\n",
           __PdoGetName(Pdo),
@@ -1355,182 +1361,52 @@ PdoSetSystemPowerDown(
 
     __PdoSetSystemPowerState(Pdo, SystemState);
 
-    status = PdoForwardIrpSynchronously(Pdo, Irp);
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return status;
-}
-
-static NTSTATUS
-PdoSetSystemPower(
-    IN  PXENFILT_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:%s)\n",
-          __PdoGetName(Pdo),
-          SystemPowerStateName(SystemState), 
-          PowerActionName(PowerAction));
-
-    if (SystemState == __PdoGetSystemPowerState(Pdo)) {
-        status = PdoForwardIrpSynchronously(Pdo, Irp);
-        IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-        goto done;
-    }
-
-    status = (SystemState < __PdoGetSystemPowerState(Pdo)) ?
-             PdoSetSystemPowerUp(Pdo, Irp) :
-             PdoSetSystemPowerDown(Pdo, Irp);
-
-done:
-    Trace("%s: <==== (%s:%s)(%08x)\n",
-          __PdoGetName(Pdo),
-          SystemPowerStateName(SystemState), 
-          PowerActionName(PowerAction),
-          status);
-    return status;
-}
-
-static NTSTATUS
-PdoQueryDevicePowerUp(
-    IN  PXENFILT_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 NTSTATUS
-PdoQueryDevicePowerDown(
-    IN  PXENFILT_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;
+    return STATUS_CONTINUE_COMPLETION;
 }
 
-static NTSTATUS
-PdoQueryDevicePower(
+static FORCEINLINE NTSTATUS
+__PdoSetSystemPowerUp(
     IN  PXENFILT_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:%s)\n",
-          __PdoGetName(Pdo),
-          DevicePowerStateName(DeviceState), 
-          PowerActionName(PowerAction));
-
-    if (DeviceState == __PdoGetDevicePowerState(Pdo)) {
-        status = PdoForwardIrpSynchronously(Pdo, Irp);
-        IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-        goto done;
-    }
-
-    status = (DeviceState < __PdoGetDevicePowerState(Pdo)) ?
-             PdoQueryDevicePowerUp(Pdo, Irp) :
-             PdoQueryDevicePowerDown(Pdo, Irp);
-
-done:
-    Trace("%s: <==== (%s:%s)(%08x)\n",
-          __PdoGetName(Pdo),
-          DevicePowerStateName(DeviceState), 
-          PowerActionName(PowerAction),
-          status);
-    return status;
-}
-
-static NTSTATUS
-PdoQuerySystemPowerUp(
-    IN  PXENFILT_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;
+    IoCopyCurrentIrpStackLocationToNext(Irp);
+    IoSetCompletionRoutine(Irp,
+                           PdoSetSystemPowerUpComplete,
+                           Pdo,
+                           TRUE,
+                           TRUE,
+                           TRUE);
+    return IoCallDriver(Pdo->LowerDeviceObject, Irp);
 }
 
-static NTSTATUS
-PdoQuerySystemPowerDown(
+static FORCEINLINE NTSTATUS
+__PdoSetSystemPowerDown(
     IN  PXENFILT_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);
+    Trace("%s: %s -> %s\n",
+          __PdoGetName(Pdo),
+          SystemPowerStateName(__PdoGetSystemPowerState(Pdo)),
+          SystemPowerStateName(SystemState));
 
-    return status;
+    __PdoSetSystemPowerState(Pdo, SystemState);
+
+    IoSkipCurrentIrpStackLocation(Irp);
+    return IoCallDriver(Pdo->LowerDeviceObject, Irp);
 }
 
 static NTSTATUS
-PdoQuerySystemPower(
+PdoSetSystemPower(
     IN  PXENFILT_PDO    Pdo,
     IN  PIRP            Irp
     )
@@ -1550,15 +1426,15 @@ PdoQuerySystemPower(
           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)) ?
-             PdoQuerySystemPowerUp(Pdo, Irp) :
-             PdoQuerySystemPowerDown(Pdo, Irp);
+             __PdoSetSystemPowerUp(Pdo, Irp) :
+             __PdoSetSystemPowerDown(Pdo, Irp);
 
 done:
     Trace("%s: <==== (%s:%s)(%08x)\n",
@@ -1566,126 +1442,34 @@ done:
           SystemPowerStateName(SystemState), 
           PowerActionName(PowerAction),
           status);
-
     return status;
 }
 
-static NTSTATUS
-PdoDevicePower(
-    IN  PXENFILT_THREAD Self,
-    IN  PVOID           Context
-    )
-{
-    PXENFILT_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  PXENFILT_THREAD Self,
-    IN  PVOID           Context
+static FORCEINLINE NTSTATUS
+__PdoDispatchSystemPower(
+    IN  PXENFILT_PDO    Pdo,
+    IN  PIRP            Irp
     )
 {
-    PXENFILT_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;
+    PIO_STACK_LOCATION  StackLocation;
+    UCHAR               MinorFunction;
+    NTSTATUS            status;
 
-        case IRP_MN_QUERY_POWER:
-            (VOID) PdoQuerySystemPower(Pdo, Irp);
-            break;
+    StackLocation = IoGetCurrentIrpStackLocation(Irp);
+    MinorFunction = StackLocation->MinorFunction;
 
-        default:
-            ASSERT(FALSE);
-            break;
-        }
+    switch (MinorFunction) {
+    case IRP_MN_SET_POWER:
+        status = PdoSetSystemPower(Pdo, Irp);
+        break;
 
-        IoReleaseRemoveLock(&Pdo->Dx->RemoveLock, Irp);
+    default:
+        IoSkipCurrentIrpStackLocation(Irp);
+        status = IoCallDriver(Pdo->LowerDeviceObject, Irp);
+        break;
     }
 
-    return STATUS_SUCCESS;
+    return status;
 }
 
 static NTSTATUS
@@ -1706,8 +1490,7 @@ PdoDispatchPower(
     StackLocation = IoGetCurrentIrpStackLocation(Irp);
     MinorFunction = StackLocation->MinorFunction;
 
-    if (MinorFunction != IRP_MN_QUERY_POWER &&
-        MinorFunction != IRP_MN_SET_POWER) {
+    if (MinorFunction != IRP_MN_SET_POWER) {
         IoSkipCurrentIrpStackLocation(Irp);
 
         status = IoCallDriver(Pdo->LowerDeviceObject, Irp);
@@ -1725,27 +1508,13 @@ PdoDispatchPower(
 
     switch (PowerType) {
     case DevicePowerState:
-        IoMarkIrpPending(Irp);
-
-        ASSERT3P(Pdo->DevicePowerIrp, ==, NULL);
-        Pdo->DevicePowerIrp = Irp;
-        KeMemoryBarrier();
-
-        ThreadWake(Pdo->DevicePowerThread);
-
-        status = STATUS_PENDING;
+        status = __PdoDispatchDevicePower(Pdo, Irp);
+        IoReleaseRemoveLock(&Pdo->Dx->RemoveLock, Irp);
         break;
 
     case SystemPowerState:
-        IoMarkIrpPending(Irp);
-
-        ASSERT3P(Pdo->SystemPowerIrp, ==, NULL);
-        Pdo->SystemPowerIrp = Irp;
-        KeMemoryBarrier();
-
-        ThreadWake(Pdo->SystemPowerThread);
-
-        status = STATUS_PENDING;
+        status = __PdoDispatchSystemPower(Pdo, Irp);
+        IoReleaseRemoveLock(&Pdo->Dx->RemoveLock, Irp);
         break;
 
     default:
@@ -1908,17 +1677,9 @@ PdoCreate(
     Pdo->LowerDeviceObject = LowerDeviceObject;
     Pdo->Type = Type;
 
-    status = ThreadCreate(PdoSystemPower, Pdo, &Pdo->SystemPowerThread);
-    if (!NT_SUCCESS(status))
-        goto fail4;
-
-    status = ThreadCreate(PdoDevicePower, Pdo, &Pdo->DevicePowerThread);
-    if (!NT_SUCCESS(status))
-        goto fail5;
-
     status = PdoSetDeviceInformation(Pdo);
     if (!NT_SUCCESS(status))
-        goto fail6;
+        goto fail4;
 
     status = DriverQueryId(Pdo->LowerDeviceObject,
                            BusQueryCompatibleIDs,
@@ -1933,7 +1694,7 @@ PdoCreate(
                                __PdoGetType(Pdo),
                                &Pdo->EmulatedObject);
     if (!NT_SUCCESS(status))
-        goto fail7;
+        goto fail5;
 
     if (CompatibleIDs)
         ExFreePool(CompatibleIDs);
@@ -1958,28 +1719,14 @@ PdoCreate(
 
     return STATUS_SUCCESS;
 
-fail7:
-    Error("fail7\n");
+fail5:
+    Error("fail5\n");
 
     if (CompatibleIDs)
         ExFreePool(CompatibleIDs);
 
     PdoClearDeviceInformation(Pdo);
 
-fail6:
-    Error("fail6\n");
-
-    ThreadAlert(Pdo->DevicePowerThread);
-    ThreadJoin(Pdo->DevicePowerThread);
-    Pdo->DevicePowerThread = NULL;
-
-fail5:
-    Error("fail5\n");
-
-    ThreadAlert(Pdo->SystemPowerThread);
-    ThreadJoin(Pdo->SystemPowerThread);
-    Pdo->SystemPowerThread = NULL;
-
 fail4:
     Error("fail4\n");
 
@@ -2041,14 +1788,6 @@ PdoDestroy(
 
     PdoClearDeviceInformation(Pdo);
 
-    ThreadAlert(Pdo->DevicePowerThread);
-    ThreadJoin(Pdo->DevicePowerThread);
-    Pdo->DevicePowerThread = NULL;
-
-    ThreadAlert(Pdo->SystemPowerThread);
-    ThreadJoin(Pdo->SystemPowerThread);
-    Pdo->SystemPowerThread = NULL;
-
     Pdo->Type = XENFILT_EMULATED_OBJECT_TYPE_UNKNOWN;
     Pdo->PhysicalDeviceObject = NULL;
     Pdo->LowerDeviceObject = 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®.