259 lines
6.9 KiB
C
259 lines
6.9 KiB
C
/***************************************************************************
|
||
|
||
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;
|
||
}
|