windows-nt/Source/XPSP1/NT/drivers/serial/serenum/power.c

299 lines
6.6 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++
Copyright (c) 1997 Microsoft Corporation
Module Name:
POWER.C
Abstract:
This module contains contains the power calls for the serenum bus driver.
@@BEGIN_DDKSPLIT
Author:
Jay Senior
@@END_DDKSPLIT
Environment:
kernel mode only
Notes:
@@BEGIN_DDKSPLIT
Revision History:
Louis J. Giliberto, Jr. 07-Jan-2000
@@END_DDKSPLIT
--*/
#include "pch.h"
#ifdef ALLOC_PRAGMA
//#pragma alloc_text (PAGE, Serenum_Power)
//#pragma alloc_text (PAGE, Serenum_FDO_Power)
//#pragma alloc_text (PAGE, Serenum_PDO_Power)
#endif
NTSTATUS
Serenum_FDOPowerComplete (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp,
IN PVOID Context)
/*++
--*/
{
POWER_STATE powerState;
POWER_STATE_TYPE powerType;
PIO_STACK_LOCATION stack;
PFDO_DEVICE_DATA data;
UNREFERENCED_PARAMETER(Context);
if (Irp->PendingReturned) {
IoMarkIrpPending(Irp);
}
data = (PFDO_DEVICE_DATA)DeviceObject->DeviceExtension;
stack = IoGetCurrentIrpStackLocation(Irp);
powerType = stack->Parameters.Power.Type;
powerState = stack->Parameters.Power.State;
switch (stack->MinorFunction) {
case IRP_MN_SET_POWER:
switch (powerType) {
case DevicePowerState:
//
// Powering Up
//
ASSERT(powerState.DeviceState < data->DeviceState);
data->DeviceState = powerState.DeviceState;
PoSetPowerState(data->Self, powerType, powerState);
break;
default:
break;
}
break;
case IRP_MN_QUERY_POWER:
ASSERT(IRP_MN_QUERY_POWER != stack->MinorFunction);
break;
default:
//
// Basically, this is ASSERT(0)
//
ASSERT(0xBADBAD == IRP_MN_QUERY_POWER);
break;
}
PoStartNextPowerIrp(Irp);
Serenum_DecIoCount(data);
return STATUS_SUCCESS; // Continue completion...
}
NTSTATUS
Serenum_FDO_Power(PFDO_DEVICE_DATA Data, PIRP Irp)
/*++
--*/
{
NTSTATUS status;
BOOLEAN hookit = FALSE;
POWER_STATE powerState;
POWER_STATE_TYPE powerType;
PIO_STACK_LOCATION stack;
stack = IoGetCurrentIrpStackLocation(Irp);
powerType = stack->Parameters.Power.Type;
powerState = stack->Parameters.Power.State;
status = Serenum_IncIoCount (Data);
if (!NT_SUCCESS(status)) {
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = status;
PoStartNextPowerIrp(Irp);
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
}
switch (stack->MinorFunction) {
case IRP_MN_SET_POWER:
//
// If it hasn't started, we just pass it through
//
if (Data->Started != TRUE) {
status = Irp->IoStatus.Status = STATUS_SUCCESS;
break;
}
Serenum_KdPrint(Data, SER_DBG_PNP_TRACE,
("Serenum-PnP Setting %s state to %d\n",
((powerType == SystemPowerState) ? "System" : "Device"),
powerState.SystemState));
switch (powerType) {
case DevicePowerState:
status = Irp->IoStatus.Status = STATUS_SUCCESS;
if (Data->DeviceState < powerState.DeviceState) {
PoSetPowerState (Data->Self, powerType, powerState);
Data->DeviceState = powerState.DeviceState;
} else if (Data->DeviceState > powerState.DeviceState) {
//
// Powering Up
//
hookit = TRUE;
}
break;
case SystemPowerState:
//
// status should be STATUS_SUCCESS
//
break;
}
break;
case IRP_MN_QUERY_POWER:
status = Irp->IoStatus.Status = STATUS_SUCCESS;
break;
default:
//
// status should be STATUS_SUCCESS
//
break;
}
IoCopyCurrentIrpStackLocationToNext (Irp);
if (hookit) {
status = Serenum_IncIoCount (Data);
ASSERT (STATUS_SUCCESS == status);
IoSetCompletionRoutine(Irp, Serenum_FDOPowerComplete, NULL, TRUE, TRUE,
TRUE);
status = PoCallDriver (Data->TopOfStack, Irp);
} else {
PoStartNextPowerIrp (Irp);
status = PoCallDriver (Data->TopOfStack, Irp);
}
Serenum_DecIoCount (Data);
return status;
}
NTSTATUS
Serenum_PDO_Power (
PPDO_DEVICE_DATA PdoData,
PIRP Irp
)
/*++
--*/
{
NTSTATUS status = STATUS_SUCCESS;
PIO_STACK_LOCATION stack;
POWER_STATE powerState;
POWER_STATE_TYPE powerType;
stack = IoGetCurrentIrpStackLocation (Irp);
powerType = stack->Parameters.Power.Type;
powerState = stack->Parameters.Power.State;
switch (stack->MinorFunction) {
case IRP_MN_SET_POWER:
switch (powerType) {
case DevicePowerState:
if (PdoData->DeviceState > powerState.DeviceState) {
PoSetPowerState (PdoData->Self, powerType, powerState);
PdoData->DeviceState = powerState.DeviceState;
} else if (PdoData->DeviceState < powerState.DeviceState) {
//
// Powering down.
//
PoSetPowerState (PdoData->Self, powerType, powerState);
PdoData->DeviceState = powerState.DeviceState;
}
break;
case SystemPowerState:
//
// Default to STATUS_SUCCESS
//
break;
default:
status = STATUS_NOT_IMPLEMENTED;
break;
}
break;
case IRP_MN_QUERY_POWER:
//
// Default to STATUS_SUCCESS
//
break;
case IRP_MN_WAIT_WAKE:
case IRP_MN_POWER_SEQUENCE:
status = STATUS_NOT_IMPLEMENTED;
break;
default:
status = Irp->IoStatus.Status;
}
Irp->IoStatus.Status = status;
PoStartNextPowerIrp (Irp);
IoCompleteRequest (Irp, IO_NO_INCREMENT);
return status;
}
NTSTATUS
Serenum_Power (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
--*/
{
PIO_STACK_LOCATION irpStack;
NTSTATUS status;
PCOMMON_DEVICE_DATA commonData;
status = STATUS_SUCCESS;
irpStack = IoGetCurrentIrpStackLocation (Irp);
ASSERT (IRP_MJ_POWER == irpStack->MajorFunction);
commonData = (PCOMMON_DEVICE_DATA) DeviceObject->DeviceExtension;
if (commonData->IsFDO) {
status =
Serenum_FDO_Power ((PFDO_DEVICE_DATA) DeviceObject->DeviceExtension,
Irp);
} else {
status =
Serenum_PDO_Power ((PPDO_DEVICE_DATA) DeviceObject->DeviceExtension,
Irp);
}
return status;
}