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

📄 pnppower.c

📁 winddk src目录下的WDM源码压缩!
💻 C
📖 第 1 页 / 共 4 页
字号:
/*++

Copyright (c) 1990  Microsoft Corporation

Module Name:

    pnppower.c

Abstract:

    SMBus Smart Battery Subsystem Miniport Driver
    (Selector, Battery, Charger) Plug and Play and
    Power Management IRP dispatch routines.

Author:

    Scott Brenden

Environment:

Notes:


Revision History:

    Chris Windle    1/27/98     Bug Fixes

--*/

#include "smbbattp.h"
#include <devioctl.h>
#include <acpiioct.h>


#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE,SmbBattPnpDispatch)
#pragma alloc_text(PAGE,SmbBattPowerDispatch)
#pragma alloc_text(PAGE,SmbBattRegisterForAlarm)
#pragma alloc_text(PAGE,SmbBattUnregisterForAlarm)
#pragma alloc_text(PAGE,SmbGetSBS)
#pragma alloc_text(PAGE,SmbGetGLK)
#pragma alloc_text(PAGE,SmbBattCreatePdos)
#pragma alloc_text(PAGE,SmbBattBuildDeviceRelations)
#pragma alloc_text(PAGE,SmbBattQueryDeviceRelations)
#pragma alloc_text(PAGE,SmbBattRemoveDevice)
#pragma alloc_text(PAGE,SmbBattQueryId)
#pragma alloc_text(PAGE,SmbBattQueryCapabilities)
#pragma alloc_text(PAGE,SmbBattBuildSelectorStruct)
#endif



NTSTATUS
SmbBattPnpDispatch(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )

/*++

Routine Description:

    This is a dispatch routine for the IRPs that come to the driver with the
    IRP_MJ_PNP major code (plug-and-play IRPs).

Arguments:

    DeviceObject - Pointer to the device object for this device

    Irp - Pointer to the IRP for the current request

Return Value:

    The function value is the final status of the call


--*/

{
    PSMB_BATT               smbBatt;

    PIO_STACK_LOCATION      irpStack        = IoGetCurrentIrpStackLocation(Irp);
    NTSTATUS                status;
    BOOLEAN                 complete        = TRUE;
    KEVENT                  syncEvent;

    //
    // This routine handles PnP IRPs for three different types of device objects:
    // the battery subsystem FDO, each battery PDO and each battery PDO.  The
    // subsystem PDO creates children since each battery in the system must have
    // it's own device object, so this driver is essential two device drivers in
    // one: the smart battery selector bus driver (It is actually it's own bus
    // because the selector arbitrates between the two batteries.) and the
    // battery function driver.  The two drivers are integrated because it would
    // not make sense to replace one and not the other, and having separate
    // drivers would require additional defined interfaces between them.
    //
    // The device extensions for the three device types are different structures.
    //

    PSMB_BATT_SUBSYSTEM     subsystemExt    =
            (PSMB_BATT_SUBSYSTEM) DeviceObject->DeviceExtension;
    PSMB_NP_BATT            batteryExt      =
            (PSMB_NP_BATT) DeviceObject->DeviceExtension;
    PDEVICE_OBJECT      lowerDevice = NULL;

    PAGED_CODE();

    status = IoAcquireRemoveLock (&batteryExt->RemoveLock, Irp);

    if (NT_SUCCESS(status)) {
        status = STATUS_NOT_SUPPORTED;

        if (batteryExt->SmbBattFdoType == SmbTypeSubsystem) {
            lowerDevice = subsystemExt->LowerDevice;
        } else if (batteryExt->SmbBattFdoType == SmbTypeBattery) {
            lowerDevice = batteryExt->LowerDevice;
        } else {
            // Assuming (batteryExt->SmbBattFdoType == SmbTypePdo)
            ASSERT (batteryExt->SmbBattFdoType == SmbTypePdo);
            lowerDevice = NULL;
        }

        switch (irpStack->MinorFunction) {

            case IRP_MN_QUERY_DEVICE_RELATIONS: {

                BattPrint(
                    BAT_IRPS,
                    ("SmbBattPnpDispatch: got IRP_MN_QUERY_DEVICE_RELATIONS, "
                     "type = %x\n",
                     irpStack->Parameters.QueryDeviceRelations.Type)
                );

                status = SmbBattQueryDeviceRelations (DeviceObject, Irp);

                break;
            }


            case IRP_MN_QUERY_CAPABILITIES: {

                BattPrint(
                    BAT_IRPS,
                    ("SmbBattPnpDispatch: got IRP_MN_QUERY_CAPABILITIES for device %x\n",
                    DeviceObject)
                );

                status = SmbBattQueryCapabilities (DeviceObject, Irp);
                break;
            }


            case IRP_MN_START_DEVICE: {

                BattPrint(
                    BAT_IRPS,
                    ("SmbBattPnpDispatch: got IRP_MN_START_DEVICE for %x\n",
                    DeviceObject)
                );

                if (subsystemExt->SmbBattFdoType == SmbTypeSubsystem) {

                    //
                    // Get the SMB host controller FDO
                    //

                    subsystemExt->SmbHcFdo = subsystemExt->LowerDevice;
                    status = STATUS_SUCCESS;

                } else if (subsystemExt->SmbBattFdoType == SmbTypeBattery) {

                    //
                    // This is a battery.  Just get the SMB host controller FDO.
                    //

                    smbBatt = batteryExt->Batt;
                    smbBatt->SmbHcFdo =
                        ((PSMB_BATT_SUBSYSTEM)(((PSMB_BATT_PDO)
                                                (smbBatt->PDO->DeviceExtension))->
                                               SubsystemFdo->DeviceExtension))->
                        LowerDevice;
                    status = STATUS_SUCCESS;
                } else if (subsystemExt->SmbBattFdoType == SmbTypePdo) {
                    status = STATUS_SUCCESS;
                }

                break;
            }


            case IRP_MN_STOP_DEVICE: {
                status = STATUS_SUCCESS;

                BattPrint(BAT_IRPS, ("SmbBattPnpDispatch: got IRP_MN_STOP_DEVICE\n"));

                break;
            }


            case IRP_MN_QUERY_REMOVE_DEVICE: {

                status = STATUS_SUCCESS;
                BattPrint(BAT_IRPS, ("SmbBattPnpDispatch: got IRP_MN_QUERY_REMOVE_DEVICE\n"));
                break;
            }


            case IRP_MN_CANCEL_REMOVE_DEVICE: {
                status = STATUS_SUCCESS;

                BattPrint(BAT_IRPS, ("SmbBattPnpDispatch: got IRP_MN_CANCEL_REMOVE_DEVICE\n"));

                break;
            }


            case IRP_MN_SURPRISE_REMOVAL: {
                status = STATUS_SUCCESS;

                BattPrint(BAT_IRPS, ("SmbBattPnpDispatch: got IRP_MN_SURPRISE_REMOVAL\n"));

                break;
            }


            case IRP_MN_REMOVE_DEVICE: {
                BattPrint(BAT_IRPS, ("SmbBattPnpDispatch: got IRP_MN_REMOVE_DEVICE\n"));

                status = SmbBattRemoveDevice (DeviceObject, Irp);

                return status;

                break;
            }


            case IRP_MN_QUERY_ID: {

                BattPrint(
                    BAT_IRPS,
                    ("SmbBattPnpDispatch: got IRP_MN_QUERY_ID for %x, query type is - %x\n",
                    DeviceObject,
                    irpStack->Parameters.QueryId.IdType)
                );

                if (batteryExt->SmbBattFdoType == SmbTypePdo) {
                    status = SmbBattQueryId (DeviceObject, Irp);
                }
                break;
            }


            case IRP_MN_QUERY_PNP_DEVICE_STATE: {

                BattPrint(BAT_IRPS, ("SmbBattPnpDispatch: got IRP_MN_PNP_DEVICE_STATE\n"));

                if (subsystemExt->SmbBattFdoType == SmbTypeSubsystem) {
                    IoCopyCurrentIrpStackLocationToNext (Irp);

                    KeInitializeEvent(&syncEvent, SynchronizationEvent, FALSE);

                    IoSetCompletionRoutine(Irp, SmbBattSynchronousRequest, &syncEvent, TRUE, TRUE, TRUE);

                    status = IoCallDriver(lowerDevice, Irp);

                    if (status == STATUS_PENDING) {
                        KeWaitForSingleObject(&syncEvent, Executive, KernelMode, FALSE, NULL);
                        status = Irp->IoStatus.Status;
                    }

                    Irp->IoStatus.Information &= ~PNP_DEVICE_NOT_DISABLEABLE;

                    IoCompleteRequest(Irp, IO_NO_INCREMENT);

                    IoReleaseRemoveLock (&batteryExt->RemoveLock, Irp);

                    return status;
                }

                break;
            }

        }   // switch (irpStack->MinorFunction)

        IoReleaseRemoveLock (&batteryExt->RemoveLock, Irp);

    }

    //
    // Only set status if we have something to add
    //
    if (status != STATUS_NOT_SUPPORTED) {

        Irp->IoStatus.Status = status ;

    }

    //
    // Do we need to send it down?
    //
    if ((NT_SUCCESS(status) || (status == STATUS_NOT_SUPPORTED)) && (lowerDevice != NULL)) {

        //
        // Forward request
        //
        IoSkipCurrentIrpStackLocation(Irp);
        status = IoCallDriver(lowerDevice,Irp);

    } else {

        //
        // Complete the request with the current status
        //
        status = Irp->IoStatus.Status;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);

    }

    return status;
}





NTSTATUS
SmbBattPowerDispatch(
    IN PDEVICE_OBJECT Fdo,
    IN PIRP Irp
    )

/*++

Routine Description:

    This is a dispatch routine for the IRPs that come to the driver with the
    IRP_MJ_POWER major code (power IRPs).

Arguments:

    DeviceObject - Pointer to the device object for this device

    Irp - Pointer to the IRP for the current request

Return Value:

    The function value is the final status of the call


--*/

{

    PIO_STACK_LOCATION  irpStack = IoGetCurrentIrpStackLocation(Irp);
    NTSTATUS            status = STATUS_NOT_SUPPORTED;
    PSMB_NP_BATT        batteryExt = (PSMB_NP_BATT) Fdo->DeviceExtension;
    PSMB_BATT_SUBSYSTEM subsystemExt = (PSMB_BATT_SUBSYSTEM) Fdo->DeviceExtension;
    PDEVICE_OBJECT      lowerDevice;

    PAGED_CODE();

    //
    // Not using Remove lock in this function because this function doesn't use
    // any resoureces that the remove lock protects.
    //

    if (batteryExt->SmbBattFdoType == SmbTypeSubsystem) {
        lowerDevice = subsystemExt->LowerDevice;
    } else if (batteryExt->SmbBattFdoType == SmbTypeBattery) {
        lowerDevice = batteryExt->LowerDevice;
    } else {
        // Assuming (batteryExt->SmbBattFdoType == SmbTypePdo)
        ASSERT (batteryExt->SmbBattFdoType == SmbTypePdo);
        lowerDevice = NULL;
        status = STATUS_SUCCESS;
    }

    switch (irpStack->MinorFunction) {

        case IRP_MN_WAIT_WAKE: {
            BattPrint(BAT_IRPS, ("SmbBattPowerDispatch: got IRP_MN_WAIT_WAKE\n"));
            
            //
            // Smart batteries can't wake the system.
            //

            status = STATUS_NOT_SUPPORTED;
            break;
        }

        case IRP_MN_POWER_SEQUENCE: {
            BattPrint(BAT_IRPS, ("SmbBattPowerDispatch: got IRP_MN_POWER_SEQUENCE\n"));
            break;
        }

        case IRP_MN_SET_POWER: {
            BattPrint(BAT_IRPS, ("SmbBattPowerDispatch: got IRP_MN_SET_POWER\n"));
            break;
        }

        case IRP_MN_QUERY_POWER: {
            BattPrint(BAT_IRPS, ("SmbBattPowerDispatch: got IRP_MN_QUERY_POWER\n"));
            break;
        }

        default: {
            status = STATUS_NOT_SUPPORTED;
        }

    }   // switch (irpStack->MinorFunction)

    if (status != STATUS_NOT_SUPPORTED) {

        Irp->IoStatus.Status = status;

    }

    PoStartNextPowerIrp( Irp );
    if ((NT_SUCCESS(status) || (status == STATUS_NOT_SUPPORTED)) && (lowerDevice != NULL)) {

        //
        // Forward the request along
        //
        IoSkipCurrentIrpStackLocation( Irp );
        status = PoCallDriver( lowerDevice, Irp );

    } else {

        //
        // Complete the request with the current status
        //
        status = Irp->IoStatus.Status;
        IoCompleteRequest( Irp, IO_NO_INCREMENT );

    }

    return status;
}



NTSTATUS
SmbBattRegisterForAlarm(
    IN PDEVICE_OBJECT Fdo
    )

/*++

Routine Description:

    This routine register with the SmbHc for alarm notifications.  This
    is only done when smart battery subsystem FDO is started.

Arguments:

    Fdo - Pointer to the Fdo for this device

    Irp - Pointer to the IRP for the current request

⌨️ 快捷键说明

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