windows-nt/Source/XPSP1/NT/base/busdrv/pccard/memcard/power.c
2020-09-26 16:20:57 +08:00

288 lines
6.2 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
Copyright (c) 1991-1998 Microsoft Corporation
Module Name:
power.c
Abstract:
This module contains code to handle IRP_MJ_POWER dispatches for
PCMCIA memory card devices
Author:
Neil Sandlin (neilsa) 26-Apr-99
Environment:
Kernel mode only.
--*/
#include "pch.h"
NTSTATUS
MemCardSetFdoPowerState(
IN PDEVICE_OBJECT Fdo,
IN OUT PIRP Irp
);
NTSTATUS
MemCardSetFdoSystemPowerState(
IN PDEVICE_OBJECT Fdo,
IN OUT PIRP Irp
);
VOID
MemCardFdoSystemPowerDeviceIrpComplete(
IN PDEVICE_OBJECT Fdo,
IN UCHAR MinorFunction,
IN POWER_STATE PowerState,
IN PVOID Context,
IN PIO_STATUS_BLOCK IoStatus
);
NTSTATUS
MemCardSetFdoDevicePowerState (
IN PDEVICE_OBJECT Fdo,
IN OUT PIRP Irp
);
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE,MemCardPower)
#endif
NTSTATUS
MemCardPower(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
Arguments:
DeviceObject - a pointer to the object that represents the device
that I/O is to be done on.
Irp - a pointer to the I/O Request Packet for this request.
Return Value:
--*/
{
NTSTATUS status = STATUS_SUCCESS;
PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation( Irp );
PMEMCARD_EXTENSION memcardExtension = DeviceObject->DeviceExtension;
MemCardDump( MEMCARDSHOW, ("MemCardPower:\n"));
switch (irpSp->MinorFunction) {
case IRP_MN_SET_POWER:
status = MemCardSetFdoPowerState(DeviceObject, Irp);
break;
case IRP_MN_QUERY_POWER:
//
// No need to send this irp down
//
status = STATUS_SUCCESS;
PoStartNextPowerIrp(Irp);
Irp->IoStatus.Status = status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
break;
default:
PoStartNextPowerIrp( Irp );
IoSkipCurrentIrpStackLocation(Irp);
status = PoCallDriver(memcardExtension->TargetObject, Irp);
break;
}
return status;
}
NTSTATUS
MemCardSetFdoPowerState(
IN PDEVICE_OBJECT Fdo,
IN OUT PIRP Irp
)
/*++
Routine Description
Dispatches the IRP based on whether a system power state
or device power state transition is requested
Arguments
DeviceObject - Pointer to the functional device object for the pcmcia controller
Irp - Pointer to the Irp for the power dispatch
Return value
status
--*/
{
PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
NTSTATUS status;
if (irpStack->Parameters.Power.Type == DevicePowerState) {
status = MemCardSetFdoDevicePowerState(Fdo, Irp);
} else if (irpStack->Parameters.Power.Type == SystemPowerState) {
status = MemCardSetFdoSystemPowerState(Fdo, Irp);
} else {
status = STATUS_NOT_SUPPORTED;
Irp->IoStatus.Status = status;
PoStartNextPowerIrp (Irp);
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
return status;
}
NTSTATUS
MemCardSetFdoSystemPowerState(
IN PDEVICE_OBJECT Fdo,
IN OUT PIRP Irp
)
/*++
Routine Description
Handles system power state IRPs for the pccard controller.
Arguments
DeviceObject - Pointer to the functional device object for the pcmcia controller
Irp - Pointer to the Irp for the power dispatch
Return value
status
--*/
{
PMEMCARD_EXTENSION memcardExtension = Fdo->DeviceExtension;
PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
SYSTEM_POWER_STATE newSystemState = irpStack->Parameters.Power.State.SystemState;
NTSTATUS status = STATUS_SUCCESS;
POWER_STATE powerState;
MemCardDump( MEMCARDSHOW, ("MemCard: Set System Power(%d)\n", newSystemState));
ASSERT(irpStack->Parameters.Power.Type == SystemPowerState);
//
// Find the device power state corresponding to this system state
//
if (newSystemState == PowerSystemWorking) {
powerState.DeviceState = PowerDeviceD0;
} else {
powerState.DeviceState = PowerDeviceD3;
}
//
// Send a D IRP to the stack if necessary
//
MemCardDump( MEMCARDSHOW, ("MemCard: generating D irp (%d)\n", powerState.DeviceState));
status = PoRequestPowerIrp(memcardExtension->DeviceObject,
IRP_MN_SET_POWER,
powerState,
MemCardFdoSystemPowerDeviceIrpComplete,
Irp,
NULL
);
return status;
}
VOID
MemCardFdoSystemPowerDeviceIrpComplete(
IN PDEVICE_OBJECT Fdo,
IN UCHAR MinorFunction,
IN POWER_STATE PowerState,
IN PVOID Context,
IN PIO_STATUS_BLOCK IoStatus
)
/*++
Routine Description
This routine is called on completion of a D irp generated by an S irp.
Parameters
DeviceObject - Pointer to the Fdo for the PCMCIA controller
MinorFunction - Minor function of the IRP_MJ_POWER request
PowerState - Power state requested
Context - Context passed in to the completion routine
IoStatus - Pointer to the status block which will contain
the returned status
Return Value
Status
--*/
{
PMEMCARD_EXTENSION memcardExtension = Fdo->DeviceExtension;
PIRP Irp = Context;
PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
ASSERT(NT_SUCCESS(IoStatus->Status));
PoSetPowerState (Fdo, SystemPowerState, irpStack->Parameters.Power.State);
//
// Send the S IRP to the pdo
//
PoStartNextPowerIrp (Irp);
IoSkipCurrentIrpStackLocation(Irp);
PoCallDriver(memcardExtension->TargetObject, Irp);
}
NTSTATUS
MemCardSetFdoDevicePowerState (
IN PDEVICE_OBJECT Fdo,
IN OUT PIRP Irp
)
/*++
Routine Description
Handles device power state IRPs for the pccard controller.
Arguments
DeviceObject - Pointer to the functional device object for the pcmcia controller
Irp - Pointer to the Irp for the power dispatch
Return value
status
--*/
{
NTSTATUS status;
PMEMCARD_EXTENSION memcardExtension = Fdo->DeviceExtension;
MemCardDump( MEMCARDSHOW, ("MemCard: Set Device Power\n"));
PoStartNextPowerIrp (Irp);
IoSkipCurrentIrpStackLocation(Irp);
status = PoCallDriver(memcardExtension->TargetObject, Irp);
return status;
}