697 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			697 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*--------------------------------------------------------------------------
 | 
						||
*
 | 
						||
*   Copyright (C) Cyclades Corporation, 2000-2001.
 | 
						||
*   All rights reserved.
 | 
						||
*
 | 
						||
*   Cyclades-Z Enumerator Driver
 | 
						||
*	
 | 
						||
*   This file:      power.c
 | 
						||
*
 | 
						||
*   Description:    This module contains contains the power calls 
 | 
						||
*                   for the cyclades-Z bus driver.
 | 
						||
*					
 | 
						||
*   Notes:          This code supports Windows 2000 and Windows XP, 
 | 
						||
*                   x86 and ia64 processors.
 | 
						||
*
 | 
						||
*   Complies with Cyclades SW Coding Standard rev 1.3.
 | 
						||
*
 | 
						||
*--------------------------------------------------------------------------
 | 
						||
*/
 | 
						||
 | 
						||
/*-------------------------------------------------------------------------
 | 
						||
*
 | 
						||
*	Change History
 | 
						||
*
 | 
						||
*--------------------------------------------------------------------------
 | 
						||
*   Initial implementation based on Microsoft sample code.
 | 
						||
*
 | 
						||
*--------------------------------------------------------------------------
 | 
						||
*/
 | 
						||
 | 
						||
#include "pch.h"
 | 
						||
 | 
						||
#ifdef ALLOC_PRAGMA
 | 
						||
//#pragma alloc_text (PAGE, Cycladz_Power)
 | 
						||
//#pragma alloc_text (PAGE, Cycladz_FDO_Power)
 | 
						||
//#pragma alloc_text (PAGE, Cycladz_PDO_Power)
 | 
						||
#endif
 | 
						||
 | 
						||
 | 
						||
typedef struct _POWER_COMPLETION_CONTEXT {
 | 
						||
 | 
						||
    PDEVICE_OBJECT  DeviceObject;
 | 
						||
    PIRP            SIrp;
 | 
						||
 | 
						||
} POWER_COMPLETION_CONTEXT, *PPOWER_COMPLETION_CONTEXT;
 | 
						||
 | 
						||
 | 
						||
VOID
 | 
						||
OnPowerRequestComplete(
 | 
						||
    PDEVICE_OBJECT DeviceObject,
 | 
						||
    UCHAR MinorFunction,
 | 
						||
    POWER_STATE state,
 | 
						||
    POWER_COMPLETION_CONTEXT* PowerContext,
 | 
						||
    PIO_STATUS_BLOCK IoStatus
 | 
						||
    )
 | 
						||
/*++
 | 
						||
 | 
						||
Routine Description:
 | 
						||
 | 
						||
   Completion routine for D-IRP.
 | 
						||
 | 
						||
Arguments:
 | 
						||
 | 
						||
 | 
						||
Return Value:
 | 
						||
 | 
						||
   NT status code
 | 
						||
 | 
						||
--*/
 | 
						||
{
 | 
						||
    PFDO_DEVICE_DATA   fdoData = (PFDO_DEVICE_DATA) PowerContext->DeviceObject->DeviceExtension;
 | 
						||
    PIRP        sIrp = PowerContext->SIrp;
 | 
						||
 | 
						||
    UNREFERENCED_PARAMETER (DeviceObject);
 | 
						||
    UNREFERENCED_PARAMETER (MinorFunction);
 | 
						||
    UNREFERENCED_PARAMETER (state);
 | 
						||
 | 
						||
    Cycladz_KdPrint(fdoData,SER_DBG_POWER_TRACE, (">OnPowerRequestComplete\n"));
 | 
						||
 | 
						||
    //
 | 
						||
    // Here we copy the D-IRP status into the S-IRP
 | 
						||
    //
 | 
						||
    sIrp->IoStatus.Status = IoStatus->Status;
 | 
						||
 | 
						||
    //
 | 
						||
    // Release the IRP
 | 
						||
    //
 | 
						||
    PoStartNextPowerIrp(sIrp);
 | 
						||
    IoCompleteRequest(sIrp, IO_NO_INCREMENT);
 | 
						||
 | 
						||
    //
 | 
						||
    // Cleanup
 | 
						||
    //
 | 
						||
    ExFreePool(PowerContext);
 | 
						||
    Cycladz_DecIoCount(fdoData);
 | 
						||
 | 
						||
    Cycladz_KdPrint(fdoData,SER_DBG_POWER_TRACE, ("<OnPowerRequestComplete\n"));
 | 
						||
 | 
						||
}
 | 
						||
 | 
						||
NTSTATUS
 | 
						||
Cycladz_FDOSystemPowerComplete (
 | 
						||
    IN PDEVICE_OBJECT DeviceObject,
 | 
						||
    IN PIRP Irp,
 | 
						||
    IN PVOID Context
 | 
						||
    )
 | 
						||
/*++
 | 
						||
--*/
 | 
						||
{
 | 
						||
    POWER_COMPLETION_CONTEXT* powerContext;
 | 
						||
    POWER_STATE         powerState;
 | 
						||
    POWER_STATE_TYPE    powerType;
 | 
						||
    PIO_STACK_LOCATION  stack;
 | 
						||
    PFDO_DEVICE_DATA    data;
 | 
						||
    NTSTATUS    status = Irp->IoStatus.Status;
 | 
						||
 | 
						||
    UNREFERENCED_PARAMETER (Context);
 | 
						||
 | 
						||
    data = (PFDO_DEVICE_DATA) DeviceObject->DeviceExtension;
 | 
						||
 | 
						||
    Cycladz_KdPrint(data,SER_DBG_POWER_TRACE, (">SystemPowerComplete\n"));
 | 
						||
 | 
						||
    if (!NT_SUCCESS(status)) {
 | 
						||
 | 
						||
        PoStartNextPowerIrp(Irp);
 | 
						||
        Cycladz_DecIoCount (data);    
 | 
						||
        Cycladz_KdPrint(data,SER_DBG_POWER_TRACE, ("<SystemPowerComplete1\n"));
 | 
						||
        return STATUS_SUCCESS;
 | 
						||
    }
 | 
						||
 | 
						||
    stack = IoGetCurrentIrpStackLocation (Irp);
 | 
						||
    powerState = stack->Parameters.Power.State;
 | 
						||
                        
 | 
						||
    switch (stack->Parameters.Power.State.SystemState) {
 | 
						||
    case PowerSystemUnspecified:
 | 
						||
        powerState.DeviceState = PowerDeviceUnspecified;
 | 
						||
        break;
 | 
						||
 | 
						||
    case PowerSystemWorking:
 | 
						||
        powerState.DeviceState = PowerDeviceD0;
 | 
						||
        break;
 | 
						||
 | 
						||
    case PowerSystemSleeping1:
 | 
						||
    case PowerSystemSleeping2:
 | 
						||
    case PowerSystemSleeping3:
 | 
						||
    case PowerSystemHibernate:
 | 
						||
    case PowerSystemShutdown:
 | 
						||
    case PowerSystemMaximum:
 | 
						||
        powerState.DeviceState = PowerDeviceD3;
 | 
						||
        break;
 | 
						||
 | 
						||
    default:
 | 
						||
        powerState.DeviceState = PowerDeviceD3;
 | 
						||
    }
 | 
						||
 | 
						||
    //
 | 
						||
    // Send IRP to change device state
 | 
						||
    //
 | 
						||
    powerContext = (POWER_COMPLETION_CONTEXT*)
 | 
						||
                ExAllocatePool(NonPagedPool, sizeof(POWER_COMPLETION_CONTEXT));
 | 
						||
 | 
						||
    if (!powerContext) {
 | 
						||
 | 
						||
        status = STATUS_INSUFFICIENT_RESOURCES;
 | 
						||
 | 
						||
    } else {
 | 
						||
 | 
						||
        powerContext->DeviceObject = DeviceObject;
 | 
						||
        powerContext->SIrp = Irp;
 | 
						||
 | 
						||
        status = PoRequestPowerIrp(data->Self, IRP_MN_SET_POWER, powerState, OnPowerRequestComplete, 
 | 
						||
                                   powerContext, NULL);
 | 
						||
    }
 | 
						||
 | 
						||
    if (!NT_SUCCESS(status)) {
 | 
						||
 | 
						||
        Cycladz_KdPrint(data,SER_DBG_POWER_TRACE, ("PoRequestPowerIrp %x\n",status));
 | 
						||
        if (powerContext) {
 | 
						||
            ExFreePool(powerContext);
 | 
						||
        }
 | 
						||
 | 
						||
        PoStartNextPowerIrp(Irp);
 | 
						||
        Irp->IoStatus.Status = status;
 | 
						||
        //IoCompleteRequest(Irp, IO_NO_INCREMENT); Toaster has this line.
 | 
						||
        Cycladz_DecIoCount(data);
 | 
						||
        Cycladz_KdPrint(data,SER_DBG_POWER_TRACE, ("<2SystemPowerComplete\n"));
 | 
						||
        return status;
 | 
						||
    }
 | 
						||
 | 
						||
    Cycladz_KdPrint(data,SER_DBG_POWER_TRACE, ("<3SystemPowerComplete\n"));
 | 
						||
    return STATUS_MORE_PROCESSING_REQUIRED;
 | 
						||
 | 
						||
}
 | 
						||
 | 
						||
VOID
 | 
						||
Cycladz_PowerOnWorkItem(
 | 
						||
    IN PDEVICE_OBJECT DeviceObject,
 | 
						||
    IN PVOID Context
 | 
						||
)
 | 
						||
/*++
 | 
						||
 | 
						||
Routine Description:
 | 
						||
 | 
						||
    This routine starts the Z hardware.
 | 
						||
 | 
						||
Arguments:
 | 
						||
 | 
						||
Return Value:
 | 
						||
 | 
						||
   NT status code
 | 
						||
 | 
						||
--*/
 | 
						||
{
 | 
						||
    PIRP                    Irp;
 | 
						||
    PFDO_DEVICE_DATA        fdoData;
 | 
						||
    PWORKER_THREAD_CONTEXT  context = (PWORKER_THREAD_CONTEXT)Context;
 | 
						||
 | 
						||
    fdoData = (PFDO_DEVICE_DATA) DeviceObject->DeviceExtension;
 | 
						||
 | 
						||
    Cycladz_KdPrint(fdoData,SER_DBG_CYCLADES, (">Cycladz_PowerOnWorkItem Irp %x\n",context->Irp));
 | 
						||
 | 
						||
    Irp = context->Irp;
 | 
						||
 | 
						||
    Cycladz_DoesBoardExist(fdoData);
 | 
						||
 | 
						||
    PoSetPowerState (DeviceObject, context->PowerType, context->PowerState);
 | 
						||
 | 
						||
    PoStartNextPowerIrp (Irp);
 | 
						||
 | 
						||
    IoCompleteRequest (context->Irp, IO_NO_INCREMENT);
 | 
						||
 | 
						||
    //
 | 
						||
    // Cleanup before exiting from the worker thread.
 | 
						||
    //
 | 
						||
    IoFreeWorkItem(context->WorkItem);
 | 
						||
    ExFreePool((PVOID)context);
 | 
						||
 | 
						||
    Cycladz_KdPrint(fdoData,SER_DBG_CYCLADES, ("<Cycladz_PowerOnWorkItem\n"));
 | 
						||
 | 
						||
    Cycladz_DecIoCount (fdoData);
 | 
						||
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
NTSTATUS
 | 
						||
Cycladz_FDOPowerComplete (
 | 
						||
    IN PDEVICE_OBJECT DeviceObject,
 | 
						||
    IN PIRP Irp,
 | 
						||
    IN PVOID Context
 | 
						||
    )
 | 
						||
/*++
 | 
						||
--*/
 | 
						||
{
 | 
						||
    PIO_WORKITEM            item;
 | 
						||
    PWORKER_THREAD_CONTEXT  context;
 | 
						||
    POWER_STATE         powerState;
 | 
						||
    POWER_STATE_TYPE    powerType;
 | 
						||
    PIO_STACK_LOCATION  stack;
 | 
						||
    PFDO_DEVICE_DATA    data;
 | 
						||
    //NTSTATUS            status = STATUS_SUCCESS;    //Removed in build 2072
 | 
						||
 | 
						||
    UNREFERENCED_PARAMETER (Context);
 | 
						||
 | 
						||
#if 0
 | 
						||
    if (Irp->PendingReturned) {  
 | 
						||
        IoMarkIrpPending(Irp);
 | 
						||
    }
 | 
						||
#endif
 | 
						||
 | 
						||
    data = (PFDO_DEVICE_DATA) DeviceObject->DeviceExtension;
 | 
						||
    stack = IoGetCurrentIrpStackLocation (Irp);
 | 
						||
    powerType = stack->Parameters.Power.Type;
 | 
						||
    powerState = stack->Parameters.Power.State;
 | 
						||
 | 
						||
    Cycladz_KdPrint(data,SER_DBG_CYCLADES, ("In Cycladz_FDOPowerComplete Irp %x\n",Irp));
 | 
						||
    
 | 
						||
    switch (stack->MinorFunction) {
 | 
						||
    case IRP_MN_SET_POWER:
 | 
						||
        switch (powerType) {
 | 
						||
        case DevicePowerState:
 | 
						||
 | 
						||
            Cycladz_KdPrint(data,SER_DBG_CYCLADES, ("IRP_MN_SET_POWER Device\n"));
 | 
						||
 | 
						||
            //
 | 
						||
            // Powering Up
 | 
						||
            // 
 | 
						||
            ASSERT (powerState.DeviceState < data->DeviceState);
 | 
						||
 | 
						||
            context = ExAllocatePool (NonPagedPool,
 | 
						||
                                      sizeof(WORKER_THREAD_CONTEXT));
 | 
						||
            if(context){
 | 
						||
                item = IoAllocateWorkItem(DeviceObject);
 | 
						||
                context->Irp = Irp;
 | 
						||
                context->DeviceObject= DeviceObject;
 | 
						||
                context->WorkItem = item;
 | 
						||
                context->PowerType = powerType;
 | 
						||
                context->PowerState = powerState;
 | 
						||
                if (item) {
 | 
						||
 | 
						||
                    IoMarkIrpPending(Irp);
 | 
						||
                    IoQueueWorkItem (item,
 | 
						||
                                     Cycladz_PowerOnWorkItem,
 | 
						||
                                     DelayedWorkQueue,
 | 
						||
                                     context);
 | 
						||
                    return STATUS_MORE_PROCESSING_REQUIRED;
 | 
						||
                } else {
 | 
						||
                    //status = STATUS_INSUFFICIENT_RESOURCES;
 | 
						||
                    // What should we do? DDK says we cannot fail SET_POWER.
 | 
						||
                }
 | 
						||
            } else {
 | 
						||
                //status = STATUS_INSUFFICIENT_RESOURCES;
 | 
						||
                // What should we do? DDK says we cannot fail SET_POWER.
 | 
						||
            }
 | 
						||
            
 | 
						||
            data->DeviceState = powerState.DeviceState;
 | 
						||
 | 
						||
            //PoSetPowerState (data->Self, powerType, powerState);
 | 
						||
 | 
						||
            break;
 | 
						||
 | 
						||
        default:
 | 
						||
           Cycladz_KdPrint(data,SER_DBG_CYCLADES, ("IRP_MN_SET_POWER not Device\n"));
 | 
						||
           break;
 | 
						||
        }
 | 
						||
        break;
 | 
						||
 | 
						||
    case IRP_MN_QUERY_POWER:
 | 
						||
 | 
						||
        Cycladz_KdPrint(data,SER_DBG_CYCLADES, ("IRP_MN_QUERY_POWER not Device\n"));
 | 
						||
        ASSERT (IRP_MN_QUERY_POWER != stack->MinorFunction);
 | 
						||
        break;
 | 
						||
 | 
						||
    default:
 | 
						||
        ASSERT (0xBADBAD == IRP_MN_QUERY_POWER);
 | 
						||
        break;
 | 
						||
    }
 | 
						||
 | 
						||
 | 
						||
    PoStartNextPowerIrp (Irp);
 | 
						||
    Cycladz_DecIoCount (data);
 | 
						||
 | 
						||
    //return status; Changed to below line in build 2072
 | 
						||
    Cycladz_KdPrint(data,SER_DBG_CYCLADES, ("Leaving Cycladz_FDOPowerComplete\n"));
 | 
						||
    return STATUS_SUCCESS; // Continue completion...
 | 
						||
}
 | 
						||
 | 
						||
NTSTATUS
 | 
						||
Cycladz_FDO_Power (
 | 
						||
    PFDO_DEVICE_DATA    Data,
 | 
						||
    PIRP                Irp
 | 
						||
    )
 | 
						||
/*++
 | 
						||
--*/
 | 
						||
{
 | 
						||
    NTSTATUS            status;
 | 
						||
    BOOLEAN             hookit = FALSE;
 | 
						||
    POWER_STATE         powerState;
 | 
						||
    POWER_STATE_TYPE    powerType;
 | 
						||
    PIO_STACK_LOCATION  stack;
 | 
						||
    // ADDED FANNY
 | 
						||
    ULONG               indexPDO;
 | 
						||
 | 
						||
    stack = IoGetCurrentIrpStackLocation (Irp);
 | 
						||
    powerType = stack->Parameters.Power.Type;
 | 
						||
    powerState = stack->Parameters.Power.State;
 | 
						||
 | 
						||
    Cycladz_KdPrint(Data,SER_DBG_CYCLADES, ("In Cycladz_FDO_Power Irp %x\n",Irp));
 | 
						||
 | 
						||
    status = Cycladz_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) {    // Added in DDK final version
 | 
						||
        //    status = Irp->IoStatus.Status = STATUS_SUCCESS;
 | 
						||
        //    break;
 | 
						||
        //}
 | 
						||
        if (Data->DevicePnPState != Started) {   // Toaster Bus compares to == NotStarted
 | 
						||
            status = Irp->IoStatus.Status = STATUS_SUCCESS;
 | 
						||
            break;
 | 
						||
        }
 | 
						||
 | 
						||
        Cycladz_KdPrint(Data,
 | 
						||
                     SER_DBG_PNP_TRACE,
 | 
						||
                     ("Cycladz-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) {
 | 
						||
                //
 | 
						||
                // Powering down
 | 
						||
                //
 | 
						||
                PoSetPowerState (Data->Self, powerType, powerState);
 | 
						||
                Data->DeviceState = powerState.DeviceState;
 | 
						||
            } else if (Data->DeviceState > powerState.DeviceState) {
 | 
						||
                //
 | 
						||
                // Powering Up
 | 
						||
                //
 | 
						||
                hookit = TRUE;
 | 
						||
            }
 | 
						||
            
 | 
						||
            break;
 | 
						||
 | 
						||
        case SystemPowerState:
 | 
						||
 | 
						||
            IoMarkIrpPending(Irp);
 | 
						||
            IoCopyCurrentIrpStackLocationToNext(Irp);
 | 
						||
 | 
						||
            status = Cycladz_IncIoCount (Data);
 | 
						||
            ASSERT (STATUS_SUCCESS == status);
 | 
						||
            IoSetCompletionRoutine (Irp,
 | 
						||
                                Cycladz_FDOSystemPowerComplete,
 | 
						||
                                NULL,
 | 
						||
                                TRUE,
 | 
						||
                                TRUE,
 | 
						||
                                TRUE);
 | 
						||
 | 
						||
            status = PoCallDriver (Data->TopOfStack, Irp);
 | 
						||
            Cycladz_KdPrint(Data,SER_DBG_CYCLADES, ("Leaving Cycladz_FDO_Power\n"));
 | 
						||
            Cycladz_DecIoCount (Data);
 | 
						||
 | 
						||
            return STATUS_PENDING;
 | 
						||
 | 
						||
        }
 | 
						||
        break;
 | 
						||
 | 
						||
    case IRP_MN_QUERY_POWER:
 | 
						||
 | 
						||
        Cycladz_KdPrint(Data,SER_DBG_CYCLADES,("IRP_MN_QUERY_POWER\n"));
 | 
						||
 | 
						||
        status = Irp->IoStatus.Status = STATUS_SUCCESS;
 | 
						||
        break;
 | 
						||
 | 
						||
    default:
 | 
						||
        //
 | 
						||
        // status should be STATUS_SUCCESS
 | 
						||
        //
 | 
						||
        break;
 | 
						||
    }
 | 
						||
    
 | 
						||
    if (hookit) {
 | 
						||
        IoMarkIrpPending(Irp);
 | 
						||
        IoCopyCurrentIrpStackLocationToNext (Irp);
 | 
						||
 | 
						||
        status = Cycladz_IncIoCount (Data);
 | 
						||
        ASSERT (STATUS_SUCCESS == status);
 | 
						||
        IoSetCompletionRoutine (Irp,
 | 
						||
                                Cycladz_FDOPowerComplete,
 | 
						||
                                NULL,
 | 
						||
                                TRUE,
 | 
						||
                                TRUE,
 | 
						||
                                TRUE);
 | 
						||
 | 
						||
        status = PoCallDriver (Data->TopOfStack, Irp);
 | 
						||
        Cycladz_KdPrint(Data,SER_DBG_CYCLADES, ("Leaving Cycladz_FDO_Power\n"));
 | 
						||
        Cycladz_DecIoCount (Data);
 | 
						||
        return STATUS_PENDING;
 | 
						||
 | 
						||
    } 
 | 
						||
 | 
						||
    PoStartNextPowerIrp (Irp);
 | 
						||
    IoSkipCurrentIrpStackLocation(Irp);
 | 
						||
    status =  PoCallDriver (Data->TopOfStack, Irp);
 | 
						||
    Cycladz_KdPrint(Data,SER_DBG_CYCLADES, ("Leaving Cycladz_FDO_Power\n"));
 | 
						||
    Cycladz_DecIoCount (Data);
 | 
						||
    return status;
 | 
						||
 | 
						||
}
 | 
						||
 | 
						||
NTSTATUS
 | 
						||
Cycladz_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:
 | 
						||
 | 
						||
            Cycladz_KdPrint(PdoData,SER_DBG_CYCLADES,("IRP_MN_SET_POWER Device Pdo %x\n",
 | 
						||
                                                                           PdoData->Self));
 | 
						||
            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:
 | 
						||
           Cycladz_KdPrint(PdoData,SER_DBG_CYCLADES,("IRP_MN_SET_POWER System Pdo %x\n",
 | 
						||
                                                                           PdoData->Self));
 | 
						||
            //
 | 
						||
            // Default to STATUS_SUCCESS
 | 
						||
            //
 | 
						||
            break;
 | 
						||
 | 
						||
        default:
 | 
						||
            status = STATUS_NOT_IMPLEMENTED;
 | 
						||
            break;
 | 
						||
        }
 | 
						||
        break;
 | 
						||
 | 
						||
    case IRP_MN_QUERY_POWER:
 | 
						||
        Cycladz_KdPrint(PdoData,SER_DBG_CYCLADES,("IRP_MN_QUERY_POWER Pdo %x\n",PdoData->Self));
 | 
						||
        //
 | 
						||
        // Default to STATUS_SUCCESS
 | 
						||
        //
 | 
						||
        break;
 | 
						||
 | 
						||
    case IRP_MN_WAIT_WAKE:
 | 
						||
    case IRP_MN_POWER_SEQUENCE:
 | 
						||
        Cycladz_KdPrint(PdoData,SER_DBG_CYCLADES,("IRP_MN_ NOT IMPLEMENTED\n"));
 | 
						||
        status = STATUS_NOT_IMPLEMENTED;
 | 
						||
        break;
 | 
						||
 | 
						||
    default:
 | 
						||
       status = Irp->IoStatus.Status;
 | 
						||
    }
 | 
						||
 | 
						||
    Irp->IoStatus.Status = status;
 | 
						||
    PoStartNextPowerIrp (Irp);
 | 
						||
    IoCompleteRequest (Irp, IO_NO_INCREMENT);
 | 
						||
 | 
						||
    return status;
 | 
						||
}
 | 
						||
 | 
						||
NTSTATUS
 | 
						||
Cycladz_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 = 
 | 
						||
            Cycladz_FDO_Power ((PFDO_DEVICE_DATA) DeviceObject->DeviceExtension,
 | 
						||
                Irp);
 | 
						||
    } else {
 | 
						||
        status = 
 | 
						||
            Cycladz_PDO_Power ((PPDO_DEVICE_DATA) DeviceObject->DeviceExtension,
 | 
						||
                Irp);
 | 
						||
    }
 | 
						||
 | 
						||
    return status;
 | 
						||
}     
 | 
						||
 | 
						||
 | 
						||
 | 
						||
NTSTATUS
 | 
						||
Cycladz_GotoPowerState(IN PDEVICE_OBJECT PDevObj,
 | 
						||
                   IN PFDO_DEVICE_DATA PDevExt,
 | 
						||
                   IN DEVICE_POWER_STATE DevPowerState)
 | 
						||
/*++
 | 
						||
 | 
						||
Routine Description:
 | 
						||
 | 
						||
    This routine causes the driver to request the stack go to a particular
 | 
						||
    power state.
 | 
						||
 | 
						||
Arguments:
 | 
						||
 | 
						||
    PDevObj - Pointer to the device object for this device
 | 
						||
 | 
						||
    PDevExt - Pointer to the device extension we are working from
 | 
						||
 | 
						||
    DevPowerState - the power state we wish to go to
 | 
						||
 | 
						||
Return Value:
 | 
						||
 | 
						||
    The function value is the final status of the call
 | 
						||
 | 
						||
 | 
						||
--*/
 | 
						||
{
 | 
						||
   KEVENT gotoPowEvent;
 | 
						||
   NTSTATUS status;
 | 
						||
   POWER_STATE powerState;
 | 
						||
 | 
						||
   UNREFERENCED_PARAMETER (PDevExt);   
 | 
						||
 | 
						||
   PAGED_CODE();
 | 
						||
 | 
						||
   Cycladz_KdPrint(PDevExt,SER_DBG_CYCLADES, ("In Cycladz_GotoPowerState\n"));
 | 
						||
 | 
						||
   powerState.DeviceState = DevPowerState;
 | 
						||
 | 
						||
   KeInitializeEvent(&gotoPowEvent, SynchronizationEvent, FALSE);
 | 
						||
 | 
						||
   status = PoRequestPowerIrp(PDevObj, IRP_MN_SET_POWER, powerState,
 | 
						||
                              Cycladz_SystemPowerCompletion, &gotoPowEvent,
 | 
						||
                              NULL);
 | 
						||
 | 
						||
   if (status == STATUS_PENDING) {
 | 
						||
      KeWaitForSingleObject(&gotoPowEvent, Executive, KernelMode, FALSE, NULL);
 | 
						||
      status = STATUS_SUCCESS;
 | 
						||
   }
 | 
						||
 | 
						||
#if DBG
 | 
						||
   if (!NT_SUCCESS(status)) {
 | 
						||
      Cycladz_KdPrint(PDevExt,SER_DBG_CYCLADES, ("Cycladz_GotoPowerState FAILED\n"));
 | 
						||
   }
 | 
						||
#endif
 | 
						||
 | 
						||
   Cycladz_KdPrint(PDevExt,SER_DBG_CYCLADES, ("Leaving Cycladz_GotoPowerState\n"));
 | 
						||
 | 
						||
   return status;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
 | 
						||
NTSTATUS
 | 
						||
Cycladz_SystemPowerCompletion(IN PDEVICE_OBJECT PDevObj, UCHAR MinorFunction,
 | 
						||
                              IN POWER_STATE PowerState, IN PVOID Context,
 | 
						||
                              PIO_STATUS_BLOCK IoStatus)
 | 
						||
/*++
 | 
						||
 | 
						||
Routine Description:
 | 
						||
 | 
						||
    This routine is the completion routine for PoRequestPowerIrp calls
 | 
						||
    in this module.
 | 
						||
 | 
						||
Arguments:
 | 
						||
 | 
						||
    PDevObj - Pointer to the device object the irp is completing for
 | 
						||
 | 
						||
    MinorFunction - IRP_MN_XXXX value requested
 | 
						||
 | 
						||
    PowerState - Power state request was made of
 | 
						||
 | 
						||
    Context - Event to set or NULL if no setting required
 | 
						||
 | 
						||
    IoStatus - Status block from request
 | 
						||
 | 
						||
Return Value:
 | 
						||
 | 
						||
    VOID
 | 
						||
 | 
						||
 | 
						||
--*/
 | 
						||
{
 | 
						||
 | 
						||
   UNREFERENCED_PARAMETER (PDevObj);   
 | 
						||
   UNREFERENCED_PARAMETER (MinorFunction);
 | 
						||
   UNREFERENCED_PARAMETER (PowerState);
 | 
						||
   UNREFERENCED_PARAMETER (IoStatus);
 | 
						||
   
 | 
						||
   if (Context != NULL) {
 | 
						||
      KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, 0);
 | 
						||
   }
 | 
						||
 | 
						||
   return STATUS_SUCCESS;
 | 
						||
}
 | 
						||
 |