⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 power.c

📁 本压缩包为作者截取的PCI9054的WDM官方驱动源码。欢迎下载。
💻 C
📖 第 1 页 / 共 2 页
字号:
/*******************************************************************************
 * Copyright (c) 2006 PLX Technology, Inc.
 *
 * PLX Technology Inc. licenses this software under specific terms and
 * conditions.  Use of any of the software or derviatives thereof in any
 * product without a PLX Technology chip is strictly prohibited.
 *
 * PLX Technology, Inc. provides this software AS IS, WITHOUT ANY WARRANTY,
 * EXPRESS OR IMPLIED, INCLUDING, WITHOUT LIMITATION, ANY WARRANTY OF
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  PLX makes no guarantee
 * or representations regarding the use of, or the results of the use of,
 * the software and documentation in terms of correctness, accuracy,
 * reliability, currentness, or otherwise; and you rely on the software,
 * documentation and results solely at your own risk.
 *
 * IN NO EVENT SHALL PLX BE LIABLE FOR ANY LOSS OF USE, LOSS OF BUSINESS,
 * LOSS OF PROFITS, INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES
 * OF ANY KIND.  IN NO EVENT SHALL PLX'S TOTAL LIABILITY EXCEED THE SUM
 * PAID TO PLX FOR THE PRODUCT LICENSED HEREUNDER.
 *
 ******************************************************************************/

/******************************************************************************
 *
 * File Name:
 *
 *      Power.c
 *
 * Description:
 *
 *      Power Management functions
 *
 * Revision History:
 *
 *      02-01-06 : PCI SDK v4.40
 *
 ******************************************************************************/


#include "ApiFunctions.h"
#include "PciSupport.h"
#include "PlugPlay.h"
#include "Power.h"
#include "SupportFunc.h"




/******************************************************************************
 *
 * Function   :  Dispatch_Power
 *
 * Description:  Handles power requests
 *
 ******************************************************************************/
NTSTATUS
Dispatch_Power(
    PDEVICE_OBJECT fdo,
    PIRP           pIrp
    )
{
    NTSTATUS           status;
    PIO_STACK_LOCATION stack;


    PlxLockDevice(
        fdo->DeviceExtension
        );

    DebugPrintf(("Received POWER Message (IRP=0x%p) ==> ", pIrp));

    stack =
        IoGetCurrentIrpStackLocation(
            pIrp
            );

    switch (stack->MinorFunction)
    {
        case IRP_MN_WAIT_WAKE:
            DebugPrintf_NoInfo(("IRP_MN_WAIT_WAKE\n"));
            status =
                DefaultPowerHandler(
                    fdo,
                    pIrp
                    );
            break;

        case IRP_MN_POWER_SEQUENCE:
            DebugPrintf_NoInfo(("IRP_MN_POWER_SEQUENCE\n"));
            status =
                DefaultPowerHandler(
                    fdo,
                    pIrp
                    );
            break;

        case IRP_MN_SET_POWER:
            DebugPrintf_NoInfo(("IRP_MN_SET_POWER\n"));
            if (stack->Parameters.Power.Type == SystemPowerState)
            {
                DebugPrintf((
                    "SystemContext = 0x%08x  SystemPowerState = 0x%08x\n",
                    stack->Parameters.Power.SystemContext,
                    stack->Parameters.Power.State.SystemState
                    ));
            }
            else
            {
                DebugPrintf((
                    "SystemContext = 0x%08x  DevicePowerState = 0x%08x\n",
                    stack->Parameters.Power.SystemContext,
                    stack->Parameters.Power.State.DeviceState
                    ));
            }

            status =
                HandleSetPower(
                    fdo,
                    pIrp
                    );
            break;

        case IRP_MN_QUERY_POWER:
            DebugPrintf_NoInfo(("IRP_MN_QUERY_POWER\n"));
            DebugPrintf((
                "SystemContext = 0x%08x\n",
                stack->Parameters.Power.SystemContext
                ));

            status =
                HandleQueryPower(
                    fdo,
                    pIrp
                    );
            break;

        default:
            DebugPrintf_NoInfo((
                "Unsupported IRP_MN_Xxx (0x%08x)\n",
                stack->MinorFunction
                ));

            status =
                DefaultPowerHandler(
                    fdo,
                    pIrp
                    );
            break;
    }

    PlxUnlockDevice(
        fdo->DeviceExtension
        );

    return status;
}




/******************************************************************************
 *
 * Function   :  DefaultPowerHandler
 *
 * Description:  Handle defaults power requests
 *
 ******************************************************************************/
NTSTATUS
DefaultPowerHandler(
    PDEVICE_OBJECT fdo,
    PIRP           pIrp
    )
{
    DebugPrintf(("Forwarded IRP to next lower driver\n"));

    // Must be done while we own the IRP
    PoStartNextPowerIrp(
        pIrp
        );

    IoSkipCurrentIrpStackLocation(
        pIrp
        );

    return PoCallDriver(
               ((DEVICE_EXTENSION *)fdo->DeviceExtension)->pLowerDeviceObject,
               pIrp
               );
}




/******************************************************************************
 *
 * Function   :  HandleSetPower
 *
 * Description:  Handles IRP_MN_SET_POWER IRP
 *
 ******************************************************************************/
NTSTATUS
HandleSetPower(
    PDEVICE_OBJECT fdo,
    PIRP           pIrp
    )
{
    U32                 context;
    NTSTATUS            status;
    POWER_STATE         state;
    POWER_STATE_TYPE    type;
    DEVICE_EXTENSION   *pdx;
    PIO_STACK_LOCATION  stack;
    DEVICE_POWER_STATE  devstate;


    pdx     = fdo->DeviceExtension;
    stack   = IoGetCurrentIrpStackLocation(pIrp);
    context = stack->Parameters.Power.SystemContext;
    type    = stack->Parameters.Power.Type;
    state   = stack->Parameters.Power.State;

    /* If this IRP pertains to a system state, we want to put ourselves into
     * a corresponding device state. The rule here is very simple: if the
     * system is below SystemWorking, me must go to D3. If the system is
     * in SystemWorking, we're allowed to pick our own state (so we pick
     * D0). We can't just change our power state now, though: we must send
     * ourselves a separate POWER IRP with the selected device state.
     */
    if (type == SystemPowerState)
    {
        if (state.SystemState <= PowerSystemWorking)
            devstate = PowerDeviceD0;
        else
            devstate = PowerDeviceD3;
    }
    else
        devstate = state.DeviceState;

    // If we're adding power, first pass the IRP down. Queue the
    // requisite device IRP in the completion routine after the
    // lower layers have restored power.

    if (devstate < pdx->PowerState)
    {
        // Adding more power
        IoCopyCurrentIrpStackLocationToNext(
            pIrp
            );

        IoSetCompletionRoutine(
            pIrp,
            (PIO_COMPLETION_ROUTINE) OnFinishPowerUp,
            NULL,
            TRUE,
            TRUE,
            TRUE
            );

        return PoCallDriver(
                   pdx->pLowerDeviceObject,
                   pIrp
                   );
    }
    else if (devstate > pdx->PowerState)
    {
        /* If we're removing power, first do the device specific part.
         * Then send the request down the stack. In the case of a system
         * power request, send ourselves a device power IRP to power down first.
         * In the case of a device power request, use PoSetPowerState to tell
         * the Power Manager what we're about to do and then actually depower
         * the hardware.
         */

        // Removing power
        if (type == SystemPowerState)
        {
            // Change in system state
            status =
                SendDeviceSetPower(
                    fdo,
                    devstate,
                    context
                    );

            if (!NT_SUCCESS(status))
            {
                // Couldn't set device power state
                PoStartNextPowerIrp(
                    pIrp
                    );

                return PlxCompleteIrpWithInformation(
                           pIrp,
                           status,
                           0
                           );
            }
        }
        else
        {
            // Change in device state
            PoSetPowerState(
                fdo,
                type,
                state
                ); // before we power down

            SetPowerState(
                fdo,
                devstate
                );
        }

        // Pass request down
        return DefaultPowerHandler(
                   fdo,
                   pIrp
                   );
    }

    // Pass request down
    return DefaultPowerHandler(
               fdo,
               pIrp
               );
}




/******************************************************************************
 *
 * Function   :  HandleQueryPower
 *
 * Description:  Handle the IRP_MN_QUERY_POWER power IRP
 *
 ******************************************************************************/
NTSTATUS
HandleQueryPower(
    PDEVICE_OBJECT fdo,
    PIRP           pIrp
    )
{
    PIO_STACK_LOCATION  stack;
    DEVICE_POWER_STATE  devstate;


    stack =
        IoGetCurrentIrpStackLocation(
            pIrp
            );

    switch (stack->Parameters.Power.Type)
    {
        case SystemPowerState:
            DebugPrintf(("Query System Power State\n"));

            if (stack->Parameters.Power.State.SystemState <= PowerSystemWorking)
                devstate = PowerDeviceD0;
            else
                devstate = PowerDeviceD3;
            break;

        case DevicePowerState:
            DebugPrintf(("Query Device Power State\n"));

            devstate = stack->Parameters.Power.State.DeviceState;

            if (PlxIsPowerLevelSupported(
                    fdo->DeviceExtension,
                    devstate - PowerDeviceD0 + D0
                    ) == FALSE)
            {
                // Unsupported power level, we must fail the IRP
                DebugPrintf((
                    "WARNING - HandleQueryPower() unsupported power level\n"
                    ));

                return PlxCompleteIrpWithInformation(
                           pIrp,
                           STATUS_POWER_STATE_INVALID,
                           0
                           );
            }
            break;

        default:
            DebugPrintf(("Unknown query power state type\n"));
            break;
    }

    // Pass request down
    return DefaultPowerHandler(
               fdo,
               pIrp

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -