[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH] Asynchronous power handling.
From: Martin Harvey <Martin.Harvey@xxxxxxxxxx> Use completion routines and IO_WORKITEMs to handle power state transitions, allowing execution to run at PASSIVE_LEVEL without blocking the current thread, and avoid blocking all power IRPs while another is executing (power IRPs should be synchronized by the power manager, but this doesnt appear to be the case in all situations). Signed-off-by: Martin Harvey <martin.harvey@xxxxxxxxxx> Refactored, wrong format comments removed Signed-off-by: Owen Smith <owen.smith@xxxxxxxxx> --- src/xenvif/fdo.c | 810 +++++++++++++++++++++++++++++------------------ src/xenvif/pdo.c | 263 +++++++-------- 2 files changed, 602 insertions(+), 471 deletions(-) diff --git a/src/xenvif/fdo.c b/src/xenvif/fdo.c index 451d582..efcd131 100644 --- a/src/xenvif/fdo.c +++ b/src/xenvif/fdo.c @@ -81,9 +81,9 @@ struct _XENVIF_FDO { ULONG Usage[DeviceUsageTypeDumpFile + 1]; BOOLEAN NotDisableable; - PXENVIF_THREAD SystemPowerThread; + PIO_WORKITEM SystemPowerWorkItem; PIRP SystemPowerIrp; - PXENVIF_THREAD DevicePowerThread; + PIO_WORKITEM DevicePowerWorkItem; PIRP DevicePowerIrp; CHAR VendorName[MAXNAMELEN]; @@ -2168,42 +2168,112 @@ FdoDispatchPnp( return status; } -static FORCEINLINE NTSTATUS -__FdoSetDevicePowerUp( - IN PXENVIF_FDO Fdo, - IN PIRP Irp +__drv_functionClass(IO_WORKITEM_ROUTINE) +__drv_sameIRQL +static VOID +FdoDevicePowerUpWorker( + IN PDEVICE_OBJECT DeviceObject, + IN PVOID Context ) { + PXENVIF_FDO Fdo = (PXENVIF_FDO) Context; + PIRP Irp; + + UNREFERENCED_PARAMETER(DeviceObject); + + Irp = InterlockedExchangePointer(&Fdo->DevicePowerIrp, NULL); + ASSERT(Irp != NULL); + + (VOID) FdoD3ToD0(Fdo); + + IoCompleteRequest(Irp, IO_NO_INCREMENT); +} + +__drv_functionClass(IO_COMPLETION_ROUTINE) +__drv_sameIRQL +static NTSTATUS +FdoSetDevicePowerUpComplete( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PVOID Context + ) +{ + PXENVIF_FDO Fdo = (PXENVIF_FDO) Context; PIO_STACK_LOCATION StackLocation; DEVICE_POWER_STATE DeviceState; - NTSTATUS status; + PVOID Exchange; - Trace("====>\n"); + UNREFERENCED_PARAMETER(DeviceObject); StackLocation = IoGetCurrentIrpStackLocation(Irp); DeviceState = StackLocation->Parameters.Power.State.DeviceState; - ASSERT3U(DeviceState, <, __FdoGetDevicePowerState(Fdo)); - - status = FdoForwardIrpSynchronously(Fdo, Irp); - if (!NT_SUCCESS(status)) - goto done; - Info("%s: %s -> %s\n", __FdoGetName(Fdo), PowerDeviceStateName(__FdoGetDevicePowerState(Fdo)), PowerDeviceStateName(DeviceState)); ASSERT3U(DeviceState, ==, PowerDeviceD0); - status = FdoD3ToD0(Fdo); - ASSERT(NT_SUCCESS(status)); -done: - Irp->IoStatus.Status = status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); + Exchange = InterlockedExchangePointer(&Fdo->DevicePowerIrp, Irp); + ASSERT(Exchange == NULL); - Trace("<==== (%08x)\n", status); - return status; + IoQueueWorkItem(Fdo->DevicePowerWorkItem, + FdoDevicePowerUpWorker, + DelayedWorkQueue, + Fdo); + + return STATUS_MORE_PROCESSING_REQUIRED; +} + +static FORCEINLINE NTSTATUS +__FdoSetDevicePowerUp( + IN PXENVIF_FDO Fdo, + IN PIRP Irp + ) +{ + PIO_STACK_LOCATION StackLocation; + DEVICE_POWER_STATE DeviceState; + + StackLocation = IoGetCurrentIrpStackLocation(Irp); + DeviceState = StackLocation->Parameters.Power.State.DeviceState; + + ASSERT3U(DeviceState, <, __FdoGetDevicePowerState(Fdo)); + + IoMarkIrpPending(Irp); + IoCopyCurrentIrpStackLocationToNext(Irp); + IoSetCompletionRoutine(Irp, + FdoSetDevicePowerUpComplete, + Fdo, + TRUE, + TRUE, + TRUE); + + (VOID) IoCallDriver(Fdo->LowerDeviceObject, Irp); + + return STATUS_PENDING; +} + +__drv_functionClass(IO_WORKITEM_ROUTINE) +__drv_sameIRQL +static VOID +FdoDevicePowerDownWorker( + IN PDEVICE_OBJECT DeviceObject, + IN PVOID Context + ) +{ + PXENVIF_FDO Fdo = (PXENVIF_FDO) Context; + PIRP Irp; + + UNREFERENCED_PARAMETER(DeviceObject); + + Irp = InterlockedExchangePointer(&Fdo->DevicePowerIrp, NULL); + ASSERT(Irp != NULL); + + FdoD0ToD3(Fdo); + + IoCopyCurrentIrpStackLocationToNext(Irp); + IoCallDriver(Fdo->LowerDeviceObject, Irp); } static FORCEINLINE NTSTATUS @@ -2228,11 +2298,24 @@ __FdoSetDevicePowerDown( ASSERT3U(DeviceState, ==, PowerDeviceD3); - if (__FdoGetDevicePowerState(Fdo) == PowerDeviceD0) - FdoD0ToD3(Fdo); + if (__FdoGetDevicePowerState(Fdo) != PowerDeviceD0) { + IoSkipCurrentIrpStackLocation(Irp); + status = IoCallDriver(Fdo->LowerDeviceObject, Irp); + } else { + PVOID Exchange; - IoSkipCurrentIrpStackLocation(Irp); - status = IoCallDriver(Fdo->LowerDeviceObject, Irp); + IoMarkIrpPending(Irp); + + Exchange = InterlockedExchangePointer(&Fdo->DevicePowerIrp, Irp); + ASSERT(Exchange == NULL); + + IoQueueWorkItem(Fdo->DevicePowerWorkItem, + FdoDevicePowerDownWorker, + DelayedWorkQueue, + Fdo); + + status = STATUS_PENDING; + } return status; } @@ -2252,12 +2335,11 @@ __FdoSetDevicePower( DeviceState = StackLocation->Parameters.Power.State.DeviceState; PowerAction = StackLocation->Parameters.Power.ShutdownType; - Trace("====> (%s:%s)\n", - PowerDeviceStateName(DeviceState), + Trace("%s: ====> (%s:%s)\n", + __FdoGetName(Fdo), + PowerDeviceStateName(DeviceState), PowerActionName(PowerAction)); - ASSERT3U(PowerAction, <, PowerActionShutdown); - if (DeviceState == __FdoGetDevicePowerState(Fdo)) { IoSkipCurrentIrpStackLocation(Irp); status = IoCallDriver(Fdo->LowerDeviceObject, Irp); @@ -2270,8 +2352,9 @@ __FdoSetDevicePower( __FdoSetDevicePowerDown(Fdo, Irp); done: - Trace("<==== (%s:%s)(%08x)\n", - PowerDeviceStateName(DeviceState), + Trace("%s: <==== (%s:%s)(%08x)\n", + __FdoGetName(Fdo), + PowerDeviceStateName(DeviceState), PowerActionName(PowerAction), status); return status; @@ -2279,8 +2362,8 @@ done: __drv_functionClass(REQUEST_POWER_COMPLETE) __drv_sameIRQL -VOID -__FdoRequestSetDevicePower( +static VOID +FdoRequestSetDevicePowerUpComplete( IN PDEVICE_OBJECT DeviceObject, IN UCHAR MinorFunction, IN POWER_STATE PowerState, @@ -2288,47 +2371,123 @@ __FdoRequestSetDevicePower( IN PIO_STATUS_BLOCK IoStatus ) { - PKEVENT Event = Context; + PIRP Irp = (PIRP) Context; UNREFERENCED_PARAMETER(DeviceObject); UNREFERENCED_PARAMETER(MinorFunction); UNREFERENCED_PARAMETER(PowerState); + UNREFERENCED_PARAMETER(IoStatus); - ASSERT(NT_SUCCESS(IoStatus->Status)); - - KeSetEvent(Event, IO_NO_INCREMENT, FALSE); + IoCompleteRequest(Irp, IO_NO_INCREMENT); } +__drv_functionClass(IO_WORKITEM_ROUTINE) +__drv_sameIRQL static VOID -FdoRequestSetDevicePower( - IN PXENVIF_FDO Fdo, - IN DEVICE_POWER_STATE DeviceState +FdoSystemPowerUpWorker( + IN PDEVICE_OBJECT DeviceObject, + IN PVOID Context ) { - POWER_STATE PowerState; - KEVENT Event; - NTSTATUS status; + PXENVIF_FDO Fdo = (PXENVIF_FDO) Context; + PIRP Irp; + PIO_STACK_LOCATION StackLocation; + SYSTEM_POWER_STATE SystemState; + POWER_STATE PowerState; + NTSTATUS status; + + UNREFERENCED_PARAMETER(DeviceObject); - Trace("%s\n", PowerDeviceStateName(DeviceState)); + Irp = InterlockedExchangePointer(&Fdo->SystemPowerIrp, NULL); + ASSERT(Irp != NULL); - ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL); + StackLocation = IoGetCurrentIrpStackLocation(Irp);; + SystemState = StackLocation->Parameters.Power.State.SystemState; - PowerState.DeviceState = DeviceState; - KeInitializeEvent(&Event, NotificationEvent, FALSE); + Info("%s: %s -> %s\n", + __FdoGetName(Fdo), + PowerSystemStateName(__FdoGetSystemPowerState(Fdo)), + PowerSystemStateName(SystemState)); + + __FdoSetSystemPowerState(Fdo, PowerSystemHibernate); + FdoS4ToS3(Fdo); + __FdoSetSystemPowerState(Fdo, SystemState); + + PowerState.DeviceState = Fdo->LowerDeviceCapabilities.DeviceState[SystemState]; status = PoRequestPowerIrp(Fdo->LowerDeviceObject, IRP_MN_SET_POWER, PowerState, - __FdoRequestSetDevicePower, - &Event, + FdoRequestSetDevicePowerUpComplete, + Irp, NULL); - ASSERT(NT_SUCCESS(status)); - (VOID) KeWaitForSingleObject(&Event, - Executive, - KernelMode, - FALSE, - NULL); + if (!NT_SUCCESS(status)) + goto fail1; + + return; + +fail1: + Error("fail1 - but continue IRP processing. (%08x)\n", status); + IoCompleteRequest(Irp, IO_NO_INCREMENT); +} + +__drv_functionClass(IO_COMPLETION_ROUTINE) +__drv_sameIRQL +static NTSTATUS +FdoSetSystemPowerUpComplete( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PVOID Context + ) +{ + PXENVIF_FDO Fdo = (PXENVIF_FDO) Context; + PIO_STACK_LOCATION StackLocation; + SYSTEM_POWER_STATE SystemState; + POWER_STATE PowerState; + NTSTATUS status; + + UNREFERENCED_PARAMETER(DeviceObject); + + StackLocation = IoGetCurrentIrpStackLocation(Irp); + SystemState = StackLocation->Parameters.Power.State.SystemState; + + if (SystemState < PowerSystemHibernate && + __FdoGetSystemPowerState(Fdo) >= PowerSystemHibernate) { + PVOID Exchange; + + Exchange = InterlockedExchangePointer(&Fdo->SystemPowerIrp, Irp); + ASSERT(Exchange == NULL); + + IoQueueWorkItem(Fdo->SystemPowerWorkItem, + FdoSystemPowerUpWorker, + DelayedWorkQueue, + Fdo); + } else { + Info("%s: %s -> %s\n", + __FdoGetName(Fdo), + PowerSystemStateName(__FdoGetSystemPowerState(Fdo)), + PowerSystemStateName(SystemState)); + + __FdoSetSystemPowerState(Fdo, SystemState); + + PowerState.DeviceState = Fdo->LowerDeviceCapabilities.DeviceState[SystemState]; + + status = PoRequestPowerIrp(Fdo->LowerDeviceObject, + IRP_MN_SET_POWER, + PowerState, + FdoRequestSetDevicePowerUpComplete, + Irp, + NULL); + if (!NT_SUCCESS(status)) + goto fail1; + } + + return STATUS_MORE_PROCESSING_REQUIRED; + +fail1: + Error("fail1 - but continue IRP processing. (%08x)\n", status); + return STATUS_CONTINUE_COMPLETION; } static FORCEINLINE NTSTATUS @@ -2337,42 +2496,103 @@ __FdoSetSystemPowerUp( IN PIRP Irp ) { + PIO_STACK_LOCATION StackLocation; + SYSTEM_POWER_STATE SystemState; + + StackLocation = IoGetCurrentIrpStackLocation(Irp); + SystemState = StackLocation->Parameters.Power.State.SystemState; + ASSERT3U(SystemState, <, __FdoGetSystemPowerState(Fdo)); + + IoCopyCurrentIrpStackLocationToNext(Irp); + IoSetCompletionRoutine(Irp, + FdoSetSystemPowerUpComplete, + Fdo, + TRUE, + TRUE, + TRUE); + + IoCallDriver(Fdo->LowerDeviceObject, Irp); + + return STATUS_PENDING; +} + +__drv_functionClass(IO_WORKITEM_ROUTINE) +__drv_sameIRQL +static VOID +FdoSystemPowerDownWorker( + IN PDEVICE_OBJECT DeviceObject, + IN PVOID Context + ) +{ + PXENVIF_FDO Fdo = (PXENVIF_FDO) Context; + PIRP Irp; PIO_STACK_LOCATION StackLocation; SYSTEM_POWER_STATE SystemState; - DEVICE_POWER_STATE DeviceState; - NTSTATUS status; + + UNREFERENCED_PARAMETER(DeviceObject); + + Irp = InterlockedExchangePointer(&Fdo->SystemPowerIrp, NULL); + ASSERT(Irp != NULL); StackLocation = IoGetCurrentIrpStackLocation(Irp); SystemState = StackLocation->Parameters.Power.State.SystemState; - ASSERT3U(SystemState, <, __FdoGetSystemPowerState(Fdo)); + __FdoSetSystemPowerState(Fdo, PowerSystemSleeping3); + FdoS3ToS4(Fdo); + __FdoSetSystemPowerState(Fdo, SystemState); - status = FdoForwardIrpSynchronously(Fdo, Irp); - if (!NT_SUCCESS(status)) - goto done; + IoCopyCurrentIrpStackLocationToNext(Irp); + IoCallDriver(Fdo->LowerDeviceObject, Irp); +} + +__drv_functionClass(REQUEST_POWER_COMPLETE) +__drv_sameIRQL +static VOID +FdoRequestSetDevicePowerDownComplete( + IN PDEVICE_OBJECT DeviceObject, + IN UCHAR MinorFunction, + IN POWER_STATE PowerState, + IN PVOID Context, + IN PIO_STATUS_BLOCK IoStatus + ) +{ + PIRP Irp = (PIRP) Context; + PIO_STACK_LOCATION StackLocation = IoGetCurrentIrpStackLocation(Irp); + PDEVICE_OBJECT UpperDeviceObject = StackLocation->DeviceObject; + PXENVIF_DX Dx = (PXENVIF_DX)UpperDeviceObject->DeviceExtension; + PXENVIF_FDO Fdo = Dx->Fdo; + SYSTEM_POWER_STATE SystemState = StackLocation->Parameters.Power.State.SystemState; + + UNREFERENCED_PARAMETER(DeviceObject); + UNREFERENCED_PARAMETER(MinorFunction); + UNREFERENCED_PARAMETER(PowerState); + + if (!NT_SUCCESS(IoStatus->Status)) + Error("fail1 - but continue IRP processing. (%08x)\n", IoStatus->Status); Info("%s: %s -> %s\n", __FdoGetName(Fdo), - PowerSystemStateName(__FdoGetSystemPowerState(Fdo)), - PowerSystemStateName(SystemState)); + PowerSystemStateName(__FdoGetSystemPowerState(Fdo)), + PowerSystemStateName(SystemState)); - if (SystemState < PowerSystemHibernate && - __FdoGetSystemPowerState(Fdo) >= PowerSystemHibernate) { - __FdoSetSystemPowerState(Fdo, PowerSystemHibernate); - FdoS4ToS3(Fdo); - } - - __FdoSetSystemPowerState(Fdo, SystemState); + if (SystemState >= PowerSystemHibernate && + __FdoGetSystemPowerState(Fdo) < PowerSystemHibernate) { + PVOID Exchange; - DeviceState = Fdo->LowerDeviceCapabilities.DeviceState[SystemState]; - FdoRequestSetDevicePower(Fdo, DeviceState); + Exchange = InterlockedExchangePointer(&Fdo->SystemPowerIrp, Irp); + ASSERT(Exchange == NULL); -done: - Irp->IoStatus.Status = status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); + IoQueueWorkItem(Fdo->DevicePowerWorkItem, + FdoSystemPowerDownWorker, + DelayedWorkQueue, + Fdo); + } else { + __FdoSetSystemPowerState(Fdo, SystemState); - return status; + IoCopyCurrentIrpStackLocationToNext(Irp); + IoCallDriver(Fdo->LowerDeviceObject, Irp); + } } static FORCEINLINE NTSTATUS @@ -2383,33 +2603,38 @@ __FdoSetSystemPowerDown( { PIO_STACK_LOCATION StackLocation; SYSTEM_POWER_STATE SystemState; - DEVICE_POWER_STATE DeviceState; + POWER_STATE PowerState; NTSTATUS status; StackLocation = IoGetCurrentIrpStackLocation(Irp); + BUG_ON(StackLocation->DeviceObject != Fdo->Dx->DeviceObject); SystemState = StackLocation->Parameters.Power.State.SystemState; - ASSERT3U(SystemState, >, __FdoGetSystemPowerState(Fdo)); - - DeviceState = Fdo->LowerDeviceCapabilities.DeviceState[SystemState]; - - FdoRequestSetDevicePower(Fdo, DeviceState); + ASSERT3U(SystemState, >, __FdoGetSystemPowerState(Fdo)); - Info("%s: %s -> %s\n", - __FdoGetName(Fdo), - PowerSystemStateName(__FdoGetSystemPowerState(Fdo)), - PowerSystemStateName(SystemState)); + PowerState.DeviceState = Fdo->LowerDeviceCapabilities.DeviceState[SystemState]; - if (SystemState >= PowerSystemHibernate && - __FdoGetSystemPowerState(Fdo) < PowerSystemHibernate) { - __FdoSetSystemPowerState(Fdo, PowerSystemSleeping3); - FdoS3ToS4(Fdo); + if (SystemState >= PowerSystemShutdown) { + IoCopyCurrentIrpStackLocationToNext(Irp); + status = IoCallDriver(Fdo->LowerDeviceObject, Irp); + } else { + status = PoRequestPowerIrp(Fdo->LowerDeviceObject, + IRP_MN_SET_POWER, + PowerState, + FdoRequestSetDevicePowerDownComplete, + Irp, + NULL); + if (!NT_SUCCESS(status)) + goto fail1; } - __FdoSetSystemPowerState(Fdo, SystemState); + return status; - IoSkipCurrentIrpStackLocation(Irp); - status = IoCallDriver(Fdo->LowerDeviceObject, Irp); +fail1: + Error("fail1 - but continue IRP processing. (%08x)\n", status); + + IoCopyCurrentIrpStackLocationToNext(Irp); + IoCallDriver(Fdo->LowerDeviceObject, Irp); return status; } @@ -2429,29 +2654,32 @@ __FdoSetSystemPower( SystemState = StackLocation->Parameters.Power.State.SystemState; PowerAction = StackLocation->Parameters.Power.ShutdownType; - Trace("====> (%s:%s)\n", - PowerSystemStateName(SystemState), - PowerActionName(PowerAction)); + IoMarkIrpPending(Irp); - ASSERT3U(PowerAction, <, PowerActionShutdown); + Trace("%s: ====> (%s:%s)\n", + __FdoGetName(Fdo), + PowerSystemStateName(SystemState), + PowerActionName(PowerAction)); if (SystemState == __FdoGetSystemPowerState(Fdo)) { - IoSkipCurrentIrpStackLocation(Irp); + IoCopyCurrentIrpStackLocationToNext(Irp); status = IoCallDriver(Fdo->LowerDeviceObject, Irp); goto done; } - status = (SystemState < __FdoGetSystemPowerState(Fdo)) ? + status = SystemState < __FdoGetSystemPowerState(Fdo) ? __FdoSetSystemPowerUp(Fdo, Irp) : __FdoSetSystemPowerDown(Fdo, Irp); done: - Trace("<==== (%s:%s)(%08x)\n", - PowerSystemStateName(SystemState), + Trace("%s: <==== (%s:%s)(%08x)\n", + __FdoGetName(Fdo), + PowerSystemStateName(SystemState), PowerActionName(PowerAction), status); - return status; + + return STATUS_PENDING; } static FORCEINLINE NTSTATUS @@ -2467,12 +2695,10 @@ __FdoQueryDevicePowerUp( StackLocation = IoGetCurrentIrpStackLocation(Irp); DeviceState = StackLocation->Parameters.Power.State.DeviceState; - ASSERT3U(DeviceState, <, __FdoGetDevicePowerState(Fdo)); - - status = FdoForwardIrpSynchronously(Fdo, Irp); + ASSERT3U(DeviceState, <, __FdoGetDevicePowerState(Fdo)); - Irp->IoStatus.Status = status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); + IoSkipCurrentIrpStackLocation(Irp); + status = IoCallDriver(Fdo->LowerDeviceObject, Irp); return status; } @@ -2490,7 +2716,7 @@ __FdoQueryDevicePowerDown( StackLocation = IoGetCurrentIrpStackLocation(Irp); DeviceState = StackLocation->Parameters.Power.State.DeviceState; - ASSERT3U(DeviceState, >, __FdoGetDevicePowerState(Fdo)); + ASSERT3U(DeviceState, >, __FdoGetDevicePowerState(Fdo)); IoSkipCurrentIrpStackLocation(Irp); status = IoCallDriver(Fdo->LowerDeviceObject, Irp); @@ -2513,12 +2739,11 @@ __FdoQueryDevicePower( DeviceState = StackLocation->Parameters.Power.State.DeviceState; PowerAction = StackLocation->Parameters.Power.ShutdownType; - Trace("====> (%s:%s)\n", - PowerDeviceStateName(DeviceState), + Trace("%s: ====> (%s:%s)\n", + __FdoGetName(Fdo), + PowerDeviceStateName(DeviceState), PowerActionName(PowerAction)); - ASSERT3U(PowerAction, <, PowerActionShutdown); - if (DeviceState == __FdoGetDevicePowerState(Fdo)) { IoSkipCurrentIrpStackLocation(Irp); status = IoCallDriver(Fdo->LowerDeviceObject, Irp); @@ -2531,8 +2756,9 @@ __FdoQueryDevicePower( __FdoQueryDevicePowerDown(Fdo, Irp); done: - Trace("<==== (%s:%s)(%08x)\n", - PowerDeviceStateName(DeviceState), + Trace("%s: <==== (%s:%s)(%08x)\n", + __FdoGetName(Fdo), + PowerDeviceStateName(DeviceState), PowerActionName(PowerAction), status); return status; @@ -2540,8 +2766,8 @@ done: __drv_functionClass(REQUEST_POWER_COMPLETE) __drv_sameIRQL -VOID -__FdoRequestQueryDevicePower( +static VOID +FdoRequestQueryDevicePowerUpComplete( IN PDEVICE_OBJECT DeviceObject, IN UCHAR MinorFunction, IN POWER_STATE PowerState, @@ -2549,47 +2775,55 @@ __FdoRequestQueryDevicePower( IN PIO_STATUS_BLOCK IoStatus ) { - PKEVENT Event = Context; + PIRP Irp = (PIRP) Context; UNREFERENCED_PARAMETER(DeviceObject); UNREFERENCED_PARAMETER(MinorFunction); UNREFERENCED_PARAMETER(PowerState); - ASSERT(NT_SUCCESS(IoStatus->Status)); + if (!NT_SUCCESS(IoStatus->Status)) + Irp->IoStatus.Status = IoStatus->Status; - KeSetEvent(Event, IO_NO_INCREMENT, FALSE); + IoCompleteRequest(Irp, IO_NO_INCREMENT); } -static VOID -FdoRequestQueryDevicePower( - IN PXENVIF_FDO Fdo, - IN DEVICE_POWER_STATE DeviceState +__drv_functionClass(IO_COMPLETION_ROUTINE) +__drv_sameIRQL +static NTSTATUS +FdoQuerySystemPowerUpComplete( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PVOID Context ) { - POWER_STATE PowerState; - KEVENT Event; - NTSTATUS status; - - Trace("%s\n", PowerDeviceStateName(DeviceState)); + PXENVIF_FDO Fdo = (PXENVIF_FDO) Context; + PIO_STACK_LOCATION StackLocation; + SYSTEM_POWER_STATE SystemState; + POWER_STATE PowerState; + NTSTATUS status; - ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL); + UNREFERENCED_PARAMETER(DeviceObject); - PowerState.DeviceState = DeviceState; - KeInitializeEvent(&Event, NotificationEvent, FALSE); + StackLocation = IoGetCurrentIrpStackLocation(Irp); + SystemState = StackLocation->Parameters.Power.State.SystemState; + PowerState.DeviceState = Fdo->LowerDeviceCapabilities.DeviceState[SystemState]; status = PoRequestPowerIrp(Fdo->LowerDeviceObject, IRP_MN_QUERY_POWER, PowerState, - __FdoRequestQueryDevicePower, - &Event, + FdoRequestQueryDevicePowerUpComplete, + Irp, NULL); - ASSERT(NT_SUCCESS(status)); + if (!NT_SUCCESS(status)) + goto fail1; - (VOID) KeWaitForSingleObject(&Event, - Executive, - KernelMode, - FALSE, - NULL); + return STATUS_MORE_PROCESSING_REQUIRED; + +fail1: + Error("fail1 (%08x)\n", status); + Irp->IoStatus.Status = status; + + return STATUS_CONTINUE_COMPLETION; } static FORCEINLINE NTSTATUS @@ -2598,30 +2832,61 @@ __FdoQuerySystemPowerUp( IN PIRP Irp ) { - PIO_STACK_LOCATION StackLocation; SYSTEM_POWER_STATE SystemState; - DEVICE_POWER_STATE DeviceState; - NTSTATUS status; StackLocation = IoGetCurrentIrpStackLocation(Irp); SystemState = StackLocation->Parameters.Power.State.SystemState; - ASSERT3U(SystemState, <, __FdoGetSystemPowerState(Fdo)); + ASSERT3U(SystemState, <, __FdoGetSystemPowerState(Fdo)); - status = FdoForwardIrpSynchronously(Fdo, Irp); - if (!NT_SUCCESS(status)) - goto done; + IoMarkIrpPending(Irp); + IoCopyCurrentIrpStackLocationToNext(Irp); + IoSetCompletionRoutine(Irp, + FdoQuerySystemPowerUpComplete, + Fdo, + TRUE, + TRUE, + TRUE); + (VOID) IoCallDriver(Fdo->LowerDeviceObject, Irp); - DeviceState = Fdo->LowerDeviceCapabilities.DeviceState[SystemState]; + return STATUS_PENDING; +} - FdoRequestQueryDevicePower(Fdo, DeviceState); +__drv_functionClass(REQUEST_POWER_COMPLETE) +__drv_sameIRQL +static VOID +FdoRequestQueryDevicePowerDownComplete( + IN PDEVICE_OBJECT DeviceObject, + IN UCHAR MinorFunction, + IN POWER_STATE PowerState, + IN PVOID Context, + IN PIO_STATUS_BLOCK IoStatus + ) +{ + PIRP Irp = (PIRP) Context; + PIO_STACK_LOCATION StackLocation = IoGetCurrentIrpStackLocation(Irp); + PDEVICE_OBJECT UpperDeviceObject = StackLocation->DeviceObject; + PXENVIF_DX Dx = (PXENVIF_DX)UpperDeviceObject->DeviceExtension; + PXENVIF_FDO Fdo = Dx->Fdo; -done: - Irp->IoStatus.Status = status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); + UNREFERENCED_PARAMETER(DeviceObject); + UNREFERENCED_PARAMETER(MinorFunction); + UNREFERENCED_PARAMETER(PowerState); - return status; + if (!NT_SUCCESS(IoStatus->Status)) + goto fail1; + + IoCopyCurrentIrpStackLocationToNext(Irp); + IoCallDriver(Fdo->LowerDeviceObject, Irp); + + return; + +fail1: + Error("fail1 (%08x)\n", IoStatus->Status); + + Irp->IoStatus.Status = IoStatus->Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); } static FORCEINLINE NTSTATUS @@ -2632,7 +2897,7 @@ __FdoQuerySystemPowerDown( { PIO_STACK_LOCATION StackLocation; SYSTEM_POWER_STATE SystemState; - DEVICE_POWER_STATE DeviceState; + POWER_STATE PowerState; NTSTATUS status; StackLocation = IoGetCurrentIrpStackLocation(Irp); @@ -2640,12 +2905,26 @@ __FdoQuerySystemPowerDown( ASSERT3U(SystemState, >, __FdoGetSystemPowerState(Fdo)); - DeviceState = Fdo->LowerDeviceCapabilities.DeviceState[SystemState]; + PowerState.DeviceState = Fdo->LowerDeviceCapabilities.DeviceState[SystemState]; + + status = PoRequestPowerIrp(Fdo->LowerDeviceObject, + IRP_MN_QUERY_POWER, + PowerState, + FdoRequestQueryDevicePowerDownComplete, + Irp, + NULL); + if (!NT_SUCCESS(status)) + goto fail1; + + IoMarkIrpPending(Irp); - FdoRequestQueryDevicePower(Fdo, DeviceState); + return STATUS_PENDING; - IoSkipCurrentIrpStackLocation(Irp); - status = IoCallDriver(Fdo->LowerDeviceObject, Irp); +fail1: + Error("fail1 (%08x)\n", status); + + Irp->IoStatus.Status = status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); return status; } @@ -2665,12 +2944,11 @@ __FdoQuerySystemPower( SystemState = StackLocation->Parameters.Power.State.SystemState; PowerAction = StackLocation->Parameters.Power.ShutdownType; - Trace("====> (%s:%s)\n", - PowerSystemStateName(SystemState), + Trace("%s: ====> (%s:%s)\n", + __FdoGetName(Fdo), + PowerSystemStateName(SystemState), PowerActionName(PowerAction)); - ASSERT3U(PowerAction, <, PowerActionShutdown); - if (SystemState == __FdoGetSystemPowerState(Fdo)) { IoSkipCurrentIrpStackLocation(Irp); status = IoCallDriver(Fdo->LowerDeviceObject, Irp); @@ -2683,184 +2961,93 @@ __FdoQuerySystemPower( __FdoQuerySystemPowerDown(Fdo, Irp); done: - Trace("<==== (%s:%s)(%08x)\n", - PowerSystemStateName(SystemState), + Trace("%s: <==== (%s:%s)(%08x)\n", + __FdoGetName(Fdo), + PowerSystemStateName(SystemState), PowerActionName(PowerAction), status); return status; } -static NTSTATUS -FdoDevicePower( - IN PXENVIF_THREAD Self, - IN PVOID Context +static FORCEINLINE NTSTATUS +__FdoDevicePower( + IN PXENVIF_FDO Fdo, + IN PIRP Irp ) { - PXENVIF_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(); + PIO_STACK_LOCATION StackLocation; + NTSTATUS status; - StackLocation = IoGetCurrentIrpStackLocation(Irp); - MinorFunction = StackLocation->MinorFunction; + StackLocation = IoGetCurrentIrpStackLocation(Irp); - switch (StackLocation->MinorFunction) { - case IRP_MN_SET_POWER: - (VOID) __FdoSetDevicePower(Fdo, Irp); - break; + switch (StackLocation->MinorFunction) { + case IRP_MN_SET_POWER: + status = __FdoSetDevicePower(Fdo, Irp); + break; - case IRP_MN_QUERY_POWER: - (VOID) __FdoQueryDevicePower(Fdo, Irp); - break; + case IRP_MN_QUERY_POWER: + status = __FdoQueryDevicePower(Fdo, Irp); + break; - default: - ASSERT(FALSE); - break; - } + default: + IoSkipCurrentIrpStackLocation(Irp); + status = IoCallDriver(Fdo->LowerDeviceObject, Irp); + break; } - return STATUS_SUCCESS; + return status; } -static NTSTATUS -FdoSystemPower( - IN PXENVIF_THREAD Self, - IN PVOID Context +static FORCEINLINE NTSTATUS +__FdoSystemPower( + IN PXENVIF_FDO Fdo, + IN PIRP Irp ) { - PXENVIF_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(); + PIO_STACK_LOCATION StackLocation; + NTSTATUS status; - StackLocation = IoGetCurrentIrpStackLocation(Irp); - MinorFunction = StackLocation->MinorFunction; + StackLocation = IoGetCurrentIrpStackLocation(Irp); - switch (StackLocation->MinorFunction) { - case IRP_MN_SET_POWER: - (VOID) __FdoSetSystemPower(Fdo, Irp); - break; + switch (StackLocation->MinorFunction) { + case IRP_MN_SET_POWER: + status = __FdoSetSystemPower(Fdo, Irp); + break; - case IRP_MN_QUERY_POWER: - (VOID) __FdoQuerySystemPower(Fdo, Irp); - break; + case IRP_MN_QUERY_POWER: + status = __FdoQuerySystemPower(Fdo, Irp); + break; - default: - ASSERT(FALSE); - break; - } + default: + IoSkipCurrentIrpStackLocation(Irp); + status = IoCallDriver(Fdo->LowerDeviceObject, Irp); + break; } - return STATUS_SUCCESS; + return status; } static DECLSPEC_NOINLINE NTSTATUS FdoDispatchPower( - IN PXENVIF_FDO Fdo, + IN PXENVIF_FDO Fdo, IN PIRP Irp ) { PIO_STACK_LOCATION StackLocation; - UCHAR MinorFunction; POWER_STATE_TYPE PowerType; - POWER_ACTION PowerAction; NTSTATUS status; StackLocation = IoGetCurrentIrpStackLocation(Irp); - MinorFunction = StackLocation->MinorFunction; - - if (MinorFunction != IRP_MN_QUERY_POWER && - MinorFunction != IRP_MN_SET_POWER) { - IoSkipCurrentIrpStackLocation(Irp); - status = IoCallDriver(Fdo->LowerDeviceObject, Irp); - - goto done; - } - PowerType = StackLocation->Parameters.Power.Type; - PowerAction = StackLocation->Parameters.Power.ShutdownType; - - if (PowerAction >= PowerActionShutdown) { - IoSkipCurrentIrpStackLocation(Irp); - status = IoCallDriver(Fdo->LowerDeviceObject, Irp); - - goto done; - } 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: @@ -2869,7 +3056,6 @@ FdoDispatchPower( break; } -done: return status; } @@ -3063,12 +3249,12 @@ FdoCreate( Fdo->LowerDeviceObject = IoAttachDeviceToDeviceStack(FunctionDeviceObject, PhysicalDeviceObject); - status = ThreadCreate(FdoSystemPower, Fdo, &Fdo->SystemPowerThread); - if (!NT_SUCCESS(status)) + Fdo->SystemPowerWorkItem = IoAllocateWorkItem(PhysicalDeviceObject); + if (Fdo->SystemPowerWorkItem == NULL) goto fail3; - status = ThreadCreate(FdoDevicePower, Fdo, &Fdo->DevicePowerThread); - if (!NT_SUCCESS(status)) + Fdo->DevicePowerWorkItem = IoAllocateWorkItem(PhysicalDeviceObject); + if (Fdo->DevicePowerWorkItem == NULL) goto fail4; status = __FdoAcquireLowerBusInterface(Fdo); @@ -3226,16 +3412,14 @@ fail6: fail5: Error("fail5\n"); - ThreadAlert(Fdo->DevicePowerThread); - ThreadJoin(Fdo->DevicePowerThread); - Fdo->DevicePowerThread = NULL; - + IoFreeWorkItem(Fdo->DevicePowerWorkItem); + Fdo->DevicePowerWorkItem = NULL; + fail4: Error("fail4\n"); - ThreadAlert(Fdo->SystemPowerThread); - ThreadJoin(Fdo->SystemPowerThread); - Fdo->SystemPowerThread = NULL; + IoFreeWorkItem(Fdo->SystemPowerWorkItem); + Fdo->SystemPowerWorkItem = NULL; fail3: Error("fail3\n"); @@ -3311,13 +3495,11 @@ FdoDestroy( __FdoReleaseLowerBusInterface(Fdo); - ThreadAlert(Fdo->DevicePowerThread); - ThreadJoin(Fdo->DevicePowerThread); - Fdo->DevicePowerThread = NULL; + IoFreeWorkItem(Fdo->DevicePowerWorkItem); + Fdo->DevicePowerWorkItem = NULL; - ThreadAlert(Fdo->SystemPowerThread); - ThreadJoin(Fdo->SystemPowerThread); - Fdo->SystemPowerThread = NULL; + IoFreeWorkItem(Fdo->SystemPowerWorkItem); + Fdo->SystemPowerWorkItem = NULL; IoDetachDevice(Fdo->LowerDeviceObject); diff --git a/src/xenvif/pdo.c b/src/xenvif/pdo.c index 0cef2d5..2979f53 100644 --- a/src/xenvif/pdo.c +++ b/src/xenvif/pdo.c @@ -68,9 +68,9 @@ struct _XENVIF_PDO { PXENVIF_DX Dx; - PXENVIF_THREAD SystemPowerThread; + PIO_WORKITEM SystemPowerWorkItem; PIRP SystemPowerIrp; - PXENVIF_THREAD DevicePowerThread; + PIO_WORKITEM DevicePowerWorkItem; PIRP DevicePowerIrp; PXENVIF_FDO Fdo; @@ -2365,28 +2365,31 @@ PdoDispatchPnp( return status; } -static FORCEINLINE NTSTATUS -__PdoSetDevicePower( - IN PXENVIF_PDO Pdo, - IN PIRP Irp +__drv_functionClass(IO_WORKITEM_ROUTINE) +__drv_sameIRQL +static VOID +PdoDevicePowerWorker( + IN PDEVICE_OBJECT DeviceObject, + IN PVOID Context ) { + PXENVIF_PDO Pdo = (PXENVIF_PDO) Context; + PIRP Irp; PIO_STACK_LOCATION StackLocation; DEVICE_POWER_STATE DeviceState; POWER_ACTION PowerAction; NTSTATUS status; + UNREFERENCED_PARAMETER(DeviceObject); + + Irp = InterlockedExchangePointer(&Pdo->DevicePowerIrp, NULL); + ASSERT(Irp != NULL); + StackLocation = IoGetCurrentIrpStackLocation(Irp); DeviceState = StackLocation->Parameters.Power.State.DeviceState; PowerAction = StackLocation->Parameters.Power.ShutdownType; - Trace("====> (%s) (%s:%s)\n", - __PdoGetName(Pdo), - PowerDeviceStateName(DeviceState), - PowerActionName(PowerAction)); - - ASSERT3U(PowerAction, <, PowerActionShutdown); - + status = STATUS_SUCCESS; if (__PdoGetDevicePowerState(Pdo) > DeviceState) { Trace("%s: POWERING UP: %s -> %s\n", __PdoGetName(Pdo), @@ -2395,7 +2398,6 @@ __PdoSetDevicePower( ASSERT3U(DeviceState, ==, PowerDeviceD0); status = PdoD3ToD0(Pdo); - ASSERT(NT_SUCCESS(status)); } else if (__PdoGetDevicePowerState(Pdo) < DeviceState) { Trace("%s: POWERING DOWN: %s -> %s\n", __PdoGetName(Pdo), @@ -2406,77 +2408,71 @@ __PdoSetDevicePower( PdoD0ToD3(Pdo); } + /* Cannot fail the IRP at this point, keep going. */ Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp, IO_NO_INCREMENT); - Trace("<==== (%s:%s)\n", + Trace("<==== (%s:%s)(%08x)\n", PowerDeviceStateName(DeviceState), - PowerActionName(PowerAction)); - - return STATUS_SUCCESS; + PowerActionName(PowerAction), + status); } -static NTSTATUS -PdoDevicePower( - IN PXENVIF_THREAD Self, - IN PVOID Context +static FORCEINLINE NTSTATUS +__PdoSetDevicePower( + IN PXENVIF_PDO Pdo, + IN PIRP Irp ) { - PXENVIF_PDO Pdo = Context; - PKEVENT Event; - - Event = ThreadGetEvent(Self); - - for (;;) { - PIRP Irp; - - if (Pdo->DevicePowerIrp == NULL) { - (VOID) KeWaitForSingleObject(Event, - Executive, - KernelMode, - FALSE, - NULL); - KeClearEvent(Event); - } + PIO_STACK_LOCATION StackLocation; + DEVICE_POWER_STATE DeviceState; + POWER_ACTION PowerAction; + PVOID Exchange; - if (ThreadIsAlerted(Self)) - break; + StackLocation = IoGetCurrentIrpStackLocation(Irp); + DeviceState = StackLocation->Parameters.Power.State.DeviceState; + PowerAction = StackLocation->Parameters.Power.ShutdownType; - Irp = Pdo->DevicePowerIrp; + Trace("====> (%s:%s)\n", + PowerDeviceStateName(DeviceState), + PowerActionName(PowerAction)); - if (Irp == NULL) - continue; + IoMarkIrpPending(Irp); - Pdo->DevicePowerIrp = NULL; - KeMemoryBarrier(); + Exchange = InterlockedExchangePointer(&Pdo->DevicePowerIrp, Irp); + ASSERT(Exchange == NULL); - (VOID) __PdoSetDevicePower(Pdo, Irp); - } + IoQueueWorkItem(Pdo->DevicePowerWorkItem, + PdoDevicePowerWorker, + DelayedWorkQueue, + Pdo); - return STATUS_SUCCESS; + return STATUS_PENDING; } -static FORCEINLINE NTSTATUS -__PdoSetSystemPower( - IN PXENVIF_PDO Pdo, - IN PIRP Irp +__drv_functionClass(IO_WORKITEM_ROUTINE) +__drv_sameIRQL +static VOID +PdoSystemPowerWorker( + IN PDEVICE_OBJECT DeviceObject, + IN PVOID Context ) { - PIO_STACK_LOCATION StackLocation; - SYSTEM_POWER_STATE SystemState; - POWER_ACTION PowerAction; + PXENVIF_PDO Pdo = (PXENVIF_PDO) Context; + PIRP Irp; + PIO_STACK_LOCATION StackLocation; + SYSTEM_POWER_STATE SystemState; + POWER_ACTION PowerAction; + + UNREFERENCED_PARAMETER(DeviceObject); + + Irp = InterlockedExchangePointer(&Pdo->SystemPowerIrp, NULL); + ASSERT(Irp != NULL); StackLocation = IoGetCurrentIrpStackLocation(Irp); SystemState = StackLocation->Parameters.Power.State.SystemState; PowerAction = StackLocation->Parameters.Power.ShutdownType; - Trace("====> (%s) (%s:%s)\n", - __PdoGetName(Pdo), - PowerSystemStateName(SystemState), - PowerActionName(PowerAction)); - - ASSERT3U(PowerAction, <, PowerActionShutdown); - if (__PdoGetSystemPowerState(Pdo) > SystemState) { if (SystemState < PowerSystemHibernate && __PdoGetSystemPowerState(Pdo) >= PowerSystemHibernate) { @@ -2488,6 +2484,7 @@ __PdoSetSystemPower( __PdoGetName(Pdo), PowerSystemStateName(__PdoGetSystemPowerState(Pdo)), PowerSystemStateName(SystemState)); + } else if (__PdoGetSystemPowerState(Pdo) < SystemState) { Trace("%s: POWERING DOWN: %s -> %s\n", __PdoGetName(Pdo), @@ -2509,97 +2506,60 @@ __PdoSetSystemPower( Trace("<==== (%s:%s)\n", PowerSystemStateName(SystemState), PowerActionName(PowerAction)); - - return STATUS_SUCCESS; } -static NTSTATUS -PdoSystemPower( - IN PXENVIF_THREAD Self, - IN PVOID Context +static FORCEINLINE NTSTATUS +__PdoSetSystemPower( + IN PXENVIF_PDO Pdo, + IN PIRP Irp ) { - PXENVIF_PDO Pdo = Context; - PKEVENT Event; - - Event = ThreadGetEvent(Self); - - for (;;) { - PIRP Irp; - - if (Pdo->SystemPowerIrp == NULL) { - (VOID) KeWaitForSingleObject(Event, - Executive, - KernelMode, - FALSE, - NULL); - KeClearEvent(Event); - } + PIO_STACK_LOCATION StackLocation; + SYSTEM_POWER_STATE SystemState; + POWER_ACTION PowerAction; + PVOID Exchange; - if (ThreadIsAlerted(Self)) - break; + StackLocation = IoGetCurrentIrpStackLocation(Irp); + SystemState = StackLocation->Parameters.Power.State.SystemState; + PowerAction = StackLocation->Parameters.Power.ShutdownType; - Irp = Pdo->SystemPowerIrp; + Trace("====> (%s:%s)\n", + PowerSystemStateName(SystemState), + PowerActionName(PowerAction)); - if (Irp == NULL) - continue; + IoMarkIrpPending(Irp); - Pdo->SystemPowerIrp = NULL; - KeMemoryBarrier(); + Exchange = InterlockedExchangePointer(&Pdo->SystemPowerIrp, Irp); + ASSERT(Exchange == NULL); - (VOID) __PdoSetSystemPower(Pdo, Irp); - } + IoQueueWorkItem(Pdo->SystemPowerWorkItem, + PdoSystemPowerWorker, + DelayedWorkQueue, + Pdo); - return STATUS_SUCCESS; + return STATUS_PENDING; } -static DECLSPEC_NOINLINE NTSTATUS -PdoSetPower( +static FORCEINLINE NTSTATUS +__PdoSetPower( IN PXENVIF_PDO Pdo, IN PIRP Irp ) { PIO_STACK_LOCATION StackLocation; POWER_STATE_TYPE PowerType; - POWER_ACTION PowerAction; NTSTATUS status; StackLocation = IoGetCurrentIrpStackLocation(Irp); PowerType = StackLocation->Parameters.Power.Type; - PowerAction = StackLocation->Parameters.Power.ShutdownType; - - if (PowerAction >= PowerActionShutdown) { - Irp->IoStatus.Status = STATUS_SUCCESS; - - status = Irp->IoStatus.Status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - goto done; - } switch (PowerType) { case DevicePowerState: - IoMarkIrpPending(Irp); - - ASSERT3P(Pdo->DevicePowerIrp, ==, NULL); - Pdo->DevicePowerIrp = Irp; - KeMemoryBarrier(); - - ThreadWake(Pdo->DevicePowerThread); - - status = STATUS_PENDING; + status = __PdoSetDevicePower(Pdo, Irp); break; case SystemPowerState: - IoMarkIrpPending(Irp); - - ASSERT3P(Pdo->SystemPowerIrp, ==, NULL); - Pdo->SystemPowerIrp = Irp; - KeMemoryBarrier(); - - ThreadWake(Pdo->SystemPowerThread); - - status = STATUS_PENDING; + status = __PdoSetSystemPower(Pdo, Irp); break; default: @@ -2608,48 +2568,41 @@ PdoSetPower( break; } -done: return status; } -static DECLSPEC_NOINLINE NTSTATUS -PdoQueryPower( - IN PXENVIF_PDO Pdo, - IN PIRP Irp +static FORCEINLINE NTSTATUS +__PdoQueryPower( + IN PXENVIF_PDO Pdo, + IN PIRP Irp ) { - NTSTATUS status; - UNREFERENCED_PARAMETER(Pdo); Irp->IoStatus.Status = STATUS_SUCCESS; - - status = Irp->IoStatus.Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); - - return status; + + return STATUS_SUCCESS; } -static DECLSPEC_NOINLINE NTSTATUS +static NTSTATUS PdoDispatchPower( IN PXENVIF_PDO Pdo, IN PIRP Irp ) { PIO_STACK_LOCATION StackLocation; - UCHAR MinorFunction; NTSTATUS status; StackLocation = IoGetCurrentIrpStackLocation(Irp); - MinorFunction = StackLocation->MinorFunction; switch (StackLocation->MinorFunction) { case IRP_MN_SET_POWER: - status = PdoSetPower(Pdo, Irp); + status = __PdoSetPower(Pdo, Irp); break; case IRP_MN_QUERY_POWER: - status = PdoQueryPower(Pdo, Irp); + status = __PdoQueryPower(Pdo, Irp); break; default: @@ -2762,12 +2715,12 @@ PdoCreate( Pdo->Dx = Dx; Pdo->Fdo = Fdo; - status = ThreadCreate(PdoSystemPower, Pdo, &Pdo->SystemPowerThread); - if (!NT_SUCCESS(status)) + Pdo->SystemPowerWorkItem = IoAllocateWorkItem(PhysicalDeviceObject); + if (Pdo->SystemPowerWorkItem == NULL) goto fail3; - status = ThreadCreate(PdoDevicePower, Pdo, &Pdo->DevicePowerThread); - if (!NT_SUCCESS(status)) + Pdo->DevicePowerWorkItem = IoAllocateWorkItem(PhysicalDeviceObject); + if (Pdo->DevicePowerWorkItem == NULL) goto fail4; __PdoSetName(Pdo, Number); @@ -2860,16 +2813,14 @@ fail6: fail5: Error("fail5\n"); - ThreadAlert(Pdo->DevicePowerThread); - ThreadJoin(Pdo->DevicePowerThread); - Pdo->DevicePowerThread = NULL; + IoFreeWorkItem(Pdo->DevicePowerWorkItem); + Pdo->DevicePowerWorkItem = NULL; fail4: Error("fail4\n"); - ThreadAlert(Pdo->SystemPowerThread); - ThreadJoin(Pdo->SystemPowerThread); - Pdo->SystemPowerThread = NULL; + IoFreeWorkItem(Pdo->SystemPowerWorkItem); + Pdo->SystemPowerWorkItem = NULL; fail3: Error("fail3\n"); @@ -2939,13 +2890,11 @@ PdoDestroy( __PdoClearPermanentAddress(Pdo); - ThreadAlert(Pdo->DevicePowerThread); - ThreadJoin(Pdo->DevicePowerThread); - Pdo->DevicePowerThread = NULL; + IoFreeWorkItem(Pdo->DevicePowerWorkItem); + Pdo->DevicePowerWorkItem = NULL; - ThreadAlert(Pdo->SystemPowerThread); - ThreadJoin(Pdo->SystemPowerThread); - Pdo->SystemPowerThread = NULL; + IoFreeWorkItem(Pdo->SystemPowerWorkItem); + Pdo->SystemPowerWorkItem = NULL; Pdo->Fdo = NULL; Pdo->Dx = NULL; -- 2.41.0.windows.3
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |