[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH] Asynchronous power handling.
From: Martin Harvey <Martin.Harvey@xxxxxxxxxx> XenDisk requires minimal IRP_MN_SET_POWER/IRP_MN_QUERY_POWER interactions. No IoWorkItems are required as operations perform no significant work. Power handlers are is limited to tracking state changes and calling PoSetPowerState. Signed-off-by: Martin Harvey <martin.harvey@xxxxxxxxxx> Refactored Signed-off-by: Owen Smith <owen.smith@xxxxxxxxx> --- src/xendisk/fdo.c | 552 +++++++++------------------------------------ src/xendisk/pdo.c | 555 +++++++++------------------------------------- 2 files changed, 209 insertions(+), 898 deletions(-) diff --git a/src/xendisk/fdo.c b/src/xendisk/fdo.c index 056e24a..2e5c0de 100644 --- a/src/xendisk/fdo.c +++ b/src/xendisk/fdo.c @@ -54,11 +54,6 @@ struct _XENDISK_FDO { PDEVICE_OBJECT LowerDeviceObject; PDEVICE_OBJECT PhysicalDeviceObject; - PXENDISK_THREAD SystemPowerThread; - PIRP SystemPowerIrp; - PXENDISK_THREAD DevicePowerThread; - PIRP DevicePowerIrp; - MUTEX Mutex; ULONG References; }; @@ -1136,36 +1131,50 @@ fail1: return status; } -static FORCEINLINE NTSTATUS -__FdoSetDevicePowerUp( - IN PXENDISK_FDO Fdo, - IN PIRP Irp +__drv_functionClass(IO_COMPLETION_ROUTINE) +__drv_sameIRQL +static NTSTATUS +FdoSetDevicePowerUpComplete( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PVOID Context ) { + PXENDISK_FDO Fdo = (PXENDISK_FDO) Context; PIO_STACK_LOCATION StackLocation; - DEVICE_POWER_STATE DeviceState; - NTSTATUS status; + POWER_STATE PowerState; - StackLocation = IoGetCurrentIrpStackLocation(Irp); - DeviceState = StackLocation->Parameters.Power.State.DeviceState; + UNREFERENCED_PARAMETER(DeviceObject); - ASSERT3U(DeviceState, <, __FdoGetDevicePowerState(Fdo)); + StackLocation = IoGetCurrentIrpStackLocation(Irp); + PowerState = StackLocation->Parameters.Power.State; - status = FdoForwardIrpSynchronously(Fdo, Irp); - if (!NT_SUCCESS(status)) - goto done; + if (Irp->PendingReturned) + IoMarkIrpPending(Irp); - Verbose("%p: %s -> %s\n", - Fdo->Dx->DeviceObject, - PowerDeviceStateName(__FdoGetDevicePowerState(Fdo)), - PowerDeviceStateName(DeviceState)); + __FdoSetDevicePowerState(Fdo, PowerState.DeviceState); + PoSetPowerState(Fdo->Dx->DeviceObject, + DevicePowerState, + PowerState); - __FdoSetDevicePowerState(Fdo, DeviceState); + return STATUS_CONTINUE_COMPLETION; +} -done: - IoCompleteRequest(Irp, IO_NO_INCREMENT); +static FORCEINLINE NTSTATUS +__FdoSetDevicePowerUp( + IN PXENDISK_FDO Fdo, + IN PIRP Irp + ) +{ + IoCopyCurrentIrpStackLocationToNext(Irp); + IoSetCompletionRoutine(Irp, + FdoSetDevicePowerUpComplete, + Fdo, + TRUE, + TRUE, + TRUE); - return status; + return IoCallDriver(Fdo->LowerDeviceObject, Irp); } static FORCEINLINE NTSTATUS @@ -1175,27 +1184,21 @@ __FdoSetDevicePowerDown( ) { PIO_STACK_LOCATION StackLocation; - DEVICE_POWER_STATE DeviceState; - NTSTATUS status; + POWER_STATE PowerState; StackLocation = IoGetCurrentIrpStackLocation(Irp); - DeviceState = StackLocation->Parameters.Power.State.DeviceState; - - ASSERT3U(DeviceState, >, __FdoGetDevicePowerState(Fdo)); - - Verbose("%p: %s -> %s\n", - Fdo->Dx->DeviceObject, - PowerDeviceStateName(__FdoGetDevicePowerState(Fdo)), - PowerDeviceStateName(DeviceState)); + PowerState = StackLocation->Parameters.Power.State; - __FdoSetDevicePowerState(Fdo, DeviceState); - - status = FdoForwardIrpSynchronously(Fdo, Irp); - IoCompleteRequest(Irp, IO_NO_INCREMENT); + __FdoSetDevicePowerState(Fdo, PowerState.DeviceState); + PoSetPowerState(Fdo->Dx->DeviceObject, + DevicePowerState, + PowerState); - return status; + IoSkipCurrentIrpStackLocation(Irp); + return IoCallDriver(Fdo->LowerDeviceObject, Irp); } +/* IRQL argnostic code, just mark power states.*/ static FORCEINLINE NTSTATUS __FdoSetDevicePower( IN PXENDISK_FDO Fdo, @@ -1216,13 +1219,12 @@ __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)) ? + status = DeviceState < __FdoGetDevicePowerState(Fdo) ? __FdoSetDevicePowerUp(Fdo, Irp) : __FdoSetDevicePowerDown(Fdo, Irp); @@ -1231,39 +1233,51 @@ done: PowerDeviceStateName(DeviceState), PowerActionName(PowerAction), status); + return status; } -static FORCEINLINE NTSTATUS -__FdoSetSystemPowerUp( - IN PXENDISK_FDO Fdo, - IN PIRP Irp +__drv_functionClass(IO_COMPLETION_ROUTINE) +__drv_sameIRQL +static NTSTATUS +FdoSetSystemPowerUpComplete( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PVOID Context ) { + PXENDISK_FDO Fdo = (PXENDISK_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)); - - status = FdoForwardIrpSynchronously(Fdo, Irp); - if (!NT_SUCCESS(status)) - goto done; - - Verbose("%p: %s -> %s\n", - Fdo->Dx->DeviceObject, - PowerSystemStateName(__FdoGetSystemPowerState(Fdo)), - PowerSystemStateName(SystemState)); + if (Irp->PendingReturned) + IoMarkIrpPending(Irp); __FdoSetSystemPowerState(Fdo, SystemState); -done: - IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_CONTINUE_COMPLETION; +} - return status; +static FORCEINLINE NTSTATUS +__FdoSetSystemPowerUp( + IN PXENDISK_FDO Fdo, + IN PIRP Irp + ) +{ + IoCopyCurrentIrpStackLocationToNext(Irp); + IoSetCompletionRoutine(Irp, + FdoSetSystemPowerUpComplete, + Fdo, + TRUE, + TRUE, + TRUE); + + return IoCallDriver(Fdo->LowerDeviceObject, Irp); } static FORCEINLINE NTSTATUS @@ -1274,29 +1288,19 @@ __FdoSetSystemPowerDown( { PIO_STACK_LOCATION StackLocation; SYSTEM_POWER_STATE SystemState; - NTSTATUS status; StackLocation = IoGetCurrentIrpStackLocation(Irp); SystemState = StackLocation->Parameters.Power.State.SystemState; - ASSERT3U(SystemState, >, __FdoGetSystemPowerState(Fdo)); - - Verbose("%p: %s -> %s\n", - Fdo->Dx->DeviceObject, - PowerSystemStateName(__FdoGetSystemPowerState(Fdo)), - PowerSystemStateName(SystemState)); - __FdoSetSystemPowerState(Fdo, SystemState); - status = FdoForwardIrpSynchronously(Fdo, Irp); - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - return status; + IoSkipCurrentIrpStackLocation(Irp); + return IoCallDriver(Fdo->LowerDeviceObject, Irp); } static FORCEINLINE NTSTATUS __FdoSetSystemPower( - IN PXENDISK_FDO Fdo, + IN PXENDISK_FDO Fdo, IN PIRP Irp ) { @@ -1314,13 +1318,12 @@ __FdoSetSystemPower( 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)) ? + status = SystemState < __FdoGetSystemPowerState(Fdo) ? __FdoSetSystemPowerUp(Fdo, Irp) : __FdoSetSystemPowerDown(Fdo, Irp); @@ -1329,310 +1332,60 @@ done: PowerSystemStateName(SystemState), PowerActionName(PowerAction), status); - return status; -} - -static FORCEINLINE NTSTATUS -__FdoQueryDevicePowerUp( - IN PXENDISK_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 FORCEINLINE NTSTATUS -__FdoQueryDevicePowerDown( - IN PXENDISK_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 FORCEINLINE NTSTATUS -__FdoQueryDevicePower( +static NTSTATUS +FdoDevicePower( IN PXENDISK_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)\n", - PowerDeviceStateName(DeviceState), - PowerActionName(PowerAction)); - - if (DeviceState == __FdoGetDevicePowerState(Fdo)) { - status = FdoForwardIrpSynchronously(Fdo, Irp); - IoCompleteRequest(Irp, IO_NO_INCREMENT); + switch (StackLocation->MinorFunction) { + case IRP_MN_SET_POWER: + status = __FdoSetDevicePower(Fdo, Irp); + break; - goto done; + default: + IoSkipCurrentIrpStackLocation(Irp); + status = IoCallDriver(Fdo->LowerDeviceObject, Irp); + break; } - status = (DeviceState < __FdoGetDevicePowerState(Fdo)) ? - __FdoQueryDevicePowerUp(Fdo, Irp) : - __FdoQueryDevicePowerDown(Fdo, Irp); - -done: - Trace("<==== (%s:%s)(%08x)\n", - PowerDeviceStateName(DeviceState), - PowerActionName(PowerAction), - status); - return status; -} - -static FORCEINLINE NTSTATUS -__FdoQuerySystemPowerUp( - IN PXENDISK_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; } -static FORCEINLINE NTSTATUS -__FdoQuerySystemPowerDown( - IN PXENDISK_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; -} - -static FORCEINLINE NTSTATUS -__FdoQuerySystemPower( +static NTSTATUS +FdoSystemPower( IN PXENDISK_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)\n", - PowerSystemStateName(SystemState), - PowerActionName(PowerAction)); - if (SystemState == __FdoGetSystemPowerState(Fdo)) { - status = FdoForwardIrpSynchronously(Fdo, Irp); - IoCompleteRequest(Irp, IO_NO_INCREMENT); + switch (StackLocation->MinorFunction) { + case IRP_MN_SET_POWER: + status = __FdoSetSystemPower(Fdo, Irp); + break; - goto done; + default: + IoSkipCurrentIrpStackLocation(Irp); + status = IoCallDriver(Fdo->LowerDeviceObject, Irp); + break; } - status = (SystemState < __FdoGetSystemPowerState(Fdo)) ? - __FdoQuerySystemPowerUp(Fdo, Irp) : - __FdoQuerySystemPowerDown(Fdo, Irp); - -done: - Trace("<==== (%s:%s)(%08x)\n", - PowerSystemStateName(SystemState), - PowerActionName(PowerAction), - status); - return status; } -static NTSTATUS -FdoDevicePower( - IN PXENDISK_THREAD Self, - IN PVOID Context - ) -{ - PXENDISK_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 PXENDISK_THREAD Self, - IN PVOID Context - ) -{ - PXENDISK_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; -} - -__drv_functionClass(IO_COMPLETION_ROUTINE) -__drv_sameIRQL -static NTSTATUS -__FdoDispatchPower( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp, - IN PVOID Context - ) -{ - PXENDISK_FDO Fdo = Context; - - UNREFERENCED_PARAMETER(DeviceObject); - - if (Irp->PendingReturned) - IoMarkIrpPending(Irp); - - IoReleaseRemoveLock(&Fdo->Dx->RemoveLock, Irp); - return STATUS_SUCCESS; -} - static DECLSPEC_NOINLINE NTSTATUS FdoDispatchPower( IN PXENDISK_FDO Fdo, @@ -1640,90 +1393,27 @@ 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; - StackLocation = IoGetCurrentIrpStackLocation(Irp); - MinorFunction = StackLocation->MinorFunction; - - if (MinorFunction != IRP_MN_QUERY_POWER && - MinorFunction != IRP_MN_SET_POWER) { - IoCopyCurrentIrpStackLocationToNext(Irp); - IoSetCompletionRoutine(Irp, - __FdoDispatchPower, - Fdo, - TRUE, - TRUE, - TRUE); - - status = IoCallDriver(Fdo->LowerDeviceObject, Irp); - - goto done; - } - PowerType = StackLocation->Parameters.Power.Type; - Trace("====> (%02x:%s)\n", - MinorFunction, - PowerMinorFunctionName(MinorFunction)); - switch (PowerType) { case DevicePowerState: - IoMarkIrpPending(Irp); - - ASSERT3P(Fdo->DevicePowerIrp, ==, NULL); - Fdo->DevicePowerIrp = Irp; - KeMemoryBarrier(); - - ThreadWake(Fdo->DevicePowerThread); - - status = STATUS_PENDING; + status = FdoDevicePower(Fdo, Irp); break; case SystemPowerState: - IoMarkIrpPending(Irp); - - ASSERT3P(Fdo->SystemPowerIrp, ==, NULL); - Fdo->SystemPowerIrp = Irp; - KeMemoryBarrier(); - - ThreadWake(Fdo->SystemPowerThread); - - status = STATUS_PENDING; + status = FdoSystemPower(Fdo, Irp); break; default: - IoCopyCurrentIrpStackLocationToNext(Irp); - IoSetCompletionRoutine(Irp, - __FdoDispatchPower, - Fdo, - TRUE, - TRUE, - TRUE); - + IoSkipCurrentIrpStackLocation(Irp); status = IoCallDriver(Fdo->LowerDeviceObject, Irp); break; } - Trace("<==== (%02x:%s) (%08x)\n", - MinorFunction, - PowerMinorFunctionName(MinorFunction), - status); - -done: - return status; - -fail1: - Error("fail1 (%08x)\n", status); - - Irp->IoStatus.Status = status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return status; } @@ -1864,14 +1554,6 @@ FdoCreate( Fdo->PhysicalDeviceObject = PhysicalDeviceObject; Fdo->LowerDeviceObject = LowerDeviceObject; - status = ThreadCreate(FdoSystemPower, Fdo, &Fdo->SystemPowerThread); - if (!NT_SUCCESS(status)) - goto fail4; - - status = ThreadCreate(FdoDevicePower, Fdo, &Fdo->DevicePowerThread); - if (!NT_SUCCESS(status)) - goto fail5; - InitializeMutex(&Fdo->Mutex); InitializeListHead(&Dx->ListEntry); Fdo->References = 1; @@ -1889,22 +1571,6 @@ FdoCreate( return STATUS_SUCCESS; -fail5: - Error("fail5\n"); - - ThreadAlert(Fdo->SystemPowerThread); - ThreadJoin(Fdo->SystemPowerThread); - Fdo->SystemPowerThread = NULL; - -fail4: - Error("fail4\n"); - - Fdo->PhysicalDeviceObject = NULL; - Fdo->LowerDeviceObject = NULL; - Fdo->Dx = NULL; - - IoDetachDevice(LowerDeviceObject); - fail3: Error("fail3\n"); @@ -1939,14 +1605,6 @@ FdoDestroy( RtlZeroMemory(&Fdo->Mutex, sizeof (MUTEX)); - ThreadAlert(Fdo->DevicePowerThread); - ThreadJoin(Fdo->DevicePowerThread); - Fdo->DevicePowerThread = NULL; - - ThreadAlert(Fdo->SystemPowerThread); - ThreadJoin(Fdo->SystemPowerThread); - Fdo->SystemPowerThread = NULL; - Fdo->LowerDeviceObject = NULL; Fdo->PhysicalDeviceObject = NULL; Fdo->Dx = NULL; diff --git a/src/xendisk/pdo.c b/src/xendisk/pdo.c index 321ecf3..f714efb 100644 --- a/src/xendisk/pdo.c +++ b/src/xendisk/pdo.c @@ -60,11 +60,6 @@ struct _XENDISK_PDO { PDEVICE_OBJECT PhysicalDeviceObject; CHAR Name[MAXNAMELEN]; - PXENDISK_THREAD SystemPowerThread; - PIRP SystemPowerIrp; - PXENDISK_THREAD DevicePowerThread; - PIRP DevicePowerIrp; - PXENDISK_FDO Fdo; BOOLEAN InterceptTrim; @@ -1416,37 +1411,50 @@ fail1: return status; } -static FORCEINLINE NTSTATUS -__PdoSetDevicePowerUp( - IN PXENDISK_PDO Pdo, - IN PIRP Irp +__drv_functionClass(IO_COMPLETION_ROUTINE) +__drv_sameIRQL +static NTSTATUS +PdoSetDevicePowerUpComplete( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PVOID Context ) { + PXENDISK_PDO Pdo = (PXENDISK_PDO) Context; PIO_STACK_LOCATION StackLocation; - DEVICE_POWER_STATE DeviceState; - NTSTATUS status; + POWER_STATE PowerState; - StackLocation = IoGetCurrentIrpStackLocation(Irp); - DeviceState = StackLocation->Parameters.Power.State.DeviceState; + UNREFERENCED_PARAMETER(DeviceObject); - ASSERT3U(DeviceState, <, __PdoGetDevicePowerState(Pdo)); + StackLocation = IoGetCurrentIrpStackLocation(Irp); + PowerState = StackLocation->Parameters.Power.State; - status = PdoForwardIrpSynchronously(Pdo, Irp); - if (!NT_SUCCESS(status)) - goto done; + if (Irp->PendingReturned) + IoMarkIrpPending(Irp); - Verbose("%s: %s -> %s\n", - __PdoGetName(Pdo), - PowerDeviceStateName(__PdoGetDevicePowerState(Pdo)), - PowerDeviceStateName(DeviceState)); + __PdoSetDevicePowerState(Pdo, PowerState.DeviceState); + PoSetPowerState(Pdo->Dx->DeviceObject, + DevicePowerState, + PowerState); - __PdoSetDevicePowerState(Pdo, DeviceState); + return STATUS_CONTINUE_COMPLETION; +} -done: - Irp->IoStatus.Status = status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); +static FORCEINLINE NTSTATUS +__PdoSetDevicePowerUp( + IN PXENDISK_PDO Pdo, + IN PIRP Irp + ) +{ + IoCopyCurrentIrpStackLocationToNext(Irp); + IoSetCompletionRoutine(Irp, + PdoSetDevicePowerUpComplete, + Pdo, + TRUE, + TRUE, + TRUE); - return status; + return IoCallDriver(Pdo->LowerDeviceObject, Irp); } static FORCEINLINE NTSTATUS @@ -1456,25 +1464,18 @@ __PdoSetDevicePowerDown( ) { PIO_STACK_LOCATION StackLocation; - DEVICE_POWER_STATE DeviceState; - NTSTATUS status; + POWER_STATE PowerState; StackLocation = IoGetCurrentIrpStackLocation(Irp); - DeviceState = StackLocation->Parameters.Power.State.DeviceState; - - ASSERT3U(DeviceState, >, __PdoGetDevicePowerState(Pdo)); - - Verbose("%s: %s -> %s\n", - __PdoGetName(Pdo), - PowerDeviceStateName(__PdoGetDevicePowerState(Pdo)), - PowerDeviceStateName(DeviceState)); + PowerState = StackLocation->Parameters.Power.State; - __PdoSetDevicePowerState(Pdo, DeviceState); - - status = PdoForwardIrpSynchronously(Pdo, Irp); - IoCompleteRequest(Irp, IO_NO_INCREMENT); + __PdoSetDevicePowerState(Pdo, PowerState.DeviceState); + PoSetPowerState(Pdo->Dx->DeviceObject, + DevicePowerState, + PowerState); - return status; + IoSkipCurrentIrpStackLocation(Irp); + return IoCallDriver(Pdo->LowerDeviceObject, Irp); } static FORCEINLINE NTSTATUS @@ -1497,13 +1498,12 @@ __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)) ? + status = DeviceState < __PdoGetDevicePowerState(Pdo) ? __PdoSetDevicePowerUp(Pdo, Irp) : __PdoSetDevicePowerDown(Pdo, Irp); @@ -1512,40 +1512,51 @@ done: PowerDeviceStateName(DeviceState), PowerActionName(PowerAction), status); + return status; } -static FORCEINLINE NTSTATUS -__PdoSetSystemPowerUp( - IN PXENDISK_PDO Pdo, - IN PIRP Irp +__drv_functionClass(IO_COMPLETION_ROUTINE) +__drv_sameIRQL +static NTSTATUS +PdoSetSystemPowerUpComplete( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PVOID Context ) { + PXENDISK_PDO Pdo = (PXENDISK_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)); - - status = PdoForwardIrpSynchronously(Pdo, Irp); - if (!NT_SUCCESS(status)) - goto done; - - Verbose("%s: %s -> %s\n", - __PdoGetName(Pdo), - PowerSystemStateName(__PdoGetSystemPowerState(Pdo)), - PowerSystemStateName(SystemState)); + if (Irp->PendingReturned) + IoMarkIrpPending(Irp); __PdoSetSystemPowerState(Pdo, SystemState); -done: - Irp->IoStatus.Status = status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_CONTINUE_COMPLETION; +} - return status; +static FORCEINLINE NTSTATUS +__PdoSetSystemPowerUp( + IN PXENDISK_PDO Pdo, + IN PIRP Irp + ) +{ + IoCopyCurrentIrpStackLocationToNext(Irp); + IoSetCompletionRoutine(Irp, + PdoSetSystemPowerUpComplete, + Pdo, + TRUE, + TRUE, + TRUE); + + return IoCallDriver(Pdo->LowerDeviceObject, Irp); } static FORCEINLINE NTSTATUS @@ -1556,24 +1567,14 @@ __PdoSetSystemPowerDown( { PIO_STACK_LOCATION StackLocation; SYSTEM_POWER_STATE SystemState; - NTSTATUS status; StackLocation = IoGetCurrentIrpStackLocation(Irp); SystemState = StackLocation->Parameters.Power.State.SystemState; - ASSERT3U(SystemState, >, __PdoGetSystemPowerState(Pdo)); - - Verbose("%s: %s -> %s\n", - __PdoGetName(Pdo), - PowerSystemStateName(__PdoGetSystemPowerState(Pdo)), - PowerSystemStateName(SystemState)); - __PdoSetSystemPowerState(Pdo, SystemState); - status = PdoForwardIrpSynchronously(Pdo, Irp); - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - return status; + IoSkipCurrentIrpStackLocation(Irp); + return IoCallDriver(Pdo->LowerDeviceObject, Irp); } static FORCEINLINE NTSTATUS @@ -1596,13 +1597,12 @@ __PdoSetSystemPower( 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)) ? + status = SystemState < __PdoGetSystemPowerState(Pdo) ? __PdoSetSystemPowerUp(Pdo, Irp) : __PdoSetSystemPowerDown(Pdo, Irp); @@ -1611,403 +1611,88 @@ done: PowerSystemStateName(SystemState), PowerActionName(PowerAction), status); - return status; -} - -static FORCEINLINE NTSTATUS -__PdoQueryDevicePowerUp( - IN PXENDISK_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 FORCEINLINE NTSTATUS -__PdoQueryDevicePowerDown( +static NTSTATUS +PdoDevicePower( IN PXENDISK_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 FORCEINLINE NTSTATUS -__PdoQueryDevicePower( - IN PXENDISK_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)\n", - PowerDeviceStateName(DeviceState), - PowerActionName(PowerAction)); - - if (DeviceState == __PdoGetDevicePowerState(Pdo)) { - status = PdoForwardIrpSynchronously(Pdo, Irp); - IoCompleteRequest(Irp, IO_NO_INCREMENT); + switch (StackLocation->MinorFunction) { + case IRP_MN_SET_POWER: + status = __PdoSetDevicePower(Pdo, Irp); + break; - goto done; + default: + IoSkipCurrentIrpStackLocation(Irp); + status = IoCallDriver(Pdo->LowerDeviceObject, Irp); + break; } - status = (DeviceState < __PdoGetDevicePowerState(Pdo)) ? - __PdoQueryDevicePowerUp(Pdo, Irp) : - __PdoQueryDevicePowerDown(Pdo, Irp); - -done: - Trace("<==== (%s:%s)(%08x)\n", - PowerDeviceStateName(DeviceState), - PowerActionName(PowerAction), - status); - return status; -} - -static FORCEINLINE NTSTATUS -__PdoQuerySystemPowerUp( - IN PXENDISK_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 FORCEINLINE NTSTATUS -__PdoQuerySystemPowerDown( +static NTSTATUS +PdoSystemPower( IN PXENDISK_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; -} - -static FORCEINLINE NTSTATUS -__PdoQuerySystemPower( - IN PXENDISK_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)\n", - PowerSystemStateName(SystemState), - PowerActionName(PowerAction)); - - if (SystemState == __PdoGetSystemPowerState(Pdo)) { - status = PdoForwardIrpSynchronously(Pdo, Irp); - IoCompleteRequest(Irp, IO_NO_INCREMENT); + switch (StackLocation->MinorFunction) { + case IRP_MN_SET_POWER: + status = __PdoSetSystemPower(Pdo, Irp); + break; - goto done; + default: + IoSkipCurrentIrpStackLocation(Irp); + status = IoCallDriver(Pdo->LowerDeviceObject, Irp); + break; } - status = (SystemState < __PdoGetSystemPowerState(Pdo)) ? - __PdoQuerySystemPowerUp(Pdo, Irp) : - __PdoQuerySystemPowerDown(Pdo, Irp); - -done: - Trace("<==== (%s:%s)(%08x)\n", - PowerSystemStateName(SystemState), - PowerActionName(PowerAction), - status); - return status; } -static NTSTATUS -PdoDevicePower( - IN PXENDISK_THREAD Self, - IN PVOID Context - ) -{ - PXENDISK_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 PXENDISK_THREAD Self, - IN PVOID Context - ) -{ - PXENDISK_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; -} - -__drv_functionClass(IO_COMPLETION_ROUTINE) -__drv_sameIRQL -static NTSTATUS -__PdoDispatchPower( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp, - IN PVOID Context - ) -{ - PXENDISK_PDO Pdo = Context; - - UNREFERENCED_PARAMETER(DeviceObject); - - if (Irp->PendingReturned) - IoMarkIrpPending(Irp); - - IoReleaseRemoveLock(&Pdo->Dx->RemoveLock, Irp); - return STATUS_SUCCESS; -} - static DECLSPEC_NOINLINE NTSTATUS PdoDispatchPower( - IN PXENDISK_PDO Pdo, + IN PXENDISK_PDO Pdo, IN PIRP Irp ) { PIO_STACK_LOCATION StackLocation; - UCHAR MinorFunction; POWER_STATE_TYPE PowerType; NTSTATUS status; - status = IoAcquireRemoveLock(&Pdo->Dx->RemoveLock, Irp); - if (!NT_SUCCESS(status)) - goto fail1; - StackLocation = IoGetCurrentIrpStackLocation(Irp); - MinorFunction = StackLocation->MinorFunction; - - if (MinorFunction != IRP_MN_QUERY_POWER && - MinorFunction != IRP_MN_SET_POWER) { - IoCopyCurrentIrpStackLocationToNext(Irp); - IoSetCompletionRoutine(Irp, - __PdoDispatchPower, - Pdo, - TRUE, - TRUE, - TRUE); - - status = IoCallDriver(Pdo->LowerDeviceObject, Irp); - - goto done; - } - PowerType = StackLocation->Parameters.Power.Type; - Trace("====> (%02x:%s)\n", - MinorFunction, - PowerMinorFunctionName(MinorFunction)); - switch (PowerType) { case DevicePowerState: - IoMarkIrpPending(Irp); - - ASSERT3P(Pdo->DevicePowerIrp, ==, NULL); - Pdo->DevicePowerIrp = Irp; - KeMemoryBarrier(); - - ThreadWake(Pdo->DevicePowerThread); - - status = STATUS_PENDING; + status = PdoDevicePower(Pdo, Irp); break; case SystemPowerState: - IoMarkIrpPending(Irp); - - ASSERT3P(Pdo->SystemPowerIrp, ==, NULL); - Pdo->SystemPowerIrp = Irp; - KeMemoryBarrier(); - - ThreadWake(Pdo->SystemPowerThread); - - status = STATUS_PENDING; + status = PdoSystemPower(Pdo, Irp); break; default: - IoCopyCurrentIrpStackLocationToNext(Irp); - IoSetCompletionRoutine(Irp, - __PdoDispatchPower, - Pdo, - TRUE, - TRUE, - TRUE); - + IoSkipCurrentIrpStackLocation(Irp); status = IoCallDriver(Pdo->LowerDeviceObject, Irp); break; } - Trace("<==== (%02x:%s) (%08x)\n", - MinorFunction, - PowerMinorFunctionName(MinorFunction), - status); - -done: - return status; - -fail1: - Error("fail1 (%08x)\n", status); - - Irp->IoStatus.Status = status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return status; } @@ -2157,14 +1842,6 @@ PdoCreate( Pdo->PhysicalDeviceObject = PhysicalDeviceObject; Pdo->LowerDeviceObject = LowerDeviceObject; - status = ThreadCreate(PdoSystemPower, Pdo, &Pdo->SystemPowerThread); - if (!NT_SUCCESS(status)) - goto fail4; - - status = ThreadCreate(PdoDevicePower, Pdo, &Pdo->DevicePowerThread); - if (!NT_SUCCESS(status)) - goto fail5; - __PdoSetName(Pdo, DeviceID, InstanceID); ParametersKey = DriverGetParametersKey(); @@ -2192,22 +1869,6 @@ PdoCreate( return STATUS_SUCCESS; -fail5: - Error("fail5\n"); - - ThreadAlert(Pdo->SystemPowerThread); - ThreadJoin(Pdo->SystemPowerThread); - Pdo->SystemPowerThread = NULL; - -fail4: - Error("fail4\n"); - - Pdo->PhysicalDeviceObject = NULL; - Pdo->LowerDeviceObject = NULL; - Pdo->Dx = NULL; - - IoDetachDevice(LowerDeviceObject); - fail3: Error("fail3\n"); @@ -2246,14 +1907,6 @@ PdoDestroy( RtlZeroMemory(Pdo->Name, sizeof (Pdo->Name)); - ThreadAlert(Pdo->DevicePowerThread); - ThreadJoin(Pdo->DevicePowerThread); - Pdo->DevicePowerThread = NULL; - - ThreadAlert(Pdo->SystemPowerThread); - ThreadJoin(Pdo->SystemPowerThread); - Pdo->SystemPowerThread = NULL; - Pdo->PhysicalDeviceObject = NULL; Pdo->LowerDeviceObject = NULL; Pdo->Dx = NULL; -- 2.41.0.windows.3
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |