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

Re: [PATCH] Improve Xenfilt power and default IRP handling.


  • To: win-pv-devel@xxxxxxxxxxxxxxxxxxxx
  • From: "Durrant, Paul" <xadimgnik@xxxxxxxxx>
  • Date: Tue, 22 Mar 2022 14:43:50 +0100
  • Delivery-date: Tue, 22 Mar 2022 13:43:58 +0000
  • List-id: Developer list for the Windows PV Drivers subproject <win-pv-devel.lists.xenproject.org>

On 14/03/2022 18:01, Martin Harvey wrote:

This is a very large patch given absolutely no explanation. It really needs a *much* more comprehensive commit comment... even be broken down into multiple incremental patches, e.g. maybe doing FDO and PDO separately.

Signed-off-by: Martin Harvey <martin.harvey@xxxxxxxxxx>
---
  src/common/util.h |   8 +
  src/xenfilt/fdo.c | 785 ++++++++++++---------------------------------
  src/xenfilt/pdo.c | 790 ++++++++++++----------------------------------
  3 files changed, 411 insertions(+), 1172 deletions(-)

diff --git a/src/common/util.h b/src/common/util.h
index 36a36dd..fb9b9b7 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -36,6 +36,14 @@
#include "assert.h" +typedef enum _XEN_IRP_STRATEGY {
+    XEN_IRP_PASSDOWN_TRANSPARENT,
+    XEN_IRP_HANDLE_INDISPATCH_AND_COMPLETE,
+    XEN_IRP_HANDLE_INDISPATCH_PASSDOWN,
+    XEN_IRP_HANDLE_INCOMPLETION,

I'm not keen on these names. What is 'incompletion'? I.e. your use of '_' or lack thereof seems rather arbitrary.

+    XEN_IRP_STRATEGY_MAX
+} XEN_IRP_STRATEGY, *PXEN_IRP_STRATEGY;
+
  #define       P2ROUNDUP(_x, _a)   \
          (-(-(_x) & -(_a)))
diff --git a/src/xenfilt/fdo.c b/src/xenfilt/fdo.c
index 63fa7b3..5d43d01 100644
--- a/src/xenfilt/fdo.c
+++ b/src/xenfilt/fdo.c
@@ -59,11 +59,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;
@@ -1004,6 +999,26 @@ fail1:
      return status;
  }
+static NTSTATUS
+FdoDispatchDefault(
+    IN  PXENFILT_FDO    Fdo,
+    IN  PIRP            Irp
+    )
+{
+    NTSTATUS status;
+    IoSkipCurrentIrpStackLocation(Irp);
+    status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
+    return status;
+
+fail1:
+    Error("fail1 (%08x)\n", status);
+    return status;
+}
+
+
  static NTSTATUS
  FdoDispatchPnp(
      IN  PXENFILT_FDO    Fdo,
@@ -1055,524 +1070,135 @@ FdoDispatchPnp(
          break;
default:
-        status = IoAcquireRemoveLock(&Fdo->Dx->RemoveLock, Irp);
-        if (!NT_SUCCESS(status))
-            goto fail1;
-
-        IoSkipCurrentIrpStackLocation(Irp);
-
-        status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
-        IoReleaseRemoveLock(&Fdo->Dx->RemoveLock, Irp);
+        status = FdoDispatchDefault(Fdo, Irp);
          break;
      }
- return status;
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    Irp->IoStatus.Status = status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return status;
-}
-
-static NTSTATUS
-FdoSetDevicePowerUp(
-    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;
-
-    ASSERT3U(DeviceState, <,  __FdoGetDevicePowerState(Fdo));
-
-    status = FdoForwardIrpSynchronously(Fdo, Irp);
-    if (!NT_SUCCESS(status))
-        goto done;
-
-    Trace("%s: %s -> %s\n",
-          __FdoGetName(Fdo),
-          DevicePowerStateName(__FdoGetDevicePowerState(Fdo)),
-          DevicePowerStateName(DeviceState));
-
-    PowerState.DeviceState = DeviceState;
-    PoSetPowerState(Fdo->Dx->DeviceObject,
-                    DevicePowerState,
-                    PowerState);
-
-    __FdoSetDevicePowerState(Fdo, DeviceState);
-
-done:
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return status;
-}
-
-static NTSTATUS
-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;
-
-    ASSERT3U(DeviceState, >,  __FdoGetDevicePowerState(Fdo));
-
-    Trace("%s: %s -> %s\n",
-          __FdoGetName(Fdo),
-          DevicePowerStateName(__FdoGetDevicePowerState(Fdo)),
-          DevicePowerStateName(DeviceState));
-
-    PowerState.DeviceState = DeviceState;
-    PoSetPowerState(Fdo->Dx->DeviceObject,
-                    DevicePowerState,
-                    PowerState);
-
-    __FdoSetDevicePowerState(Fdo, DeviceState);
-
-    status = FdoForwardIrpSynchronously(Fdo, Irp);
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return status;
-}
-
-static NTSTATUS
-FdoSetDevicePower(
-    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)) ?
-             FdoSetDevicePowerUp(Fdo, Irp) :
-             FdoSetDevicePowerDown(Fdo, Irp);
-
-done:
-    Trace("%s: <==== (%s:%s)(%08x)\n",
-          __FdoGetName(Fdo),
-          DevicePowerStateName(DeviceState),
-          PowerActionName(PowerAction),
-          status);
-    return status;
-}
-
-static NTSTATUS
-FdoSetSystemPowerUp(
-    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);
-    if (!NT_SUCCESS(status))
-        goto done;
-
-    Trace("%s: %s -> %s\n",
-          __FdoGetName(Fdo),
-          SystemPowerStateName(__FdoGetSystemPowerState(Fdo)),
-          SystemPowerStateName(SystemState));
-
-    __FdoSetSystemPowerState(Fdo, SystemState);
-
-done:
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return status;
-}
-
-static 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));
-
-    Trace("%s: %s -> %s\n",
-          __FdoGetName(Fdo),
-          SystemPowerStateName(__FdoGetSystemPowerState(Fdo)),
-          SystemPowerStateName(SystemState));
-
-    __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;
  }
static NTSTATUS
-FdoQueryDevicePowerDown(
+FdoDispatchPowerImmediate(

Is there a non-immediate variant? I can't see it.

      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;
+    NTSTATUS status = STATUS_INTERNAL_ERROR;
+    PIO_STACK_LOCATION StackLocation = IoGetCurrentIrpStackLocation(Irp);
+    UCHAR MinorFunction = StackLocation->MinorFunction;
- ASSERT3U(DeviceState, >, __FdoGetDevicePowerState(Fdo));
-
-    status = FdoForwardIrpSynchronously(Fdo, Irp);
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return status;
-}
-
-static NTSTATUS
-FdoQueryDevicePower(
-    IN  PXENFILT_FDO    Fdo,
-    IN  PIRP            Irp
-    )
-{
-    PIO_STACK_LOCATION  StackLocation;
-    DEVICE_POWER_STATE  DeviceState;
-    POWER_ACTION        PowerAction;
-    NTSTATUS            status;
+    if (MinorFunction != IRP_MN_SET_POWER)
+        goto fail1;
- StackLocation = IoGetCurrentIrpStackLocation(Irp);
-    DeviceState = StackLocation->Parameters.Power.State.DeviceState;
-    PowerAction = StackLocation->Parameters.Power.ShutdownType;
+    POWER_STATE_TYPE PowerType = StackLocation->Parameters.Power.Type;
- Trace("%s: ====> (%s:%s)\n",
-          __FdoGetName(Fdo),
-          DevicePowerStateName(DeviceState),
-          PowerActionName(PowerAction));
+    switch (PowerType) {
+    case DevicePowerState:
+        POWER_STATE PowerState;
+        DEVICE_POWER_STATE DeviceState = 
StackLocation->Parameters.Power.State.DeviceState;
+        if (DeviceState >= __FdoGetDevicePowerState(Fdo))
+            goto fail3;
- if (DeviceState == __FdoGetDevicePowerState(Fdo)) {
-        status = FdoForwardIrpSynchronously(Fdo, Irp);
-        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        __FdoSetDevicePowerState(Fdo, DeviceState);
+        PowerState.DeviceState = DeviceState;
+        PoSetPowerState(__FdoGetDeviceObject(Fdo),
+                        DevicePowerState,
+                        PowerState);
+    break;
+    case SystemPowerState:
+        SYSTEM_POWER_STATE SystemState = 
StackLocation->Parameters.Power.State.SystemState;
+        if (SystemState >= __FdoGetSystemPowerState(Fdo))
+            goto fail3;
- goto done;
+        __FdoSetSystemPowerState(Fdo, SystemState);
+    break;
+    default:
+        goto fail2;
      }
- 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_SUCCESS;
+fail3:
+    Error("fail3 (%08x)\n", status);

We don't need to spit status out at every fail level.

+fail2:
+    Error("fail2 (%08x)\n", status);
+fail1:
+    Error("fail1 (%08x)\n", status);
      return status;
  }
-static NTSTATUS
-FdoQuerySystemPowerDown(
+static VOID
+FdoCompletionPower(
      IN  PXENFILT_FDO    Fdo,
      IN  PIRP            Irp
-    )
+)
  {
-    PIO_STACK_LOCATION  StackLocation;
-    SYSTEM_POWER_STATE  SystemState;
-    NTSTATUS            status;
+    PIO_STACK_LOCATION StackLocation = IoGetCurrentIrpStackLocation(Irp);
+    UCHAR MinorFunction = StackLocation->MinorFunction;
- StackLocation = IoGetCurrentIrpStackLocation(Irp);
-    SystemState = StackLocation->Parameters.Power.State.SystemState;
-
-    ASSERT3U(SystemState, >,  __FdoGetSystemPowerState(Fdo));
-
-    status = FdoForwardIrpSynchronously(Fdo, Irp);
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return status;
-}
+    if (MinorFunction != IRP_MN_SET_POWER)
+        goto fail1;
-static NTSTATUS
-FdoQuerySystemPower(
-    IN  PXENFILT_FDO    Fdo,
-    IN  PIRP            Irp
-    )
-{
-    PIO_STACK_LOCATION  StackLocation;
-    SYSTEM_POWER_STATE  SystemState;
-    POWER_ACTION        PowerAction;
-    NTSTATUS            status;
+    POWER_STATE_TYPE PowerType = StackLocation->Parameters.Power.Type;
- StackLocation = IoGetCurrentIrpStackLocation(Irp);
-    SystemState = StackLocation->Parameters.Power.State.SystemState;
-    PowerAction = StackLocation->Parameters.Power.ShutdownType;
+    switch (PowerType) {
+    case DevicePowerState:
+        POWER_STATE PowerState;
+        DEVICE_POWER_STATE DeviceState = 
StackLocation->Parameters.Power.State.DeviceState;
+        if (DeviceState <= __FdoGetDevicePowerState(Fdo))
+            goto fail3;
- Trace("%s: ====> (%s:%s)\n",
-          __FdoGetName(Fdo),
-          SystemPowerStateName(SystemState),
-          PowerActionName(PowerAction));
+        PowerState.DeviceState = DeviceState;
+        PoSetPowerState(__FdoGetDeviceObject(Fdo),
+                        DevicePowerState,
+                        PowerState);
+        __FdoSetDevicePowerState(Fdo, DeviceState);
- if (SystemState == __FdoGetSystemPowerState(Fdo)) {
-        status = FdoForwardIrpSynchronously(Fdo, Irp);
-        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    break;
+    case SystemPowerState:
+        SYSTEM_POWER_STATE SystemState = 
StackLocation->Parameters.Power.State.SystemState;
+        if (SystemState <= __FdoGetSystemPowerState(Fdo))
+            goto fail3;
- goto done;
+        __FdoSetSystemPowerState(Fdo, SystemState);
+    break;
+    default:
+        goto fail2;
      }
- status = (SystemState < __FdoGetSystemPowerState(Fdo)) ?
-             FdoQuerySystemPowerUp(Fdo, Irp) :
-             FdoQuerySystemPowerDown(Fdo, Irp);
-
-done:
-    Trace("%s: <==== (%s:%s)(%08x)\n",
-          __FdoGetName(Fdo),
-          SystemPowerStateName(SystemState),
-          PowerActionName(PowerAction),
-          status);
+    return;
- return status;
+fail3:
+    Error("fail3\n");
+fail2:
+    Error("fail2\n");
+fail1:
+    Error("fail1");
  }
+__drv_functionClass(IO_COMPLETION_ROUTINE)
+__drv_sameIRQL
  static NTSTATUS
-FdoDevicePower(
-    IN  PXENFILT_THREAD Self,
+FdoDispatchPowerCompletionV2(

Ick. 'V2'? Really? What is V2 about it?

+    IN  PDEVICE_OBJECT  DeviceObject,
+    IN  PIRP            Irp,
      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;
+    UNREFERENCED_PARAMETER(DeviceObject);
- default:
-            ASSERT(FALSE);
-            break;
-        }
+    if (Irp->PendingReturned)
+        IoMarkIrpPending(Irp);
- IoReleaseRemoveLock(&Fdo->Dx->RemoveLock, Irp);
-    }
+    //Assumption don't need STATUS_MORE_PROCESSING_REQUIRED.
+    FdoCompletionPower(Fdo, Irp);
+ IoReleaseRemoveLock(&Fdo->Dx->RemoveLock, Irp);
      return STATUS_SUCCESS;
  }
-static NTSTATUS
-FdoSystemPower(
-    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->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;
-}
static NTSTATUS
  FdoDispatchPower(
@@ -1582,104 +1208,125 @@ 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;
+    XEN_IRP_STRATEGY    strategy;
+    BOOLEAN HaveRemoveLock = FALSE;
StackLocation = IoGetCurrentIrpStackLocation(Irp);
      MinorFunction = StackLocation->MinorFunction;
- if (MinorFunction != IRP_MN_QUERY_POWER &&
-        MinorFunction != IRP_MN_SET_POWER) {
-        IoSkipCurrentIrpStackLocation(Irp);
-
-        status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
-        IoReleaseRemoveLock(&Fdo->Dx->RemoveLock, Irp);
-
-        goto done;
-    }
-
-    PowerType = StackLocation->Parameters.Power.Type;
-
-    Trace("%s: ====> (%02x:%s)\n",
-          __FdoGetName(Fdo),
-          MinorFunction,
-          PowerMinorFunctionName(MinorFunction));
-
-    switch (PowerType) {
-    case DevicePowerState:
-        IoMarkIrpPending(Irp);
-
-        ASSERT3P(Fdo->DevicePowerIrp, ==, NULL);
-        Fdo->DevicePowerIrp = Irp;
-        KeMemoryBarrier();
-
-        ThreadWake(Fdo->DevicePowerThread);
-
-        status = STATUS_PENDING;
+    //Decide how we're going to handle this IRP.
+    switch(MinorFunction) {
+    case IRP_MN_QUERY_POWER:
+        strategy = XEN_IRP_PASSDOWN_TRANSPARENT; //Dont fail, don't need to 
check queries.
          break;
-
-    case SystemPowerState:
-        IoMarkIrpPending(Irp);
-
-        ASSERT3P(Fdo->SystemPowerIrp, ==, NULL);
-        Fdo->SystemPowerIrp = Irp;
-        KeMemoryBarrier();
-
-        ThreadWake(Fdo->SystemPowerThread);
-
-        status = STATUS_PENDING;
+    case IRP_MN_SET_POWER:
+        POWER_STATE_TYPE PowerType = StackLocation->Parameters.Power.Type;
+
+        switch (PowerType) {
+        case DevicePowerState:
+            DEVICE_POWER_STATE DeviceState = 
StackLocation->Parameters.Power.State.DeviceState;
+
+            status = IoAcquireRemoveLock(&Fdo->Dx->RemoveLock, Irp);
+            if (!NT_SUCCESS(status))
+                goto fail1;
+
+            //If fails, then pending removal or already removed,
+            //freshly initialized (or not). Consider status to return...

Can we have more complete english in comments so they are clear? Also a space after the '//' please.

+            HaveRemoveLock = TRUE;
+
+            if (DeviceState == __FdoGetDevicePowerState(Fdo)) {
+                strategy = XEN_IRP_PASSDOWN_TRANSPARENT;

No need for braces in this sequence (and similar elsewhere).

+            } else if (DeviceState < __FdoGetDevicePowerState(Fdo)) {
+                strategy = XEN_IRP_HANDLE_INDISPATCH_PASSDOWN;
+            } else {
+                strategy = XEN_IRP_HANDLE_INCOMPLETION;
+            }
+        case SystemPowerState:
+            SYSTEM_POWER_STATE SystemState = 
StackLocation->Parameters.Power.State.SystemState;
+
+            status = IoAcquireRemoveLock(&Fdo->Dx->RemoveLock, Irp);
+            if (!NT_SUCCESS(status))
+                goto fail1;
+
+            //If fails, then pending removal or already removed,
+            //freshly initialized (or not). Consider status to return...
+            HaveRemoveLock = TRUE;
+
+            if (SystemState == __FdoGetSystemPowerState(Fdo)) {
+                strategy = XEN_IRP_PASSDOWN_TRANSPARENT;
+            } else if (SystemState < __FdoGetSystemPowerState(Fdo)) {
+                strategy = XEN_IRP_HANDLE_INDISPATCH_PASSDOWN;
+            } else {
+                strategy = XEN_IRP_HANDLE_INCOMPLETION;
+            }
          break;
-
+        default:
+            strategy = XEN_IRP_PASSDOWN_TRANSPARENT;
+            break;
+        }
      default:
-        IoSkipCurrentIrpStackLocation(Irp);
-
-        status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
-        IoReleaseRemoveLock(&Fdo->Dx->RemoveLock, Irp);
+        strategy = XEN_IRP_PASSDOWN_TRANSPARENT;
          break;
      }
- Trace("%s: <==== (%02x:%s) (%08x)\n",
-          __FdoGetName(Fdo),
-          MinorFunction,
-          PowerMinorFunctionName(MinorFunction),
-          status);
-
-done:
-    return status;
-
-fail1:
-    Error("fail1 (%08x)\n", status);
+    switch(strategy) {
+        case XEN_IRP_HANDLE_INDISPATCH_PASSDOWN:
+            status = FdoDispatchPowerImmediate(Fdo, Irp);
+            if (!NT_SUCCESS(status))
+                goto fail2;
+            //Fallthru.

Is that a valid annotation format?

+        case XEN_IRP_PASSDOWN_TRANSPARENT:
+        default:
+            IoSkipCurrentIrpStackLocation(Irp);
+            status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
+            if (!NT_SUCCESS(status))
+                goto fail3;
- Irp->IoStatus.Status = status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+            if (HaveRemoveLock)
+                IoReleaseRemoveLock(&Fdo->Dx->RemoveLock, Irp);
+        break;
+        case XEN_IRP_HANDLE_INCOMPLETION:
+            IoMarkIrpPending(Irp);
+            IoCopyCurrentIrpStackLocationToNext(Irp);
+            IoSetCompletionRoutine(Irp,
+                                FdoDispatchPowerCompletionV2,
+                                Fdo,
+                                TRUE,
+                                TRUE,
+                                TRUE);
+            status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
+            if (!NT_SUCCESS(status))
+                goto fail4;
+            status = STATUS_PENDING; //Must return STATUS_PENDING after 
IoMarkIrpPending, whatever happens next.
+        break;
+    }
return status;
-}
-
-static NTSTATUS
-FdoDispatchDefault(
-    IN  PXENFILT_FDO    Fdo,
-    IN  PIRP            Irp
-    )
-{
-    NTSTATUS            status;
-
-    status = IoAcquireRemoveLock(&Fdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
- IoSkipCurrentIrpStackLocation(Irp);
-
-    status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
-    IoReleaseRemoveLock(&Fdo->Dx->RemoveLock, Irp);
+fail4:
+    //Error from lower driver, have remove lock, and completion routine.
+    //Comp routine shd be called on error to drop remove lock.
+    Error("fail4 (%08x)\n", status);
+    status = STATUS_PENDING; //Must return STATUS_PENDING after 
IoMarkIrpPending, whatever happens next.
+    return status;

The whole point of fail labels is that they undo things in sequence and *only* fail1 returns.

+fail3:
+    //Error from lower driver, have remove lock, called down.
+    Error("fail3 (%08x)\n", status);
+    if (HaveRemoveLock)
+        IoReleaseRemoveLock(&Fdo->Dx->RemoveLock, Irp);
      return status;
+fail2:
+    //Immediate error, have remove lock, not called down.
+    Error("fail2 (%08x)\n", status);
+    if (HaveRemoveLock)
+        IoReleaseRemoveLock(&Fdo->Dx->RemoveLock, Irp);
+    //Fallthru.
+
  fail1:
+    //Immediate error, no remove lock, not called down.
      Error("fail1 (%08x)\n", status);
Irp->IoStatus.Status = status;
@@ -1775,14 +1422,6 @@ 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;
@@ -1822,20 +1461,6 @@ fail7:
  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;
-
-fail4:
-    Error("fail4\n");
-
      Fdo->Type = XENFILT_EMULATED_OBJECT_TYPE_UNKNOWN;
      Fdo->PhysicalDeviceObject = NULL;
      Fdo->LowerDeviceObject = NULL;
@@ -1891,14 +1516,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 741c2f3..ee2a049 100644
--- a/src/xenfilt/pdo.c
+++ b/src/xenfilt/pdo.c
@@ -56,11 +56,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;
@@ -1101,6 +1096,26 @@ PdoEject(
      return status;
  }
+static NTSTATUS
+PdoDispatchDefault(
+    IN  PXENFILT_PDO    Pdo,
+    IN  PIRP            Irp
+    )
+{
+    NTSTATUS status;
+    IoSkipCurrentIrpStackLocation(Irp);
+    status = IoCallDriver(Pdo->LowerDeviceObject, Irp);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
+    return status;
+
+fail1:
+    Error("fail1 (%08x)\n", status);
+    return status;
+}
+
+
  static NTSTATUS
  PdoDispatchPnp(
      IN  PXENFILT_PDO    Pdo,
@@ -1164,528 +1179,136 @@ PdoDispatchPnp(
          break;
default:
-        status = IoAcquireRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-        if (!NT_SUCCESS(status))
-            goto fail1;
-
-        IoSkipCurrentIrpStackLocation(Irp);
-
-        status = IoCallDriver(Pdo->LowerDeviceObject, Irp);
-        IoReleaseRemoveLock(&Pdo->Dx->RemoveLock, Irp);
+        status = PdoDispatchDefault(Pdo, Irp);
          break;
      }
- return status;
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    Irp->IoStatus.Status = status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return status;
-}
-
-static NTSTATUS
-PdoSetDevicePowerUp(
-    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;
-
-    ASSERT3U(DeviceState, <,  __PdoGetDevicePowerState(Pdo));
-
-    status = PdoForwardIrpSynchronously(Pdo, Irp);
-    if (!NT_SUCCESS(status))
-        goto done;
-
-    Trace("%s: %s -> %s\n",
-          __PdoGetName(Pdo),
-          DevicePowerStateName(__PdoGetDevicePowerState(Pdo)),
-          DevicePowerStateName(DeviceState));
-
-    PowerState.DeviceState = DeviceState;
-    PoSetPowerState(__PdoGetDeviceObject(Pdo),
-                    DevicePowerState,
-                    PowerState);
-
-    __PdoSetDevicePowerState(Pdo, DeviceState);
-
-done:
-    Irp->IoStatus.Status = status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
      return status;
  }
-static NTSTATUS
-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;
-
-    ASSERT3U(DeviceState, >,  __PdoGetDevicePowerState(Pdo));
-
-    Trace("%s: %s -> %s\n",
-          __PdoGetName(Pdo),
-          DevicePowerStateName(__PdoGetDevicePowerState(Pdo)),
-          DevicePowerStateName(DeviceState));
-
-    PowerState.DeviceState = DeviceState;
-    PoSetPowerState(__PdoGetDeviceObject(Pdo),
-                    DevicePowerState,
-                    PowerState);
-
-    __PdoSetDevicePowerState(Pdo, DeviceState);
-
-    status = PdoForwardIrpSynchronously(Pdo, Irp);
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return status;
-}
static NTSTATUS
-PdoSetDevicePower(
+PdoDispatchPowerImmediate(
      IN  PXENFILT_PDO    Pdo,
      IN  PIRP            Irp
      )
  {
-    PIO_STACK_LOCATION  StackLocation;
-    DEVICE_POWER_STATE  DeviceState;
-    POWER_ACTION        PowerAction;
-    NTSTATUS            status;
+    NTSTATUS status = STATUS_INTERNAL_ERROR;
+    PIO_STACK_LOCATION StackLocation = IoGetCurrentIrpStackLocation(Irp);
+    UCHAR MinorFunction = StackLocation->MinorFunction;
- 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)) ?
-             PdoSetDevicePowerUp(Pdo, Irp) :
-             PdoSetDevicePowerDown(Pdo, Irp);
-
-done:
-    Trace("%s: <==== (%s:%s)(%08x)\n",
-          __PdoGetName(Pdo),
-          DevicePowerStateName(DeviceState),
-          PowerActionName(PowerAction),
-          status);
-    return status;
-}
-
-static NTSTATUS
-PdoSetSystemPowerUp(
-    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);
-    if (!NT_SUCCESS(status))
-        goto done;
-
-    Trace("%s: %s -> %s\n",
-          __PdoGetName(Pdo),
-          SystemPowerStateName(__PdoGetSystemPowerState(Pdo)),
-          SystemPowerStateName(SystemState));
-
-    __PdoSetSystemPowerState(Pdo, SystemState);
-
-done:
-    Irp->IoStatus.Status = status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return status;
-}
-
-static 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));
-
-    Trace("%s: %s -> %s\n",
-          __PdoGetName(Pdo),
-          SystemPowerStateName(__PdoGetSystemPowerState(Pdo)),
-          SystemPowerStateName(SystemState));
-
-    __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;
-}
-
-static NTSTATUS
-PdoQueryDevicePower(
-    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;
+    if (MinorFunction != IRP_MN_SET_POWER)
+        goto fail1;
- Trace("%s: ====> (%s:%s)\n",
-          __PdoGetName(Pdo),
-          DevicePowerStateName(DeviceState),
-          PowerActionName(PowerAction));
+    POWER_STATE_TYPE PowerType = StackLocation->Parameters.Power.Type;
- if (DeviceState == __PdoGetDevicePowerState(Pdo)) {
-        status = PdoForwardIrpSynchronously(Pdo, Irp);
-        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    switch (PowerType) {
+    case DevicePowerState:
+        POWER_STATE PowerState;
+        DEVICE_POWER_STATE DeviceState = 
StackLocation->Parameters.Power.State.DeviceState;
+        if (DeviceState >= __PdoGetDevicePowerState(Pdo))
+            goto fail3;
+
+        __PdoSetDevicePowerState(Pdo, DeviceState);
+        PowerState.DeviceState = DeviceState;
+        PoSetPowerState(__PdoGetDeviceObject(Pdo),
+                        DevicePowerState,
+                        PowerState);
+    break;
+    case SystemPowerState:
+        SYSTEM_POWER_STATE SystemState = 
StackLocation->Parameters.Power.State.SystemState;
+        if (SystemState >= __PdoGetSystemPowerState(Pdo))
+            goto fail3;
- goto done;
+        __PdoSetSystemPowerState(Pdo, SystemState);
+    break;
+    default:
+        goto fail2;
      }
- 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;
-}
-
-static NTSTATUS
-PdoQuerySystemPowerDown(
-    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);
+    return STATUS_SUCCESS;
+fail3:
+    Error("fail3 (%08x)\n", status);
+fail2:
+    Error("fail2 (%08x)\n", status);
+fail1:
+    Error("fail1 (%08x)\n", status);
      return status;
  }
-static NTSTATUS
-PdoQuerySystemPower(
+static VOID
+PdoCompletionPower(
      IN  PXENFILT_PDO    Pdo,
      IN  PIRP            Irp
-    )
+)
  {
-    PIO_STACK_LOCATION  StackLocation;
-    SYSTEM_POWER_STATE  SystemState;
-    POWER_ACTION        PowerAction;
-    NTSTATUS            status;
+    PIO_STACK_LOCATION StackLocation = IoGetCurrentIrpStackLocation(Irp);
+    UCHAR MinorFunction = StackLocation->MinorFunction;
- StackLocation = IoGetCurrentIrpStackLocation(Irp);
-    SystemState = StackLocation->Parameters.Power.State.SystemState;
-    PowerAction = StackLocation->Parameters.Power.ShutdownType;
+    if (MinorFunction != IRP_MN_SET_POWER)
+        goto fail1;
- Trace("%s: ====> (%s:%s)\n",
-          __PdoGetName(Pdo),
-          SystemPowerStateName(SystemState),
-          PowerActionName(PowerAction));
+    POWER_STATE_TYPE PowerType = StackLocation->Parameters.Power.Type;
- if (SystemState == __PdoGetSystemPowerState(Pdo)) {
-        status = PdoForwardIrpSynchronously(Pdo, Irp);
-        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    switch (PowerType) {
+    case DevicePowerState:
+        POWER_STATE PowerState;
+        DEVICE_POWER_STATE DeviceState = 
StackLocation->Parameters.Power.State.DeviceState;
+        if (DeviceState <= __PdoGetDevicePowerState(Pdo))
+            goto fail3;
+
+        PowerState.DeviceState = DeviceState;
+        PoSetPowerState(__PdoGetDeviceObject(Pdo),
+                        DevicePowerState,
+                        PowerState);
+        __PdoSetDevicePowerState(Pdo, DeviceState);
+
+    break;
+    case SystemPowerState:
+        SYSTEM_POWER_STATE SystemState = 
StackLocation->Parameters.Power.State.SystemState;
+        if (SystemState <= __PdoGetSystemPowerState(Pdo))
+            goto fail3;
- goto done;
+        __PdoSetSystemPowerState(Pdo, SystemState);
+    break;
+    default:
+        goto fail2;
      }
- status = (SystemState < __PdoGetSystemPowerState(Pdo)) ?
-             PdoQuerySystemPowerUp(Pdo, Irp) :
-             PdoQuerySystemPowerDown(Pdo, Irp);
+    return;
-done:
-    Trace("%s: <==== (%s:%s)(%08x)\n",
-          __PdoGetName(Pdo),
-          SystemPowerStateName(SystemState),
-          PowerActionName(PowerAction),
-          status);
-
-    return status;
+fail3:
+    Error("fail3\n");
+fail2:
+    Error("fail2\n");
+fail1:
+    Error("fail1");
  }
+__drv_functionClass(IO_COMPLETION_ROUTINE)
+__drv_sameIRQL
  static NTSTATUS
-PdoDevicePower(
-    IN  PXENFILT_THREAD Self,
+PdoDispatchPowerCompletionV2(

I assume this means that you largely duped the FDO code. Please please find some better names.

+    IN  PDEVICE_OBJECT  DeviceObject,
+    IN  PIRP            Irp,
      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;
+    UNREFERENCED_PARAMETER(DeviceObject);
- default:
-            ASSERT(FALSE);
-            break;
-        }
+    if (Irp->PendingReturned)
+        IoMarkIrpPending(Irp);
- IoReleaseRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-    }
+    //Assumption don't need STATUS_MORE_PROCESSING_REQUIRED.
+    PdoCompletionPower(Pdo, Irp);
+ IoReleaseRemoveLock(&Pdo->Dx->RemoveLock, Irp);
      return STATUS_SUCCESS;
  }
-static NTSTATUS
-PdoSystemPower(
-    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->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;
-}
static NTSTATUS
  PdoDispatchPower(
@@ -1695,104 +1318,125 @@ PdoDispatchPower(
  {
      PIO_STACK_LOCATION  StackLocation;
      UCHAR               MinorFunction;
-    POWER_STATE_TYPE    PowerType;
      NTSTATUS            status;
-
-    status = IoAcquireRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
+    XEN_IRP_STRATEGY    strategy;
+    BOOLEAN HaveRemoveLock = FALSE;

Here an elsewhere... can we keep the declarations vertically aligned and at a tabstop?

StackLocation = IoGetCurrentIrpStackLocation(Irp);
      MinorFunction = StackLocation->MinorFunction;
- if (MinorFunction != IRP_MN_QUERY_POWER &&
-        MinorFunction != IRP_MN_SET_POWER) {
-        IoSkipCurrentIrpStackLocation(Irp);
-
-        status = IoCallDriver(Pdo->LowerDeviceObject, Irp);
-        IoReleaseRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-
-        goto done;
-    }
-
-    PowerType = StackLocation->Parameters.Power.Type;
-
-    Trace("%s: ====> (%02x:%s)\n",
-          __PdoGetName(Pdo),
-          MinorFunction,
-          PowerMinorFunctionName(MinorFunction));
-
-    switch (PowerType) {
-    case DevicePowerState:
-        IoMarkIrpPending(Irp);
-
-        ASSERT3P(Pdo->DevicePowerIrp, ==, NULL);
-        Pdo->DevicePowerIrp = Irp;
-        KeMemoryBarrier();
-
-        ThreadWake(Pdo->DevicePowerThread);
-
-        status = STATUS_PENDING;
+    //Decide how we're going to handle this IRP.
+    switch(MinorFunction) {
+    case IRP_MN_QUERY_POWER:
+        strategy = XEN_IRP_PASSDOWN_TRANSPARENT; //Dont fail, don't need to 
check queries.
          break;
+    case IRP_MN_SET_POWER:
+        POWER_STATE_TYPE PowerType = StackLocation->Parameters.Power.Type;
- case SystemPowerState:
-        IoMarkIrpPending(Irp);
+        switch (PowerType) {
+        case DevicePowerState:
+            DEVICE_POWER_STATE DeviceState = 
StackLocation->Parameters.Power.State.DeviceState;
- ASSERT3P(Pdo->SystemPowerIrp, ==, NULL);
-        Pdo->SystemPowerIrp = Irp;
-        KeMemoryBarrier();
-
-        ThreadWake(Pdo->SystemPowerThread);
-
-        status = STATUS_PENDING;
+            status = IoAcquireRemoveLock(&Pdo->Dx->RemoveLock, Irp);
+            if (!NT_SUCCESS(status))
+                goto fail1;
+
+            //If fails, then pending removal or already removed,
+            //freshly initialized (or not). Consider status to return...
+            HaveRemoveLock = TRUE;
+
+            if (DeviceState == __PdoGetDevicePowerState(Pdo)) {
+                strategy = XEN_IRP_PASSDOWN_TRANSPARENT;
+            } else if (DeviceState < __PdoGetDevicePowerState(Pdo)) {
+                strategy = XEN_IRP_HANDLE_INDISPATCH_PASSDOWN;
+            } else {
+                strategy = XEN_IRP_HANDLE_INCOMPLETION;
+            }
+        case SystemPowerState:
+            SYSTEM_POWER_STATE SystemState = 
StackLocation->Parameters.Power.State.SystemState;
+
+            status = IoAcquireRemoveLock(&Pdo->Dx->RemoveLock, Irp);
+            if (!NT_SUCCESS(status))
+                goto fail1;
+
+            //If fails, then pending removal or already removed,
+            //freshly initialized (or not). Consider status to return...
+            HaveRemoveLock = TRUE;
+
+            if (SystemState == __PdoGetSystemPowerState(Pdo)) {
+                strategy = XEN_IRP_PASSDOWN_TRANSPARENT;
+            } else if (SystemState < __PdoGetSystemPowerState(Pdo)) {
+                strategy = XEN_IRP_HANDLE_INDISPATCH_PASSDOWN;
+            } else {
+                strategy = XEN_IRP_HANDLE_INCOMPLETION;
+            }
          break;
-
+        default:
+            strategy = XEN_IRP_PASSDOWN_TRANSPARENT;
+        break;
+        }
      default:
-        IoSkipCurrentIrpStackLocation(Irp);
-
-        status = IoCallDriver(Pdo->LowerDeviceObject, Irp);
-        IoReleaseRemoveLock(&Pdo->Dx->RemoveLock, Irp);
+        strategy = XEN_IRP_PASSDOWN_TRANSPARENT;
          break;
      }
- Trace("%s: <==== (%02x:%s) (%08x)\n",
-          __PdoGetName(Pdo),
-          MinorFunction,
-          PowerMinorFunctionName(MinorFunction),
-          status);
-
-done:
-    return status;
-
-fail1:
-    Error("fail1 (%08x)\n", status);
+    switch(strategy) {
+        case XEN_IRP_HANDLE_INDISPATCH_PASSDOWN:
+            status = PdoDispatchPowerImmediate(Pdo, Irp);
+            if (!NT_SUCCESS(status))
+                goto fail2;
+            //Fallthru.
+        case XEN_IRP_PASSDOWN_TRANSPARENT:
+        default:
+            IoSkipCurrentIrpStackLocation(Irp);
+            status = IoCallDriver(Pdo->LowerDeviceObject, Irp);
+            if (!NT_SUCCESS(status))
+                goto fail3;
- Irp->IoStatus.Status = status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+            if (HaveRemoveLock)
+                IoReleaseRemoveLock(&Pdo->Dx->RemoveLock, Irp);
+        break;
+        case XEN_IRP_HANDLE_INCOMPLETION:
+            IoMarkIrpPending(Irp);
+            IoCopyCurrentIrpStackLocationToNext(Irp);
+            IoSetCompletionRoutine(Irp,
+                                PdoDispatchPowerCompletionV2,
+                                Pdo,
+                               TRUE,
+                               TRUE,
+                               TRUE);
+            status = IoCallDriver(Pdo->LowerDeviceObject, Irp);
+            if (!NT_SUCCESS(status))
+                goto fail4;
+            status = STATUS_PENDING; //Must return STATUS_PENDING after 
IoMarkIrpPending, whatever happens next.
+        break;
+    }
return status;
-}
-
-static NTSTATUS
-PdoDispatchDefault(
-    IN  PXENFILT_PDO    Pdo,
-    IN  PIRP            Irp
-    )
-{
-    NTSTATUS            status;
- status = IoAcquireRemoveLock(&Pdo->Dx->RemoveLock, Irp);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    IoSkipCurrentIrpStackLocation(Irp);
-
-    status = IoCallDriver(Pdo->LowerDeviceObject, Irp);
-    IoReleaseRemoveLock(&Pdo->Dx->RemoveLock, Irp);
+fail4:
+    //Error from lower driver, have remove lock, and completion routine.
+    //Comp routine shd be called on error to drop remove lock.
+    Error("fail4 (%08x)\n", status);
+    status = STATUS_PENDING; //Must return STATUS_PENDING after 
IoMarkIrpPending, whatever happens next.
+    return status;
+fail3:
+    //Error from lower driver, have remove lock, called down.
+    Error("fail3 (%08x)\n", status);
+    if (HaveRemoveLock)
+        IoReleaseRemoveLock(&Pdo->Dx->RemoveLock, Irp);
      return status;
+fail2:
+    //Immediate error, have remove lock, not called down.
+    Error("fail2 (%08x)\n", status);
+    if (HaveRemoveLock)
+        IoReleaseRemoveLock(&Pdo->Dx->RemoveLock, Irp);
+    //Fallthru.
+
  fail1:
+    //Immediate error, no remove lock, not called down.
      Error("fail1 (%08x)\n", status);
Irp->IoStatus.Status = status;
@@ -1907,14 +1551,6 @@ 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;
@@ -1968,20 +1604,6 @@ fail7:
  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");
-
      Pdo->Type = XENFILT_EMULATED_OBJECT_TYPE_UNKNOWN;
      Pdo->PhysicalDeviceObject = NULL;
      Pdo->LowerDeviceObject = NULL;
@@ -2040,14 +1662,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;

  Paul



 


Rackspace

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