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