windows-nt/Source/XPSP1/NT/drivers/parallel/parclass/power.c

452 lines
10 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
//
// This file contains functions that handle Power Management IRPs
//
/*++
Copyright (C) Microsoft Corporation, 1998 - 1998
Module Name:
power.c
Abstract:
This file contains routines that handle ParClass Power Management IRPs.
Revision History :
--*/
#include "pch.h"
NTSTATUS
ParPower (
IN PDEVICE_OBJECT pDeviceObject,
IN PIRP pIrp
)
/*++
Routine Description:
This is the ParClass dispatch routine for all Power Management IRPs.
Arguments:
pDeviceObject - represents a parallel device
pIrp - Power IRP
Return Value:
STATUS_SUCCESS - if successful.
!STATUS_SUCCESS - otherwise.
--*/
{
PDEVICE_EXTENSION Extension = pDeviceObject->DeviceExtension;
//
// determine the type of DeviceObject and forward the call as appropriate
//
if( Extension->IsPdo ) {
return ParPdoPower (Extension, pIrp); // this is a PDO (PODOs never get Power IRPs)
} else {
return ParFdoPower (Extension, pIrp); // this is the ParClass FDO
}
}
NTSTATUS
ParPdoPower (
IN PDEVICE_EXTENSION Extension,
IN PIRP pIrp
)
/*++
Routine Description:
This routine handles all Power IRPs for PDOs.
Arguments:
pDeviceObject - represents a parallel device
pIrp - PNP Irp
Return Value:
STATUS_SUCCESS - if successful.
STATUS_UNSUCCESSFUL - otherwise.
--*/
{
POWER_STATE_TYPE powerType;
POWER_STATE powerState;
PIO_STACK_LOCATION pIrpStack;
NTSTATUS status = STATUS_SUCCESS;
ParDump2(PARPOWER, ("ParPdoPower(...)\n") );
pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
powerType = pIrpStack->Parameters.Power.Type;
powerState = pIrpStack->Parameters.Power.State;
switch (pIrpStack->MinorFunction) {
case IRP_MN_QUERY_POWER:
status = STATUS_SUCCESS;
break;
case IRP_MN_SET_POWER:
ParDump2(PARPOWER, ("PARCLASS-PnP Setting %s state to %d\n",
((powerType == SystemPowerState) ? "System" : "Device"),
powerState.SystemState) );
switch (powerType) {
case DevicePowerState:
if (Extension->DeviceState < powerState.DeviceState) {
//
// Powering down
//
if (PowerDeviceD0 == Extension->DeviceState) {
//
// Do the power on stuff here.
//
}
} else if (powerState.DeviceState < Extension->DeviceState) {
//
// Powering Up
//
}
PoSetPowerState (Extension->DeviceObject, powerType, powerState);
Extension->DeviceState = powerState.DeviceState;
break;
case SystemPowerState:
status = STATUS_SUCCESS;
break;
}
break;
default:
status = STATUS_NOT_SUPPORTED;
}
pIrp->IoStatus.Status = status;
PoStartNextPowerIrp (pIrp);
IoCompleteRequest (pIrp, IO_NO_INCREMENT);
return (status);
}
NTSTATUS
ParPowerComplete (
IN PDEVICE_OBJECT pDeviceObject,
IN PIRP pIrp,
IN PDEVICE_EXTENSION Extension
)
/*++
Routine Description:
This routine handles all IRP_MJ_POWER IRPs.
Arguments:
pDeviceObject - represents the port device
pIrp - PNP irp
Extension - Device Extension
Return Value:
Status
--*/
{
POWER_STATE_TYPE powerType;
POWER_STATE powerState;
PIO_STACK_LOCATION pIrpStack;
UNREFERENCED_PARAMETER( pDeviceObject );
ParDump2(PARPOWER, ("Enter ParPowerComplete(...)\n") );
pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
powerType = pIrpStack->Parameters.Power.Type;
powerState = pIrpStack->Parameters.Power.State;
switch (pIrpStack->MinorFunction) {
case IRP_MN_QUERY_POWER:
ASSERTMSG ("Invalid power completion minor code: Query Power\n", FALSE);
break;
case IRP_MN_SET_POWER:
ParDump2(PARPOWER, ("PARCLASS-PnP Setting %s state to %d\n",
((powerType == SystemPowerState) ? "System" : "Device"),
powerState.SystemState) );
switch (powerType) {
case DevicePowerState:
if (Extension->DeviceState < powerState.DeviceState) {
//
// Powering down
//
ASSERTMSG ("Invalid power completion Device Down\n", FALSE);
} else if (powerState.DeviceState < Extension->DeviceState) {
//
// Powering Up
//
if( Extension->IsPdo ) {
// only call for PDOs
PoSetPowerState (Extension->DeviceObject, powerType, powerState);
}
if (PowerDeviceD0 == Extension->DeviceState) {
//
// Do the power on stuff here.
//
}
Extension->DeviceState = powerState.DeviceState;
}
break;
case SystemPowerState:
if (Extension->SystemState < powerState.SystemState) {
//
// Powering down
//
ASSERTMSG ("Invalid power completion System Down\n", FALSE);
} else if (powerState.SystemState < Extension->SystemState) {
//
// Powering Up
//
if (PowerSystemWorking == powerState.SystemState) {
//
// Do the system start up stuff here.
//
powerState.DeviceState = PowerDeviceD0;
PoRequestPowerIrp (Extension->DeviceObject,
IRP_MN_SET_POWER,
powerState,
NULL, // no completion function
NULL, // and no context
NULL);
}
Extension->SystemState = powerState.SystemState;
}
break;
}
break;
default:
ASSERTMSG ("Power Complete: Bad Power State", FALSE);
}
PoStartNextPowerIrp (pIrp);
return STATUS_SUCCESS;
}
NTSTATUS
ParFdoPower (
IN PDEVICE_EXTENSION Extension,
IN PIRP pIrp
)
/*++
Routine Description:
This routine handles all Power IRPs Fdos.
Arguments:
pDeviceObject - represents a parallel device
pIrp - PNP Irp
Return Value:
STATUS_SUCCESS - if successful.
STATUS_UNSUCCESSFUL - otherwise.
--*/
{
POWER_STATE_TYPE powerType;
POWER_STATE powerState;
PIO_STACK_LOCATION pIrpStack;
NTSTATUS status = STATUS_SUCCESS;
BOOLEAN hookit = FALSE;
ParDump2(PARPOWER, ("ParFdoPower(...)\n") );
{
NTSTATUS status = ParAcquireRemoveLock(&Extension->RemoveLock, pIrp);
if (!NT_SUCCESS (status)) {
pIrp->IoStatus.Status = status;
pIrp->IoStatus.Information = 0;
PoStartNextPowerIrp( pIrp );
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return status;
}
}
pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
powerType = pIrpStack->Parameters.Power.Type;
powerState = pIrpStack->Parameters.Power.State;
switch (pIrpStack->MinorFunction) {
case IRP_MN_QUERY_POWER:
status = STATUS_SUCCESS;
break;
case IRP_MN_SET_POWER:
ParDump2(PARPOWER, ("PARCLASS-PnP Setting %s state to %d\n",
((powerType == SystemPowerState) ? "System" : "Device"),
powerState.SystemState) );
switch (powerType) {
case DevicePowerState:
if (Extension->DeviceState < powerState.DeviceState) {
//
// Powering down
//
// Don't call - this is an FDO
// PoSetPowerState (Extension->DeviceObject, powerType, powerState);
if (PowerDeviceD0 == Extension->DeviceState) {
//
// Do the power on stuff here.
//
//
// WORKWORK
//
// We must check to see that our children are in a
// consistent power state.
//
}
Extension->DeviceState = powerState.DeviceState;
} else if (powerState.DeviceState < Extension->DeviceState) {
//
// Powering Up
//
hookit = TRUE;
}
break;
case SystemPowerState:
if (Extension->SystemState < powerState.SystemState) {
//
// Powering down
//
if (PowerSystemWorking == Extension->SystemState) {
//
// Do the system shut down stuff here.
//
}
powerState.DeviceState = PowerDeviceD3;
PoRequestPowerIrp (Extension->DeviceObject,
IRP_MN_SET_POWER,
powerState,
NULL, // no completion function
NULL, // and no context
NULL);
Extension->SystemState = powerState.SystemState;
} else if (powerState.SystemState < Extension->SystemState) {
//
// Powering Up
//
hookit = TRUE;
}
break;
}
break;
default:
status = STATUS_NOT_SUPPORTED;
}
IoCopyCurrentIrpStackLocationToNext (pIrp);
if (!NT_SUCCESS (status)) {
pIrp->IoStatus.Status = status;
PoStartNextPowerIrp (pIrp);
IoCompleteRequest (pIrp, IO_NO_INCREMENT);
} else if (hookit) {
IoSetCompletionRoutine(pIrp, ParPowerComplete, Extension, TRUE, TRUE, TRUE);
status = PoCallDriver(Extension->ParentDeviceObject, pIrp);
} else {
PoStartNextPowerIrp (pIrp);
status = PoCallDriver (Extension->ParentDeviceObject, pIrp);
}
ParReleaseRemoveLock(&Extension->RemoveLock, pIrp);
return status;
}