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;
|
|||
|
}
|