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