[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
|