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