windows-nt/Source/XPSP1/NT/drivers/dot4/dot4usb/power.c
2020-09-26 16:20:57 +08:00

259 lines
6.9 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/***************************************************************************
Copyright (c) 2000 Microsoft Corporation
Module Name:
Dot4Usb.sys - Lower Filter Driver for Dot4.sys for USB connected
IEEE 1284.4 devices.
File Name:
Power.c
Abstract:
Power management functions
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) 2000 Microsoft Corporation. All Rights Reserved.
Revision History:
01/18/2000 : created
ToDo in this file:
- code cleanup and documentation
- code review
Author(s):
Joby Lafky (JobyL)
Doug Fritz (DFritz)
****************************************************************************/
#include "pch.h"
VOID
SetPowerIrpCompletion(IN PDEVICE_OBJECT DeviceObject,
IN UCHAR MinorFunction,
IN POWER_STATE PowerState,
IN PVOID Context,
IN PIO_STATUS_BLOCK IoStatus);
NTSTATUS
PowerD0Completion(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context);
NTSTATUS
DispatchPower(
IN PDEVICE_OBJECT DevObj,
IN PIRP Irp
)
{
PDEVICE_EXTENSION devExt = DevObj->DeviceExtension;
PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation( Irp );
NTSTATUS status;
POWER_STATE powerState;
POWER_STATE newState;
POWER_STATE oldState;
BOOLEAN passRequest = TRUE;
TR_VERBOSE(("DispatchPower, MinorFunction = %x", (ULONG)irpSp->MinorFunction));
//
// Acquire RemoveLock to prevent us from being Removed
//
status = IoAcquireRemoveLock( &devExt->RemoveLock, Irp );
if( !NT_SUCCESS(status) )
{
// couldn't aquire RemoveLock - we're in the process of being removed - abort
PoStartNextPowerIrp( Irp );
Irp->IoStatus.Status = status;
IoCompleteRequest( Irp, IO_NO_INCREMENT );
return status;
}
powerState = irpSp->Parameters.Power.State;
switch (irpSp->MinorFunction)
{
case IRP_MN_SET_POWER:
switch(irpSp->Parameters.Power.Type)
{
case SystemPowerState:
// save the current system state
devExt->SystemPowerState = powerState.SystemState;
// map the new system state to a new device state
if(powerState.SystemState != PowerSystemWorking)
{
newState.DeviceState = PowerDeviceD3;
}
else
{
newState.DeviceState = PowerDeviceD0;
}
if(devExt->DevicePowerState != newState.DeviceState)
{
// save the current power Irp for sending down later
devExt->CurrentPowerIrp = Irp;
// send a power Irp to set new device state
status = PoRequestPowerIrp(devExt->Pdo,
IRP_MN_SET_POWER,
newState,
SetPowerIrpCompletion,
(PVOID) devExt,
NULL);
// this will get passed down in the completion routine
passRequest = FALSE;
}
break;
case DevicePowerState:
// Update the current device state.
oldState.DeviceState = devExt->DevicePowerState;
devExt->DevicePowerState = powerState.DeviceState;
// powering up
if(oldState.DeviceState > PowerDeviceD0 &&
powerState.DeviceState == PowerDeviceD0)
{
// we need to know when this completes and our device is at the proper state
IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine(Irp,
PowerD0Completion,
devExt,
TRUE,
TRUE,
TRUE);
status = PoCallDriver(devExt->LowerDevObj, Irp);
// we already passed this one down
passRequest = FALSE;
}
else
{
// powering down, jsut set a flag and pass the request down
if(devExt->PnpState == STATE_STARTED)
{
devExt->PnpState = STATE_SUSPENDED;
}
passRequest = TRUE;
}
break;
}
}
if(passRequest)
{
//
// Send the IRP down the driver stack,
//
IoCopyCurrentIrpStackLocationToNext( Irp );
PoStartNextPowerIrp(Irp);
// release lock
IoReleaseRemoveLock( &devExt->RemoveLock, Irp );
status = PoCallDriver( devExt->LowerDevObj, Irp );
}
return status;
}
VOID
SetPowerIrpCompletion(IN PDEVICE_OBJECT DeviceObject,
IN UCHAR MinorFunction,
IN POWER_STATE PowerState,
IN PVOID Context,
IN PIO_STATUS_BLOCK IoStatus)
{
PDEVICE_EXTENSION devExt;
PIRP irp;
NTSTATUS ntStatus;
UNREFERENCED_PARAMETER( DeviceObject );
UNREFERENCED_PARAMETER( MinorFunction );
UNREFERENCED_PARAMETER( PowerState );
UNREFERENCED_PARAMETER( IoStatus );
devExt = (PDEVICE_EXTENSION) Context;
// get the current power irp
irp = devExt->CurrentPowerIrp;
devExt->CurrentPowerIrp = NULL;
// the requested DevicePowerState Irp has completed, so send the system power Irp down
PoStartNextPowerIrp(irp);
IoCopyCurrentIrpStackLocationToNext(irp);
// mark the Irp pending
IoMarkIrpPending(irp);
// release the lock
IoReleaseRemoveLock( &devExt->RemoveLock, irp );
ntStatus = PoCallDriver(devExt->LowerDevObj, irp);
}
NTSTATUS
PowerD0Completion(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context)
{
PDEVICE_EXTENSION devExt;
NTSTATUS ntStatus;
UNREFERENCED_PARAMETER( DeviceObject );
devExt = (PDEVICE_EXTENSION) Context;
// the device is powered up, set out state
if(devExt->PnpState == STATE_SUSPENDED)
{
devExt->PnpState = STATE_STARTED;
}
ntStatus = Irp->IoStatus.Status;
// release the lock
IoReleaseRemoveLock( &devExt->RemoveLock, Irp );
PoStartNextPowerIrp(Irp);
return ntStatus;
}