ULONG Usage[DeviceUsageTypeDumpFile + 1];
BOOLEAN NotDisableable;
- PXENBUS_THREAD SystemPowerThread;
+ PIO_WORKITEM SystemPowerWorkItem;
PIRP SystemPowerIrp;
- PXENBUS_THREAD DevicePowerThread;
+ PIO_WORKITEM DevicePowerWorkItem;
PIRP DevicePowerIrp;
CHAR VendorName[MAXNAMELEN];
return status;
}
+__drv_functionClass(IO_WORKITEM_ROUTINE)
+__drv_sameIRQL
+static VOID
+FdoSetDevcePowerUpWorker(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PVOID Context
+ )
+{
+ PXENBUS_FDO Fdo = (PXENBUS_FDO) Context;
+ PIRP Irp;
+
+ UNREFERENCED_PARAMETER(DeviceObject);
+
+ Irp = InterlockedExchangePointer(&Fdo->DevicePowerIrp, NULL);
+ ASSERT(Irp != NULL);
+
+ (VOID) FdoD3ToD0(Fdo);
+
+ // Cannot change Irp->IoStatus. Continue completion chain.
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+}
+
+__drv_functionClass(IO_COMPLETION_ROUTINE)
+__drv_sameIRQL
static NTSTATUS
-FdoSetDevicePowerUp(
- IN PXENBUS_FDO Fdo,
- IN PIRP Irp
+FdoSetDevicePowerUpComplete(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PVOID Context
)
{
+ PXENBUS_FDO Fdo = (PXENBUS_FDO) Context;
PIO_STACK_LOCATION StackLocation;
DEVICE_POWER_STATE DeviceState;
- NTSTATUS status;
+
+ UNREFERENCED_PARAMETER(DeviceObject);
StackLocation = IoGetCurrentIrpStackLocation(Irp);
DeviceState = StackLocation->Parameters.Power.State.DeviceState;
- ASSERT3U(DeviceState, <, __FdoGetDevicePowerState(Fdo));
-
- status = FdoForwardIrpSynchronously(Fdo, Irp);
- if (!NT_SUCCESS(status))
- goto done;
-
- Info("%s: %s -> %s\n",
- __FdoGetName(Fdo),
+ Info("%s -> %s\n",
DevicePowerStateName(__FdoGetDevicePowerState(Fdo)),
DevicePowerStateName(DeviceState));
ASSERT3U(DeviceState, ==, PowerDeviceD0);
- status = FdoD3ToD0(Fdo);
- ASSERT(NT_SUCCESS(status));
-done:
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ (VOID) InterlockedExchangePointer(&Fdo->DevicePowerIrp, Irp);
- return status;
+ IoQueueWorkItem(Fdo->DevicePowerWorkItem,
+ FdoSetDevcePowerUpWorker,
+ DelayedWorkQueue,
+ Fdo);
+
+ return STATUS_MORE_PROCESSING_REQUIRED;
+}
+
+static NTSTATUS
+FdoSetDevicePowerUp(
+ IN PXENBUS_FDO Fdo,
+ IN PIRP Irp
+ )
+{
+ IoMarkIrpPending(Irp);
+ IoCopyCurrentIrpStackLocationToNext(Irp);
+ IoSetCompletionRoutine(Irp,
+ FdoSetDevicePowerUpComplete,
+ Fdo,
+ TRUE,
+ TRUE,
+ TRUE);
+ IoCallDriver(Fdo->LowerDeviceObject, Irp);
+ return STATUS_PENDING;
+}
+
+__drv_functionClass(IO_WORKITEM_ROUTINE)
+__drv_sameIRQL
+static VOID
+FdoSetDevicePowerDownWorker(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PVOID Context
+ )
+{
+ PXENBUS_FDO Fdo = (PXENBUS_FDO)Context;
+ PIRP Irp;
+
+ UNREFERENCED_PARAMETER(DeviceObject);
+
+ Irp = InterlockedExchangePointer(&Fdo->DevicePowerIrp, NULL);
+ ASSERT(Irp != NULL);
+
+ FdoD0ToD3(Fdo);
+
+ IoCopyCurrentIrpStackLocationToNext(Irp);
+ IoCallDriver(Fdo->LowerDeviceObject, Irp);
}
static NTSTATUS
ASSERT3U(DeviceState, ==, PowerDeviceD3);
- if (__FdoGetDevicePowerState(Fdo) == PowerDeviceD0)
- FdoD0ToD3(Fdo);
+ if (__FdoGetDevicePowerState(Fdo) != PowerDeviceD0) {
+ IoSkipCurrentIrpStackLocation(Irp);
+ status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
- status = FdoForwardIrpSynchronously(Fdo, Irp);
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ goto done;
+ }
+ IoMarkIrpPending(Irp);
+ status = STATUS_PENDING;
+
+ (VOID) InterlockedExchangePointer(&Fdo->DevicePowerIrp, Irp);
+
+ IoQueueWorkItem(Fdo->DevicePowerWorkItem,
+ FdoSetDevicePowerDownWorker,
+ DelayedWorkQueue,
+ Fdo);
+
+done:
return status;
}
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;
}
__drv_functionClass(REQUEST_POWER_COMPLETE)
__drv_sameIRQL
-VOID
-FdoRequestSetDevicePowerCompletion(
+static VOID
+FdoRequestDevicePowerUpComplete(
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_requiresIRQL(PASSIVE_LEVEL)
+__drv_functionClass(IO_WORKITEM_ROUTINE)
+__drv_sameIRQL
static VOID
-FdoRequestSetDevicePower(
- IN PXENBUS_FDO Fdo,
- IN DEVICE_POWER_STATE DeviceState
+FdoSetSystemPowerUpWorker(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PVOID Context
)
{
- POWER_STATE PowerState;
- KEVENT Event;
- NTSTATUS status;
+ PXENBUS_FDO Fdo = (PXENBUS_FDO)Context;
+ PIRP Irp;
+ PIO_STACK_LOCATION StackLocation;
+ SYSTEM_POWER_STATE SystemState;
+ POWER_STATE PowerState;
+ NTSTATUS status;
- Trace("%s\n", DevicePowerStateName(DeviceState));
+ UNREFERENCED_PARAMETER(DeviceObject);
- ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
+ Irp = InterlockedExchangePointer(&Fdo->SystemPowerIrp, NULL);
+ ASSERT(Irp != NULL);
- PowerState.DeviceState = DeviceState;
- KeInitializeEvent(&Event, NotificationEvent, FALSE);
+ __FdoSetSystemPowerState(Fdo, PowerSystemHibernate);
+ FdoS4ToS3(Fdo);
+
+ StackLocation = IoGetCurrentIrpStackLocation(Irp);
+ SystemState = StackLocation->Parameters.Power.State.SystemState;
+
+ Info("%s -> %s\n",
+ SystemPowerStateName(__FdoGetSystemPowerState(Fdo)),
+ SystemPowerStateName(SystemState));
+
+ __FdoSetSystemPowerState(Fdo, SystemState);
+
+ PowerState.DeviceState = Fdo->LowerDeviceCapabilities.DeviceState[SystemState];
status = PoRequestPowerIrp(Fdo->LowerDeviceObject,
IRP_MN_SET_POWER,
PowerState,
- FdoRequestSetDevicePowerCompletion,
- &Event,
+ FdoRequestDevicePowerUpComplete,
+ Irp,
NULL);
- ASSERT(NT_SUCCESS(status));
+ if (!NT_SUCCESS(status))
+ goto fail1;
- (VOID) KeWaitForSingleObject(&Event,
- Executive,
- KernelMode,
- FALSE,
- NULL);
+ return;
+
+fail1:
+ Error("fail1 (%08x)\n", status);
+
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
+__drv_functionClass(IO_COMPLETION_ROUTINE)
+__drv_sameIRQL
static NTSTATUS
-FdoSetSystemPowerUp(
- IN PXENBUS_FDO Fdo,
- IN PIRP Irp
+FdoSetSystemPowerUpComplete(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PVOID Context
)
{
-
+ PXENBUS_FDO Fdo = (PXENBUS_FDO) Context;
PIO_STACK_LOCATION StackLocation;
SYSTEM_POWER_STATE SystemState;
- DEVICE_POWER_STATE DeviceState;
+ POWER_STATE PowerState;
NTSTATUS status;
+ UNREFERENCED_PARAMETER(DeviceObject);
+
StackLocation = IoGetCurrentIrpStackLocation(Irp);
SystemState = StackLocation->Parameters.Power.State.SystemState;
- ASSERT3U(SystemState, <, __FdoGetSystemPowerState(Fdo));
+ if (SystemState < PowerSystemHibernate &&
+ __FdoGetSystemPowerState(Fdo) >= PowerSystemHibernate) {
+
+ (VOID) InterlockedExchangePointer(&Fdo->SystemPowerIrp, Irp);
+
+ IoQueueWorkItem(Fdo->SystemPowerWorkItem,
+ FdoSetSystemPowerUpWorker,
+ DelayedWorkQueue,
+ Fdo);
- status = FdoForwardIrpSynchronously(Fdo, Irp);
- if (!NT_SUCCESS(status))
goto done;
+ }
- Info("%s: %s -> %s\n",
- __FdoGetName(Fdo),
+ Info("%s -> %s\n",
SystemPowerStateName(__FdoGetSystemPowerState(Fdo)),
SystemPowerStateName(SystemState));
- if (SystemState < PowerSystemHibernate &&
- __FdoGetSystemPowerState(Fdo) >= PowerSystemHibernate) {
- __FdoSetSystemPowerState(Fdo, PowerSystemHibernate);
- FdoS4ToS3(Fdo);
- }
-
__FdoSetSystemPowerState(Fdo, SystemState);
- DeviceState = Fdo->LowerDeviceCapabilities.DeviceState[SystemState];
- FdoRequestSetDevicePower(Fdo, DeviceState);
+ PowerState.DeviceState = Fdo->LowerDeviceCapabilities.DeviceState[SystemState];
+
+ status = PoRequestPowerIrp(Fdo->LowerDeviceObject,
+ IRP_MN_SET_POWER,
+ PowerState,
+ FdoRequestDevicePowerUpComplete,
+ Irp,
+ NULL);
+ if (!NT_SUCCESS(status))
+ goto fail1;
done:
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_MORE_PROCESSING_REQUIRED;
- return status;
+fail1:
+ Error("fail1 (%08x)\n", status);
+ return STATUS_CONTINUE_COMPLETION;
}
static NTSTATUS
-FdoSetSystemPowerDown(
+FdoSetSystemPowerUp(
IN PXENBUS_FDO Fdo,
IN PIRP Irp
)
{
+ IoCopyCurrentIrpStackLocationToNext(Irp);
+ IoSetCompletionRoutine(Irp,
+ FdoSetSystemPowerUpComplete,
+ Fdo,
+ TRUE,
+ TRUE,
+ TRUE);
+ return IoCallDriver(Fdo->LowerDeviceObject, Irp);
+}
+
+__drv_functionClass(IO_WORKITEM_ROUTINE)
+__drv_sameIRQL
+static VOID
+FdoSetSystemPowerDownWorker(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PVOID Context
+ )
+{
+ PXENBUS_FDO Fdo = (PXENBUS_FDO)Context;
PIO_STACK_LOCATION StackLocation;
SYSTEM_POWER_STATE SystemState;
- DEVICE_POWER_STATE DeviceState;
- NTSTATUS status;
+ PIRP Irp;
+
+ UNREFERENCED_PARAMETER(DeviceObject);
+
+ Irp = InterlockedExchangePointer(&Fdo->SystemPowerIrp, NULL);
+ ASSERT(Irp != NULL);
StackLocation = IoGetCurrentIrpStackLocation(Irp);
SystemState = StackLocation->Parameters.Power.State.SystemState;
- ASSERT3U(SystemState, >, __FdoGetSystemPowerState(Fdo));
+ __FdoSetSystemPowerState(Fdo, PowerSystemSleeping3);
+ FdoS3ToS4(Fdo);
+ __FdoSetSystemPowerState(Fdo, SystemState);
+
+ IoCopyCurrentIrpStackLocationToNext(Irp);
+ IoCallDriver(Fdo->LowerDeviceObject, Irp);
+}
+
+__drv_functionClass(REQUEST_POWER_COMPLETE)
+__drv_sameIRQL
+static VOID
+FdoRequestDevicePowerDownComplete(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN UCHAR MinorFunction,
+ IN POWER_STATE PowerState,
+ IN PVOID Context,
+ IN PIO_STATUS_BLOCK IoStatus
+ )
+{
+ PIRP Irp = (PIRP) Context;
+ PIO_STACK_LOCATION StackLocation = IoGetCurrentIrpStackLocation(Irp);
+ PDEVICE_OBJECT UpperDeviceObject = StackLocation->DeviceObject;
+ PXENBUS_DX Dx = (PXENBUS_DX)UpperDeviceObject->DeviceExtension;
+ PXENBUS_FDO Fdo = Dx->Fdo;
+ SYSTEM_POWER_STATE SystemState = StackLocation->Parameters.Power.State.SystemState;
+ NTSTATUS status = IoStatus->Status;
- DeviceState = Fdo->LowerDeviceCapabilities.DeviceState[SystemState];
+ UNREFERENCED_PARAMETER(DeviceObject);
+ UNREFERENCED_PARAMETER(MinorFunction);
+ UNREFERENCED_PARAMETER(PowerState);
- FdoRequestSetDevicePower(Fdo, DeviceState);
+ if (!NT_SUCCESS(status))
+ goto fail1;
Info("%s: %s -> %s\n",
__FdoGetName(Fdo),
if (SystemState >= PowerSystemHibernate &&
__FdoGetSystemPowerState(Fdo) < PowerSystemHibernate) {
- __FdoSetSystemPowerState(Fdo, PowerSystemSleeping3);
- FdoS3ToS4(Fdo);
+
+ (VOID) InterlockedExchangePointer(&Fdo->SystemPowerIrp, Irp);
+
+ IoQueueWorkItem(Fdo->SystemPowerWorkItem,
+ FdoSetSystemPowerDownWorker,
+ DelayedWorkQueue,
+ Fdo);
+ goto done;
}
__FdoSetSystemPowerState(Fdo, SystemState);
- status = FdoForwardIrpSynchronously(Fdo, Irp);
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ IoCopyCurrentIrpStackLocationToNext(Irp);
+ IoCallDriver(Fdo->LowerDeviceObject, Irp);
- return status;
+done:
+ return;
+
+fail1:
+ Error("fail1 (%08x)\n", status);
}
static NTSTATUS
-FdoSetSystemPower(
+FdoSetSystemPowerDown(
IN PXENBUS_FDO Fdo,
IN PIRP Irp
)
{
PIO_STACK_LOCATION StackLocation;
SYSTEM_POWER_STATE SystemState;
- POWER_ACTION PowerAction;
+ POWER_STATE PowerState;
NTSTATUS status;
StackLocation = IoGetCurrentIrpStackLocation(Irp);
SystemState = StackLocation->Parameters.Power.State.SystemState;
- PowerAction = StackLocation->Parameters.Power.ShutdownType;
- Trace("====> (%s:%s)\n",
- SystemPowerStateName(SystemState),
- PowerActionName(PowerAction));
+ ASSERT3U(SystemState, >, __FdoGetSystemPowerState(Fdo));
- ASSERT3U(PowerAction, <, PowerActionShutdown);
+ PowerState.DeviceState = Fdo->LowerDeviceCapabilities.DeviceState[SystemState];
- if (SystemState == __FdoGetSystemPowerState(Fdo)) {
- status = FdoForwardIrpSynchronously(Fdo, Irp);
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ if (SystemState >= PowerSystemShutdown) {
+ IoCopyCurrentIrpStackLocationToNext(Irp);
+ status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
goto done;
}
- status = (SystemState < __FdoGetSystemPowerState(Fdo)) ?
- FdoSetSystemPowerUp(Fdo, Irp) :
- FdoSetSystemPowerDown(Fdo, Irp);
+ status = PoRequestPowerIrp(Fdo->LowerDeviceObject,
+ IRP_MN_SET_POWER,
+ PowerState,
+ FdoRequestDevicePowerDownComplete,
+ Irp,
+ NULL);
+ if (!NT_SUCCESS(status))
+ goto fail1;
done:
- Trace("<==== (%s:%s)(%08x)\n",
- SystemPowerStateName(SystemState),
- PowerActionName(PowerAction),
- status);
return status;
-}
-
-static NTSTATUS
-FdoQueryDevicePowerUp(
- IN PXENBUS_FDO Fdo,
- IN PIRP Irp
- )
-{
- PIO_STACK_LOCATION StackLocation;
- DEVICE_POWER_STATE DeviceState;
- NTSTATUS status;
-
- StackLocation = IoGetCurrentIrpStackLocation(Irp);
- DeviceState = StackLocation->Parameters.Power.State.DeviceState;
-
- ASSERT3U(DeviceState, <, __FdoGetDevicePowerState(Fdo));
-
- status = FdoForwardIrpSynchronously(Fdo, Irp);
-
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- return status;
-}
-
-static NTSTATUS
-FdoQueryDevicePowerDown(
- IN PXENBUS_FDO Fdo,
- IN PIRP Irp
- )
-{
- PIO_STACK_LOCATION StackLocation;
- DEVICE_POWER_STATE DeviceState;
- NTSTATUS status;
-
- StackLocation = IoGetCurrentIrpStackLocation(Irp);
- DeviceState = StackLocation->Parameters.Power.State.DeviceState;
-
- ASSERT3U(DeviceState, >, __FdoGetDevicePowerState(Fdo));
-
- status = FdoForwardIrpSynchronously(Fdo, Irp);
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+fail1:
+ Error("fail1 (%08x)\n", status);
return status;
}
static NTSTATUS
-FdoQueryDevicePower(
+FdoSetSystemPower(
IN PXENBUS_FDO Fdo,
IN PIRP Irp
)
{
PIO_STACK_LOCATION StackLocation;
- DEVICE_POWER_STATE DeviceState;
+ SYSTEM_POWER_STATE SystemState;
POWER_ACTION PowerAction;
NTSTATUS status;
StackLocation = IoGetCurrentIrpStackLocation(Irp);
- DeviceState = StackLocation->Parameters.Power.State.DeviceState;
+ SystemState = StackLocation->Parameters.Power.State.SystemState;
PowerAction = StackLocation->Parameters.Power.ShutdownType;
+ IoMarkIrpPending(Irp);
+
Trace("====> (%s:%s)\n",
- DevicePowerStateName(DeviceState),
+ SystemPowerStateName(SystemState),
PowerActionName(PowerAction));
- ASSERT3U(PowerAction, <, PowerActionShutdown);
-
- if (DeviceState == __FdoGetDevicePowerState(Fdo)) {
- status = FdoForwardIrpSynchronously(Fdo, Irp);
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ if (SystemState == __FdoGetSystemPowerState(Fdo)) {
+ IoCopyCurrentIrpStackLocationToNext(Irp);
+ status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
goto done;
}
- status = (DeviceState < __FdoGetDevicePowerState(Fdo)) ?
- FdoQueryDevicePowerUp(Fdo, Irp) :
- FdoQueryDevicePowerDown(Fdo, Irp);
+ status = (SystemState < __FdoGetSystemPowerState(Fdo)) ?
+ FdoSetSystemPowerUp(Fdo, Irp) :
+ FdoSetSystemPowerDown(Fdo, Irp);
done:
Trace("<==== (%s:%s)(%08x)\n",
- DevicePowerStateName(DeviceState),
+ SystemPowerStateName(SystemState),
PowerActionName(PowerAction),
status);
+
return status;
}
__drv_functionClass(REQUEST_POWER_COMPLETE)
__drv_sameIRQL
-VOID
-FdoRequestQueryDevicePowerCompletion(
+static VOID
+FdoRequestQuerySystemPowerUpComplete(
IN PDEVICE_OBJECT DeviceObject,
IN UCHAR MinorFunction,
IN POWER_STATE PowerState,
IN PIO_STATUS_BLOCK IoStatus
)
{
- PKEVENT Event = Context;
+ PIRP Irp = (PIRP) Context;
UNREFERENCED_PARAMETER(DeviceObject);
UNREFERENCED_PARAMETER(MinorFunction);
UNREFERENCED_PARAMETER(PowerState);
- ASSERT(NT_SUCCESS(IoStatus->Status));
-
- KeSetEvent(Event, IO_NO_INCREMENT, FALSE);
+ if (!NT_SUCCESS(IoStatus->Status))
+ Irp->IoStatus.Status = IoStatus->Status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
-__drv_requiresIRQL(PASSIVE_LEVEL)
-static VOID
-FdoRequestQueryDevicePower(
- IN PXENBUS_FDO Fdo,
- IN DEVICE_POWER_STATE DeviceState
+__drv_functionClass(IO_COMPLETION_ROUTINE)
+__drv_sameIRQL
+static NTSTATUS
+FdoQuerySystemPowerUpComplete(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PVOID Context
)
{
- POWER_STATE PowerState;
- KEVENT Event;
- NTSTATUS status;
-
- Trace("%s\n", DevicePowerStateName(DeviceState));
+ PXENBUS_FDO Fdo = (PXENBUS_FDO) Context;
+ PIO_STACK_LOCATION StackLocation;
+ SYSTEM_POWER_STATE SystemState;
+ POWER_STATE PowerState;
+ NTSTATUS status;
- ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
+ UNREFERENCED_PARAMETER(DeviceObject);
- PowerState.DeviceState = DeviceState;
- KeInitializeEvent(&Event, NotificationEvent, FALSE);
+ StackLocation = IoGetCurrentIrpStackLocation(Irp);
+ SystemState = StackLocation->Parameters.Power.State.SystemState;
+ PowerState.DeviceState = Fdo->LowerDeviceCapabilities.DeviceState[SystemState];
status = PoRequestPowerIrp(Fdo->LowerDeviceObject,
IRP_MN_QUERY_POWER,
PowerState,
- FdoRequestQueryDevicePowerCompletion,
- &Event,
+ FdoRequestQuerySystemPowerUpComplete,
+ Irp,
NULL);
- ASSERT(NT_SUCCESS(status));
+ if (!NT_SUCCESS(status))
+ goto fail1;
- (VOID) KeWaitForSingleObject(&Event,
- Executive,
- KernelMode,
- FALSE,
- NULL);
+ return STATUS_MORE_PROCESSING_REQUIRED;
+
+fail1:
+ Error("fail1 (%08x)\n", status);
+ Irp->IoStatus.Status = status;
+
+ return STATUS_CONTINUE_COMPLETION;
}
static NTSTATUS
IN PIRP Irp
)
{
+ IoMarkIrpPending(Irp);
+ IoCopyCurrentIrpStackLocationToNext(Irp);
+ IoSetCompletionRoutine(Irp,
+ FdoQuerySystemPowerUpComplete,
+ Fdo,
+ TRUE,
+ TRUE,
+ TRUE);
+ return IoCallDriver(Fdo->LowerDeviceObject, Irp);
+}
- PIO_STACK_LOCATION StackLocation;
- SYSTEM_POWER_STATE SystemState;
- DEVICE_POWER_STATE DeviceState;
- NTSTATUS status;
-
- StackLocation = IoGetCurrentIrpStackLocation(Irp);
- SystemState = StackLocation->Parameters.Power.State.SystemState;
+__drv_functionClass(REQUEST_POWER_COMPLETE)
+__drv_sameIRQL
+static VOID
+FdoRequestQuerySystemPowerDownComplete(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN UCHAR MinorFunction,
+ IN POWER_STATE PowerState,
+ IN PVOID Context,
+ IN PIO_STATUS_BLOCK IoStatus
+ )
+{
+ PIRP Irp = (PIRP) Context;
+ PIO_STACK_LOCATION StackLocation = IoGetCurrentIrpStackLocation(Irp);
+ PDEVICE_OBJECT UpperDeviceObject = StackLocation->DeviceObject;
+ PXENBUS_DX Dx = (PXENBUS_DX)UpperDeviceObject->DeviceExtension;
+ PXENBUS_FDO Fdo = Dx->Fdo;
- ASSERT3U(SystemState, <, __FdoGetSystemPowerState(Fdo));
+ UNREFERENCED_PARAMETER(DeviceObject);
+ UNREFERENCED_PARAMETER(MinorFunction);
+ UNREFERENCED_PARAMETER(PowerState);
- status = FdoForwardIrpSynchronously(Fdo, Irp);
- if (!NT_SUCCESS(status))
- goto done;
+ if (!NT_SUCCESS(IoStatus->Status))
+ goto fail1;
- DeviceState = Fdo->LowerDeviceCapabilities.DeviceState[SystemState];
+ IoCopyCurrentIrpStackLocationToNext(Irp);
+ IoCallDriver(Fdo->LowerDeviceObject, Irp);
- FdoRequestQueryDevicePower(Fdo, DeviceState);
+ return;
-done:
+fail1:
+ Error("fail1 (%08x)\n", IoStatus->Status);
+ Irp->IoStatus.Status = IoStatus->Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- return status;
}
static NTSTATUS
{
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,
+ FdoRequestQuerySystemPowerDownComplete,
+ Irp,
+ NULL);
+ if (!NT_SUCCESS(status))
+ goto fail1;
- status = FdoForwardIrpSynchronously(Fdo, Irp);
+ IoMarkIrpPending(Irp);
+ return STATUS_PENDING;
+
+fail1:
+ Error("fail1 (%08x)\n", status);
+
+ Irp->IoStatus.Status = status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
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;
}
}
static NTSTATUS
-FdoDevicePower(
- IN PXENBUS_THREAD Self,
- IN PVOID Context
+FdoDispatchDevicePower(
+ IN PXENBUS_FDO Fdo,
+ IN PIRP Irp
)
{
- PXENBUS_FDO Fdo = Context;
- PKEVENT Event;
-
- Event = ThreadGetEvent(Self);
-
- for (;;) {
- PIRP Irp;
- PIO_STACK_LOCATION StackLocation;
- UCHAR MinorFunction;
-
- if (Fdo->DevicePowerIrp == NULL) {
- (VOID) KeWaitForSingleObject(Event,
- Executive,
- KernelMode,
- FALSE,
- NULL);
- KeClearEvent(Event);
- }
-
- if (ThreadIsAlerted(Self))
- break;
-
- Irp = Fdo->DevicePowerIrp;
-
- if (Irp == NULL)
- continue;
-
- Fdo->DevicePowerIrp = NULL;
- KeMemoryBarrier();
-
- StackLocation = IoGetCurrentIrpStackLocation(Irp);
- MinorFunction = StackLocation->MinorFunction;
+ PIO_STACK_LOCATION StackLocation;
+ NTSTATUS status;
- switch (StackLocation->MinorFunction) {
- case IRP_MN_SET_POWER:
- (VOID) FdoSetDevicePower(Fdo, Irp);
- break;
+ StackLocation = IoGetCurrentIrpStackLocation(Irp);
- case IRP_MN_QUERY_POWER:
- (VOID) FdoQueryDevicePower(Fdo, Irp);
- break;
+ switch (StackLocation->MinorFunction) {
+ case IRP_MN_SET_POWER:
+ status = FdoSetDevicePower(Fdo, Irp);
+ break;
- default:
- ASSERT(FALSE);
- break;
- }
+ default:
+ IoSkipCurrentIrpStackLocation(Irp);
+ status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
+ break;
}
- return STATUS_SUCCESS;
+ return status;
}
static NTSTATUS
-FdoSystemPower(
- IN PXENBUS_THREAD Self,
- IN PVOID Context
+FdoDispatchSystemPower(
+ IN PXENBUS_FDO Fdo,
+ IN PIRP Irp
)
{
- PXENBUS_FDO Fdo = Context;
- PKEVENT Event;
-
- Event = ThreadGetEvent(Self);
-
- for (;;) {
- PIRP Irp;
- PIO_STACK_LOCATION StackLocation;
- UCHAR MinorFunction;
-
- if (Fdo->SystemPowerIrp == NULL) {
- (VOID) KeWaitForSingleObject(Event,
- Executive,
- KernelMode,
- FALSE,
- NULL);
- KeClearEvent(Event);
- }
-
- if (ThreadIsAlerted(Self))
- break;
-
- Irp = Fdo->SystemPowerIrp;
-
- if (Irp == NULL)
- continue;
-
- Fdo->SystemPowerIrp = NULL;
- KeMemoryBarrier();
+ PIO_STACK_LOCATION StackLocation;
+ NTSTATUS status;
- StackLocation = IoGetCurrentIrpStackLocation(Irp);
- MinorFunction = StackLocation->MinorFunction;
+ StackLocation = IoGetCurrentIrpStackLocation(Irp);
- switch (StackLocation->MinorFunction) {
- case IRP_MN_SET_POWER:
- (VOID) FdoSetSystemPower(Fdo, Irp);
- break;
+ switch (StackLocation->MinorFunction) {
+ case IRP_MN_SET_POWER:
+ status = FdoSetSystemPower(Fdo, Irp);
+ break;
- case IRP_MN_QUERY_POWER:
- (VOID) FdoQuerySystemPower(Fdo, Irp);
- break;
+ case IRP_MN_QUERY_POWER:
+ status = FdoQuerySystemPower(Fdo, Irp);
+ break;
- default:
- ASSERT(FALSE);
- break;
- }
+ default:
+ IoSkipCurrentIrpStackLocation(Irp);
+ status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
+ break;
}
- return STATUS_SUCCESS;
+ return status;
}
static NTSTATUS
)
{
PIO_STACK_LOCATION StackLocation;
- UCHAR MinorFunction;
POWER_STATE_TYPE PowerType;
POWER_ACTION PowerAction;
NTSTATUS status;
StackLocation = IoGetCurrentIrpStackLocation(Irp);
- MinorFunction = StackLocation->MinorFunction;
-
- if (MinorFunction != IRP_MN_QUERY_POWER &&
- MinorFunction != IRP_MN_SET_POWER) {
- IoSkipCurrentIrpStackLocation(Irp);
- status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
-
- goto done;
- }
-
PowerType = StackLocation->Parameters.Power.Type;
PowerAction = StackLocation->Parameters.Power.ShutdownType;
- if (PowerAction >= PowerActionShutdown) {
- IoSkipCurrentIrpStackLocation(Irp);
- status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
-
- goto done;
- }
-
switch (PowerType) {
case DevicePowerState:
- IoMarkIrpPending(Irp);
-
- ASSERT3P(Fdo->DevicePowerIrp, ==, NULL);
- Fdo->DevicePowerIrp = Irp;
- KeMemoryBarrier();
-
- ThreadWake(Fdo->DevicePowerThread);
-
- status = STATUS_PENDING;
+ status = FdoDispatchDevicePower(Fdo, Irp);
break;
case SystemPowerState:
- IoMarkIrpPending(Irp);
-
- ASSERT3P(Fdo->SystemPowerIrp, ==, NULL);
- Fdo->SystemPowerIrp = Irp;
- KeMemoryBarrier();
-
- ThreadWake(Fdo->SystemPowerThread);
-
- status = STATUS_PENDING;
+ status = FdoDispatchSystemPower(Fdo, Irp);
break;
default:
break;
}
-done:
return status;
}
+
static NTSTATUS
FdoDispatchDefault(
IN PXENBUS_FDO Fdo,
Fdo->LowerDeviceObject = IoAttachDeviceToDeviceStack(FunctionDeviceObject,
PhysicalDeviceObject);
- status = ThreadCreate(FdoSystemPower, Fdo, &Fdo->SystemPowerThread);
- if (!NT_SUCCESS(status))
+ Fdo->SystemPowerWorkItem = IoAllocateWorkItem(FunctionDeviceObject);
+ if (Fdo->SystemPowerWorkItem == NULL)
goto fail3;
- status = ThreadCreate(FdoDevicePower, Fdo, &Fdo->DevicePowerThread);
- if (!NT_SUCCESS(status))
+ Fdo->DevicePowerWorkItem = IoAllocateWorkItem(FunctionDeviceObject);
+ if (Fdo->DevicePowerWorkItem == NULL)
goto fail4;
status = FdoAcquireLowerBusInterface(Fdo);
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 _XENBUS_PDO {
PXENBUS_DX Dx;
- PXENBUS_THREAD SystemPowerThread;
+ PIO_WORKITEM SystemPowerWorkItem;
PIRP SystemPowerIrp;
- PXENBUS_THREAD DevicePowerThread;
+ PIO_WORKITEM DevicePowerWorkItem;
PIRP DevicePowerIrp;
PXENBUS_FDO Fdo;
return status;
}
-static NTSTATUS
-PdoSetDevicePower(
- IN PXENBUS_PDO Pdo,
- IN PIRP Irp
+__drv_functionClass(IO_WORKITEM_ROUTINE)
+__drv_sameIRQL
+static VOID
+PdoSetDevicePowerWorker(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PVOID Context
)
{
+ PXENBUS_PDO Pdo = (PXENBUS_PDO) Context;
+ PIRP Irp;
+ NTSTATUS status;
PIO_STACK_LOCATION StackLocation;
DEVICE_POWER_STATE DeviceState;
POWER_ACTION PowerAction;
+ UNREFERENCED_PARAMETER(DeviceObject);
+
+ Irp = InterlockedExchangePointer(&Pdo->DevicePowerIrp, NULL);
+ ASSERT(Irp != NULL);
+
StackLocation = IoGetCurrentIrpStackLocation(Irp);
DeviceState = StackLocation->Parameters.Power.State.DeviceState;
PowerAction = StackLocation->Parameters.Power.ShutdownType;
- Trace("====> (%s:%s)\n",
- DevicePowerStateName(DeviceState),
- PowerActionName(PowerAction));
-
- ASSERT3U(PowerAction, <, PowerActionShutdown);
-
+ status = STATUS_SUCCESS;
if (__PdoGetDevicePowerState(Pdo) > DeviceState) {
Trace("%s: POWERING UP: %s -> %s\n",
__PdoGetName(Pdo),
DevicePowerStateName(DeviceState));
ASSERT3U(DeviceState, ==, PowerDeviceD0);
- PdoD3ToD0(Pdo);
+ status = PdoD3ToD0(Pdo);
} else if (__PdoGetDevicePowerState(Pdo) < DeviceState) {
Trace("%s: POWERING DOWN: %s -> %s\n",
__PdoGetName(Pdo),
PdoD0ToD3(Pdo);
}
+ if(NT_SUCCESS(status))
+ goto done;
+
+ Error("fail1 (%08x)\n", status);
+ /* TODO - Consider cycling device power at some later point?
+ Need PPO to retry SIRP -> DIRP */
+
+done:
+ /* Cannot fail the IRP at this point, keep going. */
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
Trace("<==== (%s:%s)\n",
DevicePowerStateName(DeviceState),
PowerActionName(PowerAction));
-
- return STATUS_SUCCESS;
}
static NTSTATUS
-PdoDevicePower(
- IN PXENBUS_THREAD Self,
- IN PVOID Context
+PdoSetDevicePower(
+ IN PXENBUS_PDO Pdo,
+ IN PIRP Irp
)
{
- PXENBUS_PDO Pdo = Context;
- PKEVENT Event;
-
- Event = ThreadGetEvent(Self);
-
- for (;;) {
- PIRP Irp;
-
- if (Pdo->DevicePowerIrp == NULL) {
- (VOID) KeWaitForSingleObject(Event,
- Executive,
- KernelMode,
- FALSE,
- NULL);
- KeClearEvent(Event);
- }
+ PIO_STACK_LOCATION StackLocation;
+ DEVICE_POWER_STATE DeviceState;
+ POWER_ACTION PowerAction;
- if (ThreadIsAlerted(Self))
- break;
+ StackLocation = IoGetCurrentIrpStackLocation(Irp);
+ DeviceState = StackLocation->Parameters.Power.State.DeviceState;
+ PowerAction = StackLocation->Parameters.Power.ShutdownType;
- Irp = Pdo->DevicePowerIrp;
+ Trace("====> (%s:%s)\n",
+ DevicePowerStateName(DeviceState),
+ PowerActionName(PowerAction));
- if (Irp == NULL)
- continue;
+ IoMarkIrpPending(Irp);
- Pdo->DevicePowerIrp = NULL;
- KeMemoryBarrier();
+ (VOID) InterlockedExchangePointer(&Pdo->DevicePowerIrp, Irp);
- (VOID) PdoSetDevicePower(Pdo, Irp);
- }
+ IoQueueWorkItem(Pdo->DevicePowerWorkItem,
+ PdoSetDevicePowerWorker,
+ DelayedWorkQueue,
+ Pdo);
- return STATUS_SUCCESS;
+ return STATUS_PENDING;
}
-static NTSTATUS
-PdoSetSystemPower(
- IN PXENBUS_PDO Pdo,
- IN PIRP Irp
+__drv_functionClass(IO_WORKITEM_ROUTINE)
+__drv_sameIRQL
+static VOID
+PdoSetSystemPowerWorker(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PVOID Context
)
{
+ PXENBUS_PDO Pdo = (PXENBUS_PDO) Context;
+ PIRP Irp;
PIO_STACK_LOCATION StackLocation;
SYSTEM_POWER_STATE SystemState;
POWER_ACTION PowerAction;
+ UNREFERENCED_PARAMETER(DeviceObject);
+
+ Irp = InterlockedExchangePointer(&Pdo->SystemPowerIrp, NULL);
+ ASSERT(Irp != NULL);
+
StackLocation = IoGetCurrentIrpStackLocation(Irp);
SystemState = StackLocation->Parameters.Power.State.SystemState;
PowerAction = StackLocation->Parameters.Power.ShutdownType;
- Trace("====> (%s:%s)\n",
- SystemPowerStateName(SystemState),
- PowerActionName(PowerAction));
-
- ASSERT3U(PowerAction, <, PowerActionShutdown);
-
if (__PdoGetSystemPowerState(Pdo) > SystemState) {
if (SystemState < PowerSystemHibernate &&
__PdoGetSystemPowerState(Pdo) >= PowerSystemHibernate) {
Trace("<==== (%s:%s)\n",
SystemPowerStateName(SystemState),
PowerActionName(PowerAction));
-
- return STATUS_SUCCESS;
}
static NTSTATUS
-PdoSystemPower(
- IN PXENBUS_THREAD Self,
- IN PVOID Context
+PdoSetSystemPower(
+ IN PXENBUS_PDO Pdo,
+ IN PIRP Irp
)
{
- PXENBUS_PDO Pdo = Context;
- PKEVENT Event;
-
- Event = ThreadGetEvent(Self);
-
- for (;;) {
- PIRP Irp;
-
- if (Pdo->SystemPowerIrp == NULL) {
- (VOID) KeWaitForSingleObject(Event,
- Executive,
- KernelMode,
- FALSE,
- NULL);
- KeClearEvent(Event);
- }
+ PIO_STACK_LOCATION StackLocation;
+ SYSTEM_POWER_STATE SystemState;
+ POWER_ACTION PowerAction;
- if (ThreadIsAlerted(Self))
- break;
+ StackLocation = IoGetCurrentIrpStackLocation(Irp);
+ SystemState = StackLocation->Parameters.Power.State.SystemState;
+ PowerAction = StackLocation->Parameters.Power.ShutdownType;
- Irp = Pdo->SystemPowerIrp;
+ Trace("====> (%s:%s)\n",
+ SystemPowerStateName(SystemState),
+ PowerActionName(PowerAction));
- if (Irp == NULL)
- continue;
+ IoMarkIrpPending(Irp);
- Pdo->SystemPowerIrp = NULL;
- KeMemoryBarrier();
+ (VOID) InterlockedExchangePointer(&Pdo->SystemPowerIrp, Irp);
- (VOID) PdoSetSystemPower(Pdo, Irp);
- }
+ IoQueueWorkItem(Pdo->SystemPowerWorkItem,
+ PdoSetSystemPowerWorker,
+ DelayedWorkQueue,
+ Pdo);
- return STATUS_SUCCESS;
+ return STATUS_PENDING;
}
static NTSTATUS
-PdoSetPower(
+PdoDispatchSetPower(
IN PXENBUS_PDO Pdo,
IN PIRP Irp
)
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 NTSTATUS
-PdoQueryPower(
- IN PXENBUS_PDO Pdo,
- IN PIRP Irp
- )
-{
- NTSTATUS status;
-
- UNREFERENCED_PARAMETER(Pdo);
-
- status = STATUS_SUCCESS;
-
- Irp->IoStatus.Status = status;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
return status;
}
switch (StackLocation->MinorFunction) {
case IRP_MN_SET_POWER:
- status = PdoSetPower(Pdo, Irp);
- break;
-
- case IRP_MN_QUERY_POWER:
- status = PdoQueryPower(Pdo, Irp);
+ status = PdoDispatchSetPower(Pdo, Irp);
break;
default:
+ /* TODO - Always complete with status success?? */
status = Irp->IoStatus.Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
break;
Pdo->Dx = Dx;
Pdo->Fdo = Fdo;
- status = ThreadCreate(PdoSystemPower, Pdo, &Pdo->SystemPowerThread);
- if (!NT_SUCCESS(status))
+ Pdo->SystemPowerWorkItem = IoAllocateWorkItem(PhysicalDeviceObject);
+ if (Pdo->SystemPowerWorkItem == NULL)
goto fail3;
- status = ThreadCreate(PdoDevicePower, Pdo, &Pdo->DevicePowerThread);
- if (!NT_SUCCESS(status))
+ Pdo->DevicePowerWorkItem = IoAllocateWorkItem(PhysicalDeviceObject);
+ if (Pdo->DevicePowerWorkItem == NULL)
goto fail4;
__PdoSetName(Pdo, Name);
Pdo->Ejectable = FALSE;
Pdo->Removable = FALSE;
- ThreadAlert(Pdo->DevicePowerThread);
- ThreadJoin(Pdo->DevicePowerThread);
- Pdo->DevicePowerThread = NULL;
+ IoFreeWorkItem(Pdo->DevicePowerWorkItem);
+ Pdo->DevicePowerWorkItem = NULL;
fail4:
Error("fail4\n");
- ThreadAlert(Pdo->SystemPowerThread);
- ThreadJoin(Pdo->SystemPowerThread);
- Pdo->SystemPowerThread = NULL;
+ IoFreeWorkItem(Pdo->SystemPowerWorkItem);
+ Pdo->SystemPowerWorkItem = NULL;
fail3:
Error("fail3\n");
Pdo->Ejectable = FALSE;
Pdo->Removable = FALSE;
- ThreadAlert(Pdo->DevicePowerThread);
- ThreadJoin(Pdo->DevicePowerThread);
- Pdo->DevicePowerThread = NULL;
-
- ThreadAlert(Pdo->SystemPowerThread);
- ThreadJoin(Pdo->SystemPowerThread);
- Pdo->SystemPowerThread = NULL;
+ IoFreeWorkItem(Pdo->DevicePowerWorkItem);
+ Pdo->DevicePowerWorkItem = NULL;
+
+ IoFreeWorkItem(Pdo->SystemPowerWorkItem);
+ Pdo->SystemPowerWorkItem = NULL;
Pdo->Fdo = NULL;
Pdo->Dx = NULL;