📄 smbbatt.c
字号:
/*++
Copyright (c) 1990 Microsoft Corporation
Module Name:
smbbatt.c
Abstract:
SMBus Smart Battery Subsystem Miniport Driver
(Selector, Battery, Charger)
Author:
Ken Reneris
Environment:
Notes:
Revision History:
Chris Windle 1/27/98 Bug Fixes
--*/
#include "smbbattp.h"
#include <initguid.h>
#include <batclass.h>
#if DEBUG
ULONG SMBBattDebug = BAT_WARN | BAT_ERROR | BAT_BIOS_ERROR;
#endif
// Global
BOOLEAN SmbBattUseGlobalLock = TRUE;
UNICODE_STRING GlobalRegistryPath;
//
// Prototypes
//
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
);
NTSTATUS
SmbBattNewDevice (
IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT PDO
);
NTSTATUS
SmbBattQueryTag (
IN PVOID Context,
OUT PULONG BatteryTag
);
NTSTATUS
SmbBattQueryInformation (
IN PVOID Context,
IN ULONG BatteryTag,
IN BATTERY_QUERY_INFORMATION_LEVEL Level,
IN LONG AtRate OPTIONAL,
OUT PVOID Buffer,
IN ULONG BufferLength,
OUT PULONG ReturnedLength
);
NTSTATUS
SmbBattSetStatusNotify (
IN PVOID Context,
IN ULONG BatteryTag,
IN PBATTERY_NOTIFY BatteryNotify
);
NTSTATUS
SmbBattDisableStatusNotify (
IN PVOID Context
);
NTSTATUS
SmbBattQueryStatus (
IN PVOID Context,
IN ULONG BatteryTag,
OUT PBATTERY_STATUS BatteryStatus
);
NTSTATUS
SmbBattCreate(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
SmbBattClose(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS
SmbBattIoctl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
VOID
SmbBattUnload(
IN PDRIVER_OBJECT DriverObject
);
VOID
SmbBattProcessSelectorAlarm (
IN PSMB_BATT_SUBSYSTEM SubsystemExt,
IN ULONG OldSelectorState,
IN ULONG NewSelectorState
);
NTSTATUS
SmbBattGetPowerState (
IN PSMB_BATT SmbBatt,
OUT PULONG PowerState,
OUT PLONG Current
);
#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT,DriverEntry)
#pragma alloc_text(PAGE,SmbBattNewDevice)
#pragma alloc_text(PAGE,SmbBattUnload)
#pragma alloc_text(PAGE,SmbBattCreate)
#pragma alloc_text(PAGE,SmbBattClose)
#pragma alloc_text(PAGE,SmbBattIoctl)
#pragma alloc_text(PAGE,SmbBattQueryTag)
#pragma alloc_text(PAGE,SmbBattQueryInformation)
#pragma alloc_text(PAGE,SmbBattSetInformation)
#pragma alloc_text(PAGE,SmbBattGetPowerState)
#pragma alloc_text(PAGE,SmbBattQueryStatus)
#pragma alloc_text(PAGE,SmbBattSetStatusNotify)
#pragma alloc_text(PAGE,SmbBattDisableStatusNotify)
#endif
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
/*++
Routine Description:
This routine initializes the Smart Battery Driver
Arguments:
DriverObject - Pointer to driver object created by system.
RegistryPath - Pointer to the Unicode name of the registry path
for this driver.
Return Value:
The function value is the final status from the initialization operation.
--*/
{
OBJECT_ATTRIBUTES objAttributes;
BattPrint(BAT_TRACE, ("SmbBatt: DriverEntry\n"));
//
// Save the RegistryPath.
//
GlobalRegistryPath.MaximumLength = RegistryPath->Length +
sizeof(UNICODE_NULL);
GlobalRegistryPath.Length = RegistryPath->Length;
GlobalRegistryPath.Buffer = ExAllocatePoolWithTag (
PagedPool,
GlobalRegistryPath.MaximumLength,
'StaB');
if (!GlobalRegistryPath.Buffer) {
BattPrint ((BAT_ERROR),("SmbBatt: Couldn't allocate pool for registry path."));
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlCopyUnicodeString(&GlobalRegistryPath, RegistryPath);
BattPrint (BAT_TRACE, ("SmbBatt DriverEntry - Obj (%08x) Path \"%ws\"\n",
DriverObject, RegistryPath->Buffer));
DriverObject->DriverUnload = SmbBattUnload;
DriverObject->DriverExtension->AddDevice = SmbBattNewDevice;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = SmbBattIoctl;
DriverObject->MajorFunction[IRP_MJ_CREATE] = SmbBattCreate;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = SmbBattClose;
DriverObject->MajorFunction[IRP_MJ_PNP] = SmbBattPnpDispatch;
DriverObject->MajorFunction[IRP_MJ_POWER] = SmbBattPowerDispatch;
DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = SmbBattSystemControl;
return STATUS_SUCCESS;
}
NTSTATUS
SmbBattNewDevice (
IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT PDO
)
/*++
Routine Description:
This creates a smb smart battery functional device objects. The first
object created will be the one for the "smart battery subsystem" which will
have a PDO from ACPI. This will receive a START Irp, then a
QUERY_DEVICE_RELATIONS Irp. In the QUERY it will create PDOs for the
batteries that are supported by the system and eventually they will end
up here for FDOs to be created and attached to them.
Arguments:
DriverObject - Pointer to driver object created by system.
PDO - PDO for the new device(s)
Return Value:
Status
--*/
{
PDEVICE_OBJECT fdo;
PSMB_BATT_SUBSYSTEM subsystemExt;
PSMB_BATT_PDO pdoExt;
PSMB_NP_BATT SmbNPBatt;
PSMB_BATT SmbBatt;
BATTERY_MINIPORT_INFO BattInit;
NTSTATUS status = STATUS_UNSUCCESSFUL;
BOOLEAN selectorPresent = FALSE;
PAGED_CODE();
BattPrint(BAT_IRPS, ("SmbBattNewDevice: AddDevice for device %x\n", PDO));
//
// Check to see if we are being asked to enumerate ourself
//
if (PDO == NULL) {
BattPrint(BAT_ERROR, ("SmbBattNewDevice: Being asked to enumerate\n"));
return STATUS_NOT_IMPLEMENTED;
}
//
// Check to see if the PDO is the battery subsystem PDO or a battery PDO. This will be
// determined by the PDO's DeviceType.
//
// FILE_DEVICE_ACPI This PDO is from ACPI and belongs to battery subsystem
// FILE_DEVICE_BATTERY This PDO is a battery PDO
//
if (PDO->DeviceType == FILE_DEVICE_ACPI) {
//
// Create the device object
//
status = IoCreateDevice(
DriverObject,
sizeof (SMB_BATT_SUBSYSTEM),
NULL,
FILE_DEVICE_BATTERY,
FILE_DEVICE_SECURE_OPEN,
FALSE,
&fdo
);
if (status != STATUS_SUCCESS) {
BattPrint(BAT_ERROR, ("SmbBattNewDevice: error creating Fdo for battery subsystem %x\n", status));
return(status);
}
//
// Initialize the Fdo
//
fdo->Flags |= DO_BUFFERED_IO;
fdo->Flags |= DO_POWER_PAGABLE;
//
// Initialize the extension
//
subsystemExt = (PSMB_BATT_SUBSYSTEM)fdo->DeviceExtension;
RtlZeroMemory (subsystemExt, sizeof (PSMB_BATT_SUBSYSTEM));
subsystemExt->DeviceObject = fdo;
subsystemExt->SmbBattFdoType = SmbTypeSubsystem;
IoInitializeRemoveLock (&subsystemExt->RemoveLock,
SMB_BATTERY_TAG,
REMOVE_LOCK_MAX_LOCKED_MINUTES,
REMOVE_LOCK_HIGH_WATER_MARK);
//
// These fields are implicitly initialize by zeroing the extension
//
// subsystemExt->NumberOfBatteries = 0;
// subsystemExt->SelectorPresent = FALSE;
// subsystemExt->Selector = NULL;
// subsystemExt->WorkerActive = 0;
KeInitializeSpinLock (&subsystemExt->AlarmListLock);
InitializeListHead (&subsystemExt->AlarmList);
subsystemExt->WorkerThread = IoAllocateWorkItem (fdo);
//
// Layer our FDO on top of the ACPI PDO.
//
subsystemExt->LowerDevice = IoAttachDeviceToDeviceStack (fdo,PDO);
if (!subsystemExt->LowerDevice) {
BattPrint(BAT_ERROR, ("SmbBattNewDevice: Error attaching subsystem to device stack.\n"));
IoDeleteDevice (fdo);
return(status);
}
//
// Zero out the battery PDO list
// This is already zeroed by the RtlZeroMemory above.
//
// RtlZeroMemory(
// &subsystemExt->BatteryPdoList[0],
// sizeof(PDEVICE_OBJECT) * MAX_SMART_BATTERIES_SUPPORTED
// );
//
// Device is ready for use
//
fdo->Flags &= ~DO_DEVICE_INITIALIZING;
} else {
//
// This is a battery PDO. Create the FDO to layer on top of it.
//
pdoExt = (PSMB_BATT_PDO) PDO->DeviceExtension;
subsystemExt = (PSMB_BATT_SUBSYSTEM) pdoExt->SubsystemFdo->DeviceExtension;
//
// Allocate space for the paged portion of the device extension
//
SmbBatt = ExAllocatePoolWithTag (PagedPool, sizeof(SMB_BATT), SMB_BATTERY_TAG);
if (!SmbBatt) {
BattPrint(BAT_ERROR, ("SmbBattNewDevice: Can't allocate Smart Battery data\n"));
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlZeroMemory (SmbBatt, sizeof(SMB_BATT));
//
// Create the device object
//
status = IoCreateDevice(
DriverObject,
sizeof (SMB_NP_BATT),
NULL,
FILE_DEVICE_BATTERY,
FILE_DEVICE_SECURE_OPEN,
FALSE,
&fdo
);
if (status != STATUS_SUCCESS) {
BattPrint(BAT_ERROR, ("SmbBattNewDevice: error creating Fdo: %x\n", status));
ExFreePool (SmbBatt);
return(status);
}
//
// Initialize the Fdo
//
fdo->Flags |= DO_BUFFERED_IO;
fdo->Flags |= DO_POWER_PAGABLE;
//
// Layer our FDO on top of the PDO.
//
SmbNPBatt = (PSMB_NP_BATT) fdo->DeviceExtension;
SmbNPBatt->LowerDevice = IoAttachDeviceToDeviceStack (fdo,PDO);
if (!SmbNPBatt->LowerDevice) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -