[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [RFC PATCH 2/3] [XenBus] Asynchronous power handling.
From: Martin Harvey <Martin.Harvey@xxxxxxxxxx> Replace a static, single thread for System and Device power transitions with an IO_WORKITEM for each transition. IO_WORKITEMs are only used when a transition requires calling codepaths that must be called at PASSIVE_LEVEL. Move the bulk of power transitions to pending IRPs and IRP completion routines. Signed-off-by: Martin Harvey <martin.harvey@xxxxxxxxxx> Refactored to only apply to XenBus power Signed-off-by: Owen Smith <owen.smith@xxxxxxxxx> --- src/xenbus/fdo.c | 792 ++++++++++++++++++++++++++--------------------- src/xenbus/pdo.c | 250 ++++++--------- 2 files changed, 534 insertions(+), 508 deletions(-) diff --git a/src/xenbus/fdo.c b/src/xenbus/fdo.c index 976a7a3..3d35e77 100644 --- a/src/xenbus/fdo.c +++ b/src/xenbus/fdo.c @@ -107,9 +107,9 @@ struct _XENBUS_FDO { ULONG Usage[DeviceUsageTypeDumpFile + 1]; BOOLEAN NotDisableable; - PXENBUS_THREAD SystemPowerThread; + PIO_WORKITEM SystemPowerWorkItem; PIRP SystemPowerIrp; - PXENBUS_THREAD DevicePowerThread; + PIO_WORKITEM DevicePowerWorkItem; PIRP DevicePowerIrp; CHAR VendorName[MAXNAMELEN]; @@ -4800,38 +4800,105 @@ FdoDispatchPnp( return status; } +__drv_functionClass(IO_WORKITEM_ROUTINE) +__drv_sameIRQL +static VOID +FdoSetDevcePowerUpWorker( + IN PDEVICE_OBJECT DeviceObject, + IN PVOID Context + ) +{ + PXENBUS_FDO Fdo = (PXENBUS_FDO) Context; + PIRP Irp; + + UNREFERENCED_PARAMETER(DeviceObject); + + Irp = InterlockedExchangePointer(&Fdo->DevicePowerIrp, NULL); + ASSERT(Irp != NULL); + + (VOID) FdoD3ToD0(Fdo); + + /* Cannot change Irp->IoStatus */ + /* Continue completion chain */ + IoCompleteRequest(Irp, IO_NO_INCREMENT); +} + +__drv_functionClass(IO_COMPLETION_ROUTINE) +__drv_sameIRQL static NTSTATUS -FdoSetDevicePowerUp( - IN PXENBUS_FDO Fdo, - IN PIRP Irp +FdoSetDevicePowerUpComplete( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PVOID Context ) { + PXENBUS_FDO Fdo = (PXENBUS_FDO) Context; PIO_STACK_LOCATION StackLocation; DEVICE_POWER_STATE DeviceState; - NTSTATUS status; + + 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), + /* Already marked pending by us */ + Info("%s -> %s\n", DevicePowerStateName(__FdoGetDevicePowerState(Fdo)), DevicePowerStateName(DeviceState)); + /* Don't worry about IRP IoStatus */ ASSERT3U(DeviceState, ==, PowerDeviceD0); - status = FdoD3ToD0(Fdo); - ASSERT(NT_SUCCESS(status)); -done: - IoCompleteRequest(Irp, IO_NO_INCREMENT); + (VOID) InterlockedExchangePointer(&Fdo->DevicePowerIrp, Irp); - return status; + IoQueueWorkItem(Fdo->DevicePowerWorkItem, + FdoSetDevcePowerUpWorker, + DelayedWorkQueue, + Fdo); + + /* Stop completion chain in all circumstances. */ + return STATUS_MORE_PROCESSING_REQUIRED; +} + +static NTSTATUS +FdoSetDevicePowerUp( + IN PXENBUS_FDO Fdo, + IN PIRP Irp + ) +{ + IoMarkIrpPending(Irp); + IoCopyCurrentIrpStackLocationToNext(Irp); + IoSetCompletionRoutine(Irp, + FdoSetDevicePowerUpComplete, + Fdo, + TRUE, + TRUE, + TRUE); + IoCallDriver(Fdo->LowerDeviceObject, Irp); + return STATUS_PENDING; +} + +__drv_functionClass(IO_WORKITEM_ROUTINE) +__drv_sameIRQL +static VOID +FdoSetDevicePowerDownWorker( + IN PDEVICE_OBJECT DeviceObject, + IN PVOID Context + ) +{ + PXENBUS_FDO Fdo = (PXENBUS_FDO)Context; + PIRP Irp; + + UNREFERENCED_PARAMETER(DeviceObject); + + Irp = InterlockedExchangePointer(&Fdo->DevicePowerIrp, NULL); + ASSERT(Irp != NULL); + + FdoD0ToD3(Fdo); + + /* We are on dispatch path here, irp pended. */ + IoCopyCurrentIrpStackLocationToNext(Irp); + IoCallDriver(Fdo->LowerDeviceObject, Irp); } static NTSTATUS @@ -4856,12 +4923,24 @@ FdoSetDevicePowerDown( ASSERT3U(DeviceState, ==, PowerDeviceD3); - if (__FdoGetDevicePowerState(Fdo) == PowerDeviceD0) - FdoD0ToD3(Fdo); + if (__FdoGetDevicePowerState(Fdo) != PowerDeviceD0) { + IoSkipCurrentIrpStackLocation(Irp); + status = IoCallDriver(Fdo->LowerDeviceObject, Irp); - status = FdoForwardIrpSynchronously(Fdo, Irp); - IoCompleteRequest(Irp, IO_NO_INCREMENT); + goto done; + } + + IoMarkIrpPending(Irp); + status = STATUS_PENDING; + + (VOID) InterlockedExchangePointer(&Fdo->DevicePowerIrp, Irp); + IoQueueWorkItem(Fdo->DevicePowerWorkItem, + FdoSetDevicePowerDownWorker, + DelayedWorkQueue, + Fdo); + +done: return status; } @@ -4884,11 +4963,9 @@ FdoSetDevicePower( DevicePowerStateName(DeviceState), PowerActionName(PowerAction)); - ASSERT3U(PowerAction, <, PowerActionShutdown); - if (DeviceState == __FdoGetDevicePowerState(Fdo)) { - status = FdoForwardIrpSynchronously(Fdo, Irp); - IoCompleteRequest(Irp, IO_NO_INCREMENT); + IoSkipCurrentIrpStackLocation(Irp); + status = IoCallDriver(Fdo->LowerDeviceObject, Irp); goto done; } @@ -4907,8 +4984,8 @@ done: __drv_functionClass(REQUEST_POWER_COMPLETE) __drv_sameIRQL -VOID -FdoRequestSetDevicePowerCompletion( +static VOID +FdoRequestDevicePowerUpComplete( IN PDEVICE_OBJECT DeviceObject, IN UCHAR MinorFunction, IN POWER_STATE PowerState, @@ -4916,112 +4993,204 @@ FdoRequestSetDevicePowerCompletion( 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); + /* Although can change Irp->IoStatus for pended IRP, drivers should not fail this. */ + IoCompleteRequest(Irp, IO_NO_INCREMENT); } -__drv_requiresIRQL(PASSIVE_LEVEL) +__drv_functionClass(IO_WORKITEM_ROUTINE) +__drv_sameIRQL static VOID -FdoRequestSetDevicePower( - IN PXENBUS_FDO Fdo, - IN DEVICE_POWER_STATE DeviceState +FdoSetSystemPowerUpWorker( + IN PDEVICE_OBJECT DeviceObject, + IN PVOID Context ) { - POWER_STATE PowerState; - KEVENT Event; - NTSTATUS status; + PXENBUS_FDO Fdo = (PXENBUS_FDO)Context; + PIRP Irp; + PIO_STACK_LOCATION StackLocation; + SYSTEM_POWER_STATE SystemState; + POWER_STATE PowerState; + NTSTATUS status; - Trace("%s\n", DevicePowerStateName(DeviceState)); + UNREFERENCED_PARAMETER(DeviceObject); - ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL); + Irp = InterlockedExchangePointer(&Fdo->SystemPowerIrp, NULL); + ASSERT(Irp != NULL); - PowerState.DeviceState = DeviceState; - KeInitializeEvent(&Event, NotificationEvent, FALSE); + __FdoSetSystemPowerState(Fdo, PowerSystemHibernate); + FdoS4ToS3(Fdo); + + StackLocation = IoGetCurrentIrpStackLocation(Irp); + SystemState = StackLocation->Parameters.Power.State.SystemState; + + Info("%s -> %s\n", + SystemPowerStateName(__FdoGetSystemPowerState(Fdo)), + SystemPowerStateName(SystemState)); + + __FdoSetSystemPowerState(Fdo, SystemState); + + PowerState.DeviceState = Fdo->LowerDeviceCapabilities.DeviceState[SystemState]; status = PoRequestPowerIrp(Fdo->LowerDeviceObject, IRP_MN_SET_POWER, PowerState, - FdoRequestSetDevicePowerCompletion, - &Event, + FdoRequestDevicePowerUpComplete, + Irp, NULL); - ASSERT(NT_SUCCESS(status)); + /* Whatever happens, we have stopped completion processing for SIrp, + to restart SIrp processing, call IoCompleteRequest. */ + if (!NT_SUCCESS(status)) + goto fail1; - (VOID) KeWaitForSingleObject(&Event, - Executive, - KernelMode, - FALSE, - NULL); + return; /* FdoRequestDevicePowerUpComplete will complete the request.*/ + +fail1: + Error("fail1 - but continue IRP processing. (%08x)\n", status); + /* Although can change Irp->IoStatus for pended IRP, drivers should not fail this. */ + IoCompleteRequest(Irp, IO_NO_INCREMENT); } +__drv_functionClass(IO_COMPLETION_ROUTINE) +__drv_sameIRQL static NTSTATUS -FdoSetSystemPowerUp( - IN PXENBUS_FDO Fdo, - IN PIRP Irp +FdoSetSystemPowerUpComplete( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PVOID Context ) { - + PXENBUS_FDO Fdo = (PXENBUS_FDO) Context; PIO_STACK_LOCATION StackLocation; SYSTEM_POWER_STATE SystemState; - DEVICE_POWER_STATE DeviceState; + POWER_STATE PowerState; NTSTATUS status; + UNREFERENCED_PARAMETER(DeviceObject); + + /* IRP marked as pending on dispatch path, no need to check pending returned */ + + /* Don't worry about IRP IoStatus */ StackLocation = IoGetCurrentIrpStackLocation(Irp); SystemState = StackLocation->Parameters.Power.State.SystemState; - ASSERT3U(SystemState, <, __FdoGetSystemPowerState(Fdo)); + if (SystemState < PowerSystemHibernate && + __FdoGetSystemPowerState(Fdo) >= PowerSystemHibernate) { - status = FdoForwardIrpSynchronously(Fdo, Irp); - if (!NT_SUCCESS(status)) - goto done; + (VOID) InterlockedExchangePointer(&Fdo->SystemPowerIrp, Irp); - Info("%s: %s -> %s\n", - __FdoGetName(Fdo), - SystemPowerStateName(__FdoGetSystemPowerState(Fdo)), - SystemPowerStateName(SystemState)); + IoQueueWorkItem(Fdo->SystemPowerWorkItem, + FdoSetSystemPowerUpWorker, + DelayedWorkQueue, + Fdo); - if (SystemState < PowerSystemHibernate && - __FdoGetSystemPowerState(Fdo) >= PowerSystemHibernate) { - __FdoSetSystemPowerState(Fdo, PowerSystemHibernate); - FdoS4ToS3(Fdo); + goto done; /* Stop completion routine for the moment... */ } + Info("%s -> %s\n", + SystemPowerStateName(__FdoGetSystemPowerState(Fdo)), + SystemPowerStateName(SystemState)); + __FdoSetSystemPowerState(Fdo, SystemState); - DeviceState = Fdo->LowerDeviceCapabilities.DeviceState[SystemState]; - FdoRequestSetDevicePower(Fdo, DeviceState); + PowerState.DeviceState = Fdo->LowerDeviceCapabilities.DeviceState[SystemState]; + + status = PoRequestPowerIrp(Fdo->LowerDeviceObject, + IRP_MN_SET_POWER, + PowerState, + FdoRequestDevicePowerUpComplete, + Irp, + NULL); + /* Whatever happens, we have stopped completion processing for SIrp, + to restart SIrp processing, call IoCompleteRequest. */ + if (!NT_SUCCESS(status)) + goto fail1; done: - IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_MORE_PROCESSING_REQUIRED; /* FdoRequestDevicePowerUpComplete will complete the request.*/ - return status; +fail1: + Error("fail1 - but continue IRP processing. (%08x)\n", status); + /* marked pending on dispatch path, don't change Irp->IoStatus, keep going.*/ + return STATUS_CONTINUE_COMPLETION; } static NTSTATUS -FdoSetSystemPowerDown( +FdoSetSystemPowerUp( IN PXENBUS_FDO Fdo, IN PIRP Irp ) { + IoCopyCurrentIrpStackLocationToNext(Irp); + IoSetCompletionRoutine(Irp, + FdoSetSystemPowerUpComplete, + Fdo, + TRUE, + TRUE, + TRUE); + return IoCallDriver(Fdo->LowerDeviceObject, Irp); +} + +__drv_functionClass(IO_WORKITEM_ROUTINE) +__drv_sameIRQL +static VOID +FdoSetSystemPowerDownWorker( + IN PDEVICE_OBJECT DeviceObject, + IN PVOID Context + ) +{ + PXENBUS_FDO Fdo = (PXENBUS_FDO)Context; PIO_STACK_LOCATION StackLocation; SYSTEM_POWER_STATE SystemState; - DEVICE_POWER_STATE DeviceState; - NTSTATUS status; + PIRP Irp; + + UNREFERENCED_PARAMETER(DeviceObject); + + Irp = InterlockedExchangePointer(&Fdo->SystemPowerIrp, NULL); + ASSERT(Irp != NULL); StackLocation = IoGetCurrentIrpStackLocation(Irp); SystemState = StackLocation->Parameters.Power.State.SystemState; - ASSERT3U(SystemState, >, __FdoGetSystemPowerState(Fdo)); + /* Meet preconditions for S3 to S4 */ + __FdoSetSystemPowerState(Fdo, PowerSystemSleeping3); + FdoS3ToS4(Fdo); + __FdoSetSystemPowerState(Fdo, SystemState); - DeviceState = Fdo->LowerDeviceCapabilities.DeviceState[SystemState]; + IoCopyCurrentIrpStackLocationToNext(Irp); /* Irp has been pended */ + IoCallDriver(Fdo->LowerDeviceObject, Irp); +} - FdoRequestSetDevicePower(Fdo, DeviceState); +__drv_functionClass(REQUEST_POWER_COMPLETE) +__drv_sameIRQL +static VOID +FdoRequestDevicePowerDownComplete( + 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; + PXENBUS_DX Dx = (PXENBUS_DX)UpperDeviceObject->DeviceExtension; + PXENBUS_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), @@ -5030,145 +5199,118 @@ FdoSetSystemPowerDown( if (SystemState >= PowerSystemHibernate && __FdoGetSystemPowerState(Fdo) < PowerSystemHibernate) { - __FdoSetSystemPowerState(Fdo, PowerSystemSleeping3); - FdoS3ToS4(Fdo); + + (VOID) InterlockedExchangePointer(&Fdo->SystemPowerIrp, Irp); + + IoQueueWorkItem(Fdo->SystemPowerWorkItem, + FdoSetSystemPowerDownWorker, + DelayedWorkQueue, + Fdo); + goto done; } __FdoSetSystemPowerState(Fdo, SystemState); - status = FdoForwardIrpSynchronously(Fdo, Irp); - IoCompleteRequest(Irp, IO_NO_INCREMENT); + IoCopyCurrentIrpStackLocationToNext(Irp); /* Irp has been pended */ + IoCallDriver(Fdo->LowerDeviceObject, Irp); - return status; +done: + return; } static NTSTATUS -FdoSetSystemPower( +FdoSetSystemPowerDown( IN PXENBUS_FDO Fdo, IN PIRP Irp ) { PIO_STACK_LOCATION StackLocation; SYSTEM_POWER_STATE SystemState; - POWER_ACTION PowerAction; + POWER_STATE PowerState; NTSTATUS status; StackLocation = IoGetCurrentIrpStackLocation(Irp); SystemState = StackLocation->Parameters.Power.State.SystemState; - PowerAction = StackLocation->Parameters.Power.ShutdownType; - Trace("====> (%s:%s)\n", - SystemPowerStateName(SystemState), - PowerActionName(PowerAction)); + ASSERT3U(SystemState, >, __FdoGetSystemPowerState(Fdo)); - ASSERT3U(PowerAction, <, PowerActionShutdown); + PowerState.DeviceState = Fdo->LowerDeviceCapabilities.DeviceState[SystemState]; - if (SystemState == __FdoGetSystemPowerState(Fdo)) { - status = FdoForwardIrpSynchronously(Fdo, Irp); - IoCompleteRequest(Irp, IO_NO_INCREMENT); + if (SystemState >= PowerSystemShutdown) { + /* No DIrp generation, no FDO Powerdown. + Legacy shutdown just yanks system power. + Best device state for S5 is advertised as D3, + which is not *really* the case, but we can't increase it. */ + IoCopyCurrentIrpStackLocationToNext(Irp); /* Irp has been pended */ + status = IoCallDriver(Fdo->LowerDeviceObject, Irp); goto done; } - status = (SystemState < __FdoGetSystemPowerState(Fdo)) ? - FdoSetSystemPowerUp(Fdo, Irp) : - FdoSetSystemPowerDown(Fdo, Irp); + status = PoRequestPowerIrp(Fdo->LowerDeviceObject, + IRP_MN_SET_POWER, + PowerState, + FdoRequestDevicePowerDownComplete, + Irp, + NULL); + if (!NT_SUCCESS(status)) + goto fail1; done: - Trace("<==== (%s:%s)(%08x)\n", - SystemPowerStateName(SystemState), - PowerActionName(PowerAction), - status); - return status; -} - -static NTSTATUS -FdoQueryDevicePowerUp( - IN PXENBUS_FDO Fdo, - IN PIRP Irp - ) -{ - PIO_STACK_LOCATION StackLocation; - DEVICE_POWER_STATE DeviceState; - NTSTATUS status; - - StackLocation = IoGetCurrentIrpStackLocation(Irp); - DeviceState = StackLocation->Parameters.Power.State.DeviceState; - - ASSERT3U(DeviceState, <, __FdoGetDevicePowerState(Fdo)); - - status = FdoForwardIrpSynchronously(Fdo, Irp); - - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return status; -} - -static NTSTATUS -FdoQueryDevicePowerDown( - IN PXENBUS_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); +fail1: + /* In theory could change IRP status, but are not supposed to fail this IRP. */ + Error("fail1 - but continue IRP processing. (%08x)\n", status); return status; } static NTSTATUS -FdoQueryDevicePower( +FdoSetSystemPower( IN PXENBUS_FDO Fdo, IN PIRP Irp ) { PIO_STACK_LOCATION StackLocation; - DEVICE_POWER_STATE DeviceState; + SYSTEM_POWER_STATE SystemState; POWER_ACTION PowerAction; NTSTATUS status; StackLocation = IoGetCurrentIrpStackLocation(Irp); - DeviceState = StackLocation->Parameters.Power.State.DeviceState; + SystemState = StackLocation->Parameters.Power.State.SystemState; PowerAction = StackLocation->Parameters.Power.ShutdownType; + /* IRP_MN_SET_POWER Setting system power, IRP's *must* be pended. */ + IoMarkIrpPending(Irp); + Trace("====> (%s:%s)\n", - DevicePowerStateName(DeviceState), + SystemPowerStateName(SystemState), PowerActionName(PowerAction)); - ASSERT3U(PowerAction, <, PowerActionShutdown); - - if (DeviceState == __FdoGetDevicePowerState(Fdo)) { - status = FdoForwardIrpSynchronously(Fdo, Irp); - IoCompleteRequest(Irp, IO_NO_INCREMENT); + if (SystemState == __FdoGetSystemPowerState(Fdo)) { + IoCopyCurrentIrpStackLocationToNext(Irp); /* Pended, copy not skip */ + status = IoCallDriver(Fdo->LowerDeviceObject, Irp); goto done; } - status = (DeviceState < __FdoGetDevicePowerState(Fdo)) ? - FdoQueryDevicePowerUp(Fdo, Irp) : - FdoQueryDevicePowerDown(Fdo, Irp); + status = (SystemState < __FdoGetSystemPowerState(Fdo)) ? + FdoSetSystemPowerUp(Fdo, Irp) : + FdoSetSystemPowerDown(Fdo, Irp); done: Trace("<==== (%s:%s)(%08x)\n", - DevicePowerStateName(DeviceState), + SystemPowerStateName(SystemState), PowerActionName(PowerAction), status); + return status; } __drv_functionClass(REQUEST_POWER_COMPLETE) __drv_sameIRQL -VOID -FdoRequestQueryDevicePowerCompletion( +static VOID +FdoRequestQuerySystemPowerUpComplete( IN PDEVICE_OBJECT DeviceObject, IN UCHAR MinorFunction, IN POWER_STATE PowerState, @@ -5176,48 +5318,56 @@ FdoRequestQueryDevicePowerCompletion( 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)); - - KeSetEvent(Event, IO_NO_INCREMENT, FALSE); + if (!NT_SUCCESS(IoStatus->Status)) + Irp->IoStatus.Status = IoStatus->Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); } -__drv_requiresIRQL(PASSIVE_LEVEL) -static VOID -FdoRequestQueryDevicePower( - IN PXENBUS_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", DevicePowerStateName(DeviceState)); + PXENBUS_FDO Fdo = (PXENBUS_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); + /* IRP marked as pending on dispatch path. */ + StackLocation = IoGetCurrentIrpStackLocation(Irp); + SystemState = StackLocation->Parameters.Power.State.SystemState; + PowerState.DeviceState = Fdo->LowerDeviceCapabilities.DeviceState[SystemState]; status = PoRequestPowerIrp(Fdo->LowerDeviceObject, IRP_MN_QUERY_POWER, PowerState, - FdoRequestQueryDevicePowerCompletion, - &Event, + FdoRequestQuerySystemPowerUpComplete, + 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: + /* Irp marked as pending on dispatch path, so can change final IoStatus, pass to completion routine above. */ + Error("fail1 (%08x)\n", status); + Irp->IoStatus.Status = status; + + return STATUS_CONTINUE_COMPLETION; } static NTSTATUS @@ -5226,29 +5376,50 @@ FdoQuerySystemPowerUp( IN PIRP Irp ) { + IoMarkIrpPending(Irp); /* Must mark IRP pending because we want to complete it *after* completion routine. */ + IoCopyCurrentIrpStackLocationToNext(Irp); + IoSetCompletionRoutine(Irp, + FdoQuerySystemPowerUpComplete, + Fdo, + TRUE, + TRUE, + TRUE); + return IoCallDriver(Fdo->LowerDeviceObject, Irp); +} - PIO_STACK_LOCATION StackLocation; - SYSTEM_POWER_STATE SystemState; - DEVICE_POWER_STATE DeviceState; - NTSTATUS status; - - StackLocation = IoGetCurrentIrpStackLocation(Irp); - SystemState = StackLocation->Parameters.Power.State.SystemState; +__drv_functionClass(REQUEST_POWER_COMPLETE) +__drv_sameIRQL +static VOID +FdoRequestQuerySystemPowerDownComplete( + 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; + PXENBUS_DX Dx = (PXENBUS_DX)UpperDeviceObject->DeviceExtension; + PXENBUS_FDO Fdo = Dx->Fdo; - ASSERT3U(SystemState, <, __FdoGetSystemPowerState(Fdo)); + UNREFERENCED_PARAMETER(DeviceObject); + UNREFERENCED_PARAMETER(MinorFunction); + UNREFERENCED_PARAMETER(PowerState); - status = FdoForwardIrpSynchronously(Fdo, Irp); - if (!NT_SUCCESS(status)) - goto done; + if (!NT_SUCCESS(IoStatus->Status)) + goto fail1; - DeviceState = Fdo->LowerDeviceCapabilities.DeviceState[SystemState]; + IoCopyCurrentIrpStackLocationToNext(Irp); /* Irp has been pended. */ + IoCallDriver(Fdo->LowerDeviceObject, Irp); - FdoRequestQueryDevicePower(Fdo, DeviceState); + return; -done: +fail1: + Error("fail1 (%08x)\n", IoStatus->Status); + Irp->IoStatus.Status = IoStatus->Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); - - return status; } static NTSTATUS @@ -5259,7 +5430,7 @@ FdoQuerySystemPowerDown( { PIO_STACK_LOCATION StackLocation; SYSTEM_POWER_STATE SystemState; - DEVICE_POWER_STATE DeviceState; + POWER_STATE PowerState; NTSTATUS status; StackLocation = IoGetCurrentIrpStackLocation(Irp); @@ -5267,11 +5438,24 @@ FdoQuerySystemPowerDown( ASSERT3U(SystemState, >, __FdoGetSystemPowerState(Fdo)); - DeviceState = Fdo->LowerDeviceCapabilities.DeviceState[SystemState]; + PowerState.DeviceState = Fdo->LowerDeviceCapabilities.DeviceState[SystemState]; - FdoRequestQueryDevicePower(Fdo, DeviceState); + status = PoRequestPowerIrp(Fdo->LowerDeviceObject, + IRP_MN_QUERY_POWER, + PowerState, + FdoRequestQuerySystemPowerDownComplete, + Irp, + NULL); + if (!NT_SUCCESS(status)) + goto fail1; - status = FdoForwardIrpSynchronously(Fdo, Irp); + IoMarkIrpPending(Irp); + return STATUS_PENDING; + +fail1: + Error("fail1 (%08x)\n", status); + + Irp->IoStatus.Status = status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return status; @@ -5296,11 +5480,9 @@ FdoQuerySystemPower( SystemPowerStateName(SystemState), PowerActionName(PowerAction)); - ASSERT3U(PowerAction, <, PowerActionShutdown); - if (SystemState == __FdoGetSystemPowerState(Fdo)) { - status = FdoForwardIrpSynchronously(Fdo, Irp); - IoCompleteRequest(Irp, IO_NO_INCREMENT); + IoSkipCurrentIrpStackLocation(Irp); + status = IoCallDriver(Fdo->LowerDeviceObject, Irp); goto done; } @@ -5319,117 +5501,57 @@ done: } static NTSTATUS -FdoDevicePower( - IN PXENBUS_THREAD Self, - IN PVOID Context +FdoDispatchDevicePower( + IN PXENBUS_FDO Fdo, + IN PIRP Irp ) { - PXENBUS_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; + PIO_STACK_LOCATION StackLocation; + NTSTATUS status; - switch (StackLocation->MinorFunction) { - case IRP_MN_SET_POWER: - (VOID) FdoSetDevicePower(Fdo, Irp); - break; + StackLocation = IoGetCurrentIrpStackLocation(Irp); - case IRP_MN_QUERY_POWER: - (VOID) FdoQueryDevicePower(Fdo, Irp); - break; + switch (StackLocation->MinorFunction) { + case IRP_MN_SET_POWER: + status = FdoSetDevicePower(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 PXENBUS_THREAD Self, - IN PVOID Context +FdoDispatchSystemPower( + IN PXENBUS_FDO Fdo, + IN PIRP Irp ) { - PXENBUS_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 NTSTATUS @@ -5439,55 +5561,21 @@ FdoDispatchPower( ) { 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 = FdoDispatchDevicePower(Fdo, Irp); break; case SystemPowerState: - IoMarkIrpPending(Irp); - - ASSERT3P(Fdo->SystemPowerIrp, ==, NULL); - Fdo->SystemPowerIrp = Irp; - KeMemoryBarrier(); - - ThreadWake(Fdo->SystemPowerThread); - - status = STATUS_PENDING; + status = FdoDispatchSystemPower(Fdo, Irp); break; default: @@ -5496,10 +5584,10 @@ FdoDispatchPower( break; } -done: return status; } + static NTSTATUS FdoDispatchDefault( IN PXENBUS_FDO Fdo, @@ -5748,12 +5836,12 @@ FdoCreate( Fdo->LowerDeviceObject = IoAttachDeviceToDeviceStack(FunctionDeviceObject, PhysicalDeviceObject); - status = ThreadCreate(FdoSystemPower, Fdo, &Fdo->SystemPowerThread); - if (!NT_SUCCESS(status)) + Fdo->SystemPowerWorkItem = IoAllocateWorkItem(FunctionDeviceObject); + if (Fdo->SystemPowerWorkItem == NULL) goto fail3; - status = ThreadCreate(FdoDevicePower, Fdo, &Fdo->DevicePowerThread); - if (!NT_SUCCESS(status)) + Fdo->DevicePowerWorkItem = IoAllocateWorkItem(FunctionDeviceObject); + if (Fdo->DevicePowerWorkItem == NULL) goto fail4; status = FdoAcquireLowerBusInterface(Fdo); @@ -5992,17 +6080,15 @@ 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"); @@ -6117,13 +6203,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/xenbus/pdo.c b/src/xenbus/pdo.c index 3f1e4c5..9163923 100644 --- a/src/xenbus/pdo.c +++ b/src/xenbus/pdo.c @@ -58,9 +58,9 @@ struct _XENBUS_PDO { PXENBUS_DX Dx; - PXENBUS_THREAD SystemPowerThread; + PIO_WORKITEM SystemPowerWorkItem; PIRP SystemPowerIrp; - PXENBUS_THREAD DevicePowerThread; + PIO_WORKITEM DevicePowerWorkItem; PIRP DevicePowerIrp; PXENBUS_FDO Fdo; @@ -1695,26 +1695,31 @@ PdoDispatchPnp( return status; } -static NTSTATUS -PdoSetDevicePower( - IN PXENBUS_PDO Pdo, - IN PIRP Irp +__drv_functionClass(IO_WORKITEM_ROUTINE) +__drv_sameIRQL +static VOID +PdoSetDevicePowerWorker( + IN PDEVICE_OBJECT DeviceObject, + IN PVOID Context ) { + PXENBUS_PDO Pdo = (PXENBUS_PDO) Context; + PIRP Irp; + NTSTATUS status; PIO_STACK_LOCATION StackLocation; DEVICE_POWER_STATE DeviceState; POWER_ACTION PowerAction; + 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)\n", - DevicePowerStateName(DeviceState), - PowerActionName(PowerAction)); - - ASSERT3U(PowerAction, <, PowerActionShutdown); - + status = STATUS_SUCCESS; if (__PdoGetDevicePowerState(Pdo) > DeviceState) { Trace("%s: POWERING UP: %s -> %s\n", __PdoGetName(Pdo), @@ -1722,7 +1727,7 @@ PdoSetDevicePower( DevicePowerStateName(DeviceState)); ASSERT3U(DeviceState, ==, PowerDeviceD0); - PdoD3ToD0(Pdo); + status = PdoD3ToD0(Pdo); } else if (__PdoGetDevicePowerState(Pdo) < DeviceState) { Trace("%s: POWERING DOWN: %s -> %s\n", __PdoGetName(Pdo), @@ -1733,76 +1738,76 @@ PdoSetDevicePower( PdoD0ToD3(Pdo); } + if(NT_SUCCESS(status)) + goto done; + + Error("fail1 (%08x)\n", status); + /* TODO - Consider cycling device power at some later point? + Need PPO to retry SIRP -> DIRP */ + +done: + /* Cannot fail the IRP at this point, keep going. */ Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp, IO_NO_INCREMENT); Trace("<==== (%s:%s)\n", DevicePowerStateName(DeviceState), PowerActionName(PowerAction)); - - return STATUS_SUCCESS; } static NTSTATUS -PdoDevicePower( - IN PXENBUS_THREAD Self, - IN PVOID Context +PdoSetDevicePower( + IN PXENBUS_PDO Pdo, + IN PIRP Irp ) { - PXENBUS_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; - 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", + DevicePowerStateName(DeviceState), + PowerActionName(PowerAction)); - if (Irp == NULL) - continue; + IoMarkIrpPending(Irp); - Pdo->DevicePowerIrp = NULL; - KeMemoryBarrier(); + (VOID) InterlockedExchangePointer(&Pdo->DevicePowerIrp, Irp); - (VOID) PdoSetDevicePower(Pdo, Irp); - } + IoQueueWorkItem(Pdo->DevicePowerWorkItem, + PdoSetDevicePowerWorker, + DelayedWorkQueue, + Pdo); - return STATUS_SUCCESS; + return STATUS_PENDING; } -static NTSTATUS -PdoSetSystemPower( - IN PXENBUS_PDO Pdo, - IN PIRP Irp +__drv_functionClass(IO_WORKITEM_ROUTINE) +__drv_sameIRQL +static VOID +PdoSetSystemPowerWorker( + IN PDEVICE_OBJECT DeviceObject, + IN PVOID Context ) { + PXENBUS_PDO Pdo = (PXENBUS_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)\n", - SystemPowerStateName(SystemState), - PowerActionName(PowerAction)); - - ASSERT3U(PowerAction, <, PowerActionShutdown); - if (__PdoGetSystemPowerState(Pdo) > SystemState) { if (SystemState < PowerSystemHibernate && __PdoGetSystemPowerState(Pdo) >= PowerSystemHibernate) { @@ -1836,52 +1841,40 @@ PdoSetSystemPower( Trace("<==== (%s:%s)\n", SystemPowerStateName(SystemState), PowerActionName(PowerAction)); - - return STATUS_SUCCESS; } static NTSTATUS -PdoSystemPower( - IN PXENBUS_THREAD Self, - IN PVOID Context +PdoSetSystemPower( + IN PXENBUS_PDO Pdo, + IN PIRP Irp ) { - PXENBUS_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; - 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", + SystemPowerStateName(SystemState), + PowerActionName(PowerAction)); - if (Irp == NULL) - continue; + IoMarkIrpPending(Irp); - Pdo->SystemPowerIrp = NULL; - KeMemoryBarrier(); + (VOID) InterlockedExchangePointer(&Pdo->SystemPowerIrp, Irp); - (VOID) PdoSetSystemPower(Pdo, Irp); - } + IoQueueWorkItem(Pdo->SystemPowerWorkItem, + PdoSetSystemPowerWorker, + DelayedWorkQueue, + Pdo); - return STATUS_SUCCESS; + return STATUS_PENDING; } static NTSTATUS -PdoSetPower( +PdoDispatchSetPower( IN PXENBUS_PDO Pdo, IN PIRP Irp ) @@ -1895,38 +1888,13 @@ PdoSetPower( 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: @@ -1935,25 +1903,6 @@ PdoSetPower( break; } -done: - return status; -} - -static NTSTATUS -PdoQueryPower( - IN PXENBUS_PDO Pdo, - IN PIRP Irp - ) -{ - NTSTATUS status; - - UNREFERENCED_PARAMETER(Pdo); - - status = STATUS_SUCCESS; - - Irp->IoStatus.Status = status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return status; } @@ -1972,14 +1921,11 @@ PdoDispatchPower( switch (StackLocation->MinorFunction) { case IRP_MN_SET_POWER: - status = PdoSetPower(Pdo, Irp); - break; - - case IRP_MN_QUERY_POWER: - status = PdoQueryPower(Pdo, Irp); + status = PdoDispatchSetPower(Pdo, Irp); break; default: + /* TODO - Always complete with status success?? */ status = Irp->IoStatus.Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); break; @@ -2093,12 +2039,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, Name); @@ -2135,16 +2081,14 @@ fail5: Pdo->Ejectable = FALSE; Pdo->Removable = FALSE; - 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"); @@ -2198,13 +2142,11 @@ PdoDestroy( Pdo->Ejectable = FALSE; Pdo->Removable = FALSE; - ThreadAlert(Pdo->DevicePowerThread); - ThreadJoin(Pdo->DevicePowerThread); - Pdo->DevicePowerThread = NULL; - - ThreadAlert(Pdo->SystemPowerThread); - ThreadJoin(Pdo->SystemPowerThread); - Pdo->SystemPowerThread = NULL; + IoFreeWorkItem(Pdo->DevicePowerWorkItem); + Pdo->DevicePowerWorkItem = 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 |