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