PDEVICE_OBJECT LowerDeviceObject;
PDEVICE_OBJECT PhysicalDeviceObject;
- PXENDISK_THREAD SystemPowerThread;
- PIRP SystemPowerIrp;
- PXENDISK_THREAD DevicePowerThread;
- PIRP DevicePowerIrp;
-
MUTEX Mutex;
ULONG References;
};
return status;
}
-static FORCEINLINE NTSTATUS
-__FdoSetDevicePowerUp(
- IN PXENDISK_FDO Fdo,
- IN PIRP Irp
+__drv_functionClass(IO_COMPLETION_ROUTINE)
+__drv_sameIRQL
+static NTSTATUS
+FdoSetDevicePowerUpComplete(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PVOID Context
)
{
+ PXENDISK_FDO Fdo = (PXENDISK_FDO) Context;
PIO_STACK_LOCATION StackLocation;
- DEVICE_POWER_STATE DeviceState;
- NTSTATUS status;
+ POWER_STATE PowerState;
- StackLocation = IoGetCurrentIrpStackLocation(Irp);
- DeviceState = StackLocation->Parameters.Power.State.DeviceState;
+ UNREFERENCED_PARAMETER(DeviceObject);
- ASSERT3U(DeviceState, <, __FdoGetDevicePowerState(Fdo));
+ StackLocation = IoGetCurrentIrpStackLocation(Irp);
+ PowerState = StackLocation->Parameters.Power.State;
- status = FdoForwardIrpSynchronously(Fdo, Irp);
- if (!NT_SUCCESS(status))
- goto done;
+ if (Irp->PendingReturned)
+ IoMarkIrpPending(Irp);
- Verbose("%p: %s -> %s\n",
- Fdo->Dx->DeviceObject,
- PowerDeviceStateName(__FdoGetDevicePowerState(Fdo)),
- PowerDeviceStateName(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
+__FdoSetDevicePowerUp(
+ IN PXENDISK_FDO Fdo,
+ IN PIRP Irp
+ )
+{
+ IoCopyCurrentIrpStackLocationToNext(Irp);
+ IoSetCompletionRoutine(Irp,
+ FdoSetDevicePowerUpComplete,
+ Fdo,
+ TRUE,
+ TRUE,
+ TRUE);
- return status;
+ return IoCallDriver(Fdo->LowerDeviceObject, Irp);
}
static FORCEINLINE NTSTATUS
)
{
PIO_STACK_LOCATION StackLocation;
- DEVICE_POWER_STATE DeviceState;
- NTSTATUS status;
+ POWER_STATE PowerState;
StackLocation = IoGetCurrentIrpStackLocation(Irp);
- DeviceState = StackLocation->Parameters.Power.State.DeviceState;
-
- ASSERT3U(DeviceState, >, __FdoGetDevicePowerState(Fdo));
-
- Verbose("%p: %s -> %s\n",
- Fdo->Dx->DeviceObject,
- PowerDeviceStateName(__FdoGetDevicePowerState(Fdo)),
- PowerDeviceStateName(DeviceState));
+ PowerState = StackLocation->Parameters.Power.State;
- __FdoSetDevicePowerState(Fdo, DeviceState);
-
- status = FdoForwardIrpSynchronously(Fdo, Irp);
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ __FdoSetDevicePowerState(Fdo, PowerState.DeviceState);
+ PoSetPowerState(Fdo->Dx->DeviceObject,
+ DevicePowerState,
+ PowerState);
- return status;
+ IoSkipCurrentIrpStackLocation(Irp);
+ return IoCallDriver(Fdo->LowerDeviceObject, Irp);
}
+/* IRQL argnostic code, just mark power states.*/
static FORCEINLINE NTSTATUS
__FdoSetDevicePower(
IN PXENDISK_FDO Fdo,
PowerActionName(PowerAction));
if (DeviceState == __FdoGetDevicePowerState(Fdo)) {
- status = FdoForwardIrpSynchronously(Fdo, Irp);
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
+ IoSkipCurrentIrpStackLocation(Irp);
+ status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
goto done;
}
PowerDeviceStateName(DeviceState),
PowerActionName(PowerAction),
status);
+
return status;
}
-static FORCEINLINE NTSTATUS
-__FdoSetSystemPowerUp(
- IN PXENDISK_FDO Fdo,
- IN PIRP Irp
+__drv_functionClass(IO_COMPLETION_ROUTINE)
+__drv_sameIRQL
+static NTSTATUS
+FdoSetSystemPowerUpComplete(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PVOID Context
)
{
+ PXENDISK_FDO Fdo = (PXENDISK_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;
-
- Verbose("%p: %s -> %s\n",
- Fdo->Dx->DeviceObject,
- PowerSystemStateName(__FdoGetSystemPowerState(Fdo)),
- PowerSystemStateName(SystemState));
+ if (Irp->PendingReturned)
+ IoMarkIrpPending(Irp);
__FdoSetSystemPowerState(Fdo, SystemState);
-done:
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_CONTINUE_COMPLETION;
+}
- return status;
+static FORCEINLINE NTSTATUS
+__FdoSetSystemPowerUp(
+ IN PXENDISK_FDO Fdo,
+ IN PIRP Irp
+ )
+{
+ IoCopyCurrentIrpStackLocationToNext(Irp);
+ IoSetCompletionRoutine(Irp,
+ FdoSetSystemPowerUpComplete,
+ Fdo,
+ TRUE,
+ TRUE,
+ TRUE);
+
+ return IoCallDriver(Fdo->LowerDeviceObject, Irp);
}
static FORCEINLINE NTSTATUS
{
PIO_STACK_LOCATION StackLocation;
SYSTEM_POWER_STATE SystemState;
- NTSTATUS status;
StackLocation = IoGetCurrentIrpStackLocation(Irp);
SystemState = StackLocation->Parameters.Power.State.SystemState;
- ASSERT3U(SystemState, >, __FdoGetSystemPowerState(Fdo));
-
- Verbose("%p: %s -> %s\n",
- Fdo->Dx->DeviceObject,
- PowerSystemStateName(__FdoGetSystemPowerState(Fdo)),
- PowerSystemStateName(SystemState));
-
__FdoSetSystemPowerState(Fdo, SystemState);
- status = FdoForwardIrpSynchronously(Fdo, Irp);
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- return status;
+ IoSkipCurrentIrpStackLocation(Irp);
+ return IoCallDriver(Fdo->LowerDeviceObject, Irp);
}
static FORCEINLINE NTSTATUS
__FdoSetSystemPower(
- IN PXENDISK_FDO Fdo,
+ IN PXENDISK_FDO Fdo,
IN PIRP Irp
)
{
PowerActionName(PowerAction));
if (SystemState == __FdoGetSystemPowerState(Fdo)) {
- status = FdoForwardIrpSynchronously(Fdo, Irp);
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
+ IoSkipCurrentIrpStackLocation(Irp);
+ status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
goto done;
}
PowerSystemStateName(SystemState),
PowerActionName(PowerAction),
status);
- return status;
-}
-
-static FORCEINLINE NTSTATUS
-__FdoQueryDevicePowerUp(
- IN PXENDISK_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 FORCEINLINE NTSTATUS
-__FdoQueryDevicePowerDown(
- IN PXENDISK_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 FORCEINLINE NTSTATUS
-__FdoQueryDevicePower(
+static NTSTATUS
+FdoDevicePower(
IN PXENDISK_FDO Fdo,
IN PIRP Irp
)
{
PIO_STACK_LOCATION StackLocation;
- DEVICE_POWER_STATE DeviceState;
- POWER_ACTION PowerAction;
NTSTATUS status;
StackLocation = IoGetCurrentIrpStackLocation(Irp);
- DeviceState = StackLocation->Parameters.Power.State.DeviceState;
- PowerAction = StackLocation->Parameters.Power.ShutdownType;
- Trace("====> (%s:%s)\n",
- PowerDeviceStateName(DeviceState),
- PowerActionName(PowerAction));
-
- if (DeviceState == __FdoGetDevicePowerState(Fdo)) {
- status = FdoForwardIrpSynchronously(Fdo, Irp);
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ switch (StackLocation->MinorFunction) {
+ case IRP_MN_SET_POWER:
+ status = __FdoSetDevicePower(Fdo, Irp);
+ break;
- goto done;
+ default:
+ IoSkipCurrentIrpStackLocation(Irp);
+ status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
+ break;
}
- status = (DeviceState < __FdoGetDevicePowerState(Fdo)) ?
- __FdoQueryDevicePowerUp(Fdo, Irp) :
- __FdoQueryDevicePowerDown(Fdo, Irp);
-
-done:
- Trace("<==== (%s:%s)(%08x)\n",
- PowerDeviceStateName(DeviceState),
- PowerActionName(PowerAction),
- status);
- return status;
-}
-
-static FORCEINLINE NTSTATUS
-__FdoQuerySystemPowerUp(
- IN PXENDISK_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;
}
-static FORCEINLINE NTSTATUS
-__FdoQuerySystemPowerDown(
- IN PXENDISK_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;
-}
-
-static FORCEINLINE NTSTATUS
-__FdoQuerySystemPower(
+static NTSTATUS
+FdoSystemPower(
IN PXENDISK_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)\n",
- PowerSystemStateName(SystemState),
- PowerActionName(PowerAction));
- if (SystemState == __FdoGetSystemPowerState(Fdo)) {
- status = FdoForwardIrpSynchronously(Fdo, Irp);
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ switch (StackLocation->MinorFunction) {
+ case IRP_MN_SET_POWER:
+ status = __FdoSetSystemPower(Fdo, Irp);
+ break;
- goto done;
+ default:
+ IoSkipCurrentIrpStackLocation(Irp);
+ status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
+ break;
}
- status = (SystemState < __FdoGetSystemPowerState(Fdo)) ?
- __FdoQuerySystemPowerUp(Fdo, Irp) :
- __FdoQuerySystemPowerDown(Fdo, Irp);
-
-done:
- Trace("<==== (%s:%s)(%08x)\n",
- PowerSystemStateName(SystemState),
- PowerActionName(PowerAction),
- status);
-
return status;
}
-static NTSTATUS
-FdoDevicePower(
- IN PXENDISK_THREAD Self,
- IN PVOID Context
- )
-{
- PXENDISK_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 PXENDISK_THREAD Self,
- IN PVOID Context
- )
-{
- PXENDISK_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;
-}
-
-__drv_functionClass(IO_COMPLETION_ROUTINE)
-__drv_sameIRQL
-static NTSTATUS
-__FdoDispatchPower(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PVOID Context
- )
-{
- PXENDISK_FDO Fdo = Context;
-
- UNREFERENCED_PARAMETER(DeviceObject);
-
- if (Irp->PendingReturned)
- IoMarkIrpPending(Irp);
-
- IoReleaseRemoveLock(&Fdo->Dx->RemoveLock, Irp);
- return STATUS_SUCCESS;
-}
-
static DECLSPEC_NOINLINE NTSTATUS
FdoDispatchPower(
IN PXENDISK_FDO Fdo,
)
{
PIO_STACK_LOCATION StackLocation;
- UCHAR MinorFunction;
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) {
- IoCopyCurrentIrpStackLocationToNext(Irp);
- IoSetCompletionRoutine(Irp,
- __FdoDispatchPower,
- Fdo,
- TRUE,
- TRUE,
- TRUE);
-
- status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
-
- goto done;
- }
-
PowerType = StackLocation->Parameters.Power.Type;
- Trace("====> (%02x:%s)\n",
- MinorFunction,
- PowerMinorFunctionName(MinorFunction));
-
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:
- IoCopyCurrentIrpStackLocationToNext(Irp);
- IoSetCompletionRoutine(Irp,
- __FdoDispatchPower,
- Fdo,
- TRUE,
- TRUE,
- TRUE);
-
+ IoSkipCurrentIrpStackLocation(Irp);
status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
break;
}
- Trace("<==== (%02x:%s) (%08x)\n",
- MinorFunction,
- PowerMinorFunctionName(MinorFunction),
- status);
-
-done:
- return status;
-
-fail1:
- Error("fail1 (%08x)\n", status);
-
- Irp->IoStatus.Status = status;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
return status;
}
Fdo->PhysicalDeviceObject = PhysicalDeviceObject;
Fdo->LowerDeviceObject = LowerDeviceObject;
- status = ThreadCreate(FdoSystemPower, Fdo, &Fdo->SystemPowerThread);
- if (!NT_SUCCESS(status))
- goto fail4;
-
- status = ThreadCreate(FdoDevicePower, Fdo, &Fdo->DevicePowerThread);
- if (!NT_SUCCESS(status))
- goto fail5;
-
InitializeMutex(&Fdo->Mutex);
InitializeListHead(&Dx->ListEntry);
Fdo->References = 1;
return STATUS_SUCCESS;
-fail5:
- Error("fail5\n");
-
- ThreadAlert(Fdo->SystemPowerThread);
- ThreadJoin(Fdo->SystemPowerThread);
- Fdo->SystemPowerThread = NULL;
-
-fail4:
- Error("fail4\n");
-
- Fdo->PhysicalDeviceObject = NULL;
- Fdo->LowerDeviceObject = NULL;
- Fdo->Dx = NULL;
-
- IoDetachDevice(LowerDeviceObject);
-
fail3:
Error("fail3\n");
RtlZeroMemory(&Fdo->Mutex, sizeof (MUTEX));
- ThreadAlert(Fdo->DevicePowerThread);
- ThreadJoin(Fdo->DevicePowerThread);
- Fdo->DevicePowerThread = NULL;
-
- ThreadAlert(Fdo->SystemPowerThread);
- ThreadJoin(Fdo->SystemPowerThread);
- Fdo->SystemPowerThread = NULL;
-
Fdo->LowerDeviceObject = NULL;
Fdo->PhysicalDeviceObject = NULL;
Fdo->Dx = NULL;
PDEVICE_OBJECT PhysicalDeviceObject;
CHAR Name[MAXNAMELEN];
- PXENDISK_THREAD SystemPowerThread;
- PIRP SystemPowerIrp;
- PXENDISK_THREAD DevicePowerThread;
- PIRP DevicePowerIrp;
-
PXENDISK_FDO Fdo;
BOOLEAN InterceptTrim;
return status;
}
-static FORCEINLINE NTSTATUS
-__PdoSetDevicePowerUp(
- IN PXENDISK_PDO Pdo,
- IN PIRP Irp
+__drv_functionClass(IO_COMPLETION_ROUTINE)
+__drv_sameIRQL
+static NTSTATUS
+PdoSetDevicePowerUpComplete(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PVOID Context
)
{
+ PXENDISK_PDO Pdo = (PXENDISK_PDO) Context;
PIO_STACK_LOCATION StackLocation;
- DEVICE_POWER_STATE DeviceState;
- NTSTATUS status;
+ POWER_STATE PowerState;
- StackLocation = IoGetCurrentIrpStackLocation(Irp);
- DeviceState = StackLocation->Parameters.Power.State.DeviceState;
+ UNREFERENCED_PARAMETER(DeviceObject);
- ASSERT3U(DeviceState, <, __PdoGetDevicePowerState(Pdo));
+ StackLocation = IoGetCurrentIrpStackLocation(Irp);
+ PowerState = StackLocation->Parameters.Power.State;
- status = PdoForwardIrpSynchronously(Pdo, Irp);
- if (!NT_SUCCESS(status))
- goto done;
+ if (Irp->PendingReturned)
+ IoMarkIrpPending(Irp);
- Verbose("%s: %s -> %s\n",
- __PdoGetName(Pdo),
- PowerDeviceStateName(__PdoGetDevicePowerState(Pdo)),
- PowerDeviceStateName(DeviceState));
+ __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
+__PdoSetDevicePowerUp(
+ IN PXENDISK_PDO Pdo,
+ IN PIRP Irp
+ )
+{
+ IoCopyCurrentIrpStackLocationToNext(Irp);
+ IoSetCompletionRoutine(Irp,
+ PdoSetDevicePowerUpComplete,
+ Pdo,
+ TRUE,
+ TRUE,
+ TRUE);
- return status;
+ return IoCallDriver(Pdo->LowerDeviceObject, Irp);
}
static FORCEINLINE NTSTATUS
)
{
PIO_STACK_LOCATION StackLocation;
- DEVICE_POWER_STATE DeviceState;
- NTSTATUS status;
+ POWER_STATE PowerState;
StackLocation = IoGetCurrentIrpStackLocation(Irp);
- DeviceState = StackLocation->Parameters.Power.State.DeviceState;
-
- ASSERT3U(DeviceState, >, __PdoGetDevicePowerState(Pdo));
-
- Verbose("%s: %s -> %s\n",
- __PdoGetName(Pdo),
- PowerDeviceStateName(__PdoGetDevicePowerState(Pdo)),
- PowerDeviceStateName(DeviceState));
+ PowerState = StackLocation->Parameters.Power.State;
- __PdoSetDevicePowerState(Pdo, DeviceState);
-
- status = PdoForwardIrpSynchronously(Pdo, Irp);
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ __PdoSetDevicePowerState(Pdo, PowerState.DeviceState);
+ PoSetPowerState(Pdo->Dx->DeviceObject,
+ DevicePowerState,
+ PowerState);
- return status;
+ IoSkipCurrentIrpStackLocation(Irp);
+ return IoCallDriver(Pdo->LowerDeviceObject, Irp);
}
static FORCEINLINE NTSTATUS
PowerActionName(PowerAction));
if (DeviceState == __PdoGetDevicePowerState(Pdo)) {
- status = PdoForwardIrpSynchronously(Pdo, Irp);
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
+ IoSkipCurrentIrpStackLocation(Irp);
+ status = IoCallDriver(Pdo->LowerDeviceObject, Irp);
goto done;
}
- status = (DeviceState < __PdoGetDevicePowerState(Pdo)) ?
+ status = DeviceState < __PdoGetDevicePowerState(Pdo) ?
__PdoSetDevicePowerUp(Pdo, Irp) :
__PdoSetDevicePowerDown(Pdo, Irp);
PowerDeviceStateName(DeviceState),
PowerActionName(PowerAction),
status);
+
return status;
}
-static FORCEINLINE NTSTATUS
-__PdoSetSystemPowerUp(
- IN PXENDISK_PDO Pdo,
- IN PIRP Irp
+__drv_functionClass(IO_COMPLETION_ROUTINE)
+__drv_sameIRQL
+static NTSTATUS
+PdoSetSystemPowerUpComplete(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PVOID Context
)
{
+ PXENDISK_PDO Pdo = (PXENDISK_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;
-
- Verbose("%s: %s -> %s\n",
- __PdoGetName(Pdo),
- PowerSystemStateName(__PdoGetSystemPowerState(Pdo)),
- PowerSystemStateName(SystemState));
+ if (Irp->PendingReturned)
+ IoMarkIrpPending(Irp);
__PdoSetSystemPowerState(Pdo, SystemState);
-done:
- Irp->IoStatus.Status = status;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_CONTINUE_COMPLETION;
+}
- return status;
+static FORCEINLINE NTSTATUS
+__PdoSetSystemPowerUp(
+ IN PXENDISK_PDO Pdo,
+ IN PIRP Irp
+ )
+{
+ IoCopyCurrentIrpStackLocationToNext(Irp);
+ IoSetCompletionRoutine(Irp,
+ PdoSetSystemPowerUpComplete,
+ Pdo,
+ TRUE,
+ TRUE,
+ TRUE);
+
+ return IoCallDriver(Pdo->LowerDeviceObject, Irp);
}
static FORCEINLINE NTSTATUS
{
PIO_STACK_LOCATION StackLocation;
SYSTEM_POWER_STATE SystemState;
- NTSTATUS status;
StackLocation = IoGetCurrentIrpStackLocation(Irp);
SystemState = StackLocation->Parameters.Power.State.SystemState;
- ASSERT3U(SystemState, >, __PdoGetSystemPowerState(Pdo));
-
- Verbose("%s: %s -> %s\n",
- __PdoGetName(Pdo),
- PowerSystemStateName(__PdoGetSystemPowerState(Pdo)),
- PowerSystemStateName(SystemState));
-
__PdoSetSystemPowerState(Pdo, SystemState);
- status = PdoForwardIrpSynchronously(Pdo, Irp);
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- return status;
+ IoSkipCurrentIrpStackLocation(Irp);
+ return IoCallDriver(Pdo->LowerDeviceObject, Irp);
}
static FORCEINLINE NTSTATUS
PowerActionName(PowerAction));
if (SystemState == __PdoGetSystemPowerState(Pdo)) {
- status = PdoForwardIrpSynchronously(Pdo, Irp);
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
+ IoSkipCurrentIrpStackLocation(Irp);
+ status = IoCallDriver(Pdo->LowerDeviceObject, Irp);
goto done;
}
- status = (SystemState < __PdoGetSystemPowerState(Pdo)) ?
+ status = SystemState < __PdoGetSystemPowerState(Pdo) ?
__PdoSetSystemPowerUp(Pdo, Irp) :
__PdoSetSystemPowerDown(Pdo, Irp);
PowerSystemStateName(SystemState),
PowerActionName(PowerAction),
status);
- return status;
-}
-
-static FORCEINLINE NTSTATUS
-__PdoQueryDevicePowerUp(
- IN PXENDISK_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 FORCEINLINE NTSTATUS
-__PdoQueryDevicePowerDown(
+static NTSTATUS
+PdoDevicePower(
IN PXENDISK_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);
-
- return status;
-}
-
-static FORCEINLINE NTSTATUS
-__PdoQueryDevicePower(
- IN PXENDISK_PDO Pdo,
- IN PIRP Irp
- )
-{
PIO_STACK_LOCATION StackLocation;
- DEVICE_POWER_STATE DeviceState;
- POWER_ACTION PowerAction;
- NTSTATUS status;
StackLocation = IoGetCurrentIrpStackLocation(Irp);
- DeviceState = StackLocation->Parameters.Power.State.DeviceState;
- PowerAction = StackLocation->Parameters.Power.ShutdownType;
- Trace("====> (%s:%s)\n",
- PowerDeviceStateName(DeviceState),
- PowerActionName(PowerAction));
-
- if (DeviceState == __PdoGetDevicePowerState(Pdo)) {
- status = PdoForwardIrpSynchronously(Pdo, Irp);
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ switch (StackLocation->MinorFunction) {
+ case IRP_MN_SET_POWER:
+ status = __PdoSetDevicePower(Pdo, Irp);
+ break;
- goto done;
+ default:
+ IoSkipCurrentIrpStackLocation(Irp);
+ status = IoCallDriver(Pdo->LowerDeviceObject, Irp);
+ break;
}
- status = (DeviceState < __PdoGetDevicePowerState(Pdo)) ?
- __PdoQueryDevicePowerUp(Pdo, Irp) :
- __PdoQueryDevicePowerDown(Pdo, Irp);
-
-done:
- Trace("<==== (%s:%s)(%08x)\n",
- PowerDeviceStateName(DeviceState),
- PowerActionName(PowerAction),
- status);
- return status;
-}
-
-static FORCEINLINE NTSTATUS
-__PdoQuerySystemPowerUp(
- IN PXENDISK_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);
-
return status;
}
-static FORCEINLINE NTSTATUS
-__PdoQuerySystemPowerDown(
+static NTSTATUS
+PdoSystemPower(
IN PXENDISK_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;
-}
-
-static FORCEINLINE NTSTATUS
-__PdoQuerySystemPower(
- IN PXENDISK_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)\n",
- PowerSystemStateName(SystemState),
- PowerActionName(PowerAction));
-
- if (SystemState == __PdoGetSystemPowerState(Pdo)) {
- status = PdoForwardIrpSynchronously(Pdo, Irp);
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ switch (StackLocation->MinorFunction) {
+ case IRP_MN_SET_POWER:
+ status = __PdoSetSystemPower(Pdo, Irp);
+ break;
- goto done;
+ default:
+ IoSkipCurrentIrpStackLocation(Irp);
+ status = IoCallDriver(Pdo->LowerDeviceObject, Irp);
+ break;
}
- status = (SystemState < __PdoGetSystemPowerState(Pdo)) ?
- __PdoQuerySystemPowerUp(Pdo, Irp) :
- __PdoQuerySystemPowerDown(Pdo, Irp);
-
-done:
- Trace("<==== (%s:%s)(%08x)\n",
- PowerSystemStateName(SystemState),
- PowerActionName(PowerAction),
- status);
-
return status;
}
-static NTSTATUS
-PdoDevicePower(
- IN PXENDISK_THREAD Self,
- IN PVOID Context
- )
-{
- PXENDISK_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;
-
- 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;
-
- default:
- ASSERT(FALSE);
- break;
- }
-
- IoReleaseRemoveLock(&Pdo->Dx->RemoveLock, Irp);
- }
-
- return STATUS_SUCCESS;
-}
-
-static NTSTATUS
-PdoSystemPower(
- IN PXENDISK_THREAD Self,
- IN PVOID Context
- )
-{
- PXENDISK_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;
-}
-
-__drv_functionClass(IO_COMPLETION_ROUTINE)
-__drv_sameIRQL
-static NTSTATUS
-__PdoDispatchPower(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PVOID Context
- )
-{
- PXENDISK_PDO Pdo = Context;
-
- UNREFERENCED_PARAMETER(DeviceObject);
-
- if (Irp->PendingReturned)
- IoMarkIrpPending(Irp);
-
- IoReleaseRemoveLock(&Pdo->Dx->RemoveLock, Irp);
- return STATUS_SUCCESS;
-}
-
static DECLSPEC_NOINLINE NTSTATUS
PdoDispatchPower(
- IN PXENDISK_PDO Pdo,
+ IN PXENDISK_PDO Pdo,
IN PIRP Irp
)
{
PIO_STACK_LOCATION StackLocation;
- UCHAR MinorFunction;
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) {
- IoCopyCurrentIrpStackLocationToNext(Irp);
- IoSetCompletionRoutine(Irp,
- __PdoDispatchPower,
- Pdo,
- TRUE,
- TRUE,
- TRUE);
-
- status = IoCallDriver(Pdo->LowerDeviceObject, Irp);
-
- goto done;
- }
-
PowerType = StackLocation->Parameters.Power.Type;
- Trace("====> (%02x:%s)\n",
- MinorFunction,
- PowerMinorFunctionName(MinorFunction));
-
switch (PowerType) {
case DevicePowerState:
- IoMarkIrpPending(Irp);
-
- ASSERT3P(Pdo->DevicePowerIrp, ==, NULL);
- Pdo->DevicePowerIrp = Irp;
- KeMemoryBarrier();
-
- ThreadWake(Pdo->DevicePowerThread);
-
- status = STATUS_PENDING;
+ status = PdoDevicePower(Pdo, Irp);
break;
case SystemPowerState:
- IoMarkIrpPending(Irp);
-
- ASSERT3P(Pdo->SystemPowerIrp, ==, NULL);
- Pdo->SystemPowerIrp = Irp;
- KeMemoryBarrier();
-
- ThreadWake(Pdo->SystemPowerThread);
-
- status = STATUS_PENDING;
+ status = PdoSystemPower(Pdo, Irp);
break;
default:
- IoCopyCurrentIrpStackLocationToNext(Irp);
- IoSetCompletionRoutine(Irp,
- __PdoDispatchPower,
- Pdo,
- TRUE,
- TRUE,
- TRUE);
-
+ IoSkipCurrentIrpStackLocation(Irp);
status = IoCallDriver(Pdo->LowerDeviceObject, Irp);
break;
}
- Trace("<==== (%02x:%s) (%08x)\n",
- MinorFunction,
- PowerMinorFunctionName(MinorFunction),
- status);
-
-done:
- return status;
-
-fail1:
- Error("fail1 (%08x)\n", status);
-
- Irp->IoStatus.Status = status;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
return status;
}
Pdo->PhysicalDeviceObject = PhysicalDeviceObject;
Pdo->LowerDeviceObject = LowerDeviceObject;
- status = ThreadCreate(PdoSystemPower, Pdo, &Pdo->SystemPowerThread);
- if (!NT_SUCCESS(status))
- goto fail4;
-
- status = ThreadCreate(PdoDevicePower, Pdo, &Pdo->DevicePowerThread);
- if (!NT_SUCCESS(status))
- goto fail5;
-
__PdoSetName(Pdo, DeviceID, InstanceID);
ParametersKey = DriverGetParametersKey();
return STATUS_SUCCESS;
-fail5:
- Error("fail5\n");
-
- ThreadAlert(Pdo->SystemPowerThread);
- ThreadJoin(Pdo->SystemPowerThread);
- Pdo->SystemPowerThread = NULL;
-
-fail4:
- Error("fail4\n");
-
- Pdo->PhysicalDeviceObject = NULL;
- Pdo->LowerDeviceObject = NULL;
- Pdo->Dx = NULL;
-
- IoDetachDevice(LowerDeviceObject);
-
fail3:
Error("fail3\n");
RtlZeroMemory(Pdo->Name, sizeof (Pdo->Name));
- ThreadAlert(Pdo->DevicePowerThread);
- ThreadJoin(Pdo->DevicePowerThread);
- Pdo->DevicePowerThread = NULL;
-
- ThreadAlert(Pdo->SystemPowerThread);
- ThreadJoin(Pdo->SystemPowerThread);
- Pdo->SystemPowerThread = NULL;
-
Pdo->PhysicalDeviceObject = NULL;
Pdo->LowerDeviceObject = NULL;
Pdo->Dx = NULL;