|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [RFC PATCH 1/3] [XenFilt] Asynchronous power handling
From: Martin Harvey <Martin.Harvey@xxxxxxxxxx>
XenFilt requires minimal IRP_MN_SET_POWER/IRP_MN_QUERY_POWER interactions.
No IoWorkItems are required as operationsperform no significant work.
Power handlers are is limited to tracking state changes and calling
PoSetPowerState.
Signed-off-by: Martin Harvey <martin.harvey@xxxxxxxxxx>
Refactored and limited to XenFilt changes
Signed-off-by: Owen Smith <owen.smith@xxxxxxxxx>
---
src/xenfilt/fdo.c | 498 +++++++++++----------------------------------
src/xenfilt/pdo.c | 503 +++++++++++-----------------------------------
2 files changed, 242 insertions(+), 759 deletions(-)
diff --git a/src/xenfilt/fdo.c b/src/xenfilt/fdo.c
index 78228de..08cf5a7 100644
--- a/src/xenfilt/fdo.c
+++ b/src/xenfilt/fdo.c
@@ -60,11 +60,6 @@ struct _XENFILT_FDO {
PDEVICE_OBJECT PhysicalDeviceObject;
CHAR Name[MAXNAMELEN];
- PXENFILT_THREAD SystemPowerThread;
- PIRP SystemPowerIrp;
- PXENFILT_THREAD DevicePowerThread;
- PIRP DevicePowerIrp;
-
MUTEX Mutex;
LIST_ENTRY List;
ULONG References;
@@ -1078,76 +1073,87 @@ fail1:
return status;
}
+__drv_functionClass(IO_COMPLETION_ROUTINE)
+__drv_sameIRQL
static NTSTATUS
-FdoSetDevicePowerUp(
- IN PXENFILT_FDO Fdo,
- IN PIRP Irp
+FdoSetDevicePowerUpComplete(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PVOID Context
)
{
+ PXENFILT_FDO Fdo = (PXENFILT_FDO)Context;
PIO_STACK_LOCATION StackLocation;
- DEVICE_POWER_STATE DeviceState;
POWER_STATE PowerState;
- NTSTATUS status;
+
+ UNREFERENCED_PARAMETER(DeviceObject);
StackLocation = IoGetCurrentIrpStackLocation(Irp);
- DeviceState = StackLocation->Parameters.Power.State.DeviceState;
+ PowerState = StackLocation->Parameters.Power.State;
- ASSERT3U(DeviceState, <, __FdoGetDevicePowerState(Fdo));
+ ASSERT3U(PowerState.DeviceState, <, __FdoGetDevicePowerState(Fdo));
- status = FdoForwardIrpSynchronously(Fdo, Irp);
- if (!NT_SUCCESS(status))
- goto done;
+ if (Irp->PendingReturned)
+ IoMarkIrpPending(Irp);
Trace("%s: %s -> %s\n",
__FdoGetName(Fdo),
DevicePowerStateName(__FdoGetDevicePowerState(Fdo)),
- DevicePowerStateName(DeviceState));
+ DevicePowerStateName(PowerState.DeviceState));
- PowerState.DeviceState = DeviceState;
PoSetPowerState(Fdo->Dx->DeviceObject,
DevicePowerState,
PowerState);
- __FdoSetDevicePowerState(Fdo, DeviceState);
+ __FdoSetDevicePowerState(Fdo, PowerState.DeviceState);
-done:
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_CONTINUE_COMPLETION;
+}
- return status;
+static FORCEINLINE NTSTATUS
+__FdoSetDevicePowerUp(
+ IN PXENFILT_FDO Fdo,
+ IN PIRP Irp
+ )
+{
+ IoCopyCurrentIrpStackLocationToNext(Irp);
+ IoSetCompletionRoutine(Irp,
+ FdoSetDevicePowerUpComplete,
+ Fdo,
+ TRUE,
+ TRUE,
+ TRUE);
+
+ return IoCallDriver(Fdo->LowerDeviceObject, Irp);
}
static NTSTATUS
-FdoSetDevicePowerDown(
+__FdoSetDevicePowerDown(
IN PXENFILT_FDO Fdo,
IN PIRP Irp
)
{
PIO_STACK_LOCATION StackLocation;
- DEVICE_POWER_STATE DeviceState;
POWER_STATE PowerState;
- NTSTATUS status;
StackLocation = IoGetCurrentIrpStackLocation(Irp);
- DeviceState = StackLocation->Parameters.Power.State.DeviceState;
+ PowerState = StackLocation->Parameters.Power.State;
- ASSERT3U(DeviceState, >, __FdoGetDevicePowerState(Fdo));
+ ASSERT3U(PowerState.DeviceState, >, __FdoGetDevicePowerState(Fdo));
Trace("%s: %s -> %s\n",
__FdoGetName(Fdo),
DevicePowerStateName(__FdoGetDevicePowerState(Fdo)),
- DevicePowerStateName(DeviceState));
+ DevicePowerStateName(PowerState.DeviceState));
- PowerState.DeviceState = DeviceState;
PoSetPowerState(Fdo->Dx->DeviceObject,
DevicePowerState,
PowerState);
- __FdoSetDevicePowerState(Fdo, DeviceState);
+ __FdoSetDevicePowerState(Fdo, PowerState.DeviceState);
- status = FdoForwardIrpSynchronously(Fdo, Irp);
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- return status;
+ IoSkipCurrentIrpStackLocation(Irp);
+ return IoCallDriver(Fdo->LowerDeviceObject, Irp);
}
static NTSTATUS
@@ -1171,15 +1177,15 @@ FdoSetDevicePower(
PowerActionName(PowerAction));
if (DeviceState == __FdoGetDevicePowerState(Fdo)) {
- status = FdoForwardIrpSynchronously(Fdo, Irp);
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ IoSkipCurrentIrpStackLocation(Irp);
+ status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
goto done;
}
status = (DeviceState < __FdoGetDevicePowerState(Fdo)) ?
- FdoSetDevicePowerUp(Fdo, Irp) :
- FdoSetDevicePowerDown(Fdo, Irp);
+ __FdoSetDevicePowerUp(Fdo, Irp) :
+ __FdoSetDevicePowerDown(Fdo, Irp);
done:
Trace("%s: <==== (%s:%s)(%08x)\n",
@@ -1190,52 +1196,55 @@ done:
return status;
}
-static NTSTATUS
-FdoSetSystemPowerUp(
+static FORCEINLINE NTSTATUS
+__FdoDispatchDevicePower(
IN PXENFILT_FDO Fdo,
IN PIRP Irp
)
{
PIO_STACK_LOCATION StackLocation;
- SYSTEM_POWER_STATE SystemState;
+ UCHAR MinorFunction;
NTSTATUS status;
StackLocation = IoGetCurrentIrpStackLocation(Irp);
- SystemState = StackLocation->Parameters.Power.State.SystemState;
-
- ASSERT3U(SystemState, <, __FdoGetSystemPowerState(Fdo));
-
- status = FdoForwardIrpSynchronously(Fdo, Irp);
- if (!NT_SUCCESS(status))
- goto done;
-
- Trace("%s: %s -> %s\n",
- __FdoGetName(Fdo),
- SystemPowerStateName(__FdoGetSystemPowerState(Fdo)),
- SystemPowerStateName(SystemState));
+ MinorFunction = StackLocation->MinorFunction;
- __FdoSetSystemPowerState(Fdo, SystemState);
+ switch (MinorFunction) {
+ case IRP_MN_SET_POWER:
+ status = FdoSetDevicePower(Fdo, Irp);
+ break;
-done:
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ default:
+ IoSkipCurrentIrpStackLocation(Irp);
+ status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
+ break;
+ }
return status;
}
+__drv_functionClass(IO_COMPLETION_ROUTINE)
+__drv_sameIRQL
static NTSTATUS
-FdoSetSystemPowerDown(
- IN PXENFILT_FDO Fdo,
- IN PIRP Irp
+FdoSetSystemPowerUpComplete(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PVOID Context
)
{
+ PXENFILT_FDO Fdo = (PXENFILT_FDO)Context;
PIO_STACK_LOCATION StackLocation;
SYSTEM_POWER_STATE SystemState;
- NTSTATUS status;
+
+ UNREFERENCED_PARAMETER(DeviceObject);
StackLocation = IoGetCurrentIrpStackLocation(Irp);
SystemState = StackLocation->Parameters.Power.State.SystemState;
- ASSERT3U(SystemState, >, __FdoGetSystemPowerState(Fdo));
+ ASSERT3U(SystemState, <, __FdoGetSystemPowerState(Fdo));
+
+ if (Irp->PendingReturned)
+ IoMarkIrpPending(Irp);
Trace("%s: %s -> %s\n",
__FdoGetName(Fdo),
@@ -1244,180 +1253,52 @@ FdoSetSystemPowerDown(
__FdoSetSystemPowerState(Fdo, SystemState);
- status = FdoForwardIrpSynchronously(Fdo, Irp);
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- return status;
-}
-
-static NTSTATUS
-FdoSetSystemPower(
- IN PXENFILT_FDO Fdo,
- IN PIRP Irp
- )
-{
- PIO_STACK_LOCATION StackLocation;
- SYSTEM_POWER_STATE SystemState;
- POWER_ACTION PowerAction;
- NTSTATUS status;
-
- StackLocation = IoGetCurrentIrpStackLocation(Irp);
- SystemState = StackLocation->Parameters.Power.State.SystemState;
- PowerAction = StackLocation->Parameters.Power.ShutdownType;
-
- Trace("%s: ====> (%s:%s)\n",
- __FdoGetName(Fdo),
- SystemPowerStateName(SystemState),
- PowerActionName(PowerAction));
-
- if (SystemState == __FdoGetSystemPowerState(Fdo)) {
- status = FdoForwardIrpSynchronously(Fdo, Irp);
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- goto done;
- }
-
- status = (SystemState < __FdoGetSystemPowerState(Fdo)) ?
- FdoSetSystemPowerUp(Fdo, Irp) :
- FdoSetSystemPowerDown(Fdo, Irp);
-
-done:
- Trace("%s: <==== (%s:%s)(%08x)\n",
- __FdoGetName(Fdo),
- SystemPowerStateName(SystemState),
- PowerActionName(PowerAction),
- status);
- return status;
-}
-
-static NTSTATUS
-FdoQueryDevicePowerUp(
- IN PXENFILT_FDO Fdo,
- IN PIRP Irp
- )
-{
- PIO_STACK_LOCATION StackLocation;
- DEVICE_POWER_STATE DeviceState;
- NTSTATUS status;
-
- StackLocation = IoGetCurrentIrpStackLocation(Irp);
- DeviceState = StackLocation->Parameters.Power.State.DeviceState;
-
- ASSERT3U(DeviceState, <, __FdoGetDevicePowerState(Fdo));
-
- status = FdoForwardIrpSynchronously(Fdo, Irp);
-
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- return status;
+ return STATUS_CONTINUE_COMPLETION;
}
-static NTSTATUS
-FdoQueryDevicePowerDown(
- IN PXENFILT_FDO Fdo,
- IN PIRP Irp
- )
-{
- PIO_STACK_LOCATION StackLocation;
- DEVICE_POWER_STATE DeviceState;
- NTSTATUS status;
-
- StackLocation = IoGetCurrentIrpStackLocation(Irp);
- DeviceState = StackLocation->Parameters.Power.State.DeviceState;
-
- ASSERT3U(DeviceState, >, __FdoGetDevicePowerState(Fdo));
-
- status = FdoForwardIrpSynchronously(Fdo, Irp);
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- return status;
-}
-
-static NTSTATUS
-FdoQueryDevicePower(
+static FORCEINLINE NTSTATUS
+__FdoSetSystemPowerUp(
IN PXENFILT_FDO Fdo,
IN PIRP Irp
)
{
- PIO_STACK_LOCATION StackLocation;
- DEVICE_POWER_STATE DeviceState;
- POWER_ACTION PowerAction;
- NTSTATUS status;
-
- StackLocation = IoGetCurrentIrpStackLocation(Irp);
- DeviceState = StackLocation->Parameters.Power.State.DeviceState;
- PowerAction = StackLocation->Parameters.Power.ShutdownType;
-
- Trace("%s: ====> (%s:%s)\n",
- __FdoGetName(Fdo),
- DevicePowerStateName(DeviceState),
- PowerActionName(PowerAction));
-
- if (DeviceState == __FdoGetDevicePowerState(Fdo)) {
- status = FdoForwardIrpSynchronously(Fdo, Irp);
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- goto done;
- }
-
- status = (DeviceState < __FdoGetDevicePowerState(Fdo)) ?
- FdoQueryDevicePowerUp(Fdo, Irp) :
- FdoQueryDevicePowerDown(Fdo, Irp);
-
-done:
- Trace("%s: <==== (%s:%s)(%08x)\n",
- __FdoGetName(Fdo),
- DevicePowerStateName(DeviceState),
- PowerActionName(PowerAction),
- status);
- return status;
-}
-
-static NTSTATUS
-FdoQuerySystemPowerUp(
- IN PXENFILT_FDO Fdo,
- IN PIRP Irp
- )
-{
- PIO_STACK_LOCATION StackLocation;
- SYSTEM_POWER_STATE SystemState;
- NTSTATUS status;
-
- StackLocation = IoGetCurrentIrpStackLocation(Irp);
- SystemState = StackLocation->Parameters.Power.State.SystemState;
-
- ASSERT3U(SystemState, <, __FdoGetSystemPowerState(Fdo));
-
- status = FdoForwardIrpSynchronously(Fdo, Irp);
-
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- return status;
+ IoCopyCurrentIrpStackLocationToNext(Irp);
+ IoSetCompletionRoutine(Irp,
+ FdoSetSystemPowerUpComplete,
+ Fdo,
+ TRUE,
+ TRUE,
+ TRUE);
+ return IoCallDriver(Fdo->LowerDeviceObject, Irp);
}
-static NTSTATUS
-FdoQuerySystemPowerDown(
+static FORCEINLINE NTSTATUS
+__FdoSetSystemPowerDown(
IN PXENFILT_FDO Fdo,
IN PIRP Irp
)
{
PIO_STACK_LOCATION StackLocation;
SYSTEM_POWER_STATE SystemState;
- NTSTATUS status;
StackLocation = IoGetCurrentIrpStackLocation(Irp);
SystemState = StackLocation->Parameters.Power.State.SystemState;
ASSERT3U(SystemState, >, __FdoGetSystemPowerState(Fdo));
- status = FdoForwardIrpSynchronously(Fdo, Irp);
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ Trace("%s: %s -> %s\n",
+ __FdoGetName(Fdo),
+ SystemPowerStateName(__FdoGetSystemPowerState(Fdo)),
+ SystemPowerStateName(SystemState));
- return status;
+ __FdoSetSystemPowerState(Fdo, SystemState);
+
+ IoSkipCurrentIrpStackLocation(Irp);
+ return IoCallDriver(Fdo->LowerDeviceObject, Irp);
}
static NTSTATUS
-FdoQuerySystemPower(
+FdoSetSystemPower(
IN PXENFILT_FDO Fdo,
IN PIRP Irp
)
@@ -1437,15 +1318,15 @@ FdoQuerySystemPower(
PowerActionName(PowerAction));
if (SystemState == __FdoGetSystemPowerState(Fdo)) {
- status = FdoForwardIrpSynchronously(Fdo, Irp);
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ IoSkipCurrentIrpStackLocation(Irp);
+ status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
goto done;
}
status = (SystemState < __FdoGetSystemPowerState(Fdo)) ?
- FdoQuerySystemPowerUp(Fdo, Irp) :
- FdoQuerySystemPowerDown(Fdo, Irp);
+ __FdoSetSystemPowerUp(Fdo, Irp) :
+ __FdoSetSystemPowerDown(Fdo, Irp);
done:
Trace("%s: <==== (%s:%s)(%08x)\n",
@@ -1453,126 +1334,34 @@ done:
SystemPowerStateName(SystemState),
PowerActionName(PowerAction),
status);
-
return status;
}
-static NTSTATUS
-FdoDevicePower(
- IN PXENFILT_THREAD Self,
- IN PVOID Context
- )
-{
- PXENFILT_FDO Fdo = Context;
- PKEVENT Event;
-
- Event = ThreadGetEvent(Self);
-
- for (;;) {
- PIRP Irp;
- PIO_STACK_LOCATION StackLocation;
- UCHAR MinorFunction;
-
- if (Fdo->DevicePowerIrp == NULL) {
- (VOID) KeWaitForSingleObject(Event,
- Executive,
- KernelMode,
- FALSE,
- NULL);
- KeClearEvent(Event);
- }
-
- if (ThreadIsAlerted(Self))
- break;
-
- Irp = Fdo->DevicePowerIrp;
-
- if (Irp == NULL)
- continue;
-
- Fdo->DevicePowerIrp = NULL;
- KeMemoryBarrier();
-
- StackLocation = IoGetCurrentIrpStackLocation(Irp);
- MinorFunction = StackLocation->MinorFunction;
-
- switch (StackLocation->MinorFunction) {
- case IRP_MN_SET_POWER:
- (VOID) FdoSetDevicePower(Fdo, Irp);
- break;
-
- case IRP_MN_QUERY_POWER:
- (VOID) FdoQueryDevicePower(Fdo, Irp);
- break;
-
- default:
- ASSERT(FALSE);
- break;
- }
-
- IoReleaseRemoveLock(&Fdo->Dx->RemoveLock, Irp);
- }
-
- return STATUS_SUCCESS;
-}
-
-static NTSTATUS
-FdoSystemPower(
- IN PXENFILT_THREAD Self,
- IN PVOID Context
+static FORCEINLINE NTSTATUS
+__FdoDispatchSystemPower(
+ IN PXENFILT_FDO Fdo,
+ IN PIRP Irp
)
{
- PXENFILT_FDO Fdo = Context;
- PKEVENT Event;
-
- Event = ThreadGetEvent(Self);
-
- for (;;) {
- PIRP Irp;
- PIO_STACK_LOCATION StackLocation;
- UCHAR MinorFunction;
-
- if (Fdo->SystemPowerIrp == NULL) {
- (VOID) KeWaitForSingleObject(Event,
- Executive,
- KernelMode,
- FALSE,
- NULL);
- KeClearEvent(Event);
- }
-
- if (ThreadIsAlerted(Self))
- break;
-
- Irp = Fdo->SystemPowerIrp;
-
- if (Irp == NULL)
- continue;
-
- Fdo->SystemPowerIrp = NULL;
- KeMemoryBarrier();
-
- StackLocation = IoGetCurrentIrpStackLocation(Irp);
- MinorFunction = StackLocation->MinorFunction;
-
- switch (StackLocation->MinorFunction) {
- case IRP_MN_SET_POWER:
- (VOID) FdoSetSystemPower(Fdo, Irp);
- break;
+ PIO_STACK_LOCATION StackLocation;
+ UCHAR MinorFunction;
+ NTSTATUS status;
- case IRP_MN_QUERY_POWER:
- (VOID) FdoQuerySystemPower(Fdo, Irp);
- break;
+ StackLocation = IoGetCurrentIrpStackLocation(Irp);
+ MinorFunction = StackLocation->MinorFunction;
- default:
- ASSERT(FALSE);
- break;
- }
+ switch (MinorFunction) {
+ case IRP_MN_SET_POWER:
+ status = FdoSetSystemPower(Fdo, Irp);
+ break;
- IoReleaseRemoveLock(&Fdo->Dx->RemoveLock, Irp);
+ default:
+ IoSkipCurrentIrpStackLocation(Irp);
+ status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
+ break;
}
- return STATUS_SUCCESS;
+ return status;
}
static NTSTATUS
@@ -1593,8 +1382,7 @@ FdoDispatchPower(
StackLocation = IoGetCurrentIrpStackLocation(Irp);
MinorFunction = StackLocation->MinorFunction;
- if (MinorFunction != IRP_MN_QUERY_POWER &&
- MinorFunction != IRP_MN_SET_POWER) {
+ if (MinorFunction != IRP_MN_SET_POWER) {
IoSkipCurrentIrpStackLocation(Irp);
status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
@@ -1612,27 +1400,13 @@ FdoDispatchPower(
switch (PowerType) {
case DevicePowerState:
- IoMarkIrpPending(Irp);
-
- ASSERT3P(Fdo->DevicePowerIrp, ==, NULL);
- Fdo->DevicePowerIrp = Irp;
- KeMemoryBarrier();
-
- ThreadWake(Fdo->DevicePowerThread);
-
- status = STATUS_PENDING;
+ status = __FdoDispatchDevicePower(Fdo, Irp);
+ IoReleaseRemoveLock(&Fdo->Dx->RemoveLock, Irp);
break;
case SystemPowerState:
- IoMarkIrpPending(Irp);
-
- ASSERT3P(Fdo->SystemPowerIrp, ==, NULL);
- Fdo->SystemPowerIrp = Irp;
- KeMemoryBarrier();
-
- ThreadWake(Fdo->SystemPowerThread);
-
- status = STATUS_PENDING;
+ status = __FdoDispatchSystemPower(Fdo, Irp);
+ IoReleaseRemoveLock(&Fdo->Dx->RemoveLock, Irp);
break;
default:
@@ -1776,21 +1550,13 @@ FdoCreate(
Fdo->LowerDeviceObject = LowerDeviceObject;
Fdo->Type = Type;
- status = ThreadCreate(FdoSystemPower, Fdo, &Fdo->SystemPowerThread);
- if (!NT_SUCCESS(status))
- goto fail4;
-
- status = ThreadCreate(FdoDevicePower, Fdo, &Fdo->DevicePowerThread);
- if (!NT_SUCCESS(status))
- goto fail5;
-
status = __FdoSetDeviceID(Fdo);
if (!NT_SUCCESS(status))
- goto fail6;
+ goto fail4;
status = __FdoSetInstanceID(Fdo);
if (!NT_SUCCESS(status))
- goto fail7;
+ goto fail5;
__FdoSetName(Fdo);
@@ -1815,24 +1581,10 @@ FdoCreate(
return STATUS_SUCCESS;
-fail7:
- Error("fail7\n");
-
- __FdoClearDeviceID(Fdo);
-
-fail6:
- Error("fail6\n");
-
- ThreadAlert(Fdo->DevicePowerThread);
- ThreadJoin(Fdo->DevicePowerThread);
- Fdo->DevicePowerThread = NULL;
-
fail5:
Error("fail5\n");
- ThreadAlert(Fdo->SystemPowerThread);
- ThreadJoin(Fdo->SystemPowerThread);
- Fdo->SystemPowerThread = NULL;
+ __FdoClearDeviceID(Fdo);
fail4:
Error("fail4\n");
@@ -1892,14 +1644,6 @@ FdoDestroy(
__FdoClearInstanceID(Fdo);
__FdoClearDeviceID(Fdo);
- ThreadAlert(Fdo->DevicePowerThread);
- ThreadJoin(Fdo->DevicePowerThread);
- Fdo->DevicePowerThread = NULL;
-
- ThreadAlert(Fdo->SystemPowerThread);
- ThreadJoin(Fdo->SystemPowerThread);
- Fdo->SystemPowerThread = NULL;
-
Fdo->Type = XENFILT_EMULATED_OBJECT_TYPE_UNKNOWN;
Fdo->LowerDeviceObject = NULL;
Fdo->PhysicalDeviceObject = NULL;
diff --git a/src/xenfilt/pdo.c b/src/xenfilt/pdo.c
index be84996..3ce30a8 100644
--- a/src/xenfilt/pdo.c
+++ b/src/xenfilt/pdo.c
@@ -57,11 +57,6 @@ struct _XENFILT_PDO {
PDEVICE_OBJECT PhysicalDeviceObject;
CHAR Name[MAXNAMELEN];
- PXENFILT_THREAD SystemPowerThread;
- PIRP SystemPowerIrp;
- PXENFILT_THREAD DevicePowerThread;
- PIRP DevicePowerIrp;
-
PXENFILT_FDO Fdo;
BOOLEAN Missing;
const CHAR *Reason;
@@ -1187,77 +1182,86 @@ fail1:
return status;
}
+__drv_functionClass(IO_COMPLETION_ROUTINE)
+__drv_sameIRQL
static NTSTATUS
-PdoSetDevicePowerUp(
- IN PXENFILT_PDO Pdo,
- IN PIRP Irp
+PdoSetDevicePowerUpComplete(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PVOID Context
)
{
+ PXENFILT_PDO Pdo = (PXENFILT_PDO)Context;
PIO_STACK_LOCATION StackLocation;
- DEVICE_POWER_STATE DeviceState;
POWER_STATE PowerState;
- NTSTATUS status;
+
+ UNREFERENCED_PARAMETER(DeviceObject);
StackLocation = IoGetCurrentIrpStackLocation(Irp);
- DeviceState = StackLocation->Parameters.Power.State.DeviceState;
+ PowerState = StackLocation->Parameters.Power.State;
- ASSERT3U(DeviceState, <, __PdoGetDevicePowerState(Pdo));
+ ASSERT3U(PowerState.DeviceState, <, __PdoGetDevicePowerState(Pdo));
- status = PdoForwardIrpSynchronously(Pdo, Irp);
- if (!NT_SUCCESS(status))
- goto done;
+ if (Irp->PendingReturned)
+ IoMarkIrpPending(Irp);
Trace("%s: %s -> %s\n",
__PdoGetName(Pdo),
DevicePowerStateName(__PdoGetDevicePowerState(Pdo)),
- DevicePowerStateName(DeviceState));
+ DevicePowerStateName(PowerState.DeviceState));
- PowerState.DeviceState = DeviceState;
PoSetPowerState(__PdoGetDeviceObject(Pdo),
DevicePowerState,
PowerState);
- __PdoSetDevicePowerState(Pdo, DeviceState);
+ __PdoSetDevicePowerState(Pdo, PowerState.DeviceState);
-done:
- Irp->IoStatus.Status = status;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_CONTINUE_COMPLETION;
+}
- return status;
+static FORCEINLINE NTSTATUS
+__PdoSetDevicePowerUp(
+ IN PXENFILT_PDO Pdo,
+ IN PIRP Irp
+ )
+{
+ IoCopyCurrentIrpStackLocationToNext(Irp);
+ IoSetCompletionRoutine(Irp,
+ PdoSetDevicePowerUpComplete,
+ Pdo,
+ TRUE,
+ TRUE,
+ TRUE);
+ return IoCallDriver(Pdo->LowerDeviceObject, Irp);
}
static NTSTATUS
-PdoSetDevicePowerDown(
+__PdoSetDevicePowerDown(
IN PXENFILT_PDO Pdo,
IN PIRP Irp
)
{
PIO_STACK_LOCATION StackLocation;
- DEVICE_POWER_STATE DeviceState;
POWER_STATE PowerState;
- NTSTATUS status;
StackLocation = IoGetCurrentIrpStackLocation(Irp);
- DeviceState = StackLocation->Parameters.Power.State.DeviceState;
+ PowerState = StackLocation->Parameters.Power.State;
- ASSERT3U(DeviceState, >, __PdoGetDevicePowerState(Pdo));
+ ASSERT3U(PowerState.DeviceState, >, __PdoGetDevicePowerState(Pdo));
Trace("%s: %s -> %s\n",
__PdoGetName(Pdo),
DevicePowerStateName(__PdoGetDevicePowerState(Pdo)),
- DevicePowerStateName(DeviceState));
+ DevicePowerStateName(PowerState.DeviceState));
- PowerState.DeviceState = DeviceState;
PoSetPowerState(__PdoGetDeviceObject(Pdo),
DevicePowerState,
PowerState);
- __PdoSetDevicePowerState(Pdo, DeviceState);
+ __PdoSetDevicePowerState(Pdo, PowerState.DeviceState);
- status = PdoForwardIrpSynchronously(Pdo, Irp);
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- return status;
+ IoSkipCurrentIrpStackLocation(Irp);
+ return IoCallDriver(Pdo->LowerDeviceObject, Irp);
}
static NTSTATUS
@@ -1281,15 +1285,15 @@ PdoSetDevicePower(
PowerActionName(PowerAction));
if (DeviceState == __PdoGetDevicePowerState(Pdo)) {
- status = PdoForwardIrpSynchronously(Pdo, Irp);
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ IoSkipCurrentIrpStackLocation(Irp);
+ status = IoCallDriver(Pdo->LowerDeviceObject, Irp);
goto done;
}
status = (DeviceState < __PdoGetDevicePowerState(Pdo)) ?
- PdoSetDevicePowerUp(Pdo, Irp) :
- PdoSetDevicePowerDown(Pdo, Irp);
+ __PdoSetDevicePowerUp(Pdo, Irp) :
+ __PdoSetDevicePowerDown(Pdo, Irp);
done:
Trace("%s: <==== (%s:%s)(%08x)\n",
@@ -1300,53 +1304,55 @@ done:
return status;
}
-static NTSTATUS
-PdoSetSystemPowerUp(
+static FORCEINLINE NTSTATUS
+__PdoDispatchDevicePower(
IN PXENFILT_PDO Pdo,
IN PIRP Irp
)
{
PIO_STACK_LOCATION StackLocation;
- SYSTEM_POWER_STATE SystemState;
+ UCHAR MinorFunction;
NTSTATUS status;
StackLocation = IoGetCurrentIrpStackLocation(Irp);
- SystemState = StackLocation->Parameters.Power.State.SystemState;
-
- ASSERT3U(SystemState, <, __PdoGetSystemPowerState(Pdo));
-
- status = PdoForwardIrpSynchronously(Pdo, Irp);
- if (!NT_SUCCESS(status))
- goto done;
-
- Trace("%s: %s -> %s\n",
- __PdoGetName(Pdo),
- SystemPowerStateName(__PdoGetSystemPowerState(Pdo)),
- SystemPowerStateName(SystemState));
+ MinorFunction = StackLocation->MinorFunction;
- __PdoSetSystemPowerState(Pdo, SystemState);
+ switch (MinorFunction) {
+ case IRP_MN_SET_POWER:
+ status = PdoSetDevicePower(Pdo, Irp);
+ break;
-done:
- Irp->IoStatus.Status = status;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ default:
+ IoSkipCurrentIrpStackLocation(Irp);
+ status = IoCallDriver(Pdo->LowerDeviceObject, Irp);
+ break;
+ }
return status;
}
+__drv_functionClass(IO_COMPLETION_ROUTINE)
+__drv_sameIRQL
static NTSTATUS
-PdoSetSystemPowerDown(
- IN PXENFILT_PDO Pdo,
- IN PIRP Irp
+PdoSetSystemPowerUpComplete(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PVOID Context
)
{
+ PXENFILT_PDO Pdo = (PXENFILT_PDO)Context;
PIO_STACK_LOCATION StackLocation;
SYSTEM_POWER_STATE SystemState;
- NTSTATUS status;
+
+ UNREFERENCED_PARAMETER(DeviceObject);
StackLocation = IoGetCurrentIrpStackLocation(Irp);
SystemState = StackLocation->Parameters.Power.State.SystemState;
- ASSERT3U(SystemState, >, __PdoGetSystemPowerState(Pdo));
+ ASSERT3U(SystemState, <, __PdoGetSystemPowerState(Pdo));
+
+ if (Irp->PendingReturned)
+ IoMarkIrpPending(Irp);
Trace("%s: %s -> %s\n",
__PdoGetName(Pdo),
@@ -1355,182 +1361,52 @@ PdoSetSystemPowerDown(
__PdoSetSystemPowerState(Pdo, SystemState);
- status = PdoForwardIrpSynchronously(Pdo, Irp);
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- return status;
-}
-
-static NTSTATUS
-PdoSetSystemPower(
- IN PXENFILT_PDO Pdo,
- IN PIRP Irp
- )
-{
- PIO_STACK_LOCATION StackLocation;
- SYSTEM_POWER_STATE SystemState;
- POWER_ACTION PowerAction;
- NTSTATUS status;
-
- StackLocation = IoGetCurrentIrpStackLocation(Irp);
- SystemState = StackLocation->Parameters.Power.State.SystemState;
- PowerAction = StackLocation->Parameters.Power.ShutdownType;
-
- Trace("%s: ====> (%s:%s)\n",
- __PdoGetName(Pdo),
- SystemPowerStateName(SystemState),
- PowerActionName(PowerAction));
-
- if (SystemState == __PdoGetSystemPowerState(Pdo)) {
- status = PdoForwardIrpSynchronously(Pdo, Irp);
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- goto done;
- }
-
- status = (SystemState < __PdoGetSystemPowerState(Pdo)) ?
- PdoSetSystemPowerUp(Pdo, Irp) :
- PdoSetSystemPowerDown(Pdo, Irp);
-
-done:
- Trace("%s: <==== (%s:%s)(%08x)\n",
- __PdoGetName(Pdo),
- SystemPowerStateName(SystemState),
- PowerActionName(PowerAction),
- status);
- return status;
-}
-
-static NTSTATUS
-PdoQueryDevicePowerUp(
- IN PXENFILT_PDO Pdo,
- IN PIRP Irp
- )
-{
- PIO_STACK_LOCATION StackLocation;
- DEVICE_POWER_STATE DeviceState;
- NTSTATUS status;
-
- StackLocation = IoGetCurrentIrpStackLocation(Irp);
- DeviceState = StackLocation->Parameters.Power.State.DeviceState;
-
- ASSERT3U(DeviceState, <, __PdoGetDevicePowerState(Pdo));
-
- status = PdoForwardIrpSynchronously(Pdo, Irp);
-
- Irp->IoStatus.Status = status;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- return status;
-}
-
-static NTSTATUS
-PdoQueryDevicePowerDown(
- IN PXENFILT_PDO Pdo,
- IN PIRP Irp
- )
-{
- PIO_STACK_LOCATION StackLocation;
- DEVICE_POWER_STATE DeviceState;
- NTSTATUS status;
-
- StackLocation = IoGetCurrentIrpStackLocation(Irp);
- DeviceState = StackLocation->Parameters.Power.State.DeviceState;
-
- ASSERT3U(DeviceState, >, __PdoGetDevicePowerState(Pdo));
-
- status = PdoForwardIrpSynchronously(Pdo, Irp);
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- return status;
+ return STATUS_CONTINUE_COMPLETION;
}
-static NTSTATUS
-PdoQueryDevicePower(
+static FORCEINLINE NTSTATUS
+__PdoSetSystemPowerUp(
IN PXENFILT_PDO Pdo,
IN PIRP Irp
)
{
- PIO_STACK_LOCATION StackLocation;
- DEVICE_POWER_STATE DeviceState;
- POWER_ACTION PowerAction;
- NTSTATUS status;
-
- StackLocation = IoGetCurrentIrpStackLocation(Irp);
- DeviceState = StackLocation->Parameters.Power.State.DeviceState;
- PowerAction = StackLocation->Parameters.Power.ShutdownType;
-
- Trace("%s: ====> (%s:%s)\n",
- __PdoGetName(Pdo),
- DevicePowerStateName(DeviceState),
- PowerActionName(PowerAction));
-
- if (DeviceState == __PdoGetDevicePowerState(Pdo)) {
- status = PdoForwardIrpSynchronously(Pdo, Irp);
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- goto done;
- }
-
- status = (DeviceState < __PdoGetDevicePowerState(Pdo)) ?
- PdoQueryDevicePowerUp(Pdo, Irp) :
- PdoQueryDevicePowerDown(Pdo, Irp);
-
-done:
- Trace("%s: <==== (%s:%s)(%08x)\n",
- __PdoGetName(Pdo),
- DevicePowerStateName(DeviceState),
- PowerActionName(PowerAction),
- status);
- return status;
-}
-
-static NTSTATUS
-PdoQuerySystemPowerUp(
- IN PXENFILT_PDO Pdo,
- IN PIRP Irp
- )
-{
- PIO_STACK_LOCATION StackLocation;
- SYSTEM_POWER_STATE SystemState;
- NTSTATUS status;
-
- StackLocation = IoGetCurrentIrpStackLocation(Irp);
- SystemState = StackLocation->Parameters.Power.State.SystemState;
-
- ASSERT3U(SystemState, <, __PdoGetSystemPowerState(Pdo));
-
- status = PdoForwardIrpSynchronously(Pdo, Irp);
-
- Irp->IoStatus.Status = status;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- return status;
+ IoCopyCurrentIrpStackLocationToNext(Irp);
+ IoSetCompletionRoutine(Irp,
+ PdoSetSystemPowerUpComplete,
+ Pdo,
+ TRUE,
+ TRUE,
+ TRUE);
+ return IoCallDriver(Pdo->LowerDeviceObject, Irp);
}
-static NTSTATUS
-PdoQuerySystemPowerDown(
+static FORCEINLINE NTSTATUS
+__PdoSetSystemPowerDown(
IN PXENFILT_PDO Pdo,
IN PIRP Irp
)
{
PIO_STACK_LOCATION StackLocation;
SYSTEM_POWER_STATE SystemState;
- NTSTATUS status;
StackLocation = IoGetCurrentIrpStackLocation(Irp);
SystemState = StackLocation->Parameters.Power.State.SystemState;
ASSERT3U(SystemState, >, __PdoGetSystemPowerState(Pdo));
- status = PdoForwardIrpSynchronously(Pdo, Irp);
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ Trace("%s: %s -> %s\n",
+ __PdoGetName(Pdo),
+ SystemPowerStateName(__PdoGetSystemPowerState(Pdo)),
+ SystemPowerStateName(SystemState));
- return status;
+ __PdoSetSystemPowerState(Pdo, SystemState);
+
+ IoSkipCurrentIrpStackLocation(Irp);
+ return IoCallDriver(Pdo->LowerDeviceObject, Irp);
}
static NTSTATUS
-PdoQuerySystemPower(
+PdoSetSystemPower(
IN PXENFILT_PDO Pdo,
IN PIRP Irp
)
@@ -1550,15 +1426,15 @@ PdoQuerySystemPower(
PowerActionName(PowerAction));
if (SystemState == __PdoGetSystemPowerState(Pdo)) {
- status = PdoForwardIrpSynchronously(Pdo, Irp);
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ IoSkipCurrentIrpStackLocation(Irp);
+ status = IoCallDriver(Pdo->LowerDeviceObject, Irp);
goto done;
}
status = (SystemState < __PdoGetSystemPowerState(Pdo)) ?
- PdoQuerySystemPowerUp(Pdo, Irp) :
- PdoQuerySystemPowerDown(Pdo, Irp);
+ __PdoSetSystemPowerUp(Pdo, Irp) :
+ __PdoSetSystemPowerDown(Pdo, Irp);
done:
Trace("%s: <==== (%s:%s)(%08x)\n",
@@ -1566,126 +1442,34 @@ done:
SystemPowerStateName(SystemState),
PowerActionName(PowerAction),
status);
-
return status;
}
-static NTSTATUS
-PdoDevicePower(
- IN PXENFILT_THREAD Self,
- IN PVOID Context
- )
-{
- PXENFILT_PDO Pdo = Context;
- PKEVENT Event;
-
- Event = ThreadGetEvent(Self);
-
- for (;;) {
- PIRP Irp;
- PIO_STACK_LOCATION StackLocation;
- UCHAR MinorFunction;
-
- if (Pdo->DevicePowerIrp == NULL) {
- (VOID) KeWaitForSingleObject(Event,
- Executive,
- KernelMode,
- FALSE,
- NULL);
- KeClearEvent(Event);
- }
-
- if (ThreadIsAlerted(Self))
- break;
-
- Irp = Pdo->DevicePowerIrp;
-
- if (Irp == NULL)
- continue;
-
- Pdo->DevicePowerIrp = NULL;
- KeMemoryBarrier();
-
- StackLocation = IoGetCurrentIrpStackLocation(Irp);
- MinorFunction = StackLocation->MinorFunction;
-
- switch (StackLocation->MinorFunction) {
- case IRP_MN_SET_POWER:
- (VOID) PdoSetDevicePower(Pdo, Irp);
- break;
-
- case IRP_MN_QUERY_POWER:
- (VOID) PdoQueryDevicePower(Pdo, Irp);
- break;
-
- default:
- ASSERT(FALSE);
- break;
- }
-
- IoReleaseRemoveLock(&Pdo->Dx->RemoveLock, Irp);
- }
-
- return STATUS_SUCCESS;
-}
-
-static NTSTATUS
-PdoSystemPower(
- IN PXENFILT_THREAD Self,
- IN PVOID Context
+static FORCEINLINE NTSTATUS
+__PdoDispatchSystemPower(
+ IN PXENFILT_PDO Pdo,
+ IN PIRP Irp
)
{
- PXENFILT_PDO Pdo = Context;
- PKEVENT Event;
-
- Event = ThreadGetEvent(Self);
-
- for (;;) {
- PIRP Irp;
- PIO_STACK_LOCATION StackLocation;
- UCHAR MinorFunction;
-
- if (Pdo->SystemPowerIrp == NULL) {
- (VOID) KeWaitForSingleObject(Event,
- Executive,
- KernelMode,
- FALSE,
- NULL);
- KeClearEvent(Event);
- }
-
- if (ThreadIsAlerted(Self))
- break;
-
- Irp = Pdo->SystemPowerIrp;
-
- if (Irp == NULL)
- continue;
-
- Pdo->SystemPowerIrp = NULL;
- KeMemoryBarrier();
-
- StackLocation = IoGetCurrentIrpStackLocation(Irp);
- MinorFunction = StackLocation->MinorFunction;
-
- switch (StackLocation->MinorFunction) {
- case IRP_MN_SET_POWER:
- (VOID) PdoSetSystemPower(Pdo, Irp);
- break;
+ PIO_STACK_LOCATION StackLocation;
+ UCHAR MinorFunction;
+ NTSTATUS status;
- case IRP_MN_QUERY_POWER:
- (VOID) PdoQuerySystemPower(Pdo, Irp);
- break;
+ StackLocation = IoGetCurrentIrpStackLocation(Irp);
+ MinorFunction = StackLocation->MinorFunction;
- default:
- ASSERT(FALSE);
- break;
- }
+ switch (MinorFunction) {
+ case IRP_MN_SET_POWER:
+ status = PdoSetSystemPower(Pdo, Irp);
+ break;
- IoReleaseRemoveLock(&Pdo->Dx->RemoveLock, Irp);
+ default:
+ IoSkipCurrentIrpStackLocation(Irp);
+ status = IoCallDriver(Pdo->LowerDeviceObject, Irp);
+ break;
}
- return STATUS_SUCCESS;
+ return status;
}
static NTSTATUS
@@ -1706,8 +1490,7 @@ PdoDispatchPower(
StackLocation = IoGetCurrentIrpStackLocation(Irp);
MinorFunction = StackLocation->MinorFunction;
- if (MinorFunction != IRP_MN_QUERY_POWER &&
- MinorFunction != IRP_MN_SET_POWER) {
+ if (MinorFunction != IRP_MN_SET_POWER) {
IoSkipCurrentIrpStackLocation(Irp);
status = IoCallDriver(Pdo->LowerDeviceObject, Irp);
@@ -1725,27 +1508,13 @@ PdoDispatchPower(
switch (PowerType) {
case DevicePowerState:
- IoMarkIrpPending(Irp);
-
- ASSERT3P(Pdo->DevicePowerIrp, ==, NULL);
- Pdo->DevicePowerIrp = Irp;
- KeMemoryBarrier();
-
- ThreadWake(Pdo->DevicePowerThread);
-
- status = STATUS_PENDING;
+ status = __PdoDispatchDevicePower(Pdo, Irp);
+ IoReleaseRemoveLock(&Pdo->Dx->RemoveLock, Irp);
break;
case SystemPowerState:
- IoMarkIrpPending(Irp);
-
- ASSERT3P(Pdo->SystemPowerIrp, ==, NULL);
- Pdo->SystemPowerIrp = Irp;
- KeMemoryBarrier();
-
- ThreadWake(Pdo->SystemPowerThread);
-
- status = STATUS_PENDING;
+ status = __PdoDispatchSystemPower(Pdo, Irp);
+ IoReleaseRemoveLock(&Pdo->Dx->RemoveLock, Irp);
break;
default:
@@ -1908,17 +1677,9 @@ PdoCreate(
Pdo->LowerDeviceObject = LowerDeviceObject;
Pdo->Type = Type;
- status = ThreadCreate(PdoSystemPower, Pdo, &Pdo->SystemPowerThread);
- if (!NT_SUCCESS(status))
- goto fail4;
-
- status = ThreadCreate(PdoDevicePower, Pdo, &Pdo->DevicePowerThread);
- if (!NT_SUCCESS(status))
- goto fail5;
-
status = PdoSetDeviceInformation(Pdo);
if (!NT_SUCCESS(status))
- goto fail6;
+ goto fail4;
status = DriverQueryId(Pdo->LowerDeviceObject,
BusQueryCompatibleIDs,
@@ -1933,7 +1694,7 @@ PdoCreate(
__PdoGetType(Pdo),
&Pdo->EmulatedObject);
if (!NT_SUCCESS(status))
- goto fail7;
+ goto fail5;
if (CompatibleIDs)
ExFreePool(CompatibleIDs);
@@ -1958,28 +1719,14 @@ PdoCreate(
return STATUS_SUCCESS;
-fail7:
- Error("fail7\n");
+fail5:
+ Error("fail5\n");
if (CompatibleIDs)
ExFreePool(CompatibleIDs);
PdoClearDeviceInformation(Pdo);
-fail6:
- Error("fail6\n");
-
- ThreadAlert(Pdo->DevicePowerThread);
- ThreadJoin(Pdo->DevicePowerThread);
- Pdo->DevicePowerThread = NULL;
-
-fail5:
- Error("fail5\n");
-
- ThreadAlert(Pdo->SystemPowerThread);
- ThreadJoin(Pdo->SystemPowerThread);
- Pdo->SystemPowerThread = NULL;
-
fail4:
Error("fail4\n");
@@ -2041,14 +1788,6 @@ PdoDestroy(
PdoClearDeviceInformation(Pdo);
- ThreadAlert(Pdo->DevicePowerThread);
- ThreadJoin(Pdo->DevicePowerThread);
- Pdo->DevicePowerThread = NULL;
-
- ThreadAlert(Pdo->SystemPowerThread);
- ThreadJoin(Pdo->SystemPowerThread);
- Pdo->SystemPowerThread = NULL;
-
Pdo->Type = XENFILT_EMULATED_OBJECT_TYPE_UNKNOWN;
Pdo->PhysicalDeviceObject = NULL;
Pdo->LowerDeviceObject = NULL;
--
2.41.0.windows.3
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |