ULONG Usage[DeviceUsageTypeDumpFile + 1];
BOOLEAN NotDisableable;
- PXENVIF_THREAD SystemPowerThread;
+ PIO_WORKITEM SystemPowerWorkItem;
PIRP SystemPowerIrp;
- PXENVIF_THREAD DevicePowerThread;
+ PIO_WORKITEM DevicePowerWorkItem;
PIRP DevicePowerIrp;
CHAR VendorName[MAXNAMELEN];
return status;
}
-static FORCEINLINE NTSTATUS
-__FdoSetDevicePowerUp(
- IN PXENVIF_FDO Fdo,
- IN PIRP Irp
+__drv_functionClass(IO_WORKITEM_ROUTINE)
+__drv_sameIRQL
+static VOID
+FdoDevicePowerUpWorker(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PVOID Context
)
{
+ PXENVIF_FDO Fdo = (PXENVIF_FDO)Context;
+ PIRP Irp;
+
+ UNREFERENCED_PARAMETER(DeviceObject);
+
+ Irp = InterlockedExchangePointer(&Fdo->DevicePowerIrp, NULL);
+ ASSERT(Irp != NULL);
+
+ (VOID) FdoD3ToD0(Fdo);
+
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+}
+
+__drv_functionClass(IO_COMPLETION_ROUTINE)
+__drv_sameIRQL
+static NTSTATUS
+FdoSetDevicePowerUpComplete(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PVOID Context
+ )
+{
+ PXENVIF_FDO Fdo = (PXENVIF_FDO)Context;
PIO_STACK_LOCATION StackLocation;
DEVICE_POWER_STATE DeviceState;
- NTSTATUS status;
+ PVOID Exchange;
- Trace("====>\n");
+ UNREFERENCED_PARAMETER(DeviceObject);
StackLocation = IoGetCurrentIrpStackLocation(Irp);
DeviceState = StackLocation->Parameters.Power.State.DeviceState;
- ASSERT3U(DeviceState, <, __FdoGetDevicePowerState(Fdo));
-
- status = FdoForwardIrpSynchronously(Fdo, Irp);
- if (!NT_SUCCESS(status))
- goto done;
-
Info("%s: %s -> %s\n",
__FdoGetName(Fdo),
PowerDeviceStateName(__FdoGetDevicePowerState(Fdo)),
PowerDeviceStateName(DeviceState));
ASSERT3U(DeviceState, ==, PowerDeviceD0);
- status = FdoD3ToD0(Fdo);
- ASSERT(NT_SUCCESS(status));
-done:
- Irp->IoStatus.Status = status;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ Exchange = InterlockedExchangePointer(&Fdo->DevicePowerIrp, Irp);
+ ASSERT(Exchange == NULL);
- Trace("<==== (%08x)\n", status);
- return status;
+ IoQueueWorkItem(Fdo->DevicePowerWorkItem,
+ FdoDevicePowerUpWorker,
+ DelayedWorkQueue,
+ Fdo);
+
+ return STATUS_MORE_PROCESSING_REQUIRED;
+}
+
+static FORCEINLINE NTSTATUS
+__FdoSetDevicePowerUp(
+ IN PXENVIF_FDO Fdo,
+ IN PIRP Irp
+ )
+{
+ PIO_STACK_LOCATION StackLocation;
+ DEVICE_POWER_STATE DeviceState;
+
+ StackLocation = IoGetCurrentIrpStackLocation(Irp);
+ DeviceState = StackLocation->Parameters.Power.State.DeviceState;
+
+ ASSERT3U(DeviceState, <, __FdoGetDevicePowerState(Fdo));
+
+ IoMarkIrpPending(Irp);
+ IoCopyCurrentIrpStackLocationToNext(Irp);
+ IoSetCompletionRoutine(Irp,
+ FdoSetDevicePowerUpComplete,
+ Fdo,
+ TRUE,
+ TRUE,
+ TRUE);
+
+ (VOID) IoCallDriver(Fdo->LowerDeviceObject, Irp);
+
+ return STATUS_PENDING;
+}
+
+__drv_functionClass(IO_WORKITEM_ROUTINE)
+__drv_sameIRQL
+static VOID
+FdoDevicePowerDownWorker(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PVOID Context
+ )
+{
+ PXENVIF_FDO Fdo = (PXENVIF_FDO)Context;
+ PIRP Irp;
+
+ UNREFERENCED_PARAMETER(DeviceObject);
+
+ Irp = InterlockedExchangePointer(&Fdo->DevicePowerIrp, NULL);
+ ASSERT(Irp != NULL);
+
+ FdoD0ToD3(Fdo);
+
+ IoCopyCurrentIrpStackLocationToNext(Irp);
+ IoCallDriver(Fdo->LowerDeviceObject, Irp);
}
static FORCEINLINE NTSTATUS
ASSERT3U(DeviceState, ==, PowerDeviceD3);
- if (__FdoGetDevicePowerState(Fdo) == PowerDeviceD0)
- FdoD0ToD3(Fdo);
+ if (__FdoGetDevicePowerState(Fdo) != PowerDeviceD0) {
+ IoSkipCurrentIrpStackLocation(Irp);
+ status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
+ } else {
+ PVOID Exchange;
- IoSkipCurrentIrpStackLocation(Irp);
- status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
+ IoMarkIrpPending(Irp);
+
+ Exchange = InterlockedExchangePointer(&Fdo->DevicePowerIrp, Irp);
+ ASSERT(Exchange == NULL);
+
+ IoQueueWorkItem(Fdo->DevicePowerWorkItem,
+ FdoDevicePowerDownWorker,
+ DelayedWorkQueue,
+ Fdo);
+
+ status = STATUS_PENDING;
+ }
return status;
}
DeviceState = StackLocation->Parameters.Power.State.DeviceState;
PowerAction = StackLocation->Parameters.Power.ShutdownType;
- Trace("====> (%s:%s)\n",
- PowerDeviceStateName(DeviceState),
+ Trace("%s: ====> (%s:%s)\n",
+ __FdoGetName(Fdo),
+ PowerDeviceStateName(DeviceState),
PowerActionName(PowerAction));
- ASSERT3U(PowerAction, <, PowerActionShutdown);
-
if (DeviceState == __FdoGetDevicePowerState(Fdo)) {
IoSkipCurrentIrpStackLocation(Irp);
status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
__FdoSetDevicePowerDown(Fdo, Irp);
done:
- Trace("<==== (%s:%s)(%08x)\n",
- PowerDeviceStateName(DeviceState),
+ Trace("%s: <==== (%s:%s)(%08x)\n",
+ __FdoGetName(Fdo),
+ PowerDeviceStateName(DeviceState),
PowerActionName(PowerAction),
status);
return status;
__drv_functionClass(REQUEST_POWER_COMPLETE)
__drv_sameIRQL
-VOID
-__FdoRequestSetDevicePower(
+static VOID
+FdoRequestSetDevicePowerUpComplete(
IN PDEVICE_OBJECT DeviceObject,
IN UCHAR MinorFunction,
IN POWER_STATE PowerState,
IN PIO_STATUS_BLOCK IoStatus
)
{
- PKEVENT Event = Context;
+ PIRP Irp = (PIRP)Context;
UNREFERENCED_PARAMETER(DeviceObject);
UNREFERENCED_PARAMETER(MinorFunction);
UNREFERENCED_PARAMETER(PowerState);
+ UNREFERENCED_PARAMETER(IoStatus);
- ASSERT(NT_SUCCESS(IoStatus->Status));
-
- KeSetEvent(Event, IO_NO_INCREMENT, FALSE);
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
+__drv_functionClass(IO_WORKITEM_ROUTINE)
+__drv_sameIRQL
static VOID
-FdoRequestSetDevicePower(
- IN PXENVIF_FDO Fdo,
- IN DEVICE_POWER_STATE DeviceState
+FdoSystemPowerUpWorker(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PVOID Context
)
{
- POWER_STATE PowerState;
- KEVENT Event;
- NTSTATUS status;
+ PXENVIF_FDO Fdo = (PXENVIF_FDO)Context;
+ PIRP Irp;
+ PIO_STACK_LOCATION StackLocation;
+ SYSTEM_POWER_STATE SystemState;
+ POWER_STATE PowerState;
+ NTSTATUS status;
- Trace("%s\n", PowerDeviceStateName(DeviceState));
+ UNREFERENCED_PARAMETER(DeviceObject);
- ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
+ Irp = InterlockedExchangePointer(&Fdo->SystemPowerIrp, NULL);
+ ASSERT(Irp != NULL);
- PowerState.DeviceState = DeviceState;
- KeInitializeEvent(&Event, NotificationEvent, FALSE);
+ StackLocation = IoGetCurrentIrpStackLocation(Irp);;
+ SystemState = StackLocation->Parameters.Power.State.SystemState;
+
+ Info("%s: %s -> %s\n",
+ __FdoGetName(Fdo),
+ PowerSystemStateName(__FdoGetSystemPowerState(Fdo)),
+ PowerSystemStateName(SystemState));
+
+ __FdoSetSystemPowerState(Fdo, PowerSystemHibernate);
+ FdoS4ToS3(Fdo);
+ __FdoSetSystemPowerState(Fdo, SystemState);
+
+ PowerState.DeviceState = Fdo->LowerDeviceCapabilities.DeviceState[SystemState];
status = PoRequestPowerIrp(Fdo->LowerDeviceObject,
IRP_MN_SET_POWER,
PowerState,
- __FdoRequestSetDevicePower,
- &Event,
+ FdoRequestSetDevicePowerUpComplete,
+ Irp,
NULL);
- ASSERT(NT_SUCCESS(status));
- (VOID) KeWaitForSingleObject(&Event,
- Executive,
- KernelMode,
- FALSE,
- NULL);
+ if (!NT_SUCCESS(status))
+ goto fail1;
+
+ return;
+
+fail1:
+ Error("fail1 (%08x)\n", status);
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+}
+
+__drv_functionClass(IO_COMPLETION_ROUTINE)
+__drv_sameIRQL
+static NTSTATUS
+FdoSetSystemPowerUpComplete(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PVOID Context
+ )
+{
+ PXENVIF_FDO Fdo = (PXENVIF_FDO)Context;
+ PIO_STACK_LOCATION StackLocation;
+ SYSTEM_POWER_STATE SystemState;
+ POWER_STATE PowerState;
+ NTSTATUS status;
+
+ UNREFERENCED_PARAMETER(DeviceObject);
+
+ StackLocation = IoGetCurrentIrpStackLocation(Irp);
+ SystemState = StackLocation->Parameters.Power.State.SystemState;
+
+ if (SystemState < PowerSystemHibernate &&
+ __FdoGetSystemPowerState(Fdo) >= PowerSystemHibernate) {
+ PVOID Exchange;
+
+ Exchange = InterlockedExchangePointer(&Fdo->SystemPowerIrp, Irp);
+ ASSERT(Exchange == NULL);
+
+ IoQueueWorkItem(Fdo->SystemPowerWorkItem,
+ FdoSystemPowerUpWorker,
+ DelayedWorkQueue,
+ Fdo);
+ } else {
+ Info("%s: %s -> %s\n",
+ __FdoGetName(Fdo),
+ PowerSystemStateName(__FdoGetSystemPowerState(Fdo)),
+ PowerSystemStateName(SystemState));
+
+ __FdoSetSystemPowerState(Fdo, SystemState);
+
+ PowerState.DeviceState = Fdo->LowerDeviceCapabilities.DeviceState[SystemState];
+
+ status = PoRequestPowerIrp(Fdo->LowerDeviceObject,
+ IRP_MN_SET_POWER,
+ PowerState,
+ FdoRequestSetDevicePowerUpComplete,
+ Irp,
+ NULL);
+ if (!NT_SUCCESS(status))
+ goto fail1;
+ }
+
+ return STATUS_MORE_PROCESSING_REQUIRED;
+
+fail1:
+ Error("fail1 (%08x)\n", status);
+ return STATUS_CONTINUE_COMPLETION;
}
static FORCEINLINE NTSTATUS
IN PIRP Irp
)
{
+ PIO_STACK_LOCATION StackLocation;
+ SYSTEM_POWER_STATE SystemState;
+
+ StackLocation = IoGetCurrentIrpStackLocation(Irp);
+ SystemState = StackLocation->Parameters.Power.State.SystemState;
+
+ ASSERT3U(SystemState, <, __FdoGetSystemPowerState(Fdo));
+
+ IoCopyCurrentIrpStackLocationToNext(Irp);
+ IoSetCompletionRoutine(Irp,
+ FdoSetSystemPowerUpComplete,
+ Fdo,
+ TRUE,
+ TRUE,
+ TRUE);
+
+ IoCallDriver(Fdo->LowerDeviceObject, Irp);
+
+ return STATUS_PENDING;
+}
+__drv_functionClass(IO_WORKITEM_ROUTINE)
+__drv_sameIRQL
+static VOID
+FdoSystemPowerDownWorker(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PVOID Context
+ )
+{
+ PXENVIF_FDO Fdo = (PXENVIF_FDO)Context;
+ PIRP Irp;
PIO_STACK_LOCATION StackLocation;
SYSTEM_POWER_STATE SystemState;
- DEVICE_POWER_STATE DeviceState;
- NTSTATUS status;
+
+ UNREFERENCED_PARAMETER(DeviceObject);
+
+ Irp = InterlockedExchangePointer(&Fdo->SystemPowerIrp, NULL);
+ ASSERT(Irp != NULL);
StackLocation = IoGetCurrentIrpStackLocation(Irp);
SystemState = StackLocation->Parameters.Power.State.SystemState;
- ASSERT3U(SystemState, <, __FdoGetSystemPowerState(Fdo));
+ __FdoSetSystemPowerState(Fdo, PowerSystemSleeping3);
+ FdoS3ToS4(Fdo);
+ __FdoSetSystemPowerState(Fdo, SystemState);
+
+ IoCopyCurrentIrpStackLocationToNext(Irp);
+ IoCallDriver(Fdo->LowerDeviceObject, Irp);
+}
- status = FdoForwardIrpSynchronously(Fdo, Irp);
- if (!NT_SUCCESS(status))
- goto done;
+__drv_functionClass(REQUEST_POWER_COMPLETE)
+__drv_sameIRQL
+static VOID
+FdoRequestSetDevicePowerDownComplete(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN UCHAR MinorFunction,
+ IN POWER_STATE PowerState,
+ IN PVOID Context,
+ IN PIO_STATUS_BLOCK IoStatus
+ )
+{
+ PIRP Irp = (PIRP)Context;
+ PIO_STACK_LOCATION StackLocation = IoGetCurrentIrpStackLocation(Irp);
+ PDEVICE_OBJECT UpperDeviceObject = StackLocation->DeviceObject;
+ PXENVIF_DX Dx = (PXENVIF_DX)UpperDeviceObject->DeviceExtension;
+ PXENVIF_FDO Fdo = Dx->Fdo;
+ SYSTEM_POWER_STATE SystemState = StackLocation->Parameters.Power.State.SystemState;
+
+ UNREFERENCED_PARAMETER(DeviceObject);
+ UNREFERENCED_PARAMETER(MinorFunction);
+ UNREFERENCED_PARAMETER(PowerState);
+
+ if (!NT_SUCCESS(IoStatus->Status))
+ Error("fail1 (%08x)\n", IoStatus->Status);
Info("%s: %s -> %s\n",
__FdoGetName(Fdo),
- PowerSystemStateName(__FdoGetSystemPowerState(Fdo)),
- PowerSystemStateName(SystemState));
+ PowerSystemStateName(__FdoGetSystemPowerState(Fdo)),
+ PowerSystemStateName(SystemState));
- if (SystemState < PowerSystemHibernate &&
- __FdoGetSystemPowerState(Fdo) >= PowerSystemHibernate) {
- __FdoSetSystemPowerState(Fdo, PowerSystemHibernate);
- FdoS4ToS3(Fdo);
- }
-
- __FdoSetSystemPowerState(Fdo, SystemState);
+ if (SystemState >= PowerSystemHibernate &&
+ __FdoGetSystemPowerState(Fdo) < PowerSystemHibernate) {
+ PVOID Exchange;
- DeviceState = Fdo->LowerDeviceCapabilities.DeviceState[SystemState];
- FdoRequestSetDevicePower(Fdo, DeviceState);
+ Exchange = InterlockedExchangePointer(&Fdo->SystemPowerIrp, Irp);
+ ASSERT(Exchange == NULL);
-done:
- Irp->IoStatus.Status = status;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ IoQueueWorkItem(Fdo->DevicePowerWorkItem,
+ FdoSystemPowerDownWorker,
+ DelayedWorkQueue,
+ Fdo);
+ } else {
+ __FdoSetSystemPowerState(Fdo, SystemState);
- return status;
+ IoCopyCurrentIrpStackLocationToNext(Irp);
+ IoCallDriver(Fdo->LowerDeviceObject, Irp);
+ }
}
static FORCEINLINE NTSTATUS
{
PIO_STACK_LOCATION StackLocation;
SYSTEM_POWER_STATE SystemState;
- DEVICE_POWER_STATE DeviceState;
+ POWER_STATE PowerState;
NTSTATUS status;
StackLocation = IoGetCurrentIrpStackLocation(Irp);
+ BUG_ON(StackLocation->DeviceObject != Fdo->Dx->DeviceObject);
SystemState = StackLocation->Parameters.Power.State.SystemState;
- ASSERT3U(SystemState, >, __FdoGetSystemPowerState(Fdo));
-
- DeviceState = Fdo->LowerDeviceCapabilities.DeviceState[SystemState];
-
- FdoRequestSetDevicePower(Fdo, DeviceState);
+ ASSERT3U(SystemState, >, __FdoGetSystemPowerState(Fdo));
- Info("%s: %s -> %s\n",
- __FdoGetName(Fdo),
- PowerSystemStateName(__FdoGetSystemPowerState(Fdo)),
- PowerSystemStateName(SystemState));
+ PowerState.DeviceState = Fdo->LowerDeviceCapabilities.DeviceState[SystemState];
- if (SystemState >= PowerSystemHibernate &&
- __FdoGetSystemPowerState(Fdo) < PowerSystemHibernate) {
- __FdoSetSystemPowerState(Fdo, PowerSystemSleeping3);
- FdoS3ToS4(Fdo);
+ if (SystemState >= PowerSystemShutdown) {
+ IoCopyCurrentIrpStackLocationToNext(Irp);
+ status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
+ } else {
+ status = PoRequestPowerIrp(Fdo->LowerDeviceObject,
+ IRP_MN_SET_POWER,
+ PowerState,
+ FdoRequestSetDevicePowerDownComplete,
+ Irp,
+ NULL);
+ if (!NT_SUCCESS(status))
+ goto fail1;
}
- __FdoSetSystemPowerState(Fdo, SystemState);
+ return status;
- IoSkipCurrentIrpStackLocation(Irp);
- status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
+fail1:
+ Error("fail1 (%08x)\n", status);
+
+ IoCopyCurrentIrpStackLocationToNext(Irp);
+ IoCallDriver(Fdo->LowerDeviceObject, Irp);
return status;
}
SystemState = StackLocation->Parameters.Power.State.SystemState;
PowerAction = StackLocation->Parameters.Power.ShutdownType;
- Trace("====> (%s:%s)\n",
- PowerSystemStateName(SystemState),
- PowerActionName(PowerAction));
+ IoMarkIrpPending(Irp);
- ASSERT3U(PowerAction, <, PowerActionShutdown);
+ Trace("%s: ====> (%s:%s)\n",
+ __FdoGetName(Fdo),
+ PowerSystemStateName(SystemState),
+ PowerActionName(PowerAction));
if (SystemState == __FdoGetSystemPowerState(Fdo)) {
- IoSkipCurrentIrpStackLocation(Irp);
+ IoCopyCurrentIrpStackLocationToNext(Irp);
status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
goto done;
}
- status = (SystemState < __FdoGetSystemPowerState(Fdo)) ?
+ status = SystemState < __FdoGetSystemPowerState(Fdo) ?
__FdoSetSystemPowerUp(Fdo, Irp) :
__FdoSetSystemPowerDown(Fdo, Irp);
done:
- Trace("<==== (%s:%s)(%08x)\n",
- PowerSystemStateName(SystemState),
+ Trace("%s: <==== (%s:%s)(%08x)\n",
+ __FdoGetName(Fdo),
+ PowerSystemStateName(SystemState),
PowerActionName(PowerAction),
status);
- return status;
+
+ return STATUS_PENDING;
}
static FORCEINLINE NTSTATUS
StackLocation = IoGetCurrentIrpStackLocation(Irp);
DeviceState = StackLocation->Parameters.Power.State.DeviceState;
- ASSERT3U(DeviceState, <, __FdoGetDevicePowerState(Fdo));
-
- status = FdoForwardIrpSynchronously(Fdo, Irp);
+ ASSERT3U(DeviceState, <, __FdoGetDevicePowerState(Fdo));
- Irp->IoStatus.Status = status;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ IoSkipCurrentIrpStackLocation(Irp);
+ status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
return status;
}
StackLocation = IoGetCurrentIrpStackLocation(Irp);
DeviceState = StackLocation->Parameters.Power.State.DeviceState;
- ASSERT3U(DeviceState, >, __FdoGetDevicePowerState(Fdo));
+ ASSERT3U(DeviceState, >, __FdoGetDevicePowerState(Fdo));
IoSkipCurrentIrpStackLocation(Irp);
status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
DeviceState = StackLocation->Parameters.Power.State.DeviceState;
PowerAction = StackLocation->Parameters.Power.ShutdownType;
- Trace("====> (%s:%s)\n",
- PowerDeviceStateName(DeviceState),
+ Trace("%s: ====> (%s:%s)\n",
+ __FdoGetName(Fdo),
+ PowerDeviceStateName(DeviceState),
PowerActionName(PowerAction));
- ASSERT3U(PowerAction, <, PowerActionShutdown);
-
if (DeviceState == __FdoGetDevicePowerState(Fdo)) {
IoSkipCurrentIrpStackLocation(Irp);
status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
__FdoQueryDevicePowerDown(Fdo, Irp);
done:
- Trace("<==== (%s:%s)(%08x)\n",
- PowerDeviceStateName(DeviceState),
+ Trace("%s: <==== (%s:%s)(%08x)\n",
+ __FdoGetName(Fdo),
+ PowerDeviceStateName(DeviceState),
PowerActionName(PowerAction),
status);
return status;
__drv_functionClass(REQUEST_POWER_COMPLETE)
__drv_sameIRQL
-VOID
-__FdoRequestQueryDevicePower(
+static VOID
+FdoRequestQueryDevicePowerUpComplete(
IN PDEVICE_OBJECT DeviceObject,
IN UCHAR MinorFunction,
IN POWER_STATE PowerState,
IN PIO_STATUS_BLOCK IoStatus
)
{
- PKEVENT Event = Context;
+ PIRP Irp = (PIRP)Context;
UNREFERENCED_PARAMETER(DeviceObject);
UNREFERENCED_PARAMETER(MinorFunction);
UNREFERENCED_PARAMETER(PowerState);
- ASSERT(NT_SUCCESS(IoStatus->Status));
+ if (!NT_SUCCESS(IoStatus->Status))
+ Irp->IoStatus.Status = IoStatus->Status;
- KeSetEvent(Event, IO_NO_INCREMENT, FALSE);
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
-static VOID
-FdoRequestQueryDevicePower(
- IN PXENVIF_FDO Fdo,
- IN DEVICE_POWER_STATE DeviceState
+__drv_functionClass(IO_COMPLETION_ROUTINE)
+__drv_sameIRQL
+static NTSTATUS
+FdoQuerySystemPowerUpComplete(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PVOID Context
)
{
- POWER_STATE PowerState;
- KEVENT Event;
- NTSTATUS status;
-
- Trace("%s\n", PowerDeviceStateName(DeviceState));
+ PXENVIF_FDO Fdo = (PXENVIF_FDO)Context;
+ PIO_STACK_LOCATION StackLocation;
+ SYSTEM_POWER_STATE SystemState;
+ POWER_STATE PowerState;
+ NTSTATUS status;
- ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
+ UNREFERENCED_PARAMETER(DeviceObject);
- PowerState.DeviceState = DeviceState;
- KeInitializeEvent(&Event, NotificationEvent, FALSE);
+ StackLocation = IoGetCurrentIrpStackLocation(Irp);
+ SystemState = StackLocation->Parameters.Power.State.SystemState;
+ PowerState.DeviceState = Fdo->LowerDeviceCapabilities.DeviceState[SystemState];
status = PoRequestPowerIrp(Fdo->LowerDeviceObject,
IRP_MN_QUERY_POWER,
PowerState,
- __FdoRequestQueryDevicePower,
- &Event,
+ FdoRequestQueryDevicePowerUpComplete,
+ Irp,
NULL);
- ASSERT(NT_SUCCESS(status));
+ if (!NT_SUCCESS(status))
+ goto fail1;
- (VOID) KeWaitForSingleObject(&Event,
- Executive,
- KernelMode,
- FALSE,
- NULL);
+ return STATUS_MORE_PROCESSING_REQUIRED;
+
+fail1:
+ Error("fail1 (%08x)\n", status);
+ Irp->IoStatus.Status = status;
+
+ return STATUS_CONTINUE_COMPLETION;
}
static FORCEINLINE NTSTATUS
IN PIRP Irp
)
{
-
PIO_STACK_LOCATION StackLocation;
SYSTEM_POWER_STATE SystemState;
- DEVICE_POWER_STATE DeviceState;
- NTSTATUS status;
StackLocation = IoGetCurrentIrpStackLocation(Irp);
SystemState = StackLocation->Parameters.Power.State.SystemState;
- ASSERT3U(SystemState, <, __FdoGetSystemPowerState(Fdo));
+ ASSERT3U(SystemState, <, __FdoGetSystemPowerState(Fdo));
- status = FdoForwardIrpSynchronously(Fdo, Irp);
- if (!NT_SUCCESS(status))
- goto done;
+ IoMarkIrpPending(Irp);
+ IoCopyCurrentIrpStackLocationToNext(Irp);
+ IoSetCompletionRoutine(Irp,
+ FdoQuerySystemPowerUpComplete,
+ Fdo,
+ TRUE,
+ TRUE,
+ TRUE);
+ (VOID) IoCallDriver(Fdo->LowerDeviceObject, Irp);
+
+ return STATUS_PENDING;
+}
+
+__drv_functionClass(REQUEST_POWER_COMPLETE)
+__drv_sameIRQL
+static VOID
+FdoRequestQueryDevicePowerDownComplete(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN UCHAR MinorFunction,
+ IN POWER_STATE PowerState,
+ IN PVOID Context,
+ IN PIO_STATUS_BLOCK IoStatus
+ )
+{
+ PIRP Irp = (PIRP)Context;
+ PIO_STACK_LOCATION StackLocation = IoGetCurrentIrpStackLocation(Irp);
+ PDEVICE_OBJECT UpperDeviceObject = StackLocation->DeviceObject;
+ PXENVIF_DX Dx = (PXENVIF_DX)UpperDeviceObject->DeviceExtension;
+ PXENVIF_FDO Fdo = Dx->Fdo;
- DeviceState = Fdo->LowerDeviceCapabilities.DeviceState[SystemState];
+ UNREFERENCED_PARAMETER(DeviceObject);
+ UNREFERENCED_PARAMETER(MinorFunction);
+ UNREFERENCED_PARAMETER(PowerState);
- FdoRequestQueryDevicePower(Fdo, DeviceState);
+ if (!NT_SUCCESS(IoStatus->Status))
+ goto fail1;
-done:
- Irp->IoStatus.Status = status;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ IoCopyCurrentIrpStackLocationToNext(Irp);
+ IoCallDriver(Fdo->LowerDeviceObject, Irp);
- return status;
+ return;
+
+fail1:
+ Error("fail1 (%08x)\n", IoStatus->Status);
+
+ Irp->IoStatus.Status = IoStatus->Status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
static FORCEINLINE NTSTATUS
{
PIO_STACK_LOCATION StackLocation;
SYSTEM_POWER_STATE SystemState;
- DEVICE_POWER_STATE DeviceState;
+ POWER_STATE PowerState;
NTSTATUS status;
StackLocation = IoGetCurrentIrpStackLocation(Irp);
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,
+ FdoRequestQueryDevicePowerDownComplete,
+ Irp,
+ NULL);
+ if (!NT_SUCCESS(status))
+ goto fail1;
- IoSkipCurrentIrpStackLocation(Irp);
- status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
+ IoMarkIrpPending(Irp);
+
+ return STATUS_PENDING;
+
+fail1:
+ Error("fail1 (%08x)\n", status);
+
+ Irp->IoStatus.Status = status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
}
SystemState = StackLocation->Parameters.Power.State.SystemState;
PowerAction = StackLocation->Parameters.Power.ShutdownType;
- Trace("====> (%s:%s)\n",
- PowerSystemStateName(SystemState),
+ Trace("%s: ====> (%s:%s)\n",
+ __FdoGetName(Fdo),
+ PowerSystemStateName(SystemState),
PowerActionName(PowerAction));
- ASSERT3U(PowerAction, <, PowerActionShutdown);
-
if (SystemState == __FdoGetSystemPowerState(Fdo)) {
IoSkipCurrentIrpStackLocation(Irp);
status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
__FdoQuerySystemPowerDown(Fdo, Irp);
done:
- Trace("<==== (%s:%s)(%08x)\n",
- PowerSystemStateName(SystemState),
+ Trace("%s: <==== (%s:%s)(%08x)\n",
+ __FdoGetName(Fdo),
+ PowerSystemStateName(SystemState),
PowerActionName(PowerAction),
status);
return status;
}
-static NTSTATUS
-FdoDevicePower(
- IN PXENVIF_THREAD Self,
- IN PVOID Context
+static FORCEINLINE NTSTATUS
+__FdoDevicePower(
+ IN PXENVIF_FDO Fdo,
+ IN PIRP Irp
)
{
- PXENVIF_FDO Fdo = Context;
- PKEVENT Event;
-
- Event = ThreadGetEvent(Self);
-
- for (;;) {
- PIRP Irp;
- PIO_STACK_LOCATION StackLocation;
- UCHAR MinorFunction;
-
- if (Fdo->DevicePowerIrp == NULL) {
- (VOID) KeWaitForSingleObject(Event,
- Executive,
- KernelMode,
- FALSE,
- NULL);
- KeClearEvent(Event);
- }
-
- if (ThreadIsAlerted(Self))
- break;
-
- Irp = Fdo->DevicePowerIrp;
-
- if (Irp == NULL)
- continue;
-
- Fdo->DevicePowerIrp = NULL;
- KeMemoryBarrier();
+ PIO_STACK_LOCATION StackLocation;
+ NTSTATUS status;
- StackLocation = IoGetCurrentIrpStackLocation(Irp);
- MinorFunction = StackLocation->MinorFunction;
+ StackLocation = IoGetCurrentIrpStackLocation(Irp);
- switch (StackLocation->MinorFunction) {
- case IRP_MN_SET_POWER:
- (VOID) __FdoSetDevicePower(Fdo, Irp);
- break;
+ switch (StackLocation->MinorFunction) {
+ case IRP_MN_SET_POWER:
+ status = __FdoSetDevicePower(Fdo, Irp);
+ break;
- case IRP_MN_QUERY_POWER:
- (VOID) __FdoQueryDevicePower(Fdo, Irp);
- break;
+ case IRP_MN_QUERY_POWER:
+ status = __FdoQueryDevicePower(Fdo, Irp);
+ break;
- default:
- ASSERT(FALSE);
- break;
- }
+ default:
+ IoSkipCurrentIrpStackLocation(Irp);
+ status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
+ break;
}
- return STATUS_SUCCESS;
+ return status;
}
-static NTSTATUS
-FdoSystemPower(
- IN PXENVIF_THREAD Self,
- IN PVOID Context
+static FORCEINLINE NTSTATUS
+__FdoSystemPower(
+ IN PXENVIF_FDO Fdo,
+ IN PIRP Irp
)
{
- PXENVIF_FDO Fdo = Context;
- PKEVENT Event;
-
- Event = ThreadGetEvent(Self);
-
- for (;;) {
- PIRP Irp;
- PIO_STACK_LOCATION StackLocation;
- UCHAR MinorFunction;
-
- if (Fdo->SystemPowerIrp == NULL) {
- (VOID) KeWaitForSingleObject(Event,
- Executive,
- KernelMode,
- FALSE,
- NULL);
- KeClearEvent(Event);
- }
-
- if (ThreadIsAlerted(Self))
- break;
-
- Irp = Fdo->SystemPowerIrp;
-
- if (Irp == NULL)
- continue;
-
- Fdo->SystemPowerIrp = NULL;
- KeMemoryBarrier();
+ PIO_STACK_LOCATION StackLocation;
+ NTSTATUS status;
- StackLocation = IoGetCurrentIrpStackLocation(Irp);
- MinorFunction = StackLocation->MinorFunction;
+ StackLocation = IoGetCurrentIrpStackLocation(Irp);
- switch (StackLocation->MinorFunction) {
- case IRP_MN_SET_POWER:
- (VOID) __FdoSetSystemPower(Fdo, Irp);
- break;
+ switch (StackLocation->MinorFunction) {
+ case IRP_MN_SET_POWER:
+ status = __FdoSetSystemPower(Fdo, Irp);
+ break;
- case IRP_MN_QUERY_POWER:
- (VOID) __FdoQuerySystemPower(Fdo, Irp);
- break;
+ case IRP_MN_QUERY_POWER:
+ status = __FdoQuerySystemPower(Fdo, Irp);
+ break;
- default:
- ASSERT(FALSE);
- break;
- }
+ default:
+ IoSkipCurrentIrpStackLocation(Irp);
+ status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
+ break;
}
- return STATUS_SUCCESS;
+ return status;
}
static DECLSPEC_NOINLINE NTSTATUS
FdoDispatchPower(
- IN PXENVIF_FDO Fdo,
+ IN PXENVIF_FDO Fdo,
IN PIRP Irp
)
{
PIO_STACK_LOCATION StackLocation;
- UCHAR MinorFunction;
POWER_STATE_TYPE PowerType;
- POWER_ACTION PowerAction;
NTSTATUS status;
StackLocation = IoGetCurrentIrpStackLocation(Irp);
- MinorFunction = StackLocation->MinorFunction;
-
- if (MinorFunction != IRP_MN_QUERY_POWER &&
- MinorFunction != IRP_MN_SET_POWER) {
- IoSkipCurrentIrpStackLocation(Irp);
- status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
-
- goto done;
- }
-
PowerType = StackLocation->Parameters.Power.Type;
- PowerAction = StackLocation->Parameters.Power.ShutdownType;
-
- if (PowerAction >= PowerActionShutdown) {
- IoSkipCurrentIrpStackLocation(Irp);
- status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
-
- goto done;
- }
switch (PowerType) {
case DevicePowerState:
- IoMarkIrpPending(Irp);
-
- ASSERT3P(Fdo->DevicePowerIrp, ==, NULL);
- Fdo->DevicePowerIrp = Irp;
- KeMemoryBarrier();
-
- ThreadWake(Fdo->DevicePowerThread);
-
- status = STATUS_PENDING;
+ status = __FdoDevicePower(Fdo, Irp);
break;
case SystemPowerState:
- IoMarkIrpPending(Irp);
-
- ASSERT3P(Fdo->SystemPowerIrp, ==, NULL);
- Fdo->SystemPowerIrp = Irp;
- KeMemoryBarrier();
-
- ThreadWake(Fdo->SystemPowerThread);
-
- status = STATUS_PENDING;
+ status = __FdoSystemPower(Fdo, Irp);
break;
default:
break;
}
-done:
return status;
}
Fdo->LowerDeviceObject = IoAttachDeviceToDeviceStack(FunctionDeviceObject,
PhysicalDeviceObject);
- status = ThreadCreate(FdoSystemPower, Fdo, &Fdo->SystemPowerThread);
- if (!NT_SUCCESS(status))
+ Fdo->SystemPowerWorkItem = IoAllocateWorkItem(PhysicalDeviceObject);
+ if (Fdo->SystemPowerWorkItem == NULL)
goto fail3;
- status = ThreadCreate(FdoDevicePower, Fdo, &Fdo->DevicePowerThread);
- if (!NT_SUCCESS(status))
+ Fdo->DevicePowerWorkItem = IoAllocateWorkItem(PhysicalDeviceObject);
+ if (Fdo->DevicePowerWorkItem == NULL)
goto fail4;
status = __FdoAcquireLowerBusInterface(Fdo);
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");
__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);
struct _XENVIF_PDO {
PXENVIF_DX Dx;
- PXENVIF_THREAD SystemPowerThread;
+ PIO_WORKITEM SystemPowerWorkItem;
PIRP SystemPowerIrp;
- PXENVIF_THREAD DevicePowerThread;
+ PIO_WORKITEM DevicePowerWorkItem;
PIRP DevicePowerIrp;
PXENVIF_FDO Fdo;
return status;
}
-static FORCEINLINE NTSTATUS
-__PdoSetDevicePower(
- IN PXENVIF_PDO Pdo,
- IN PIRP Irp
+__drv_functionClass(IO_WORKITEM_ROUTINE)
+__drv_sameIRQL
+static VOID
+PdoDevicePowerWorker(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PVOID Context
)
{
+ PXENVIF_PDO Pdo = (PXENVIF_PDO)Context;
+ PIRP Irp;
PIO_STACK_LOCATION StackLocation;
DEVICE_POWER_STATE DeviceState;
POWER_ACTION PowerAction;
NTSTATUS status;
+ UNREFERENCED_PARAMETER(DeviceObject);
+
+ Irp = InterlockedExchangePointer(&Pdo->DevicePowerIrp, NULL);
+ ASSERT(Irp != NULL);
+
StackLocation = IoGetCurrentIrpStackLocation(Irp);
DeviceState = StackLocation->Parameters.Power.State.DeviceState;
PowerAction = StackLocation->Parameters.Power.ShutdownType;
- Trace("====> (%s) (%s:%s)\n",
- __PdoGetName(Pdo),
- PowerDeviceStateName(DeviceState),
- PowerActionName(PowerAction));
-
- ASSERT3U(PowerAction, <, PowerActionShutdown);
-
+ status = STATUS_SUCCESS;
if (__PdoGetDevicePowerState(Pdo) > DeviceState) {
Trace("%s: POWERING UP: %s -> %s\n",
__PdoGetName(Pdo),
ASSERT3U(DeviceState, ==, PowerDeviceD0);
status = PdoD3ToD0(Pdo);
- ASSERT(NT_SUCCESS(status));
} else if (__PdoGetDevicePowerState(Pdo) < DeviceState) {
Trace("%s: POWERING DOWN: %s -> %s\n",
__PdoGetName(Pdo),
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
- Trace("<==== (%s:%s)\n",
+ Trace("<==== (%s:%s)(%08x)\n",
PowerDeviceStateName(DeviceState),
- PowerActionName(PowerAction));
-
- return STATUS_SUCCESS;
+ PowerActionName(PowerAction),
+ status);
}
-static NTSTATUS
-PdoDevicePower(
- IN PXENVIF_THREAD Self,
- IN PVOID Context
+static FORCEINLINE NTSTATUS
+__PdoSetDevicePower(
+ IN PXENVIF_PDO Pdo,
+ IN PIRP Irp
)
{
- PXENVIF_PDO Pdo = Context;
- PKEVENT Event;
-
- Event = ThreadGetEvent(Self);
-
- for (;;) {
- PIRP Irp;
-
- if (Pdo->DevicePowerIrp == NULL) {
- (VOID) KeWaitForSingleObject(Event,
- Executive,
- KernelMode,
- FALSE,
- NULL);
- KeClearEvent(Event);
- }
+ PIO_STACK_LOCATION StackLocation;
+ DEVICE_POWER_STATE DeviceState;
+ POWER_ACTION PowerAction;
+ PVOID Exchange;
- if (ThreadIsAlerted(Self))
- break;
+ StackLocation = IoGetCurrentIrpStackLocation(Irp);
+ DeviceState = StackLocation->Parameters.Power.State.DeviceState;
+ PowerAction = StackLocation->Parameters.Power.ShutdownType;
- Irp = Pdo->DevicePowerIrp;
+ Trace("====> (%s:%s)\n",
+ PowerDeviceStateName(DeviceState),
+ PowerActionName(PowerAction));
- if (Irp == NULL)
- continue;
+ IoMarkIrpPending(Irp);
- Pdo->DevicePowerIrp = NULL;
- KeMemoryBarrier();
+ Exchange = InterlockedExchangePointer(&Pdo->DevicePowerIrp, Irp);
+ ASSERT(Exchange == NULL);
- (VOID) __PdoSetDevicePower(Pdo, Irp);
- }
+ IoQueueWorkItem(Pdo->DevicePowerWorkItem,
+ PdoDevicePowerWorker,
+ DelayedWorkQueue,
+ Pdo);
- return STATUS_SUCCESS;
+ return STATUS_PENDING;
}
-static FORCEINLINE NTSTATUS
-__PdoSetSystemPower(
- IN PXENVIF_PDO Pdo,
- IN PIRP Irp
+__drv_functionClass(IO_WORKITEM_ROUTINE)
+__drv_sameIRQL
+static VOID
+PdoSystemPowerWorker(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PVOID Context
)
{
- PIO_STACK_LOCATION StackLocation;
- SYSTEM_POWER_STATE SystemState;
- POWER_ACTION PowerAction;
+ PXENVIF_PDO Pdo = (PXENVIF_PDO)Context;
+ PIRP Irp;
+ PIO_STACK_LOCATION StackLocation;
+ SYSTEM_POWER_STATE SystemState;
+ POWER_ACTION PowerAction;
+
+ UNREFERENCED_PARAMETER(DeviceObject);
+
+ Irp = InterlockedExchangePointer(&Pdo->SystemPowerIrp, NULL);
+ ASSERT(Irp != NULL);
StackLocation = IoGetCurrentIrpStackLocation(Irp);
SystemState = StackLocation->Parameters.Power.State.SystemState;
PowerAction = StackLocation->Parameters.Power.ShutdownType;
- Trace("====> (%s) (%s:%s)\n",
- __PdoGetName(Pdo),
- PowerSystemStateName(SystemState),
- PowerActionName(PowerAction));
-
- ASSERT3U(PowerAction, <, PowerActionShutdown);
-
if (__PdoGetSystemPowerState(Pdo) > SystemState) {
if (SystemState < PowerSystemHibernate &&
__PdoGetSystemPowerState(Pdo) >= PowerSystemHibernate) {
__PdoGetName(Pdo),
PowerSystemStateName(__PdoGetSystemPowerState(Pdo)),
PowerSystemStateName(SystemState));
+
} else if (__PdoGetSystemPowerState(Pdo) < SystemState) {
Trace("%s: POWERING DOWN: %s -> %s\n",
__PdoGetName(Pdo),
Trace("<==== (%s:%s)\n",
PowerSystemStateName(SystemState),
PowerActionName(PowerAction));
-
- return STATUS_SUCCESS;
}
-static NTSTATUS
-PdoSystemPower(
- IN PXENVIF_THREAD Self,
- IN PVOID Context
+static FORCEINLINE NTSTATUS
+__PdoSetSystemPower(
+ IN PXENVIF_PDO Pdo,
+ IN PIRP Irp
)
{
- PXENVIF_PDO Pdo = Context;
- PKEVENT Event;
-
- Event = ThreadGetEvent(Self);
-
- for (;;) {
- PIRP Irp;
-
- if (Pdo->SystemPowerIrp == NULL) {
- (VOID) KeWaitForSingleObject(Event,
- Executive,
- KernelMode,
- FALSE,
- NULL);
- KeClearEvent(Event);
- }
+ PIO_STACK_LOCATION StackLocation;
+ SYSTEM_POWER_STATE SystemState;
+ POWER_ACTION PowerAction;
+ PVOID Exchange;
- if (ThreadIsAlerted(Self))
- break;
+ StackLocation = IoGetCurrentIrpStackLocation(Irp);
+ SystemState = StackLocation->Parameters.Power.State.SystemState;
+ PowerAction = StackLocation->Parameters.Power.ShutdownType;
- Irp = Pdo->SystemPowerIrp;
+ Trace("====> (%s:%s)\n",
+ PowerSystemStateName(SystemState),
+ PowerActionName(PowerAction));
- if (Irp == NULL)
- continue;
+ IoMarkIrpPending(Irp);
- Pdo->SystemPowerIrp = NULL;
- KeMemoryBarrier();
+ Exchange = InterlockedExchangePointer(&Pdo->SystemPowerIrp, Irp);
+ ASSERT(Exchange == NULL);
- (VOID) __PdoSetSystemPower(Pdo, Irp);
- }
+ IoQueueWorkItem(Pdo->SystemPowerWorkItem,
+ PdoSystemPowerWorker,
+ DelayedWorkQueue,
+ Pdo);
- return STATUS_SUCCESS;
+ return STATUS_PENDING;
}
-static DECLSPEC_NOINLINE NTSTATUS
-PdoSetPower(
+static FORCEINLINE NTSTATUS
+__PdoSetPower(
IN PXENVIF_PDO Pdo,
IN PIRP Irp
)
{
PIO_STACK_LOCATION StackLocation;
POWER_STATE_TYPE PowerType;
- POWER_ACTION PowerAction;
NTSTATUS status;
StackLocation = IoGetCurrentIrpStackLocation(Irp);
PowerType = StackLocation->Parameters.Power.Type;
- PowerAction = StackLocation->Parameters.Power.ShutdownType;
-
- if (PowerAction >= PowerActionShutdown) {
- Irp->IoStatus.Status = STATUS_SUCCESS;
-
- status = Irp->IoStatus.Status;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- goto done;
- }
switch (PowerType) {
case DevicePowerState:
- IoMarkIrpPending(Irp);
-
- ASSERT3P(Pdo->DevicePowerIrp, ==, NULL);
- Pdo->DevicePowerIrp = Irp;
- KeMemoryBarrier();
-
- ThreadWake(Pdo->DevicePowerThread);
-
- status = STATUS_PENDING;
+ status = __PdoSetDevicePower(Pdo, Irp);
break;
case SystemPowerState:
- IoMarkIrpPending(Irp);
-
- ASSERT3P(Pdo->SystemPowerIrp, ==, NULL);
- Pdo->SystemPowerIrp = Irp;
- KeMemoryBarrier();
-
- ThreadWake(Pdo->SystemPowerThread);
-
- status = STATUS_PENDING;
+ status = __PdoSetSystemPower(Pdo, Irp);
break;
default:
break;
}
-done:
return status;
}
-static DECLSPEC_NOINLINE NTSTATUS
-PdoQueryPower(
- IN PXENVIF_PDO Pdo,
- IN PIRP Irp
+static FORCEINLINE NTSTATUS
+__PdoQueryPower(
+ IN PXENVIF_PDO Pdo,
+ IN PIRP Irp
)
{
- NTSTATUS status;
-
UNREFERENCED_PARAMETER(Pdo);
Irp->IoStatus.Status = STATUS_SUCCESS;
-
- status = Irp->IoStatus.Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- return status;
+
+ return STATUS_SUCCESS;
}
-static DECLSPEC_NOINLINE NTSTATUS
+static NTSTATUS
PdoDispatchPower(
IN PXENVIF_PDO Pdo,
IN PIRP Irp
)
{
PIO_STACK_LOCATION StackLocation;
- UCHAR MinorFunction;
NTSTATUS status;
StackLocation = IoGetCurrentIrpStackLocation(Irp);
- MinorFunction = StackLocation->MinorFunction;
switch (StackLocation->MinorFunction) {
case IRP_MN_SET_POWER:
- status = PdoSetPower(Pdo, Irp);
+ status = __PdoSetPower(Pdo, Irp);
break;
case IRP_MN_QUERY_POWER:
- status = PdoQueryPower(Pdo, Irp);
+ status = __PdoQueryPower(Pdo, Irp);
break;
default:
Pdo->Dx = Dx;
Pdo->Fdo = Fdo;
- status = ThreadCreate(PdoSystemPower, Pdo, &Pdo->SystemPowerThread);
- if (!NT_SUCCESS(status))
+ Pdo->SystemPowerWorkItem = IoAllocateWorkItem(PhysicalDeviceObject);
+ if (Pdo->SystemPowerWorkItem == NULL)
goto fail3;
- status = ThreadCreate(PdoDevicePower, Pdo, &Pdo->DevicePowerThread);
- if (!NT_SUCCESS(status))
+ Pdo->DevicePowerWorkItem = IoAllocateWorkItem(PhysicalDeviceObject);
+ if (Pdo->DevicePowerWorkItem == NULL)
goto fail4;
__PdoSetName(Pdo, Number);
fail5:
Error("fail5\n");
- ThreadAlert(Pdo->DevicePowerThread);
- ThreadJoin(Pdo->DevicePowerThread);
- Pdo->DevicePowerThread = NULL;
+ IoFreeWorkItem(Pdo->DevicePowerWorkItem);
+ Pdo->DevicePowerWorkItem = NULL;
fail4:
Error("fail4\n");
- ThreadAlert(Pdo->SystemPowerThread);
- ThreadJoin(Pdo->SystemPowerThread);
- Pdo->SystemPowerThread = NULL;
+ IoFreeWorkItem(Pdo->SystemPowerWorkItem);
+ Pdo->SystemPowerWorkItem = NULL;
fail3:
Error("fail3\n");
__PdoClearPermanentAddress(Pdo);
- ThreadAlert(Pdo->DevicePowerThread);
- ThreadJoin(Pdo->DevicePowerThread);
- Pdo->DevicePowerThread = NULL;
+ IoFreeWorkItem(Pdo->DevicePowerWorkItem);
+ Pdo->DevicePowerWorkItem = NULL;
- ThreadAlert(Pdo->SystemPowerThread);
- ThreadJoin(Pdo->SystemPowerThread);
- Pdo->SystemPowerThread = NULL;
+ IoFreeWorkItem(Pdo->SystemPowerWorkItem);
+ Pdo->SystemPowerWorkItem = NULL;
Pdo->Fdo = NULL;
Pdo->Dx = NULL;