[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH] [RFQ] Asynchronous power handling.
This patch submitted for comment as part of recent efforts to improve reliability and performance in the windows PV drivers, particularly in the hibernate and shutdown testcases under driver verifier. This patch is just one sample (for xenbus). We also have patches for all the other xen* windows drivers. Internal test results indicate that this code removes at least one failure case on the shutdown path, and also demonstrates that an existing interittent hibernate bug is not due to the PV driver stack. We are performing long-term soak testing of this branch in parallel with mainstream development to check that it solves (or ameliorates, or aids investigation) into intermittent test failures. We hope to provide full WHQL test results, and statistical failure rates for this change in the coming months, as well as an analysis of any other bugs or problems uncovered. If this change turns out to be significantly better than the current codebase, then we expect it will be possible to break-down this patch into small pieces (by file or by device object) for easier merging and integration. Signed-off-by: Martin Harvey <martin.harvey@xxxxxxxxxx> --- src/xenbus/fdo.c | 1051 +++++++++++++++++++++++++++++--------------- src/xenbus/pdo.c | 302 ++++++------- src/xenbus/store.c | 6 +- src/xenbus/types.h | 5 + src/xenfilt/fdo.c | 600 +++++++------------------ src/xenfilt/pdo.c | 611 +++++++------------------ 6 files changed, 1166 insertions(+), 1409 deletions(-) diff --git a/src/xenbus/fdo.c b/src/xenbus/fdo.c index d08c518..9501c31 100644 --- a/src/xenbus/fdo.c +++ b/src/xenbus/fdo.c @@ -63,6 +63,7 @@ #include "dbg_print.h" #include "assert.h" #include "util.h" +#include "types.h" #define XENBUS_FDO_TAG 'ODF' @@ -106,11 +107,6 @@ struct _XENBUS_FDO { ULONG Usage[DeviceUsageTypeDumpFile + 1]; BOOLEAN NotDisableable; - PXENBUS_THREAD SystemPowerThread; - PIRP SystemPowerIrp; - PXENBUS_THREAD DevicePowerThread; - PIRP DevicePowerIrp; - CHAR VendorName[MAXNAMELEN]; MUTEX Mutex; @@ -168,6 +164,11 @@ struct _XENBUS_FDO { PXENBUS_SUSPEND_CALLBACK SuspendCallbackLate; BOOLEAN ConsoleAcquired; PLOG_DISPOSITION LogDisposition; + + PIO_WORKITEM FdoSPowerWorkItem; + XENBUS_POWER_WORKITEM_CONTEXT FdoSPowerContext; + PIO_WORKITEM FdoDPowerWorkItem; + XENBUS_POWER_WORKITEM_CONTEXT FdoDPowerContext; }; static FORCEINLINE PVOID @@ -4585,6 +4586,9 @@ FdoQueryCapabilities( DEVICE_POWER_STATE DevicePowerState; DevicePowerState = Fdo->LowerDeviceCapabilities.DeviceState[SystemPowerState]; + Trace("PowerCaps: SystemState: %s (%u), best device power: %s (%u)\n", + SystemPowerStateName(SystemPowerState), SystemPowerState, + DevicePowerStateName(DevicePowerState), DevicePowerState); } IoCompleteRequest(Irp, IO_NO_INCREMENT); @@ -4775,42 +4779,142 @@ FdoDispatchPnp( return status; } +VOID _FdoD3toD0PowerWorker( + IN PDEVICE_OBJECT DeviceObject, + IN PVOID Context + ) +{ + PXENBUS_POWER_WORKITEM_CONTEXT PowerContext = (PXENBUS_POWER_WORKITEM_CONTEXT)Context; + PXENBUS_FDO Fdo = (PXENBUS_FDO) PowerContext->FdoOrPdo; + PIRP Irp; + NTSTATUS status; + + UNREFERENCED_PARAMETER(DeviceObject); + + Irp = InterlockedExchangePointer(&PowerContext->Irp, NULL); + ASSERT(Irp != NULL); + + status = FdoD3ToD0(Fdo); + if (!NT_SUCCESS(status)) + Error("fail1 - but continue IRP processing. (%08x)\n", status); + + /* Cannot change Irp->IoStatus */ + /* Continue completion chain */ + IoCompleteRequest(Irp, IO_NO_INCREMENT); +} + +VOID FdoD3toD0PowerWorker( + IN PXENBUS_FDO Fdo, + IN PIRP Irp +) +{ + PVOID Exchange; + + ASSERT(Fdo->FdoDPowerContext.FdoOrPdo == Fdo); + Exchange = InterlockedExchangePointer(&Fdo->FdoDPowerContext.Irp, Irp); + ASSERT(Exchange == NULL); + + IoQueueWorkItem(Fdo->FdoDPowerWorkItem, + _FdoD3toD0PowerWorker, + DelayedWorkQueue, + &Fdo->FdoDPowerContext); +} + +__drv_functionClass(IO_COMPLETION_ROUTINE) +__drv_sameIRQL +static NTSTATUS +FdoCompleteSetDevicePowerUp( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PVOID Context + ) +{ + PXENBUS_FDO Fdo = (PXENBUS_FDO) Context; + PIO_STACK_LOCATION StackLocation = IoGetCurrentIrpStackLocation(Irp); + DEVICE_POWER_STATE DeviceState = StackLocation->Parameters.Power.State.DeviceState; + + UNREFERENCED_PARAMETER(DeviceObject); + + /* Already marked pending by us */ + Info("%s -> %s\n", + DevicePowerStateName(__FdoGetDevicePowerState(Fdo)), + DevicePowerStateName(DeviceState)); + + /* Don't worry about IRP IoStatus */ + ASSERT3U(DeviceState, ==, PowerDeviceD0); + FdoD3toD0PowerWorker(Fdo, Irp); + + /* Stop completion chain in all circumstances. */ + return STATUS_MORE_PROCESSING_REQUIRED; +} + static NTSTATUS -FdoSetDevicePowerUp( +FdoDispatchSetDevicePowerUp( IN PXENBUS_FDO Fdo, IN PIRP Irp ) { PIO_STACK_LOCATION StackLocation; DEVICE_POWER_STATE DeviceState; - NTSTATUS status; + + Trace("====>\n"); StackLocation = IoGetCurrentIrpStackLocation(Irp); DeviceState = StackLocation->Parameters.Power.State.DeviceState; ASSERT3U(DeviceState, <, __FdoGetDevicePowerState(Fdo)); - status = FdoForwardIrpSynchronously(Fdo, Irp); - if (!NT_SUCCESS(status)) - goto done; + IoMarkIrpPending(Irp); + IoCopyCurrentIrpStackLocationToNext(Irp); + IoSetCompletionRoutine(Irp, + FdoCompleteSetDevicePowerUp, + Fdo, + TRUE, + TRUE, + TRUE); + IoCallDriver(Fdo->LowerDeviceObject, Irp); + return STATUS_PENDING; +} - Info("%s: %s -> %s\n", - __FdoGetName(Fdo), - DevicePowerStateName(__FdoGetDevicePowerState(Fdo)), - DevicePowerStateName(DeviceState)); +VOID _FdoD0toD3PowerWorker( + IN PDEVICE_OBJECT DeviceObject, + IN PVOID Context + ) +{ + PXENBUS_POWER_WORKITEM_CONTEXT PowerContext = (PXENBUS_POWER_WORKITEM_CONTEXT)Context; + PXENBUS_FDO Fdo = (PXENBUS_FDO) PowerContext->FdoOrPdo; + PIRP Irp; - ASSERT3U(DeviceState, ==, PowerDeviceD0); - status = FdoD3ToD0(Fdo); - ASSERT(NT_SUCCESS(status)); + UNREFERENCED_PARAMETER(DeviceObject); -done: - IoCompleteRequest(Irp, IO_NO_INCREMENT); + Irp = InterlockedExchangePointer(&PowerContext->Irp, NULL); + ASSERT(Irp != NULL); - return status; + FdoD0ToD3(Fdo); + /* We are on dispatch path here, irp pended. */ + IoCopyCurrentIrpStackLocationToNext(Irp); + IoCallDriver(Fdo->LowerDeviceObject, Irp); +} + +VOID FdoD0ToD3PowerWorker( + IN PXENBUS_FDO Fdo, + IN PIRP Irp +) +{ + PVOID Exchange; + + ASSERT(Fdo->FdoDPowerContext.FdoOrPdo == Fdo); + Exchange = InterlockedExchangePointer(&Fdo->FdoDPowerContext.Irp, Irp); + ASSERT(Exchange == NULL); + + IoQueueWorkItem(Fdo->FdoDPowerWorkItem, + _FdoD0toD3PowerWorker, + DelayedWorkQueue, + &Fdo->FdoDPowerContext); } static NTSTATUS -FdoSetDevicePowerDown( +FdoDispatchSetDevicePowerDown( IN PXENBUS_FDO Fdo, IN PIRP Irp ) @@ -4831,17 +4935,22 @@ FdoSetDevicePowerDown( ASSERT3U(DeviceState, ==, PowerDeviceD3); - if (__FdoGetDevicePowerState(Fdo) == PowerDeviceD0) - FdoD0ToD3(Fdo); - - status = FdoForwardIrpSynchronously(Fdo, Irp); - IoCompleteRequest(Irp, IO_NO_INCREMENT); + /* All handled in dispatch, no extra error handling */ + if (__FdoGetDevicePowerState(Fdo) == PowerDeviceD0) { + IoMarkIrpPending(Irp); + FdoD0ToD3PowerWorker(Fdo, Irp); + status = STATUS_PENDING; + } else { + /* Not marked pending, can skip */ + IoSkipCurrentIrpStackLocation(Irp); + status = IoCallDriver(Fdo->LowerDeviceObject, Irp); + } return status; } static NTSTATUS -FdoSetDevicePower( +FdoDispatchSetDevicePower( IN PXENBUS_FDO Fdo, IN PIRP Irp ) @@ -4859,18 +4968,16 @@ 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; } status = (DeviceState < __FdoGetDevicePowerState(Fdo)) ? - FdoSetDevicePowerUp(Fdo, Irp) : - FdoSetDevicePowerDown(Fdo, Irp); + FdoDispatchSetDevicePowerUp(Fdo, Irp) : + FdoDispatchSetDevicePowerDown(Fdo, Irp); done: Trace("<==== (%s:%s)(%08x)\n", @@ -4880,10 +4987,34 @@ done: return status; } +static NTSTATUS +FdoRequestSetDevicePower( + IN PXENBUS_FDO Fdo, + IN DEVICE_POWER_STATE DeviceState, + IN PREQUEST_POWER_COMPLETE CompletionFunction, + IN PVOID Context + ) +{ + POWER_STATE PowerState; + NTSTATUS status; + + Trace("%s\n", DevicePowerStateName(DeviceState)); + + PowerState.DeviceState = DeviceState; + + status = PoRequestPowerIrp(Fdo->LowerDeviceObject, + IRP_MN_SET_POWER, + PowerState, + CompletionFunction, + Context, + NULL); + return status; +} + __drv_functionClass(REQUEST_POWER_COMPLETE) __drv_sameIRQL VOID -FdoRequestSetDevicePowerCompletion( +FdoCompleteSetSystemPowerUp2( IN PDEVICE_OBJECT DeviceObject, IN UCHAR MinorFunction, IN POWER_STATE PowerState, @@ -4891,112 +5022,238 @@ 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)); + /* Although can change Irp->IoStatus for pended IRP, drivers should not fail this. */ + IoCompleteRequest(Irp, IO_NO_INCREMENT); +} - KeSetEvent(Event, IO_NO_INCREMENT, FALSE); +static NTSTATUS +FdoCompleteSetSystemPowerUpTail( + IN PXENBUS_FDO Fdo, + IN PIRP Irp +) +{ + PIO_STACK_LOCATION StackLocation = IoGetCurrentIrpStackLocation(Irp);; + SYSTEM_POWER_STATE SystemState = StackLocation->Parameters.Power.State.SystemState; + DEVICE_POWER_STATE DeviceState; + /* This executes in two contexts: + 1. When we are in the completion routine FdoCompleteSetSystemPowerUp + 2. When we at the end of the worker routine FdoS4ToS3PowerWorker + */ + + Info("%s -> %s\n", + SystemPowerStateName(__FdoGetSystemPowerState(Fdo)), + SystemPowerStateName(SystemState)); + + __FdoSetSystemPowerState(Fdo, SystemState); + + DeviceState = Fdo->LowerDeviceCapabilities.DeviceState[SystemState]; + return FdoRequestSetDevicePower(Fdo, DeviceState, FdoCompleteSetSystemPowerUp2, Irp); } -__drv_requiresIRQL(PASSIVE_LEVEL) -static VOID -FdoRequestSetDevicePower( - IN PXENBUS_FDO Fdo, - IN DEVICE_POWER_STATE DeviceState - ) +VOID _FdoS4ToS3PowerWorker( + IN PDEVICE_OBJECT DeviceObject, + IN PVOID Context + ) { - POWER_STATE PowerState; - KEVENT Event; - NTSTATUS status; + PXENBUS_POWER_WORKITEM_CONTEXT PowerContext = (PXENBUS_POWER_WORKITEM_CONTEXT)Context; + PXENBUS_FDO Fdo = (PXENBUS_FDO) PowerContext->FdoOrPdo; + PIRP Irp; + NTSTATUS status; - Trace("%s\n", DevicePowerStateName(DeviceState)); + UNREFERENCED_PARAMETER(DeviceObject); - ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL); + Irp = InterlockedExchangePointer(&PowerContext->Irp, NULL); + ASSERT(Irp != NULL); - PowerState.DeviceState = DeviceState; - KeInitializeEvent(&Event, NotificationEvent, FALSE); + __FdoSetSystemPowerState(Fdo, PowerSystemHibernate); /* Meet preconds for S4 to S3 */ + FdoS4ToS3(Fdo); + status = FdoCompleteSetSystemPowerUpTail(Fdo, Irp); /* And set final system state, S3 or higher */ - status = PoRequestPowerIrp(Fdo->LowerDeviceObject, - IRP_MN_SET_POWER, - PowerState, - FdoRequestSetDevicePowerCompletion, - &Event, - 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; /* FdoCompleteSetSystemPowerUp2 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); +} + +VOID FdoS4ToS3PowerWorker( + IN PXENBUS_FDO Fdo, + IN PIRP Irp +) +{ + PVOID Exchange; + + ASSERT(Fdo->FdoSPowerContext.FdoOrPdo == Fdo); + Exchange = InterlockedExchangePointer(&Fdo->FdoSPowerContext.Irp, Irp); + ASSERT(Exchange == NULL); + + IoQueueWorkItem(Fdo->FdoDPowerWorkItem, + _FdoS4ToS3PowerWorker, + DelayedWorkQueue, + &Fdo->FdoSPowerContext); } +__drv_functionClass(IO_COMPLETION_ROUTINE) +__drv_sameIRQL static NTSTATUS -FdoSetSystemPowerUp( - IN PXENBUS_FDO Fdo, - IN PIRP Irp +FdoCompleteSetSystemPowerUp( + 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; NTSTATUS status; - StackLocation = IoGetCurrentIrpStackLocation(Irp); - SystemState = StackLocation->Parameters.Power.State.SystemState; - - ASSERT3U(SystemState, <, __FdoGetSystemPowerState(Fdo)); + UNREFERENCED_PARAMETER(DeviceObject); - status = FdoForwardIrpSynchronously(Fdo, Irp); - if (!NT_SUCCESS(status)) - goto done; + /* IRP marked as pending on dispatch path, no need to check pending returned */ - Info("%s: %s -> %s\n", - __FdoGetName(Fdo), - SystemPowerStateName(__FdoGetSystemPowerState(Fdo)), - SystemPowerStateName(SystemState)); + /* Don't worry about IRP IoStatus */ + StackLocation = IoGetCurrentIrpStackLocation(Irp); + BUG_ON(StackLocation->DeviceObject != Fdo->Dx->DeviceObject); + SystemState = StackLocation->Parameters.Power.State.SystemState; if (SystemState < PowerSystemHibernate && __FdoGetSystemPowerState(Fdo) >= PowerSystemHibernate) { - __FdoSetSystemPowerState(Fdo, PowerSystemHibernate); - FdoS4ToS3(Fdo); + FdoS4ToS3PowerWorker(Fdo, Irp); + goto done; /* Stop completion routine for the moment... */ } - __FdoSetSystemPowerState(Fdo, SystemState); + status = FdoCompleteSetSystemPowerUpTail(Fdo, Irp); + if (!NT_SUCCESS(status)) + goto fail1; - DeviceState = Fdo->LowerDeviceCapabilities.DeviceState[SystemState]; - FdoRequestSetDevicePower(Fdo, DeviceState); + goto done; -done: - IoCompleteRequest(Irp, IO_NO_INCREMENT); +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; - return status; +done: + /* Will later complete the IRP (which is marked pending, in worker or 2nd level comp routine.)*/ + return STATUS_MORE_PROCESSING_REQUIRED; } -static NTSTATUS -FdoSetSystemPowerDown( +static VOID +FdoDispatchSetSystemPowerUp( IN PXENBUS_FDO Fdo, IN PIRP Irp ) { PIO_STACK_LOCATION StackLocation; SYSTEM_POWER_STATE SystemState; - DEVICE_POWER_STATE DeviceState; - NTSTATUS status; StackLocation = IoGetCurrentIrpStackLocation(Irp); + BUG_ON(StackLocation->DeviceObject != Fdo->Dx->DeviceObject); SystemState = StackLocation->Parameters.Power.State.SystemState; - ASSERT3U(SystemState, >, __FdoGetSystemPowerState(Fdo)); + ASSERT3U(SystemState, <, __FdoGetSystemPowerState(Fdo)); - DeviceState = Fdo->LowerDeviceCapabilities.DeviceState[SystemState]; + /* IRP already pended, and we want to complete it *after* completion routine. */ + IoCopyCurrentIrpStackLocationToNext(Irp); + IoSetCompletionRoutine(Irp, + FdoCompleteSetSystemPowerUp, + Fdo, + TRUE, + TRUE, + TRUE); + IoCallDriver(Fdo->LowerDeviceObject, Irp); +} + +VOID +FdoDispatchSetSystemPowerDown2Tail( + IN PXENBUS_FDO Fdo, + IN PIRP Irp +) +{ + PIO_STACK_LOCATION StackLocation = IoGetCurrentIrpStackLocation(Irp); + SYSTEM_POWER_STATE SystemState = StackLocation->Parameters.Power.State.SystemState; + + __FdoSetSystemPowerState(Fdo, SystemState); +} + +VOID _FdoS3ToS4PowerWorker( + IN PDEVICE_OBJECT DeviceObject, + IN PVOID Context + ) +{ + PXENBUS_POWER_WORKITEM_CONTEXT PowerContext = (PXENBUS_POWER_WORKITEM_CONTEXT)Context; + PXENBUS_FDO Fdo = (PXENBUS_FDO) PowerContext->FdoOrPdo; + PIRP Irp; + + UNREFERENCED_PARAMETER(DeviceObject); + + Irp = InterlockedExchangePointer(&PowerContext->Irp, NULL); + ASSERT(Irp != NULL); + + /* Meet preconditions for S3 to S4 */ + __FdoSetSystemPowerState(Fdo, PowerSystemSleeping3); + FdoS3ToS4(Fdo); + FdoDispatchSetSystemPowerDown2Tail(Fdo, Irp); + + IoCopyCurrentIrpStackLocationToNext(Irp); /* Irp has been pended */ + IoCallDriver(Fdo->LowerDeviceObject, Irp); +} + +VOID FdoS3ToS4PowerWorker( + IN PXENBUS_FDO Fdo, + IN PIRP Irp +) +{ + PVOID Exchange; + + ASSERT(Fdo->FdoSPowerContext.FdoOrPdo == Fdo); + Exchange = InterlockedExchangePointer(&Fdo->FdoSPowerContext.Irp, Irp); + ASSERT(Exchange == NULL); + + IoQueueWorkItem(Fdo->FdoDPowerWorkItem, + _FdoS3ToS4PowerWorker, + DelayedWorkQueue, + &Fdo->FdoSPowerContext); +} + +__drv_functionClass(REQUEST_POWER_COMPLETE) +__drv_sameIRQL +VOID +FdoDispatchSetSystemPowerDown2( + 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); - FdoRequestSetDevicePower(Fdo, DeviceState); + if (!NT_SUCCESS(IoStatus->Status)) { + Error("fail1 - but continue IRP processing. (%08x)\n", IoStatus->Status); + } Info("%s: %s -> %s\n", __FdoGetName(Fdo), @@ -5005,60 +5262,110 @@ FdoSetSystemPowerDown( if (SystemState >= PowerSystemHibernate && __FdoGetSystemPowerState(Fdo) < PowerSystemHibernate) { - __FdoSetSystemPowerState(Fdo, PowerSystemSleeping3); - FdoS3ToS4(Fdo); + FdoS3ToS4PowerWorker(Fdo, Irp); + goto done; } - __FdoSetSystemPowerState(Fdo, SystemState); + FdoDispatchSetSystemPowerDown2Tail(Fdo, Irp); - status = FdoForwardIrpSynchronously(Fdo, Irp); - IoCompleteRequest(Irp, IO_NO_INCREMENT); + goto calldown; - return status; +calldown: + IoCopyCurrentIrpStackLocationToNext(Irp); /* Irp has been pended */ + IoCallDriver(Fdo->LowerDeviceObject, Irp); + return; + +done: + ; } -static NTSTATUS -FdoSetSystemPower( + +static VOID +FdoDispatchSetSystemPowerDown( IN PXENBUS_FDO Fdo, IN PIRP Irp ) { PIO_STACK_LOCATION StackLocation; SYSTEM_POWER_STATE SystemState; - POWER_ACTION PowerAction; + DEVICE_POWER_STATE DeviceState; NTSTATUS status; StackLocation = IoGetCurrentIrpStackLocation(Irp); + BUG_ON(StackLocation->DeviceObject != Fdo->Dx->DeviceObject); SystemState = StackLocation->Parameters.Power.State.SystemState; - PowerAction = StackLocation->Parameters.Power.ShutdownType; - - Trace("====> (%s:%s)\n", - SystemPowerStateName(SystemState), - PowerActionName(PowerAction)); - ASSERT3U(PowerAction, <, PowerActionShutdown); + ASSERT3U(SystemState, >, __FdoGetSystemPowerState(Fdo)); - if (SystemState == __FdoGetSystemPowerState(Fdo)) { - status = FdoForwardIrpSynchronously(Fdo, Irp); - IoCompleteRequest(Irp, IO_NO_INCREMENT); + DeviceState = Fdo->LowerDeviceCapabilities.DeviceState[SystemState]; + 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. */ goto done; } - status = (SystemState < __FdoGetSystemPowerState(Fdo)) ? - FdoSetSystemPowerUp(Fdo, Irp) : - FdoSetSystemPowerDown(Fdo, Irp); + status = FdoRequestSetDevicePower(Fdo, DeviceState, FdoDispatchSetSystemPowerDown2, Irp); + if (!NT_SUCCESS(status)) + goto fail1; + /* IRP already marked pending - nothing more to do if awaiting callback. */ + return; + +fail1: + /* In theory could change IRP status, but are not supposed to fail this IRP. */ + Error("fail1 - but continue IRP processing. (%08x)\n", status); done: - Trace("<==== (%s:%s)(%08x)\n", - SystemPowerStateName(SystemState), - PowerActionName(PowerAction), - status); - return status; + IoCopyCurrentIrpStackLocationToNext(Irp); /* Irp has been pended */ + IoCallDriver(Fdo->LowerDeviceObject, Irp); } static NTSTATUS -FdoQueryDevicePowerUp( +FdoDispatchSetSystemPower( + IN PXENBUS_FDO Fdo, + IN PIRP Irp + ) +{ + PIO_STACK_LOCATION StackLocation; + SYSTEM_POWER_STATE SystemState; + POWER_ACTION PowerAction; + + StackLocation = IoGetCurrentIrpStackLocation(Irp); + 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", + SystemPowerStateName(SystemState), + PowerActionName(PowerAction)); + + if (SystemState == __FdoGetSystemPowerState(Fdo)) { + IoCopyCurrentIrpStackLocationToNext(Irp); /* Pended, copy not skip */ + IoCallDriver(Fdo->LowerDeviceObject, Irp); + goto done; + } + + if (SystemState < __FdoGetSystemPowerState(Fdo)) { + FdoDispatchSetSystemPowerUp(Fdo, Irp); + } else { + FdoDispatchSetSystemPowerDown(Fdo, Irp); + } + +done: + Trace("<==== (%s:%s)\n", + SystemPowerStateName(SystemState), + PowerActionName(PowerAction)); + + return STATUS_PENDING; +} + + +static NTSTATUS +FdoDispatchQueryDevicePowerUp( IN PXENBUS_FDO Fdo, IN PIRP Irp ) @@ -5072,15 +5379,15 @@ FdoQueryDevicePowerUp( ASSERT3U(DeviceState, <, __FdoGetDevicePowerState(Fdo)); - status = FdoForwardIrpSynchronously(Fdo, Irp); - - IoCompleteRequest(Irp, IO_NO_INCREMENT); + /* N.B. Shutdown / hibernation failures caused by our device state could be vetoed here. */ + IoSkipCurrentIrpStackLocation(Irp); + status = IoCallDriver(Fdo->LowerDeviceObject, Irp); return status; } static NTSTATUS -FdoQueryDevicePowerDown( +FdoDispatchQueryDevicePowerDown( IN PXENBUS_FDO Fdo, IN PIRP Irp ) @@ -5094,14 +5401,15 @@ FdoQueryDevicePowerDown( ASSERT3U(DeviceState, >, __FdoGetDevicePowerState(Fdo)); - status = FdoForwardIrpSynchronously(Fdo, Irp); - IoCompleteRequest(Irp, IO_NO_INCREMENT); + /* N.B. Shutdown / hibernation failures caused by our device state could be vetoed here. */ + IoSkipCurrentIrpStackLocation(Irp); + status = IoCallDriver(Fdo->LowerDeviceObject, Irp); return status; } static NTSTATUS -FdoQueryDevicePower( +FdoDispatchQueryDevicePower( IN PXENBUS_FDO Fdo, IN PIRP Irp ) @@ -5119,18 +5427,16 @@ FdoQueryDevicePower( 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; } status = (DeviceState < __FdoGetDevicePowerState(Fdo)) ? - FdoQueryDevicePowerUp(Fdo, Irp) : - FdoQueryDevicePowerDown(Fdo, Irp); + FdoDispatchQueryDevicePowerUp(Fdo, Irp) : + FdoDispatchQueryDevicePowerDown(Fdo, Irp); done: Trace("<==== (%s:%s)(%08x)\n", @@ -5140,10 +5446,35 @@ done: return status; } + +static NTSTATUS +FdoRequestQueryDevicePower( + IN PXENBUS_FDO Fdo, + IN DEVICE_POWER_STATE DeviceState, + IN PREQUEST_POWER_COMPLETE CompletionFunction, + IN PVOID Context + ) +{ + POWER_STATE PowerState; + NTSTATUS status; + + Trace("%s\n", DevicePowerStateName(DeviceState)); + + PowerState.DeviceState = DeviceState; + + status = PoRequestPowerIrp(Fdo->LowerDeviceObject, + IRP_MN_QUERY_POWER, + PowerState, + CompletionFunction, + Context, + NULL); + return status; +} + __drv_functionClass(REQUEST_POWER_COMPLETE) __drv_sameIRQL VOID -FdoRequestQueryDevicePowerCompletion( +FdoCompleteQuerySystemPowerUp2( IN PDEVICE_OBJECT DeviceObject, IN UCHAR MinorFunction, IN POWER_STATE PowerState, @@ -5151,83 +5482,121 @@ 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 +FdoCompleteQuerySystemPowerUp( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PVOID Context ) { - POWER_STATE PowerState; - KEVENT Event; - NTSTATUS status; + PXENBUS_FDO Fdo = (PXENBUS_FDO) Context; + PIO_STACK_LOCATION StackLocation; + SYSTEM_POWER_STATE SystemState; + DEVICE_POWER_STATE DeviceState; + NTSTATUS status; - Trace("%s\n", DevicePowerStateName(DeviceState)); + UNREFERENCED_PARAMETER(DeviceObject); - ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL); + /* IRP marked as pending on dispatch path. */ + StackLocation = IoGetCurrentIrpStackLocation(Irp); + BUG_ON(StackLocation->DeviceObject != Fdo->Dx->DeviceObject); + SystemState = StackLocation->Parameters.Power.State.SystemState; + DeviceState = Fdo->LowerDeviceCapabilities.DeviceState[SystemState]; + status = FdoRequestQueryDevicePower(Fdo, DeviceState, FdoCompleteQuerySystemPowerUp2, Irp); + if (!NT_SUCCESS(status)) + goto fail1; - PowerState.DeviceState = DeviceState; - KeInitializeEvent(&Event, NotificationEvent, FALSE); + goto done; - status = PoRequestPowerIrp(Fdo->LowerDeviceObject, - IRP_MN_QUERY_POWER, - PowerState, - FdoRequestQueryDevicePowerCompletion, - &Event, - NULL); - ASSERT(NT_SUCCESS(status)); +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; - (VOID) KeWaitForSingleObject(&Event, - Executive, - KernelMode, - FALSE, - NULL); +done: + /* Will later complete the IRP (which is marked pending, in 2nd level comp routine.)*/ + return STATUS_MORE_PROCESSING_REQUIRED; } static NTSTATUS -FdoQuerySystemPowerUp( +FdoDispatchQuerySystemPowerUp( IN PXENBUS_FDO Fdo, IN PIRP Irp ) { - PIO_STACK_LOCATION StackLocation; SYSTEM_POWER_STATE SystemState; - DEVICE_POWER_STATE DeviceState; NTSTATUS status; StackLocation = IoGetCurrentIrpStackLocation(Irp); + BUG_ON(StackLocation->DeviceObject != Fdo->Dx->DeviceObject); SystemState = StackLocation->Parameters.Power.State.SystemState; ASSERT3U(SystemState, <, __FdoGetSystemPowerState(Fdo)); - status = FdoForwardIrpSynchronously(Fdo, Irp); - if (!NT_SUCCESS(status)) - goto done; + IoMarkIrpPending(Irp); /* Must mark IRP pending because we want to complete it *after* completion routine. */ + IoCopyCurrentIrpStackLocationToNext(Irp); + IoSetCompletionRoutine(Irp, + FdoCompleteQuerySystemPowerUp, + Fdo, + TRUE, + TRUE, + TRUE); + status = IoCallDriver(Fdo->LowerDeviceObject, Irp); + return STATUS_PENDING; +} - DeviceState = Fdo->LowerDeviceCapabilities.DeviceState[SystemState]; +VOID +FdoDispatchQuerySystemPowerDown2( + 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; + + UNREFERENCED_PARAMETER(DeviceObject); + UNREFERENCED_PARAMETER(MinorFunction); + UNREFERENCED_PARAMETER(PowerState); - FdoRequestQueryDevicePower(Fdo, DeviceState); + if (!NT_SUCCESS(IoStatus->Status)) + goto fail1; -done: + IoCopyCurrentIrpStackLocationToNext(Irp); /* Irp has been pended. */ + IoCallDriver(Fdo->LowerDeviceObject, Irp); + goto done; + +fail1: + Error("fail1 (%08x)\n", IoStatus->Status); + Irp->IoStatus.Status = IoStatus->Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); - return status; +done: + ; } static NTSTATUS -FdoQuerySystemPowerDown( +FdoDispatchQuerySystemPowerDown( IN PXENBUS_FDO Fdo, IN PIRP Irp ) @@ -5238,22 +5607,32 @@ FdoQuerySystemPowerDown( 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]; - FdoRequestQueryDevicePower(Fdo, DeviceState); + status = FdoRequestQueryDevicePower(Fdo, DeviceState, FdoDispatchQuerySystemPowerDown2, Irp); + if (!NT_SUCCESS(status)) + goto fail1; + + IoMarkIrpPending(Irp); + status = STATUS_PENDING; + goto done; - status = FdoForwardIrpSynchronously(Fdo, Irp); - IoCompleteRequest(Irp, IO_NO_INCREMENT); +fail1: + Error("fail1 (%08x)\n", status); + Irp->IoStatus.Status = status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); +done: return status; } static NTSTATUS -FdoQuerySystemPower( +FdoDispatchQuerySystemPower( IN PXENBUS_FDO Fdo, IN PIRP Irp ) @@ -5271,18 +5650,15 @@ 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; } status = (SystemState < __FdoGetSystemPowerState(Fdo)) ? - FdoQuerySystemPowerUp(Fdo, Irp) : - FdoQuerySystemPowerDown(Fdo, Irp); + FdoDispatchQuerySystemPowerUp(Fdo, Irp) : + FdoDispatchQuerySystemPowerDown(Fdo, Irp); done: Trace("<==== (%s:%s)(%08x)\n", @@ -5294,117 +5670,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; + NTSTATUS status; + PIO_STACK_LOCATION StackLocation = IoGetCurrentIrpStackLocation(Irp); switch (StackLocation->MinorFunction) { case IRP_MN_SET_POWER: - (VOID) FdoSetDevicePower(Fdo, Irp); + status = FdoDispatchSetDevicePower(Fdo, Irp); break; case IRP_MN_QUERY_POWER: - (VOID) FdoQueryDevicePower(Fdo, Irp); + status = FdoDispatchQueryDevicePower(Fdo, Irp); break; default: ASSERT(FALSE); + 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); - } + NTSTATUS status; + PIO_STACK_LOCATION StackLocation = IoGetCurrentIrpStackLocation(Irp); - 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; + switch (StackLocation->MinorFunction) { + case IRP_MN_SET_POWER: + status = FdoDispatchSetSystemPower(Fdo, Irp); + break; - case IRP_MN_QUERY_POWER: - (VOID) FdoQuerySystemPower(Fdo, Irp); - break; + case IRP_MN_QUERY_POWER: + status = FdoDispatchQuerySystemPower(Fdo, Irp); + break; - default: - ASSERT(FALSE); - break; - } + default: + ASSERT(FALSE); + IoSkipCurrentIrpStackLocation(Irp); + status = IoCallDriver(Fdo->LowerDeviceObject, Irp); + break; } - - return STATUS_SUCCESS; + return status; } static NTSTATUS @@ -5433,36 +5749,13 @@ FdoDispatchPower( 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: @@ -5475,6 +5768,7 @@ done: return status; } + static NTSTATUS FdoDispatchDefault( IN PXENBUS_FDO Fdo, @@ -5822,87 +6116,79 @@ FdoCreate( Fdo->LowerDeviceObject = IoAttachDeviceToDeviceStack(FunctionDeviceObject, PhysicalDeviceObject); - status = ThreadCreate(FdoSystemPower, Fdo, &Fdo->SystemPowerThread); - if (!NT_SUCCESS(status)) - goto fail3; - - status = ThreadCreate(FdoDevicePower, Fdo, &Fdo->DevicePowerThread); - if (!NT_SUCCESS(status)) - goto fail4; - status = FdoAcquireLowerBusInterface(Fdo); if (!NT_SUCCESS(status)) - goto fail5; + goto fail3; if (FdoGetBusData(Fdo, PCI_WHICHSPACE_CONFIG, &Header, 0, sizeof (PCI_COMMON_HEADER)) == 0) - goto fail6; + goto fail4; status = __FdoSetVendorName(Fdo, Header.VendorID, Header.DeviceID); if (!NT_SUCCESS(status)) - goto fail7; + goto fail5; __FdoSetName(Fdo); status = FdoSetActive(Fdo); if (!NT_SUCCESS(status)) - goto fail8; + goto fail6; if (!__FdoIsActive(Fdo)) goto done; status = __FdoAllocateBuffer(Fdo); if (!NT_SUCCESS(status)) - goto fail9; + goto fail7; status = DebugInitialize(Fdo, &Fdo->DebugContext); if (!NT_SUCCESS(status)) - goto fail10; + goto fail8; status = SuspendInitialize(Fdo, &Fdo->SuspendContext); if (!NT_SUCCESS(status)) - goto fail11; + goto fail9; status = SharedInfoInitialize(Fdo, &Fdo->SharedInfoContext); if (!NT_SUCCESS(status)) - goto fail12; + goto fail10; status = EvtchnInitialize(Fdo, &Fdo->EvtchnContext); if (!NT_SUCCESS(status)) - goto fail13; + goto fail11; status = RangeSetInitialize(Fdo, &Fdo->RangeSetContext); if (!NT_SUCCESS(status)) - goto fail14; + goto fail12; status = CacheInitialize(Fdo, &Fdo->CacheContext); if (!NT_SUCCESS(status)) - goto fail15; + goto fail13; status = GnttabInitialize(Fdo, &Fdo->GnttabContext); if (!NT_SUCCESS(status)) - goto fail16; + goto fail14; status = StoreInitialize(Fdo, &Fdo->StoreContext); if (!NT_SUCCESS(status)) - goto fail17; + goto fail15; status = ConsoleInitialize(Fdo, &Fdo->ConsoleContext); if (!NT_SUCCESS(status)) - goto fail18; + goto fail16; status = UnplugInitialize(Fdo, &Fdo->UnplugContext); if (!NT_SUCCESS(status)) - goto fail19; + goto fail17; status = FdoBalloonInitialize(Fdo); if (!NT_SUCCESS(status)) - goto fail20; + goto fail18; status = DebugGetInterface(__FdoGetDebugContext(Fdo), XENBUS_DEBUG_INTERFACE_VERSION_MAX, @@ -5952,6 +6238,20 @@ FdoCreate( sizeof (Fdo->BalloonInterface)); ASSERT(NT_SUCCESS(status)); + Fdo->FdoSPowerWorkItem = IoAllocateWorkItem(FunctionDeviceObject); + if (Fdo->FdoSPowerWorkItem == NULL) + goto fail19; + + Fdo->FdoSPowerContext.FdoOrPdo = Fdo; + Fdo->FdoSPowerContext.Irp = NULL; + + Fdo->FdoDPowerWorkItem = IoAllocateWorkItem(FunctionDeviceObject); + if (Fdo->FdoDPowerWorkItem == NULL) + goto fail20; + + Fdo->FdoDPowerContext.FdoOrPdo = Fdo; + Fdo->FdoDPowerContext.Irp = NULL; + done: InitializeMutex(&Fdo->Mutex); InitializeListHead(&Fdo->List); @@ -5975,105 +6275,122 @@ done: fail20: Error("fail20\n"); - - UnplugTeardown(Fdo->UnplugContext); - Fdo->UnplugContext = NULL; + IoFreeWorkItem(Fdo->FdoSPowerWorkItem); + Fdo->FdoSPowerWorkItem = NULL; + RtlZeroMemory(&Fdo->FdoSPowerContext, sizeof(Fdo->FdoSPowerContext)); fail19: Error("fail19\n"); + RtlZeroMemory(&Fdo->BalloonInterface, + sizeof (XENBUS_BALLOON_INTERFACE)); - ConsoleTeardown(Fdo->ConsoleContext); - Fdo->ConsoleContext = NULL; + RtlZeroMemory(&Fdo->ConsoleInterface, + sizeof (XENBUS_CONSOLE_INTERFACE)); + + RtlZeroMemory(&Fdo->StoreInterface, + sizeof (XENBUS_STORE_INTERFACE)); + + RtlZeroMemory(&Fdo->RangeSetInterface, + sizeof (XENBUS_RANGE_SET_INTERFACE)); + + RtlZeroMemory(&Fdo->EvtchnInterface, + sizeof (XENBUS_EVTCHN_INTERFACE)); + + RtlZeroMemory(&Fdo->SuspendInterface, + sizeof (XENBUS_SUSPEND_INTERFACE)); + + RtlZeroMemory(&Fdo->DebugInterface, + sizeof (XENBUS_DEBUG_INTERFACE)); + + FdoBalloonTeardown(Fdo); fail18: Error("fail18\n"); - StoreTeardown(Fdo->StoreContext); - Fdo->StoreContext = NULL; + UnplugTeardown(Fdo->UnplugContext); + Fdo->UnplugContext = NULL; fail17: Error("fail17\n"); - GnttabTeardown(Fdo->GnttabContext); - Fdo->GnttabContext = NULL; + ConsoleTeardown(Fdo->ConsoleContext); + Fdo->ConsoleContext = NULL; fail16: Error("fail16\n"); - CacheTeardown(Fdo->CacheContext); - Fdo->CacheContext = NULL; + StoreTeardown(Fdo->StoreContext); + Fdo->StoreContext = NULL; fail15: Error("fail15\n"); - RangeSetTeardown(Fdo->RangeSetContext); - Fdo->RangeSetContext = NULL; + GnttabTeardown(Fdo->GnttabContext); + Fdo->GnttabContext = NULL; fail14: Error("fail14\n"); - EvtchnTeardown(Fdo->EvtchnContext); - Fdo->EvtchnContext = NULL; + CacheTeardown(Fdo->CacheContext); + Fdo->CacheContext = NULL; fail13: Error("fail13\n"); - SharedInfoTeardown(Fdo->SharedInfoContext); - Fdo->SharedInfoContext = NULL; + RangeSetTeardown(Fdo->RangeSetContext); + Fdo->RangeSetContext = NULL; fail12: Error("fail12\n"); - SuspendTeardown(Fdo->SuspendContext); - Fdo->SuspendContext = NULL; + EvtchnTeardown(Fdo->EvtchnContext); + Fdo->EvtchnContext = NULL; fail11: Error("fail11\n"); - DebugTeardown(Fdo->DebugContext); - Fdo->DebugContext = NULL; + SharedInfoTeardown(Fdo->SharedInfoContext); + Fdo->SharedInfoContext = NULL; fail10: Error("fail10\n"); - __FdoFreeBuffer(Fdo); + SuspendTeardown(Fdo->SuspendContext); + Fdo->SuspendContext = NULL; fail9: Error("fail9\n"); - // - // We don't want to call DriverClearActive() so just - // clear the FDO flag. - // - Fdo->Active = FALSE; + DebugTeardown(Fdo->DebugContext); + Fdo->DebugContext = NULL; fail8: Error("fail8\n"); - RtlZeroMemory(Fdo->VendorName, MAXNAMELEN); + __FdoFreeBuffer(Fdo); fail7: Error("fail7\n"); + // + // We don't want to call DriverClearActive() so just + // clear the FDO flag. + // + Fdo->Active = FALSE; + fail6: Error("fail6\n"); - FdoReleaseLowerBusInterface(Fdo); + RtlZeroMemory(Fdo->VendorName, MAXNAMELEN); fail5: Error("fail5\n"); - ThreadAlert(Fdo->DevicePowerThread); - ThreadJoin(Fdo->DevicePowerThread); - Fdo->DevicePowerThread = NULL; - fail4: Error("fail4\n"); - ThreadAlert(Fdo->SystemPowerThread); - ThreadJoin(Fdo->SystemPowerThread); - Fdo->SystemPowerThread = NULL; - + FdoReleaseLowerBusInterface(Fdo); + fail3: Error("fail3\n"); @@ -6125,6 +6442,16 @@ FdoDestroy( RtlZeroMemory(&Fdo->List, sizeof (LIST_ENTRY)); RtlZeroMemory(&Fdo->Mutex, sizeof (MUTEX)); + IoFreeWorkItem(Fdo->FdoSPowerWorkItem); + ASSERT(Fdo->FdoSPowerContext.Irp == NULL); + IoFreeWorkItem(Fdo->FdoDPowerWorkItem); + ASSERT(Fdo->FdoDPowerContext.Irp == NULL); + + RtlZeroMemory(&Fdo->FdoSPowerWorkItem, sizeof(Fdo->FdoSPowerWorkItem)); + RtlZeroMemory(&Fdo->FdoDPowerWorkItem, sizeof(Fdo->FdoDPowerWorkItem)); + RtlZeroMemory(&Fdo->FdoSPowerContext, sizeof(Fdo->FdoSPowerContext)); + RtlZeroMemory(&Fdo->FdoDPowerContext, sizeof(Fdo->FdoDPowerContext)); + if (__FdoIsActive(Fdo)) { RtlZeroMemory(&Fdo->BalloonInterface, sizeof (XENBUS_BALLOON_INTERFACE)); @@ -6188,14 +6515,6 @@ FdoDestroy( FdoReleaseLowerBusInterface(Fdo); - ThreadAlert(Fdo->DevicePowerThread); - ThreadJoin(Fdo->DevicePowerThread); - Fdo->DevicePowerThread = NULL; - - ThreadAlert(Fdo->SystemPowerThread); - ThreadJoin(Fdo->SystemPowerThread); - Fdo->SystemPowerThread = NULL; - IoDetachDevice(Fdo->LowerDeviceObject); RtlZeroMemory(&Fdo->LowerDeviceCapabilities, sizeof (DEVICE_CAPABILITIES)); diff --git a/src/xenbus/pdo.c b/src/xenbus/pdo.c index efd29dc..1ae2f07 100644 --- a/src/xenbus/pdo.c +++ b/src/xenbus/pdo.c @@ -49,6 +49,7 @@ #include "util.h" #include "version.h" #include "revision.h" +#include "types.h" #define PDO_TAG 'ODP' @@ -57,11 +58,6 @@ struct _XENBUS_PDO { PXENBUS_DX Dx; - PXENBUS_THREAD SystemPowerThread; - PIRP SystemPowerIrp; - PXENBUS_THREAD DevicePowerThread; - PIRP DevicePowerIrp; - PXENBUS_FDO Fdo; BOOLEAN Missing; const CHAR *Reason; @@ -73,6 +69,11 @@ struct _XENBUS_PDO { XENBUS_SUSPEND_INTERFACE SuspendInterface; PXENBUS_SUSPEND_CALLBACK SuspendCallbackLate; + + PIO_WORKITEM PdoSPowerWorkItem; + XENBUS_POWER_WORKITEM_CONTEXT PdoSPowerContext; + PIO_WORKITEM PdoDPowerWorkItem; + XENBUS_POWER_WORKITEM_CONTEXT PdoDPowerContext; }; static FORCEINLINE PVOID @@ -1700,26 +1701,29 @@ PdoDispatchPnp( return status; } -static NTSTATUS -PdoSetDevicePower( - IN PXENBUS_PDO Pdo, - IN PIRP Irp - ) +VOID _PdoDStatePowerWorker( + IN PDEVICE_OBJECT DeviceObject, + IN PVOID Context + ) { + PXENBUS_POWER_WORKITEM_CONTEXT PowerContext = (PXENBUS_POWER_WORKITEM_CONTEXT)Context; + PXENBUS_PDO Pdo = (PXENBUS_PDO) PowerContext->FdoOrPdo; + PIRP Irp; + NTSTATUS status; PIO_STACK_LOCATION StackLocation; DEVICE_POWER_STATE DeviceState; POWER_ACTION PowerAction; + UNREFERENCED_PARAMETER(DeviceObject); + + Irp = InterlockedExchangePointer(&PowerContext->Irp, 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), @@ -1727,7 +1731,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), @@ -1738,76 +1742,81 @@ 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 - ) +VOID PdoDStatePowerWorker( + 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); - } - - if (ThreadIsAlerted(Self)) - break; - - Irp = Pdo->DevicePowerIrp; + PVOID Exchange; - if (Irp == NULL) - continue; + ASSERT(Pdo->PdoDPowerContext.FdoOrPdo == Pdo); + Exchange = InterlockedExchangePointer(&Pdo->PdoDPowerContext.Irp, Irp); + ASSERT(Exchange == NULL); - Pdo->DevicePowerIrp = NULL; - KeMemoryBarrier(); - - (VOID) PdoSetDevicePower(Pdo, Irp); - } - - return STATUS_SUCCESS; + IoQueueWorkItem(Pdo->PdoDPowerWorkItem, + _PdoDStatePowerWorker, + DelayedWorkQueue, + &Pdo->PdoDPowerContext); } static NTSTATUS -PdoSetSystemPower( +PdoDispatchSetDevicePower( IN PXENBUS_PDO Pdo, IN PIRP Irp ) { + PIO_STACK_LOCATION StackLocation = IoGetCurrentIrpStackLocation(Irp); + DEVICE_POWER_STATE DeviceState = StackLocation->Parameters.Power.State.DeviceState; + POWER_ACTION PowerAction = StackLocation->Parameters.Power.ShutdownType; + + Trace("====> (%s:%s)\n", + DevicePowerStateName(DeviceState), + PowerActionName(PowerAction)); + + IoMarkIrpPending(Irp); + PdoDStatePowerWorker(Pdo, Irp); + return STATUS_PENDING; +} + + +VOID _PdoSStatePowerWorker( + IN PDEVICE_OBJECT DeviceObject, + IN PVOID Context + ) +{ + PXENBUS_POWER_WORKITEM_CONTEXT PowerContext = (PXENBUS_POWER_WORKITEM_CONTEXT)Context; + PXENBUS_PDO Pdo = (PXENBUS_PDO) PowerContext->FdoOrPdo; + PIRP Irp; PIO_STACK_LOCATION StackLocation; SYSTEM_POWER_STATE SystemState; POWER_ACTION PowerAction; + UNREFERENCED_PARAMETER(DeviceObject); + + Irp = InterlockedExchangePointer(&PowerContext->Irp, 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) { @@ -1841,52 +1850,50 @@ PdoSetSystemPower( Trace("<==== (%s:%s)\n", SystemPowerStateName(SystemState), PowerActionName(PowerAction)); - - return STATUS_SUCCESS; } -static NTSTATUS -PdoSystemPower( - IN PXENBUS_THREAD Self, - IN PVOID Context - ) +VOID PdoSStatePowerWorker( + IN PXENBUS_PDO Pdo, + IN PIRP Irp +) { - PXENBUS_PDO Pdo = Context; - PKEVENT Event; - - Event = ThreadGetEvent(Self); + PVOID Exchange; - for (;;) { - PIRP Irp; + ASSERT(Pdo->PdoSPowerContext.FdoOrPdo == Pdo); + Exchange = InterlockedExchangePointer(&Pdo->PdoSPowerContext.Irp, Irp); + ASSERT(Exchange == NULL); - if (Pdo->SystemPowerIrp == NULL) { - (VOID) KeWaitForSingleObject(Event, - Executive, - KernelMode, - FALSE, - NULL); - KeClearEvent(Event); - } - - if (ThreadIsAlerted(Self)) - break; - - Irp = Pdo->SystemPowerIrp; + IoQueueWorkItem(Pdo->PdoSPowerWorkItem, + _PdoSStatePowerWorker, + DelayedWorkQueue, + &Pdo->PdoSPowerContext); +} - if (Irp == NULL) - continue; +static NTSTATUS +PdoDispatchSetSystemPower( + IN PXENBUS_PDO Pdo, + IN PIRP Irp + ) +{ + PIO_STACK_LOCATION StackLocation; + SYSTEM_POWER_STATE SystemState; + POWER_ACTION PowerAction; - Pdo->SystemPowerIrp = NULL; - KeMemoryBarrier(); + StackLocation = IoGetCurrentIrpStackLocation(Irp); + SystemState = StackLocation->Parameters.Power.State.SystemState; + PowerAction = StackLocation->Parameters.Power.ShutdownType; - (VOID) PdoSetSystemPower(Pdo, Irp); - } + Trace("====> (%s:%s)\n", + SystemPowerStateName(SystemState), + PowerActionName(PowerAction)); - return STATUS_SUCCESS; + IoMarkIrpPending(Irp); + PdoSStatePowerWorker(Pdo, Irp); + return STATUS_PENDING; } static NTSTATUS -PdoSetPower( +PdoDispatchSetPower( IN PXENBUS_PDO Pdo, IN PIRP Irp ) @@ -1900,38 +1907,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 = PdoDispatchSetDevicePower(Pdo, Irp); break; case SystemPowerState: - IoMarkIrpPending(Irp); - - ASSERT3P(Pdo->SystemPowerIrp, ==, NULL); - Pdo->SystemPowerIrp = Irp; - KeMemoryBarrier(); - - ThreadWake(Pdo->SystemPowerThread); - - status = STATUS_PENDING; + status = PdoDispatchSetSystemPower(Pdo, Irp); break; default: @@ -1940,26 +1922,20 @@ PdoSetPower( break; } -done: return status; } static NTSTATUS -PdoQueryPower( +PdoDispatchQueryPower( IN PXENBUS_PDO Pdo, IN PIRP Irp ) { - NTSTATUS status; - UNREFERENCED_PARAMETER(Pdo); - status = STATUS_SUCCESS; - - Irp->IoStatus.Status = status; + Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp, IO_NO_INCREMENT); - - return status; + return STATUS_SUCCESS; } static NTSTATUS @@ -1977,14 +1953,15 @@ PdoDispatchPower( switch (StackLocation->MinorFunction) { case IRP_MN_SET_POWER: - status = PdoSetPower(Pdo, Irp); + status = PdoDispatchSetPower(Pdo, Irp); break; case IRP_MN_QUERY_POWER: - status = PdoQueryPower(Pdo, Irp); + status = PdoDispatchQueryPower(Pdo, Irp); break; default: + /* TODO - Always complete with status success?? */ status = Irp->IoStatus.Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); break; @@ -2098,21 +2075,13 @@ PdoCreate( Pdo->Dx = Dx; Pdo->Fdo = Fdo; - status = ThreadCreate(PdoSystemPower, Pdo, &Pdo->SystemPowerThread); - if (!NT_SUCCESS(status)) - goto fail3; - - status = ThreadCreate(PdoDevicePower, Pdo, &Pdo->DevicePowerThread); - if (!NT_SUCCESS(status)) - goto fail4; - __PdoSetName(Pdo, Name); __PdoSetRemovable(Pdo); __PdoSetEjectable(Pdo); status = BusInitialize(Pdo, &Pdo->BusInterface); if (!NT_SUCCESS(status)) - goto fail5; + goto fail3; status = SuspendGetInterface(FdoGetSuspendContext(Fdo), XENBUS_SUSPEND_INTERFACE_VERSION_MAX, @@ -2127,6 +2096,20 @@ PdoCreate( PdoDumpRevisions(Pdo); + Pdo->PdoSPowerWorkItem = IoAllocateWorkItem(PhysicalDeviceObject); + if (Pdo->PdoSPowerWorkItem == NULL) + goto fail4; + + Pdo->PdoSPowerContext.FdoOrPdo = Pdo; + Pdo->PdoSPowerContext.Irp = NULL; + + Pdo->PdoDPowerWorkItem = IoAllocateWorkItem(PhysicalDeviceObject); + if (Pdo->PdoDPowerWorkItem == NULL) + goto fail5; + + Pdo->PdoDPowerContext.FdoOrPdo = Pdo; + Pdo->PdoDPowerContext.Irp = NULL; + Dx->Pdo = Pdo; PhysicalDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; @@ -2137,23 +2120,21 @@ PdoCreate( fail5: Error("fail5\n"); - Pdo->Ejectable = FALSE; - Pdo->Removable = FALSE; - - ThreadAlert(Pdo->DevicePowerThread); - ThreadJoin(Pdo->DevicePowerThread); - Pdo->DevicePowerThread = NULL; + IoFreeWorkItem(Pdo->PdoSPowerWorkItem); + Pdo->PdoSPowerWorkItem = NULL; + RtlZeroMemory(&Pdo->PdoSPowerContext, sizeof(Pdo->PdoSPowerContext)); fail4: Error("fail4\n"); - ThreadAlert(Pdo->SystemPowerThread); - ThreadJoin(Pdo->SystemPowerThread); - Pdo->SystemPowerThread = NULL; + RtlZeroMemory(&Pdo->SuspendInterface, + sizeof (XENBUS_SUSPEND_INTERFACE)); fail3: Error("fail3\n"); + Pdo->Ejectable = FALSE; + Pdo->Removable = FALSE; Pdo->Fdo = NULL; Pdo->Dx = NULL; @@ -2187,6 +2168,16 @@ PdoDestroy( FdoRemovePhysicalDeviceObject(Fdo, Pdo); + IoFreeWorkItem(Pdo->PdoSPowerWorkItem); + ASSERT(Pdo->PdoSPowerContext.Irp == NULL); + IoFreeWorkItem(Pdo->PdoDPowerWorkItem); + ASSERT(Pdo->PdoDPowerContext.Irp == NULL); + + RtlZeroMemory(&Pdo->PdoSPowerWorkItem, sizeof(Pdo->PdoSPowerWorkItem)); + RtlZeroMemory(&Pdo->PdoDPowerWorkItem, sizeof(Pdo->PdoDPowerWorkItem)); + RtlZeroMemory(&Pdo->PdoSPowerContext, sizeof(Pdo->PdoSPowerContext)); + RtlZeroMemory(&Pdo->PdoDPowerContext, sizeof(Pdo->PdoDPowerContext)); + Info("%p (%s) (%s)\n", PhysicalDeviceObject, __PdoGetName(Pdo), @@ -2202,15 +2193,6 @@ 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; - Pdo->Fdo = NULL; Pdo->Dx = NULL; diff --git a/src/xenbus/store.c b/src/xenbus/store.c index 5ffea1f..cf31e3b 100644 --- a/src/xenbus/store.c +++ b/src/xenbus/store.c @@ -40,9 +40,13 @@ #include "thread.h" #include "fdo.h" #include "dbg_print.h" -#include "assert.h" #include "util.h" +//Temp workaround for CA-371783 testing checked builds. +#undef ASSERT +#define ASSERT(x) ((void)0) + + extern ULONG NTAPI RtlRandomEx ( diff --git a/src/xenbus/types.h b/src/xenbus/types.h index 0f08627..8f84860 100644 --- a/src/xenbus/types.h +++ b/src/xenbus/types.h @@ -50,4 +50,9 @@ typedef enum _DEVICE_PNP_STATE { Deleted } DEVICE_PNP_STATE, *PDEVICE_PNP_STATE; +typedef struct _XENBUS_POWER_WORKITEM_CONTEXT { + PVOID FdoOrPdo; + PIRP Irp; +} XENBUS_POWER_WORKITEM_CONTEXT, *PXENBUS_POWER_WORKITEM_CONTEXT; + #endif // _XENBUS_TYPES_H diff --git a/src/xenfilt/fdo.c b/src/xenfilt/fdo.c index 63fa7b3..1e4affa 100644 --- a/src/xenfilt/fdo.c +++ b/src/xenfilt/fdo.c @@ -59,11 +59,6 @@ struct _XENFILT_FDO { PDEVICE_OBJECT PhysicalDeviceObject; CHAR Name[MAXNAMELEN]; - PXENFILT_THREAD SystemPowerThread; - PIRP SystemPowerIrp; - PXENFILT_THREAD DevicePowerThread; - PIRP DevicePowerIrp; - MUTEX Mutex; LIST_ENTRY List; ULONG References; @@ -1077,81 +1072,82 @@ fail1: return status; } + +__drv_functionClass(IO_COMPLETION_ROUTINE) +__drv_sameIRQL static NTSTATUS -FdoSetDevicePowerUp( - IN PXENFILT_FDO Fdo, - IN PIRP Irp +FdoCompleteSetDevicePowerUp( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PVOID Context ) { + PXENFILT_FDO Fdo = (PXENFILT_FDO) Context; PIO_STACK_LOCATION StackLocation; - DEVICE_POWER_STATE DeviceState; POWER_STATE PowerState; - NTSTATUS status; - StackLocation = IoGetCurrentIrpStackLocation(Irp); - DeviceState = StackLocation->Parameters.Power.State.DeviceState; - - ASSERT3U(DeviceState, <, __FdoGetDevicePowerState(Fdo)); + UNREFERENCED_PARAMETER(DeviceObject); - status = FdoForwardIrpSynchronously(Fdo, Irp); - if (!NT_SUCCESS(status)) - goto done; + StackLocation = IoGetCurrentIrpStackLocation(Irp); + PowerState = StackLocation->Parameters.Power.State; - Trace("%s: %s -> %s\n", - __FdoGetName(Fdo), - DevicePowerStateName(__FdoGetDevicePowerState(Fdo)), - DevicePowerStateName(DeviceState)); + if (Irp->PendingReturned) { + IoMarkIrpPending(Irp); + } - PowerState.DeviceState = 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 +FdoDispatchSetDevicePowerUp( + IN PXENFILT_FDO Fdo, + IN PIRP Irp + ) +{ + PIO_STACK_LOCATION StackLocation; - return status; + StackLocation = IoGetCurrentIrpStackLocation(Irp); + + IoCopyCurrentIrpStackLocationToNext(Irp); + IoSetCompletionRoutine(Irp, + FdoCompleteSetDevicePowerUp, + Fdo, + TRUE, + TRUE, + TRUE); + return IoCallDriver(Fdo->LowerDeviceObject, Irp); } -static NTSTATUS -FdoSetDevicePowerDown( - IN PXENFILT_FDO Fdo, +static FORCEINLINE NTSTATUS +FdoDispatchSetDevicePowerDown( + IN PXENFILT_FDO Fdo, IN PIRP Irp ) { PIO_STACK_LOCATION StackLocation; - DEVICE_POWER_STATE DeviceState; POWER_STATE PowerState; - NTSTATUS status; StackLocation = IoGetCurrentIrpStackLocation(Irp); - DeviceState = StackLocation->Parameters.Power.State.DeviceState; + PowerState = StackLocation->Parameters.Power.State; - ASSERT3U(DeviceState, >, __FdoGetDevicePowerState(Fdo)); - - Trace("%s: %s -> %s\n", - __FdoGetName(Fdo), - DevicePowerStateName(__FdoGetDevicePowerState(Fdo)), - DevicePowerStateName(DeviceState)); - - PowerState.DeviceState = DeviceState; + __FdoSetDevicePowerState(Fdo, PowerState.DeviceState); PoSetPowerState(Fdo->Dx->DeviceObject, DevicePowerState, PowerState); - __FdoSetDevicePowerState(Fdo, DeviceState); - - status = FdoForwardIrpSynchronously(Fdo, Irp); - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - return status; + IoSkipCurrentIrpStackLocation(Irp); + return IoCallDriver(Fdo->LowerDeviceObject, Irp); } -static NTSTATUS -FdoSetDevicePower( - IN PXENFILT_FDO Fdo, +/* IRQL argnostic code, just mark power states.*/ +static FORCEINLINE NTSTATUS +FdoDispatchSetDevicePower( + IN PXENFILT_FDO Fdo, IN PIRP Irp ) { @@ -1164,419 +1160,220 @@ FdoSetDevicePower( DeviceState = StackLocation->Parameters.Power.State.DeviceState; PowerAction = StackLocation->Parameters.Power.ShutdownType; - Trace("%s: ====> (%s:%s)\n", - __FdoGetName(Fdo), - DevicePowerStateName(DeviceState), + /* See if we can get away without pending the IRP in a filter + driver. */ + + Trace("====> (%s:%s)\n", + DevicePowerStateName(DeviceState), PowerActionName(PowerAction)); - if (DeviceState == __FdoGetDevicePowerState(Fdo)) { - status = FdoForwardIrpSynchronously(Fdo, Irp); - IoCompleteRequest(Irp, IO_NO_INCREMENT); + if (DeviceState == __FdoGetDevicePowerState(Fdo)) { + IoSkipCurrentIrpStackLocation(Irp); + status = IoCallDriver(Fdo->LowerDeviceObject, Irp); goto done; } - status = (DeviceState < __FdoGetDevicePowerState(Fdo)) ? - FdoSetDevicePowerUp(Fdo, Irp) : - FdoSetDevicePowerDown(Fdo, Irp); + if (DeviceState < __FdoGetDevicePowerState(Fdo)) { + status = FdoDispatchSetDevicePowerUp(Fdo, Irp); + } else { + status = FdoDispatchSetDevicePowerDown(Fdo, Irp); + } done: - Trace("%s: <==== (%s:%s)(%08x)\n", - __FdoGetName(Fdo), - DevicePowerStateName(DeviceState), - PowerActionName(PowerAction), - status); + Trace("<==== (%s:%s)\n", + DevicePowerStateName(DeviceState), + PowerActionName(PowerAction)); + return status; } +__drv_functionClass(IO_COMPLETION_ROUTINE) +__drv_sameIRQL static NTSTATUS -FdoSetSystemPowerUp( - IN PXENFILT_FDO Fdo, - IN PIRP Irp +FdoCompleteSetSystemPowerUp( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PVOID Context ) { + PXENFILT_FDO Fdo = (PXENFILT_FDO) Context; PIO_STACK_LOCATION StackLocation; SYSTEM_POWER_STATE SystemState; - NTSTATUS status; + + UNREFERENCED_PARAMETER(DeviceObject); StackLocation = IoGetCurrentIrpStackLocation(Irp); SystemState = StackLocation->Parameters.Power.State.SystemState; - ASSERT3U(SystemState, <, __FdoGetSystemPowerState(Fdo)); - - status = FdoForwardIrpSynchronously(Fdo, Irp); - if (!NT_SUCCESS(status)) - goto done; - - Trace("%s: %s -> %s\n", - __FdoGetName(Fdo), - SystemPowerStateName(__FdoGetSystemPowerState(Fdo)), - SystemPowerStateName(SystemState)); + if (Irp->PendingReturned) { + IoMarkIrpPending(Irp); + } __FdoSetSystemPowerState(Fdo, SystemState); -done: - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - return status; + return STATUS_CONTINUE_COMPLETION; } -static NTSTATUS -FdoSetSystemPowerDown( +static FORCEINLINE NTSTATUS +FdoDispatchSetSystemPowerUp( IN PXENFILT_FDO Fdo, IN PIRP Irp ) { PIO_STACK_LOCATION StackLocation; - SYSTEM_POWER_STATE SystemState; - NTSTATUS status; StackLocation = IoGetCurrentIrpStackLocation(Irp); - SystemState = StackLocation->Parameters.Power.State.SystemState; - - ASSERT3U(SystemState, >, __FdoGetSystemPowerState(Fdo)); - - Trace("%s: %s -> %s\n", - __FdoGetName(Fdo), - SystemPowerStateName(__FdoGetSystemPowerState(Fdo)), - SystemPowerStateName(SystemState)); - - __FdoSetSystemPowerState(Fdo, SystemState); - - status = FdoForwardIrpSynchronously(Fdo, Irp); - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return status; + IoCopyCurrentIrpStackLocationToNext(Irp); + IoSetCompletionRoutine(Irp, + FdoCompleteSetSystemPowerUp, + Fdo, + TRUE, + TRUE, + TRUE); + return IoCallDriver(Fdo->LowerDeviceObject, Irp); } -static NTSTATUS -FdoSetSystemPower( - IN PXENFILT_FDO Fdo, +static FORCEINLINE NTSTATUS +FdoDispatchSetSystemPowerDown( + IN PXENFILT_FDO Fdo, IN PIRP Irp ) { PIO_STACK_LOCATION StackLocation; SYSTEM_POWER_STATE SystemState; - POWER_ACTION PowerAction; - NTSTATUS status; StackLocation = IoGetCurrentIrpStackLocation(Irp); SystemState = StackLocation->Parameters.Power.State.SystemState; - PowerAction = StackLocation->Parameters.Power.ShutdownType; - - Trace("%s: ====> (%s:%s)\n", - __FdoGetName(Fdo), - SystemPowerStateName(SystemState), - PowerActionName(PowerAction)); - - if (SystemState == __FdoGetSystemPowerState(Fdo)) { - status = FdoForwardIrpSynchronously(Fdo, Irp); - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - goto done; - } - status = (SystemState < __FdoGetSystemPowerState(Fdo)) ? - FdoSetSystemPowerUp(Fdo, Irp) : - FdoSetSystemPowerDown(Fdo, Irp); - -done: - Trace("%s: <==== (%s:%s)(%08x)\n", - __FdoGetName(Fdo), - SystemPowerStateName(SystemState), - PowerActionName(PowerAction), - status); - return status; -} - -static NTSTATUS -FdoQueryDevicePowerUp( - IN PXENFILT_FDO Fdo, - IN PIRP Irp - ) -{ - PIO_STACK_LOCATION StackLocation; - DEVICE_POWER_STATE DeviceState; - NTSTATUS status; - - StackLocation = IoGetCurrentIrpStackLocation(Irp); - DeviceState = StackLocation->Parameters.Power.State.DeviceState; - - ASSERT3U(DeviceState, <, __FdoGetDevicePowerState(Fdo)); - - status = FdoForwardIrpSynchronously(Fdo, Irp); - - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - return status; -} - -static NTSTATUS -FdoQueryDevicePowerDown( - IN PXENFILT_FDO Fdo, - IN PIRP Irp - ) -{ - PIO_STACK_LOCATION StackLocation; - DEVICE_POWER_STATE DeviceState; - NTSTATUS status; - - StackLocation = IoGetCurrentIrpStackLocation(Irp); - DeviceState = StackLocation->Parameters.Power.State.DeviceState; - - ASSERT3U(DeviceState, >, __FdoGetDevicePowerState(Fdo)); - - status = FdoForwardIrpSynchronously(Fdo, Irp); - IoCompleteRequest(Irp, IO_NO_INCREMENT); + __FdoSetSystemPowerState(Fdo, SystemState); - return status; + IoSkipCurrentIrpStackLocation(Irp); + return IoCallDriver(Fdo->LowerDeviceObject, Irp); } -static NTSTATUS -FdoQueryDevicePower( - IN PXENFILT_FDO Fdo, +/* IRQL argnostic code, just mark power states.*/ +static FORCEINLINE NTSTATUS +FdoDispatchSetSystemPower( + IN PXENFILT_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; - Trace("%s: ====> (%s:%s)\n", - __FdoGetName(Fdo), - DevicePowerStateName(DeviceState), - PowerActionName(PowerAction)); + /* See if we can get away without pending the IRP in a filter + driver. */ - if (DeviceState == __FdoGetDevicePowerState(Fdo)) { - status = FdoForwardIrpSynchronously(Fdo, Irp); - IoCompleteRequest(Irp, IO_NO_INCREMENT); + Trace("====> (%s:%s)\n", + SystemPowerStateName(SystemState), + PowerActionName(PowerAction)); + if (SystemState == __FdoGetSystemPowerState(Fdo)) { + IoSkipCurrentIrpStackLocation(Irp); + status = IoCallDriver(Fdo->LowerDeviceObject, Irp); goto done; } - status = (DeviceState < __FdoGetDevicePowerState(Fdo)) ? - FdoQueryDevicePowerUp(Fdo, Irp) : - FdoQueryDevicePowerDown(Fdo, Irp); + if (SystemState < __FdoGetSystemPowerState(Fdo)) { + status = FdoDispatchSetSystemPowerUp(Fdo, Irp); + } else { + status = FdoDispatchSetSystemPowerDown(Fdo, Irp); + } done: - Trace("%s: <==== (%s:%s)(%08x)\n", - __FdoGetName(Fdo), - DevicePowerStateName(DeviceState), - PowerActionName(PowerAction), - status); + Trace("<==== (%s:%s)\n", + SystemPowerStateName(SystemState), + PowerActionName(PowerAction)); + return status; } -static NTSTATUS -FdoQuerySystemPowerUp( +static FORCEINLINE NTSTATUS +FdoDispatchQueryPower( IN PXENFILT_FDO Fdo, IN PIRP Irp ) { PIO_STACK_LOCATION StackLocation; SYSTEM_POWER_STATE SystemState; - NTSTATUS status; StackLocation = IoGetCurrentIrpStackLocation(Irp); SystemState = StackLocation->Parameters.Power.State.SystemState; - ASSERT3U(SystemState, <, __FdoGetSystemPowerState(Fdo)); - - status = FdoForwardIrpSynchronously(Fdo, Irp); - - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - return status; + /* Queries we will just pass thru, regardless of what they are. + Don't need to pend or set any completion routines. */ + IoSkipCurrentIrpStackLocation(Irp); + return IoCallDriver(Fdo->LowerDeviceObject, Irp); } +/* Dispatch - call down, and/or set completion, IRP not pended */ static NTSTATUS -FdoQuerySystemPowerDown( - IN PXENFILT_FDO Fdo, +FdoDispatchDevicePower( + IN PXENFILT_FDO Fdo, IN PIRP Irp ) { - PIO_STACK_LOCATION StackLocation; - SYSTEM_POWER_STATE SystemState; - NTSTATUS status; + NTSTATUS status; + PIO_STACK_LOCATION StackLocation = IoGetCurrentIrpStackLocation(Irp); - StackLocation = IoGetCurrentIrpStackLocation(Irp); - SystemState = StackLocation->Parameters.Power.State.SystemState; - - ASSERT3U(SystemState, >, __FdoGetSystemPowerState(Fdo)); + switch (StackLocation->MinorFunction) { + case IRP_MN_SET_POWER: + status = FdoDispatchSetDevicePower(Fdo, Irp); + break; - status = FdoForwardIrpSynchronously(Fdo, Irp); - IoCompleteRequest(Irp, IO_NO_INCREMENT); + case IRP_MN_QUERY_POWER: + status = FdoDispatchQueryPower(Fdo, Irp); + break; + default: + ASSERT(FALSE); + IoSkipCurrentIrpStackLocation(Irp); + status = IoCallDriver(Fdo->LowerDeviceObject, Irp); + break; + } return status; } +/* Dispatch - call down, and/or set completion, IRP not pended */ static NTSTATUS -FdoQuerySystemPower( - IN PXENFILT_FDO Fdo, +FdoDispatchSystemPower( + IN PXENFILT_FDO Fdo, IN PIRP Irp ) { - PIO_STACK_LOCATION StackLocation; - SYSTEM_POWER_STATE SystemState; - POWER_ACTION PowerAction; - NTSTATUS status; - - StackLocation = IoGetCurrentIrpStackLocation(Irp); - SystemState = StackLocation->Parameters.Power.State.SystemState; - PowerAction = StackLocation->Parameters.Power.ShutdownType; + NTSTATUS status; + PIO_STACK_LOCATION StackLocation = IoGetCurrentIrpStackLocation(Irp); - Trace("%s: ====> (%s:%s)\n", - __FdoGetName(Fdo), - SystemPowerStateName(SystemState), - PowerActionName(PowerAction)); + switch (StackLocation->MinorFunction) { + case IRP_MN_SET_POWER: + status = FdoDispatchSetSystemPower(Fdo, Irp); + break; - if (SystemState == __FdoGetSystemPowerState(Fdo)) { - status = FdoForwardIrpSynchronously(Fdo, Irp); - IoCompleteRequest(Irp, IO_NO_INCREMENT); + case IRP_MN_QUERY_POWER: + status = FdoDispatchQueryPower(Fdo, Irp); + break; - goto done; + default: + ASSERT(FALSE); + IoSkipCurrentIrpStackLocation(Irp); + status = IoCallDriver(Fdo->LowerDeviceObject, Irp); + break; } - - status = (SystemState < __FdoGetSystemPowerState(Fdo)) ? - FdoQuerySystemPowerUp(Fdo, Irp) : - FdoQuerySystemPowerDown(Fdo, Irp); - -done: - Trace("%s: <==== (%s:%s)(%08x)\n", - __FdoGetName(Fdo), - SystemPowerStateName(SystemState), - PowerActionName(PowerAction), - status); - return status; } -static NTSTATUS -FdoDevicePower( - IN PXENFILT_THREAD Self, - IN PVOID Context - ) -{ - PXENFILT_FDO Fdo = Context; - PKEVENT Event; - - Event = ThreadGetEvent(Self); - - for (;;) { - PIRP Irp; - PIO_STACK_LOCATION StackLocation; - UCHAR MinorFunction; - - if (Fdo->DevicePowerIrp == NULL) { - (VOID) KeWaitForSingleObject(Event, - Executive, - KernelMode, - FALSE, - NULL); - KeClearEvent(Event); - } - - if (ThreadIsAlerted(Self)) - break; - - Irp = Fdo->DevicePowerIrp; - if (Irp == NULL) - continue; - - Fdo->DevicePowerIrp = NULL; - KeMemoryBarrier(); - - StackLocation = IoGetCurrentIrpStackLocation(Irp); - MinorFunction = StackLocation->MinorFunction; - - switch (StackLocation->MinorFunction) { - case IRP_MN_SET_POWER: - (VOID) FdoSetDevicePower(Fdo, Irp); - break; - - case IRP_MN_QUERY_POWER: - (VOID) FdoQueryDevicePower(Fdo, Irp); - break; - - default: - ASSERT(FALSE); - break; - } - - IoReleaseRemoveLock(&Fdo->Dx->RemoveLock, Irp); - } - - return STATUS_SUCCESS; -} - -static NTSTATUS -FdoSystemPower( - IN PXENFILT_THREAD Self, - IN PVOID Context - ) -{ - PXENFILT_FDO Fdo = Context; - PKEVENT Event; - - Event = ThreadGetEvent(Self); - - for (;;) { - PIRP Irp; - PIO_STACK_LOCATION StackLocation; - UCHAR MinorFunction; - - if (Fdo->SystemPowerIrp == NULL) { - (VOID) KeWaitForSingleObject(Event, - Executive, - KernelMode, - FALSE, - NULL); - KeClearEvent(Event); - } - - if (ThreadIsAlerted(Self)) - break; - - Irp = Fdo->SystemPowerIrp; - - if (Irp == NULL) - continue; - - Fdo->SystemPowerIrp = NULL; - KeMemoryBarrier(); - - StackLocation = IoGetCurrentIrpStackLocation(Irp); - MinorFunction = StackLocation->MinorFunction; - - switch (StackLocation->MinorFunction) { - case IRP_MN_SET_POWER: - (VOID) FdoSetSystemPower(Fdo, Irp); - break; - - case IRP_MN_QUERY_POWER: - (VOID) FdoQuerySystemPower(Fdo, Irp); - break; - - default: - ASSERT(FALSE); - break; - } - - IoReleaseRemoveLock(&Fdo->Dx->RemoveLock, Irp); - } - - return STATUS_SUCCESS; -} - -static NTSTATUS +static DECLSPEC_NOINLINE NTSTATUS FdoDispatchPower( - IN PXENFILT_FDO Fdo, + IN PXENFILT_FDO Fdo, IN PIRP Irp ) { @@ -1585,79 +1382,36 @@ FdoDispatchPower( 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) { IoSkipCurrentIrpStackLocation(Irp); - status = IoCallDriver(Fdo->LowerDeviceObject, Irp); - IoReleaseRemoveLock(&Fdo->Dx->RemoveLock, Irp); goto done; } PowerType = StackLocation->Parameters.Power.Type; - Trace("%s: ====> (%02x:%s)\n", - __FdoGetName(Fdo), - MinorFunction, - PowerMinorFunctionName(MinorFunction)); - 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: IoSkipCurrentIrpStackLocation(Irp); - status = IoCallDriver(Fdo->LowerDeviceObject, Irp); - IoReleaseRemoveLock(&Fdo->Dx->RemoveLock, Irp); break; } - Trace("%s: <==== (%02x:%s) (%08x)\n", - __FdoGetName(Fdo), - MinorFunction, - PowerMinorFunctionName(MinorFunction), - status); - done: return status; - -fail1: - Error("fail1 (%08x)\n", status); - - Irp->IoStatus.Status = status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - return status; } static NTSTATUS @@ -1775,21 +1529,13 @@ FdoCreate( Fdo->LowerDeviceObject = LowerDeviceObject; Fdo->Type = Type; - status = ThreadCreate(FdoSystemPower, Fdo, &Fdo->SystemPowerThread); - if (!NT_SUCCESS(status)) - goto fail4; - - status = ThreadCreate(FdoDevicePower, Fdo, &Fdo->DevicePowerThread); - if (!NT_SUCCESS(status)) - goto fail5; - status = __FdoSetDeviceID(Fdo); if (!NT_SUCCESS(status)) - goto fail6; + goto fail4; status = __FdoSetInstanceID(Fdo); if (!NT_SUCCESS(status)) - goto fail7; + goto fail5; __FdoSetName(Fdo); @@ -1814,24 +1560,10 @@ FdoCreate( return STATUS_SUCCESS; -fail7: - Error("fail7\n"); - - __FdoClearDeviceID(Fdo); - -fail6: - Error("fail6\n"); - - ThreadAlert(Fdo->DevicePowerThread); - ThreadJoin(Fdo->DevicePowerThread); - Fdo->DevicePowerThread = NULL; - fail5: Error("fail5\n"); - ThreadAlert(Fdo->SystemPowerThread); - ThreadJoin(Fdo->SystemPowerThread); - Fdo->SystemPowerThread = NULL; + __FdoClearDeviceID(Fdo); fail4: Error("fail4\n"); @@ -1891,14 +1623,6 @@ FdoDestroy( __FdoClearInstanceID(Fdo); __FdoClearDeviceID(Fdo); - ThreadAlert(Fdo->DevicePowerThread); - ThreadJoin(Fdo->DevicePowerThread); - Fdo->DevicePowerThread = NULL; - - ThreadAlert(Fdo->SystemPowerThread); - ThreadJoin(Fdo->SystemPowerThread); - Fdo->SystemPowerThread = NULL; - Fdo->Type = XENFILT_EMULATED_OBJECT_TYPE_UNKNOWN; Fdo->LowerDeviceObject = NULL; Fdo->PhysicalDeviceObject = NULL; diff --git a/src/xenfilt/pdo.c b/src/xenfilt/pdo.c index 741c2f3..2475c6a 100644 --- a/src/xenfilt/pdo.c +++ b/src/xenfilt/pdo.c @@ -56,11 +56,6 @@ struct _XENFILT_PDO { PDEVICE_OBJECT PhysicalDeviceObject; CHAR Name[MAXNAMELEN]; - PXENFILT_THREAD SystemPowerThread; - PIRP SystemPowerIrp; - PXENFILT_THREAD DevicePowerThread; - PIRP DevicePowerIrp; - PXENFILT_FDO Fdo; BOOLEAN Missing; const CHAR *Reason; @@ -1186,82 +1181,84 @@ fail1: return status; } + + + +__drv_functionClass(IO_COMPLETION_ROUTINE) +__drv_sameIRQL static NTSTATUS -PdoSetDevicePowerUp( - IN PXENFILT_PDO Pdo, - IN PIRP Irp +PdoCompleteSetDevicePowerUp( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PVOID Context ) { + PXENFILT_PDO Pdo = (PXENFILT_PDO) Context; PIO_STACK_LOCATION StackLocation; - DEVICE_POWER_STATE DeviceState; POWER_STATE PowerState; - NTSTATUS status; - - StackLocation = IoGetCurrentIrpStackLocation(Irp); - DeviceState = StackLocation->Parameters.Power.State.DeviceState; - ASSERT3U(DeviceState, <, __PdoGetDevicePowerState(Pdo)); + UNREFERENCED_PARAMETER(DeviceObject); - status = PdoForwardIrpSynchronously(Pdo, Irp); - if (!NT_SUCCESS(status)) - goto done; + StackLocation = IoGetCurrentIrpStackLocation(Irp); + PowerState = StackLocation->Parameters.Power.State; - Trace("%s: %s -> %s\n", - __PdoGetName(Pdo), - DevicePowerStateName(__PdoGetDevicePowerState(Pdo)), - DevicePowerStateName(DeviceState)); + if (Irp->PendingReturned) { + IoMarkIrpPending(Irp); + } - PowerState.DeviceState = DeviceState; - PoSetPowerState(__PdoGetDeviceObject(Pdo), + __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 +PdoDispatchSetDevicePowerUp( + IN PXENFILT_PDO Pdo, + IN PIRP Irp + ) +{ + PIO_STACK_LOCATION StackLocation; - return status; + StackLocation = IoGetCurrentIrpStackLocation(Irp); + + IoCopyCurrentIrpStackLocationToNext(Irp); + IoSetCompletionRoutine(Irp, + PdoCompleteSetDevicePowerUp, + Pdo, + TRUE, + TRUE, + TRUE); + return IoCallDriver(Pdo->LowerDeviceObject, Irp); } -static NTSTATUS -PdoSetDevicePowerDown( +static FORCEINLINE NTSTATUS +PdoDispatchSetDevicePowerDown( IN PXENFILT_PDO Pdo, IN PIRP Irp ) { PIO_STACK_LOCATION StackLocation; - DEVICE_POWER_STATE DeviceState; POWER_STATE PowerState; - NTSTATUS status; StackLocation = IoGetCurrentIrpStackLocation(Irp); - DeviceState = StackLocation->Parameters.Power.State.DeviceState; + PowerState = StackLocation->Parameters.Power.State; - ASSERT3U(DeviceState, >, __PdoGetDevicePowerState(Pdo)); - - Trace("%s: %s -> %s\n", - __PdoGetName(Pdo), - DevicePowerStateName(__PdoGetDevicePowerState(Pdo)), - DevicePowerStateName(DeviceState)); - - PowerState.DeviceState = DeviceState; - PoSetPowerState(__PdoGetDeviceObject(Pdo), + __PdoSetDevicePowerState(Pdo, PowerState.DeviceState); + PoSetPowerState(Pdo->Dx->DeviceObject, DevicePowerState, PowerState); - __PdoSetDevicePowerState(Pdo, DeviceState); - - status = PdoForwardIrpSynchronously(Pdo, Irp); - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - return status; + IoSkipCurrentIrpStackLocation(Irp); + return IoCallDriver(Pdo->LowerDeviceObject, Irp); } -static NTSTATUS -PdoSetDevicePower( - IN PXENFILT_PDO Pdo, +/* IRQL argnostic code, just mark power states.*/ +static FORCEINLINE NTSTATUS +PdoDispatchSetDevicePower( + IN PXENFILT_PDO Pdo, IN PIRP Irp ) { @@ -1274,422 +1271,220 @@ PdoSetDevicePower( DeviceState = StackLocation->Parameters.Power.State.DeviceState; PowerAction = StackLocation->Parameters.Power.ShutdownType; - Trace("%s: ====> (%s:%s)\n", - __PdoGetName(Pdo), - DevicePowerStateName(DeviceState), + /* See if we can get away without pending the IRP in a filter + driver. */ + + Trace("====> (%s:%s)\n", + DevicePowerStateName(DeviceState), PowerActionName(PowerAction)); - if (DeviceState == __PdoGetDevicePowerState(Pdo)) { - status = PdoForwardIrpSynchronously(Pdo, Irp); - IoCompleteRequest(Irp, IO_NO_INCREMENT); + if (DeviceState == __PdoGetDevicePowerState(Pdo)) { + IoSkipCurrentIrpStackLocation(Irp); + status = IoCallDriver(Pdo->LowerDeviceObject, Irp); goto done; } - status = (DeviceState < __PdoGetDevicePowerState(Pdo)) ? - PdoSetDevicePowerUp(Pdo, Irp) : - PdoSetDevicePowerDown(Pdo, Irp); + if (DeviceState < __PdoGetDevicePowerState(Pdo)) { + status = PdoDispatchSetDevicePowerUp(Pdo, Irp); + } else { + status = PdoDispatchSetDevicePowerDown(Pdo, Irp); + } done: - Trace("%s: <==== (%s:%s)(%08x)\n", - __PdoGetName(Pdo), - DevicePowerStateName(DeviceState), - PowerActionName(PowerAction), - status); + Trace("<==== (%s:%s)\n", + DevicePowerStateName(DeviceState), + PowerActionName(PowerAction)); + return status; } +__drv_functionClass(IO_COMPLETION_ROUTINE) +__drv_sameIRQL static NTSTATUS -PdoSetSystemPowerUp( - IN PXENFILT_PDO Pdo, - IN PIRP Irp +PdoCompleteSetSystemPowerUp( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PVOID Context ) { + PXENFILT_PDO Pdo = (PXENFILT_PDO) Context; PIO_STACK_LOCATION StackLocation; SYSTEM_POWER_STATE SystemState; - NTSTATUS status; + + UNREFERENCED_PARAMETER(DeviceObject); StackLocation = IoGetCurrentIrpStackLocation(Irp); SystemState = StackLocation->Parameters.Power.State.SystemState; - ASSERT3U(SystemState, <, __PdoGetSystemPowerState(Pdo)); - - status = PdoForwardIrpSynchronously(Pdo, Irp); - if (!NT_SUCCESS(status)) - goto done; - - Trace("%s: %s -> %s\n", - __PdoGetName(Pdo), - SystemPowerStateName(__PdoGetSystemPowerState(Pdo)), - SystemPowerStateName(SystemState)); + if (Irp->PendingReturned) { + IoMarkIrpPending(Irp); + } __PdoSetSystemPowerState(Pdo, SystemState); -done: - Irp->IoStatus.Status = status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - return status; + return STATUS_CONTINUE_COMPLETION; } -static NTSTATUS -PdoSetSystemPowerDown( +static FORCEINLINE NTSTATUS +PdoDispatchSetSystemPowerUp( IN PXENFILT_PDO Pdo, IN PIRP Irp ) { PIO_STACK_LOCATION StackLocation; - SYSTEM_POWER_STATE SystemState; - NTSTATUS status; StackLocation = IoGetCurrentIrpStackLocation(Irp); - SystemState = StackLocation->Parameters.Power.State.SystemState; - - ASSERT3U(SystemState, >, __PdoGetSystemPowerState(Pdo)); - - Trace("%s: %s -> %s\n", - __PdoGetName(Pdo), - SystemPowerStateName(__PdoGetSystemPowerState(Pdo)), - SystemPowerStateName(SystemState)); - - __PdoSetSystemPowerState(Pdo, SystemState); - status = PdoForwardIrpSynchronously(Pdo, Irp); - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - return status; + IoCopyCurrentIrpStackLocationToNext(Irp); + IoSetCompletionRoutine(Irp, + PdoCompleteSetSystemPowerUp, + Pdo, + TRUE, + TRUE, + TRUE); + return IoCallDriver(Pdo->LowerDeviceObject, Irp); } -static NTSTATUS -PdoSetSystemPower( - IN PXENFILT_PDO Pdo, +static FORCEINLINE NTSTATUS +PdoDispatchSetSystemPowerDown( + IN PXENFILT_PDO Pdo, IN PIRP Irp ) { PIO_STACK_LOCATION StackLocation; SYSTEM_POWER_STATE SystemState; - POWER_ACTION PowerAction; - NTSTATUS status; StackLocation = IoGetCurrentIrpStackLocation(Irp); SystemState = StackLocation->Parameters.Power.State.SystemState; - PowerAction = StackLocation->Parameters.Power.ShutdownType; - - Trace("%s: ====> (%s:%s)\n", - __PdoGetName(Pdo), - SystemPowerStateName(SystemState), - PowerActionName(PowerAction)); - - if (SystemState == __PdoGetSystemPowerState(Pdo)) { - status = PdoForwardIrpSynchronously(Pdo, Irp); - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - goto done; - } - - status = (SystemState < __PdoGetSystemPowerState(Pdo)) ? - PdoSetSystemPowerUp(Pdo, Irp) : - PdoSetSystemPowerDown(Pdo, Irp); - -done: - Trace("%s: <==== (%s:%s)(%08x)\n", - __PdoGetName(Pdo), - SystemPowerStateName(SystemState), - PowerActionName(PowerAction), - status); - return status; -} - -static NTSTATUS -PdoQueryDevicePowerUp( - IN PXENFILT_PDO Pdo, - IN PIRP Irp - ) -{ - PIO_STACK_LOCATION StackLocation; - DEVICE_POWER_STATE DeviceState; - NTSTATUS status; - - StackLocation = IoGetCurrentIrpStackLocation(Irp); - DeviceState = StackLocation->Parameters.Power.State.DeviceState; - - ASSERT3U(DeviceState, <, __PdoGetDevicePowerState(Pdo)); - - status = PdoForwardIrpSynchronously(Pdo, Irp); - - Irp->IoStatus.Status = status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - return status; -} - -static NTSTATUS -PdoQueryDevicePowerDown( - IN PXENFILT_PDO Pdo, - IN PIRP Irp - ) -{ - PIO_STACK_LOCATION StackLocation; - DEVICE_POWER_STATE DeviceState; - NTSTATUS status; - - StackLocation = IoGetCurrentIrpStackLocation(Irp); - DeviceState = StackLocation->Parameters.Power.State.DeviceState; - - ASSERT3U(DeviceState, >, __PdoGetDevicePowerState(Pdo)); - status = PdoForwardIrpSynchronously(Pdo, Irp); - IoCompleteRequest(Irp, IO_NO_INCREMENT); + __PdoSetSystemPowerState(Pdo, SystemState); - return status; + IoSkipCurrentIrpStackLocation(Irp); + return IoCallDriver(Pdo->LowerDeviceObject, Irp); } -static NTSTATUS -PdoQueryDevicePower( - IN PXENFILT_PDO Pdo, +/* IRQL argnostic code, just mark power states.*/ +static FORCEINLINE NTSTATUS +PdoDispatchSetSystemPower( + IN PXENFILT_PDO Pdo, 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; - Trace("%s: ====> (%s:%s)\n", - __PdoGetName(Pdo), - DevicePowerStateName(DeviceState), - PowerActionName(PowerAction)); + /* See if we can get away without pending the IRP in a filter + driver. */ - if (DeviceState == __PdoGetDevicePowerState(Pdo)) { - status = PdoForwardIrpSynchronously(Pdo, Irp); - IoCompleteRequest(Irp, IO_NO_INCREMENT); + Trace("====> (%s:%s)\n", + SystemPowerStateName(SystemState), + PowerActionName(PowerAction)); + if (SystemState == __PdoGetSystemPowerState(Pdo)) { + IoSkipCurrentIrpStackLocation(Irp); + status = IoCallDriver(Pdo->LowerDeviceObject, Irp); goto done; } - status = (DeviceState < __PdoGetDevicePowerState(Pdo)) ? - PdoQueryDevicePowerUp(Pdo, Irp) : - PdoQueryDevicePowerDown(Pdo, Irp); + if (SystemState < __PdoGetSystemPowerState(Pdo)) { + status = PdoDispatchSetSystemPowerUp(Pdo, Irp); + } else { + status = PdoDispatchSetSystemPowerDown(Pdo, Irp); + } done: - Trace("%s: <==== (%s:%s)(%08x)\n", - __PdoGetName(Pdo), - DevicePowerStateName(DeviceState), - PowerActionName(PowerAction), - status); - return status; -} - -static NTSTATUS -PdoQuerySystemPowerUp( - IN PXENFILT_PDO Pdo, - IN PIRP Irp - ) -{ - PIO_STACK_LOCATION StackLocation; - SYSTEM_POWER_STATE SystemState; - NTSTATUS status; - - StackLocation = IoGetCurrentIrpStackLocation(Irp); - SystemState = StackLocation->Parameters.Power.State.SystemState; - - ASSERT3U(SystemState, <, __PdoGetSystemPowerState(Pdo)); - - status = PdoForwardIrpSynchronously(Pdo, Irp); - - Irp->IoStatus.Status = status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); + Trace("<==== (%s:%s)\n", + SystemPowerStateName(SystemState), + PowerActionName(PowerAction)); return status; } -static NTSTATUS -PdoQuerySystemPowerDown( +static FORCEINLINE NTSTATUS +PdoDispatchQueryPower( IN PXENFILT_PDO Pdo, IN PIRP Irp ) { PIO_STACK_LOCATION StackLocation; SYSTEM_POWER_STATE SystemState; - NTSTATUS status; StackLocation = IoGetCurrentIrpStackLocation(Irp); SystemState = StackLocation->Parameters.Power.State.SystemState; - ASSERT3U(SystemState, >, __PdoGetSystemPowerState(Pdo)); - - status = PdoForwardIrpSynchronously(Pdo, Irp); - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - return status; + /* Queries we will just pass thru, regardless of what they are. + Don't need to pend or set any completion routines. */ + IoSkipCurrentIrpStackLocation(Irp); + return IoCallDriver(Pdo->LowerDeviceObject, Irp); } +/* Dispatch - call down, and/or set completion, IRP not pended */ static NTSTATUS -PdoQuerySystemPower( - IN PXENFILT_PDO Pdo, +PdoDispatchDevicePower( + IN PXENFILT_PDO Pdo, IN PIRP Irp ) { - PIO_STACK_LOCATION StackLocation; - SYSTEM_POWER_STATE SystemState; - POWER_ACTION PowerAction; - NTSTATUS status; - - StackLocation = IoGetCurrentIrpStackLocation(Irp); - SystemState = StackLocation->Parameters.Power.State.SystemState; - PowerAction = StackLocation->Parameters.Power.ShutdownType; + NTSTATUS status; + PIO_STACK_LOCATION StackLocation = IoGetCurrentIrpStackLocation(Irp); - Trace("%s: ====> (%s:%s)\n", - __PdoGetName(Pdo), - SystemPowerStateName(SystemState), - PowerActionName(PowerAction)); + switch (StackLocation->MinorFunction) { + case IRP_MN_SET_POWER: + status = PdoDispatchSetDevicePower(Pdo, Irp); + break; - if (SystemState == __PdoGetSystemPowerState(Pdo)) { - status = PdoForwardIrpSynchronously(Pdo, Irp); - IoCompleteRequest(Irp, IO_NO_INCREMENT); + case IRP_MN_QUERY_POWER: + status = PdoDispatchQueryPower(Pdo, Irp); + break; - goto done; + default: + ASSERT(FALSE); + IoSkipCurrentIrpStackLocation(Irp); + status = IoCallDriver(Pdo->LowerDeviceObject, Irp); + break; } - - status = (SystemState < __PdoGetSystemPowerState(Pdo)) ? - PdoQuerySystemPowerUp(Pdo, Irp) : - PdoQuerySystemPowerDown(Pdo, Irp); - -done: - Trace("%s: <==== (%s:%s)(%08x)\n", - __PdoGetName(Pdo), - SystemPowerStateName(SystemState), - PowerActionName(PowerAction), - status); - return status; } +/* Dispatch - call down, and/or set completion, IRP not pended */ static NTSTATUS -PdoDevicePower( - IN PXENFILT_THREAD Self, - IN PVOID Context +PdoDispatchSystemPower( + IN PXENFILT_PDO Pdo, + IN PIRP Irp ) { - PXENFILT_PDO Pdo = Context; - PKEVENT Event; - - Event = ThreadGetEvent(Self); - - for (;;) { - PIRP Irp; - PIO_STACK_LOCATION StackLocation; - UCHAR MinorFunction; - - if (Pdo->DevicePowerIrp == NULL) { - (VOID) KeWaitForSingleObject(Event, - Executive, - KernelMode, - FALSE, - NULL); - KeClearEvent(Event); - } - - if (ThreadIsAlerted(Self)) - break; - - Irp = Pdo->DevicePowerIrp; + NTSTATUS status; + PIO_STACK_LOCATION StackLocation = IoGetCurrentIrpStackLocation(Irp); - 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; + switch (StackLocation->MinorFunction) { + case IRP_MN_SET_POWER: + status = PdoDispatchSetSystemPower(Pdo, Irp); + break; - default: - ASSERT(FALSE); - break; - } + case IRP_MN_QUERY_POWER: + status = PdoDispatchQueryPower(Pdo, Irp); + break; - IoReleaseRemoveLock(&Pdo->Dx->RemoveLock, Irp); + default: + ASSERT(FALSE); + IoSkipCurrentIrpStackLocation(Irp); + status = IoCallDriver(Pdo->LowerDeviceObject, Irp); + break; } - - return STATUS_SUCCESS; + return status; } -static NTSTATUS -PdoSystemPower( - IN PXENFILT_THREAD Self, - IN PVOID Context - ) -{ - PXENFILT_PDO Pdo = Context; - PKEVENT Event; - - Event = ThreadGetEvent(Self); - - for (;;) { - PIRP Irp; - PIO_STACK_LOCATION StackLocation; - UCHAR MinorFunction; - - if (Pdo->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; -} - -static NTSTATUS +static DECLSPEC_NOINLINE NTSTATUS PdoDispatchPower( - IN PXENFILT_PDO Pdo, + IN PXENFILT_PDO Pdo, IN PIRP Irp ) { @@ -1698,81 +1493,39 @@ PdoDispatchPower( 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) { IoSkipCurrentIrpStackLocation(Irp); - status = IoCallDriver(Pdo->LowerDeviceObject, Irp); - IoReleaseRemoveLock(&Pdo->Dx->RemoveLock, Irp); goto done; } PowerType = StackLocation->Parameters.Power.Type; - Trace("%s: ====> (%02x:%s)\n", - __PdoGetName(Pdo), - MinorFunction, - PowerMinorFunctionName(MinorFunction)); - switch (PowerType) { case DevicePowerState: - IoMarkIrpPending(Irp); - - ASSERT3P(Pdo->DevicePowerIrp, ==, NULL); - Pdo->DevicePowerIrp = Irp; - KeMemoryBarrier(); - - ThreadWake(Pdo->DevicePowerThread); - - status = STATUS_PENDING; + status = PdoDispatchDevicePower(Pdo, Irp); break; case SystemPowerState: - IoMarkIrpPending(Irp); - - ASSERT3P(Pdo->SystemPowerIrp, ==, NULL); - Pdo->SystemPowerIrp = Irp; - KeMemoryBarrier(); - - ThreadWake(Pdo->SystemPowerThread); - - status = STATUS_PENDING; + status = PdoDispatchSystemPower(Pdo, Irp); break; default: IoSkipCurrentIrpStackLocation(Irp); - status = IoCallDriver(Pdo->LowerDeviceObject, Irp); - IoReleaseRemoveLock(&Pdo->Dx->RemoveLock, Irp); break; } - Trace("%s: <==== (%02x:%s) (%08x)\n", - __PdoGetName(Pdo), - MinorFunction, - PowerMinorFunctionName(MinorFunction), - status); - done: return status; - -fail1: - Error("fail1 (%08x)\n", status); - - Irp->IoStatus.Status = status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - return status; } + static NTSTATUS PdoDispatchDefault( IN PXENFILT_PDO Pdo, @@ -1907,17 +1660,9 @@ PdoCreate( Pdo->LowerDeviceObject = LowerDeviceObject; Pdo->Type = Type; - status = ThreadCreate(PdoSystemPower, Pdo, &Pdo->SystemPowerThread); - if (!NT_SUCCESS(status)) - goto fail4; - - status = ThreadCreate(PdoDevicePower, Pdo, &Pdo->DevicePowerThread); - if (!NT_SUCCESS(status)) - goto fail5; - status = PdoSetDeviceInformation(Pdo); if (!NT_SUCCESS(status)) - goto fail6; + goto fail4; status = DriverQueryId(Pdo->LowerDeviceObject, BusQueryCompatibleIDs, @@ -1932,7 +1677,7 @@ PdoCreate( __PdoGetType(Pdo), &Pdo->EmulatedObject); if (!NT_SUCCESS(status)) - goto fail7; + goto fail5; if (CompatibleIDs) ExFreePool(CompatibleIDs); @@ -1957,28 +1702,14 @@ PdoCreate( return STATUS_SUCCESS; -fail7: - Error("fail7\n"); +fail5: + Error("fail5\n"); if (CompatibleIDs) ExFreePool(CompatibleIDs); PdoClearDeviceInformation(Pdo); -fail6: - Error("fail6\n"); - - ThreadAlert(Pdo->DevicePowerThread); - ThreadJoin(Pdo->DevicePowerThread); - Pdo->DevicePowerThread = NULL; - -fail5: - Error("fail5\n"); - - ThreadAlert(Pdo->SystemPowerThread); - ThreadJoin(Pdo->SystemPowerThread); - Pdo->SystemPowerThread = NULL; - fail4: Error("fail4\n"); @@ -2040,14 +1771,6 @@ PdoDestroy( PdoClearDeviceInformation(Pdo); - ThreadAlert(Pdo->DevicePowerThread); - ThreadJoin(Pdo->DevicePowerThread); - Pdo->DevicePowerThread = NULL; - - ThreadAlert(Pdo->SystemPowerThread); - ThreadJoin(Pdo->SystemPowerThread); - Pdo->SystemPowerThread = NULL; - Pdo->Type = XENFILT_EMULATED_OBJECT_TYPE_UNKNOWN; Pdo->PhysicalDeviceObject = NULL; Pdo->LowerDeviceObject = NULL; -- 2.25.0.windows.1
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |