|
|
/***************************************************************************
Copyright (c) 2002 Microsoft Corporation
Module Name:
power.C
Abstract:
Power Routines for Smartcard Driver Utility Library
Environment:
Kernel Mode Only
Notes:
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
Copyright (c) 2001 Microsoft Corporation. All Rights Reserved.
Revision History:
05/14/2002 : created
Authors:
Randy Aull
****************************************************************************/
#include "pch.h"
NTSTATUS ScUtil_Power( PDEVICE_OBJECT DeviceObject, PIRP Irp ) { NTSTATUS status = STATUS_UNSUCCESSFUL; PSCUTIL_EXTENSION pExt = *((PSCUTIL_EXTENSION*) DeviceObject->DeviceExtension); PIO_STACK_LOCATION irpStack;
ASSERT(pExt);
PAGED_CODE();
__try { SmartcardDebug(DEBUG_TRACE, ("Enter: ScUtil_Power\n")); irpStack = IoGetCurrentIrpStackLocation(Irp);
status = IoAcquireRemoveLock(pExt->RemoveLock, Irp);
if (!NT_SUCCESS(status)) {
PoStartNextPowerIrp(Irp); Irp->IoStatus.Status = status; IoCompleteRequest(Irp, IO_NO_INCREMENT); __leave;
}
if ((irpStack->MinorFunction != IRP_MN_QUERY_POWER) && (irpStack->MinorFunction != IRP_MN_SET_POWER) ) { // We don't handle these irps
PoStartNextPowerIrp(Irp); IoSkipCurrentIrpStackLocation(Irp);
status = PoCallDriver(pExt->LowerDeviceObject, Irp);
IoReleaseRemoveLock(pExt->RemoveLock, Irp);
__leave; }
switch (irpStack->Parameters.Power.Type) { case DevicePowerState: status = ScUtilDevicePower(DeviceObject, Irp); break; case SystemPowerState:
status = ScUtilSystemPower(DeviceObject, Irp); break; default: break;
}
}
__finally { SmartcardDebug(DEBUG_TRACE, ("Exit: ScUtil_Power (0x%x)\n", status)); }
return status;
}
NTSTATUS ScUtilDevicePower( PDEVICE_OBJECT DeviceObject, PIRP Irp ) /*++
Routine Description: Handles Device Power Irps
Arguments:
Return Value:
--*/ {
NTSTATUS status = STATUS_SUCCESS; PSCUTIL_EXTENSION pExt = *((PSCUTIL_EXTENSION*) DeviceObject->DeviceExtension); PIO_STACK_LOCATION stack; BOOLEAN postWaitWake; POWER_STATE state;
__try {
SmartcardDebug( DEBUG_TRACE, ("ScUtilDevicePower Enter\n"));
stack = IoGetCurrentIrpStackLocation(Irp); state.DeviceState = stack->Parameters.Power.State.DeviceState;
switch (stack->MinorFunction) { case IRP_MN_QUERY_POWER:
//
// Since we can always wait for our irps to complete, so we just always succeed
//
StopIoctls(pExt); IoReleaseRemoveLock(pExt->RemoveLock, Irp);
PoStartNextPowerIrp(Irp);
IoSkipCurrentIrpStackLocation(Irp); status = PoCallDriver(pExt->LowerDeviceObject, Irp);
break;
case IRP_MN_SET_POWER:
if (state.DeviceState < pExt->PowerState) {
//
// We are coming up!! We must let lower drivers power up before we do
//
SmartcardDebug( DEBUG_TRACE, ("ScUtilDevicePower Coming Up!\n")); IoMarkIrpPending(Irp); IoCopyCurrentIrpStackLocationToNext(Irp); IoSetCompletionRoutine(Irp, ScUtilDevicePowerUpCompletion, pExt, TRUE, TRUE, TRUE);
status = PoCallDriver(pExt->LowerDeviceObject, Irp);
status = STATUS_PENDING;
} else {
//
// We are moving to a lower power state, so we handle it before
// passing it down
//
SmartcardDebug( DEBUG_TRACE, ("ScUtilDevicePower Going Down!\n"));
StopIoctls(pExt); DecIoCount(pExt);
KeWaitForSingleObject(&pExt->OkToStop, Executive, KernelMode, FALSE, NULL);
status = pExt->SetPowerState(DeviceObject, state.DeviceState, &postWaitWake); PoSetPowerState(DeviceObject, DevicePowerState, state);
pExt->PowerState = state.DeviceState;
PoStartNextPowerIrp(Irp); IoSkipCurrentIrpStackLocation(Irp);
status = PoCallDriver(pExt->LowerDeviceObject, Irp);
IoReleaseRemoveLock(pExt->RemoveLock, Irp);
} break; default: // We shouldn't be here
ASSERT(FALSE); break; }
}
__finally {
SmartcardDebug( DEBUG_TRACE, ("ScUtilDevicePower Exit : 0x%x\n", status ));
}
return status;
}
NTSTATUS ScUtilSystemPower( PDEVICE_OBJECT DeviceObject, PIRP Irp ) /*++
Routine Description: Handles system power irps
Arguments:
Return Value:
--*/ {
NTSTATUS status = STATUS_SUCCESS; PSCUTIL_EXTENSION pExt = *((PSCUTIL_EXTENSION*) DeviceObject->DeviceExtension);
__try {
SmartcardDebug( DEBUG_TRACE, ("ScUtilSystemPower Enter\n" ));
IoMarkIrpPending(Irp); IoCopyCurrentIrpStackLocationToNext(Irp); IoSetCompletionRoutine(Irp, ScUtilSystemPowerCompletion, pExt, TRUE, TRUE, TRUE);
status = PoCallDriver(pExt->LowerDeviceObject, Irp);
status = STATUS_PENDING;
}
__finally {
SmartcardDebug( DEBUG_TRACE, ("ScUtilSystemPower Exit : 0x%x\n", status ));
}
return status;
}
NTSTATUS ScUtilSystemPowerCompletion( PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context ) /*++
Routine Description: Completion routine called after system power irp has been passed down the stack. handles mapping system state to device state and requests the device power irp.
Arguments:
Return Value:
--*/ {
NTSTATUS status = STATUS_SUCCESS; PSCUTIL_EXTENSION pExt = (PSCUTIL_EXTENSION) Context; PIO_STACK_LOCATION irpStack; POWER_STATE state; POWER_STATE systemState;
__try {
SmartcardDebug( DEBUG_TRACE, ("ScUtilSystemPowerCompletion Enter\n" )); if (!NT_SUCCESS(Irp->IoStatus.Status)) { SmartcardDebug( DEBUG_TRACE, ("ScUtilSystemPowerCompletion SIRP failed by lower driver\n" ));
PoStartNextPowerIrp(Irp); IoCompleteRequest(Irp, IO_NO_INCREMENT); status = Irp->IoStatus.Status; IoReleaseRemoveLock(pExt->RemoveLock, Irp);
__leave; }
irpStack = IoGetCurrentIrpStackLocation(Irp);
systemState = irpStack->Parameters.Power.State; state.DeviceState = pExt->DeviceCapabilities.DeviceState[systemState.SystemState];
if (systemState.DeviceState != PowerSystemWorking) { // Wait for D IRP completion
status = PoRequestPowerIrp(DeviceObject, irpStack->MinorFunction, state, ScUtilDeviceRequestCompletion, (PVOID) Irp, NULL);
if (!NT_SUCCESS(status)) { PoStartNextPowerIrp(Irp); Irp->IoStatus.Status = status; IoCompleteRequest(Irp, IO_NO_INCREMENT); IoReleaseRemoveLock(pExt->RemoveLock, Irp);
status = STATUS_PENDING; __leave;
} status = STATUS_MORE_PROCESSING_REQUIRED;
} else {
// Don't wait for completion of D irp to speed up resume time
status = PoRequestPowerIrp(DeviceObject, irpStack->MinorFunction, state, NULL, NULL, NULL);
if (!NT_SUCCESS(status)) {
Irp->IoStatus.Status = status; status = STATUS_PENDING;
PoStartNextPowerIrp(Irp); IoCompleteRequest(Irp, IO_NO_INCREMENT); } else { PoStartNextPowerIrp(Irp);
}
IoReleaseRemoveLock(pExt->RemoveLock, Irp);
}
}
__finally {
SmartcardDebug( DEBUG_TRACE, ("ScUtilSystemPowerCompletion Exit : 0x%x\n", status ));
}
return status;
}
VOID ScUtilDeviceRequestCompletion( PDEVICE_OBJECT DeviceObject, UCHAR MinorFunction, POWER_STATE PowerState, PVOID Context, PIO_STATUS_BLOCK IoStatus ) /*++
Routine Description: Completion routine called after device power irp completes. Completes the system power irp.
Arguments:
Return Value:
--*/ {
NTSTATUS status = STATUS_SUCCESS; PSCUTIL_EXTENSION pExt = *((PSCUTIL_EXTENSION*) DeviceObject->DeviceExtension); PIRP irp;
__try {
SmartcardDebug( DEBUG_TRACE, ("ScUtilDeviceRequestCompletion Enter\n" ));
irp = (PIRP) Context;
PoStartNextPowerIrp(irp); irp->IoStatus.Status = IoStatus->Status; IoCompleteRequest(irp, IO_NO_INCREMENT);
IoReleaseRemoveLock(pExt->RemoveLock, irp);
}
__finally {
SmartcardDebug( DEBUG_TRACE, ("ScUtilDeviceRequestCompletion Exit : 0x%x\n", status ));
}
return;
}
NTSTATUS ScUtilDevicePowerUpCompletion( PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context ) /*++
Routine Description: Completion routine called after device irp for higher power state has been passed down the stack.
Arguments:
Return Value:
--*/ {
NTSTATUS status = STATUS_SUCCESS; PSCUTIL_EXTENSION pExt = *((PSCUTIL_EXTENSION*) DeviceObject->DeviceExtension); PIO_STACK_LOCATION irpStack; BOOLEAN postWaitWake; // We don't really care about this
__try {
SmartcardDebug( DEBUG_TRACE, ("ScUtilDevicePowerUpCompletion Enter\n" ));
irpStack = IoGetCurrentIrpStackLocation(Irp); status = pExt->SetPowerState(DeviceObject, irpStack->Parameters.Power.State.DeviceState, &postWaitWake); pExt->PowerState = irpStack->Parameters.Power.State.DeviceState; IncIoCount(pExt); StartIoctls(pExt);
PoSetPowerState(DeviceObject, DevicePowerState, irpStack->Parameters.Power.State);
PoStartNextPowerIrp(Irp); }
__finally {
IoReleaseRemoveLock(pExt->RemoveLock, Irp);
SmartcardDebug( DEBUG_TRACE, ("ScUtilDevicePowerUpCompletion Exit : 0x%x\n", status ));
}
return status;
}
|