windows-nt/Source/XPSP1/NT/base/busdrv/acpi/cmbatt/cmexe.c
2020-09-26 16:20:57 +08:00

1000 lines
24 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
Copyright (c) 1990 Microsoft Corporation
Module Name:
CmBatt.c
Abstract:
Control Method Battery Miniport Driver
Author:
Ron Mosgrove (Intel)
Environment:
Kernel mode
Revision History:
--*/
#include "CmBattp.h"
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, CmBattSendDownStreamIrp)
#pragma alloc_text(PAGE, CmBattGetUniqueId)
#pragma alloc_text(PAGE, CmBattGetStaData)
#pragma alloc_text(PAGE, CmBattSetTripPpoint)
#endif
#define EXPECTED_DATA_SIZE 512
NTSTATUS
CmBattSendDownStreamIrp(
IN PDEVICE_OBJECT Pdo,
IN ULONG Ioctl,
IN PVOID InputBuffer,
IN ULONG InputSize,
IN PVOID OutputBuffer,
IN ULONG OutputSize
)
/*++
Routine Description:
Called to send a request to the Pdo
Arguments:
Pdo - The request is sent to this device object
Ioctl - the request
InputBuffer - The incoming request
InputSize - The size of the incoming request
OutputBuffer - The answer
OutputSize - The size of the answer buffer
Return Value:
NT Status of the operation
--*/
{
IO_STATUS_BLOCK ioBlock;
KEVENT event;
NTSTATUS status;
PIRP irp;
PAGED_CODE();
//
// Initialize an event to wait on
//
KeInitializeEvent( &event, SynchronizationEvent, FALSE );
//
// Build the request
//
irp = IoBuildDeviceIoControlRequest(
Ioctl,
Pdo,
InputBuffer,
InputSize,
OutputBuffer,
OutputSize,
FALSE,
&event,
&ioBlock
);
if (!irp) {
CmBattPrint((CMBATT_ERROR | CMBATT_CM_EXE),
("CmBattSendDownStreamIrp: Failed to allocate Irp\n"));
return STATUS_INSUFFICIENT_RESOURCES;
}
CmBattPrint(
CMBATT_CM_EXE,
("CmBattSendDownStreamIrp: Irp %x [Tid] %x\n", irp, GetTid() )
);
//
// Pass request to Pdo, always wait for completion routine
//
status = IoCallDriver(Pdo, irp);
if (status == STATUS_PENDING) {
//
// Wait for the irp to be completed, then grab the real status code
//
KeWaitForSingleObject(
&event,
Executive,
KernelMode,
FALSE,
NULL
);
status = ioBlock.Status;
}
//
// Sanity check the data
//
if (OutputBuffer != NULL) {
if ( ( (PACPI_EVAL_OUTPUT_BUFFER) OutputBuffer)->Signature != ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE ||
( (PACPI_EVAL_OUTPUT_BUFFER) OutputBuffer)->Count == 0) {
status = STATUS_ACPI_INVALID_DATA;
}
}
CmBattPrint(
CMBATT_CM_EXE,
("CmBattSendDownStreamIrp: Irp %x completed %x! [Tid] %x\n",
irp, status, GetTid() )
);
//
// Done
//
return status;
}
NTSTATUS
CmBattGetUniqueId(
IN PDEVICE_OBJECT Pdo,
OUT PULONG UniqueId
)
/*++
Routine Description:
Obtain the UID (unique ID) for a battery.
Arguments:
CmBatt - The extension for this device.
UniqueId - Pointer to where the ID is stored.
Return Value:
NT Status of the operation
--*/
{
ACPI_EVAL_INPUT_BUFFER inputBuffer;
ACPI_EVAL_OUTPUT_BUFFER outputBuffer;
NTSTATUS status;
PACPI_METHOD_ARGUMENT argument;
PAGED_CODE();
CmBattPrint(
CMBATT_CM_EXE,
("CmBattGetUniqueId: Entered with Pdo %x Tid %x\n", Pdo, GetTid() )
);
ASSERT( UniqueId != NULL );
*UniqueId = 0;
//
// Fill in the input data
//
inputBuffer.MethodNameAsUlong = CM_UID_METHOD;
inputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIGNATURE;
//
// Send the request along
//
status = CmBattSendDownStreamIrp(
Pdo,
IOCTL_ACPI_EVAL_METHOD,
&inputBuffer,
sizeof(ACPI_EVAL_INPUT_BUFFER),
&outputBuffer,
sizeof(ACPI_EVAL_OUTPUT_BUFFER)
);
if (!NT_SUCCESS(status)) {
CmBattPrint(
(CMBATT_CM_EXE | CMBATT_BIOS),
("CmBattGetUniqueId: Failed _UID method - Status (0x%x)\n", status)
);
return status;
}
//
// Grab the argument
//
argument = outputBuffer.Argument;
status = GetDwordElement( argument, UniqueId );
CmBattPrint(
(CMBATT_CM_EXE | CMBATT_BIOS),
("CmBattGetUniqueId: _UID method returned 0x%x\n", *UniqueId)
);
return status;
}
NTSTATUS
CmBattGetStaData(
IN PDEVICE_OBJECT Pdo,
OUT PULONG ReturnStatus
)
/*++
Routine Description:
Called to get a device status via the _STA method. Generic, works for
any device with the _STA method (assuming caller has a Pdo).
Arguments:
Pdo - For the device.
ReturnStatus - Pointer to where the status data is placed.
Return Value:
NT Status of the operation
--*/
{
ACPI_EVAL_INPUT_BUFFER inputBuffer;
ACPI_EVAL_OUTPUT_BUFFER outputBuffer;
NTSTATUS status;
PACPI_METHOD_ARGUMENT argument;
PAGED_CODE();
CmBattPrint(
CMBATT_CM_EXE,
("CmBattGetStaData: Entered with Pdo %x Tid %x\n", Pdo, GetTid() )
);
ASSERT( ReturnStatus != NULL );
*ReturnStatus = 0x0;
//
// Fill in the input data
//
inputBuffer.MethodNameAsUlong = CM_STA_METHOD;
inputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIGNATURE;
//
// Send the request along
//
status = CmBattSendDownStreamIrp(
Pdo,
IOCTL_ACPI_EVAL_METHOD,
&inputBuffer,
sizeof(ACPI_EVAL_INPUT_BUFFER),
&outputBuffer,
sizeof(ACPI_EVAL_OUTPUT_BUFFER)
);
if (!NT_SUCCESS(status)) {
CmBattPrint(
(CMBATT_ERROR | CMBATT_CM_EXE | CMBATT_BIOS),
("CmBattGetStaData: Failed _STA method - Status (0x%x)\n", status)
);
return STATUS_NO_SUCH_DEVICE;
}
//
// Grab the argument
//
argument = outputBuffer.Argument;
status = GetDwordElement( argument, ReturnStatus );
CmBattPrint(
(CMBATT_CM_EXE | CMBATT_BIOS),
("CmBattGetStaData: _STA method returned %x \n", *ReturnStatus )
);
return status;
}
NTSTATUS
CmBattGetPsrData(
IN PDEVICE_OBJECT Pdo,
OUT PULONG ReturnStatus
)
/*++
Routine Description:
Called to get the AC adapter device status via the _PSR method.
Arguments:
Pdo - For the device.
ReturnStatus - Pointer to where the status data is placed.
Return Value:
NT Status of the operation
--*/
{
ACPI_EVAL_INPUT_BUFFER inputBuffer;
ACPI_EVAL_OUTPUT_BUFFER outputBuffer;
NTSTATUS status;
PACPI_METHOD_ARGUMENT argument;
PAGED_CODE();
CmBattPrint(
CMBATT_CM_EXE,
("CmBattGetPsrData: Entered with Pdo %x Tid %x\n", Pdo, GetTid() )
);
ASSERT( ReturnStatus != NULL );
*ReturnStatus = 0x0;
//
// Fill in the input data
//
inputBuffer.MethodNameAsUlong = CM_PSR_METHOD;
inputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIGNATURE;
//
// Send the request along
//
status = CmBattSendDownStreamIrp(
Pdo,
IOCTL_ACPI_EVAL_METHOD,
&inputBuffer,
sizeof(ACPI_EVAL_INPUT_BUFFER),
&outputBuffer,
sizeof(ACPI_EVAL_OUTPUT_BUFFER)
);
if (!NT_SUCCESS(status)) {
CmBattPrint(
(CMBATT_ERROR | CMBATT_CM_EXE | CMBATT_BIOS),
("CmBattGetPsrData: Failed _PSR method - Status (0x%x)\n", status)
);
return status;
}
//
// Get the value
//
argument = outputBuffer.Argument;
status = GetDwordElement( argument, ReturnStatus );
CmBattPrint(
(CMBATT_CM_EXE | CMBATT_BIOS),
("CmBattGetPsrData: _PSR method returned %x \n", *ReturnStatus )
);
return status;
}
NTSTATUS
CmBattSetTripPpoint(
IN PCM_BATT CmBatt,
IN ULONG TripPoint
)
/*++
Routine Description:
Called to set the tripPoint via the BTP control method.
Arguments:
CmBatt - The extension for this device.
TripPoint - The desired alarm value
Return Value:
NT Status of the operation
--*/
{
ACPI_EVAL_INPUT_BUFFER_SIMPLE_INTEGER inputBuffer;
NTSTATUS status;
PAGED_CODE();
CmBattPrint(
(CMBATT_CM_EXE | CMBATT_BIOS),
("CmBattSetTripPpoint: _BTP Alarm Value %x Device %x Tid %x\n",
TripPoint, CmBatt->DeviceNumber, GetTid() )
);
//
// Fill in the input data
//
inputBuffer.MethodNameAsUlong = CM_BTP_METHOD;
inputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIMPLE_INTEGER_SIGNATURE;
inputBuffer.IntegerArgument = TripPoint;
//
// Send the request along
//
status = CmBattSendDownStreamIrp(
CmBatt->LowerDeviceObject,
IOCTL_ACPI_EVAL_METHOD,
&inputBuffer,
sizeof(ACPI_EVAL_INPUT_BUFFER_SIMPLE_INTEGER),
NULL,
0
);
if (!NT_SUCCESS(status)) {
CmBattPrint(
(CMBATT_CM_EXE | CMBATT_BIOS),
("CmBattSetTripPpoint: Failed _BTP method on device %x - Status (0x%x)\n",
CmBatt->DeviceNumber, status)
);
}
//
// Done
//
return status;
}
NTSTATUS
CmBattGetBifData(
IN PCM_BATT CmBatt,
OUT PCM_BIF_BAT_INFO BifBuf
)
/*++
Routine Description:
Called to read the BIF package from ACPI
Arguments:
CmBatt - The extension for this device.
BifBuf - Output buffer for the BIF data
Return Value:
NT Status of the operation
--*/
{
ACPI_EVAL_INPUT_BUFFER inputBuffer;
NTSTATUS status;
PACPI_EVAL_OUTPUT_BUFFER outputBuffer;
PACPI_METHOD_ARGUMENT argument;
CmBattPrint(
CMBATT_CM_EXE,
("CmBattGetBifData: Buffer (0x%x) Device %x Tid %x\n",
BifBuf, CmBatt->DeviceNumber, GetTid() )
);
//
// Allocate a buffer for this
//
outputBuffer = ExAllocatePoolWithTag(
PagedPool,
EXPECTED_DATA_SIZE,
'MtaB'
);
if (!outputBuffer) {
CmBattPrint(
(CMBATT_ERROR | CMBATT_CM_EXE),
("CmBattGetBifData: Failed to allocate Buffer\n")
);
return STATUS_INSUFFICIENT_RESOURCES;
}
//
// Clear the buffers
//
RtlZeroMemory(outputBuffer, EXPECTED_DATA_SIZE);
RtlZeroMemory(BifBuf, sizeof(CM_BIF_BAT_INFO));
//
// Set the request data
//
inputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIGNATURE;
inputBuffer.MethodNameAsUlong = CM_BIF_METHOD;
//
// Send the request along
//
status = CmBattSendDownStreamIrp(
CmBatt->LowerDeviceObject,
IOCTL_ACPI_EVAL_METHOD,
&inputBuffer,
sizeof(ACPI_EVAL_INPUT_BUFFER),
outputBuffer,
EXPECTED_DATA_SIZE
);
if (!NT_SUCCESS(status)) {
CmBattPrint(
(CMBATT_ERROR | CMBATT_CM_EXE | CMBATT_BIOS),
("CmBattGetBifData: Failed _BIF method on device %x - Status (0x%x)\n",
CmBatt->DeviceNumber, status)
);
goto CmBattGetBifDataExit;
}
//
// Sanity check the return count
//
if (outputBuffer->Count != NUMBER_OF_BIF_ELEMENTS) {
//
// Package did not contain the correct number of elements to be a BIF
//
CmBattPrint(
(CMBATT_ERROR | CMBATT_CM_EXE | CMBATT_BIOS),
("CmBattGetBifData: _BIF returned %d elements. BIF requires %d\n",
outputBuffer->Count,
NUMBER_OF_BIF_ELEMENTS)
);
status = STATUS_ACPI_INVALID_DATA;
goto CmBattGetBifDataExit;
}
//
// Look at the return arguments
//
argument = outputBuffer->Argument;
//
// Parse the package data that is returned. This should look like:
//
status = GetDwordElement (argument, &BifBuf->PowerUnit);
if (!NT_SUCCESS (status)) {
CmBattPrint(
(CMBATT_ERROR | CMBATT_CM_EXE | CMBATT_BIOS),
("CmBattGetBifData: Failed to get PowerUnit\n")
);
goto CmBattGetBifDataExit;
}
argument = ACPI_METHOD_NEXT_ARGUMENT( argument );
status = GetDwordElement (argument, &BifBuf->DesignCapacity);
if (!NT_SUCCESS (status)) {
CmBattPrint(
(CMBATT_ERROR | CMBATT_CM_EXE | CMBATT_BIOS),
("CmBattGetBifData: Failed to get DesignCapacity\n")
);
goto CmBattGetBifDataExit;
}
argument = ACPI_METHOD_NEXT_ARGUMENT( argument );
status = GetDwordElement (argument, &BifBuf->LastFullChargeCapacity);
if (!NT_SUCCESS (status)) {
CmBattPrint(
(CMBATT_ERROR | CMBATT_CM_EXE | CMBATT_BIOS),
("CmBattGetBifData: Failed to get LastFullChargeCapacity\n")
);
goto CmBattGetBifDataExit;
}
argument = ACPI_METHOD_NEXT_ARGUMENT( argument );
status = GetDwordElement (argument, &BifBuf->BatteryTechnology);
if (!NT_SUCCESS (status)) {
CmBattPrint(
(CMBATT_ERROR | CMBATT_CM_EXE | CMBATT_BIOS),
("CmBattGetBifData: Failed to get BatteryTechnology\n")
);
goto CmBattGetBifDataExit;
}
argument = ACPI_METHOD_NEXT_ARGUMENT( argument );
status = GetDwordElement (argument, &BifBuf->DesignVoltage);
if (!NT_SUCCESS (status)) {
CmBattPrint(
(CMBATT_ERROR | CMBATT_CM_EXE | CMBATT_BIOS),
("CmBattGetBifData: Failed to get DesignVoltage\n")
);
goto CmBattGetBifDataExit;
}
argument = ACPI_METHOD_NEXT_ARGUMENT( argument );
status = GetDwordElement (argument, &BifBuf->DesignCapacityOfWarning);
if (!NT_SUCCESS (status)) {
CmBattPrint(
(CMBATT_ERROR | CMBATT_CM_EXE | CMBATT_BIOS),
("CmBattGetBifData: Failed to get DesignCapacityOfWarning\n")
);
goto CmBattGetBifDataExit;
}
argument = ACPI_METHOD_NEXT_ARGUMENT( argument );
status = GetDwordElement (argument, &BifBuf->DesignCapacityOfLow);
if (!NT_SUCCESS (status)) {
CmBattPrint(
(CMBATT_ERROR | CMBATT_CM_EXE | CMBATT_BIOS),
("CmBattGetBifData: Failed to get DesignCapacityOfLow\n")
);
goto CmBattGetBifDataExit;
}
argument = ACPI_METHOD_NEXT_ARGUMENT( argument );
status = GetDwordElement (argument, &BifBuf->BatteryCapacityGran_1);
if (!NT_SUCCESS (status)) {
CmBattPrint(
(CMBATT_ERROR | CMBATT_CM_EXE | CMBATT_BIOS),
("CmBattGetBifData: Failed to get BatteryCapacityGran_1\n")
);
goto CmBattGetBifDataExit;
}
argument = ACPI_METHOD_NEXT_ARGUMENT( argument );
status = GetDwordElement (argument, &BifBuf->BatteryCapacityGran_2);
if (!NT_SUCCESS (status)) {
CmBattPrint(
(CMBATT_ERROR | CMBATT_CM_EXE | CMBATT_BIOS),
("CmBattGetBifData: Failed to get BatteryCapacityGran_2\n")
);
goto CmBattGetBifDataExit;
}
RtlZeroMemory (&BifBuf->ModelNumber[0], CM_MAX_STRING_LENGTH);
argument = ACPI_METHOD_NEXT_ARGUMENT( argument );
status = GetStringElement (argument, &BifBuf->ModelNumber[0]);
if (!NT_SUCCESS (status)) {
CmBattPrint(
(CMBATT_ERROR | CMBATT_CM_EXE | CMBATT_BIOS),
("CmBattGetBifData: Failed to get ModelNumber\n")
);
goto CmBattGetBifDataExit;
}
RtlZeroMemory (&BifBuf->SerialNumber[0], CM_MAX_STRING_LENGTH);
argument = ACPI_METHOD_NEXT_ARGUMENT( argument );
status = GetStringElement (argument, &BifBuf->SerialNumber[0]);
if (!NT_SUCCESS (status)) {
CmBattPrint(
(CMBATT_ERROR | CMBATT_CM_EXE | CMBATT_BIOS),
("CmBattGetBifData: Failed to get SerialNumber\n")
);
goto CmBattGetBifDataExit;
}
RtlZeroMemory (&BifBuf->BatteryType[0], CM_MAX_STRING_LENGTH);
argument = ACPI_METHOD_NEXT_ARGUMENT( argument );
status = GetStringElement (argument, &BifBuf->BatteryType[0]);
if (!NT_SUCCESS (status)) {
CmBattPrint(
(CMBATT_ERROR | CMBATT_CM_EXE | CMBATT_BIOS),
("CmBattGetBifData: Failed to get BatteryType\n")
);
goto CmBattGetBifDataExit;
}
RtlZeroMemory (&BifBuf->OEMInformation[0], CM_MAX_STRING_LENGTH);
argument = ACPI_METHOD_NEXT_ARGUMENT( argument );
//
// This returns an ASCIIZ string normally,
// but returns integer 0x00 if OEMInformation isn't supported.
//
if (argument->Type == ACPI_METHOD_ARGUMENT_INTEGER) {
if (argument->Argument != 0) {
CmBattPrint(
(CMBATT_ERROR | CMBATT_CM_EXE | CMBATT_BIOS),
("CmBattGetBifData: Failed to get OEMInformation\n")
);
goto CmBattGetBifDataExit;
}
BifBuf->OEMInformation[0] = 0;
status = STATUS_SUCCESS;
} else {
status = GetStringElement (argument, &BifBuf->OEMInformation[0]);
if (!NT_SUCCESS (status)) {
CmBattPrint(
(CMBATT_ERROR | CMBATT_CM_EXE | CMBATT_BIOS),
("CmBattGetBifData: OEMInformation not supported\n")
);
}
}
CmBattGetBifDataExit:
//
// Done
//
ExFreePool (outputBuffer);
return status;
}
NTSTATUS
CmBattGetBstData(
IN PCM_BATT CmBatt,
OUT PCM_BST_BAT_INFO BstBuf
)
/*++
Routine Description:
Called to read the BST package from ACPI
Arguments:
CmBatt - The extension for this device.
BstBuf - Output buffer for the BST data
Return Value:
NT Status of the operation
--*/
{
ACPI_EVAL_INPUT_BUFFER inputBuffer;
NTSTATUS status;
PACPI_EVAL_OUTPUT_BUFFER outputBuffer;
PACPI_METHOD_ARGUMENT argument;
CmBattPrint(
CMBATT_CM_EXE,
("CmBattGetBstData: Buffer (0x%x) Device %x Tid %x\n",
BstBuf, CmBatt->DeviceNumber, GetTid() )
);
//
// Allocate a buffer for this
//
outputBuffer = ExAllocatePoolWithTag(
PagedPool,
EXPECTED_DATA_SIZE,
'MtaB'
);
if (!outputBuffer) {
CmBattPrint(
(CMBATT_ERROR | CMBATT_CM_EXE),
("CmBattGetBstData: Failed to allocate Buffer\n")
);
return STATUS_INSUFFICIENT_RESOURCES;
}
//
// Clear the buffers
//
RtlZeroMemory(outputBuffer, EXPECTED_DATA_SIZE);
RtlZeroMemory(BstBuf, sizeof(CM_BST_BAT_INFO));
//
// Set the request data
//
inputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIGNATURE;
inputBuffer.MethodNameAsUlong = CM_BST_METHOD;
//
// Send the request along
//
status = CmBattSendDownStreamIrp(
CmBatt->LowerDeviceObject,
IOCTL_ACPI_EVAL_METHOD,
&inputBuffer,
sizeof(ACPI_EVAL_INPUT_BUFFER),
outputBuffer,
EXPECTED_DATA_SIZE
);
if (!NT_SUCCESS(status)) {
CmBattPrint(
(CMBATT_ERROR | CMBATT_CM_EXE | CMBATT_BIOS),
("CmBattGetBstData: Failed _BST method on device %x - Status (0x%x)\n",
CmBatt->DeviceNumber, status)
);
goto CmBattGetBstDataExit;
}
//
// Sanity check the return value
//
if (outputBuffer->Signature != ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE ||
outputBuffer->Count != NUMBER_OF_BST_ELEMENTS) {
//
// Package did not contain the correct number of elements to be a BIF
//
CmBattPrint(
(CMBATT_ERROR | CMBATT_CM_EXE | CMBATT_BIOS),
("CmBattGetBstData: _BST returned %d elements. BIF requires %d\n",
outputBuffer->Count,
NUMBER_OF_BST_ELEMENTS)
);
status = STATUS_ACPI_INVALID_DATA;
goto CmBattGetBstDataExit;
}
//
// Look at the return arguments
//
argument = outputBuffer->Argument;
//
// Parse the package data that is returned. This should look like:
//
status = GetDwordElement (argument, &BstBuf->BatteryState);
if (!NT_SUCCESS (status)) {
CmBattPrint(
(CMBATT_ERROR | CMBATT_CM_EXE | CMBATT_BIOS),
("CmBattGetBstData: Failed to get BatteryState\n")
);
goto CmBattGetBstDataExit;
}
argument = ACPI_METHOD_NEXT_ARGUMENT( argument );
status = GetDwordElement (argument, &BstBuf->PresentRate);
if (!NT_SUCCESS (status)) {
CmBattPrint(
(CMBATT_ERROR | CMBATT_CM_EXE | CMBATT_BIOS),
("CmBattGetBstData: Failed to get PresentRate\n")
);
goto CmBattGetBstDataExit;
}
argument = ACPI_METHOD_NEXT_ARGUMENT( argument );
status = GetDwordElement (argument, &BstBuf->RemainingCapacity);
if (!NT_SUCCESS (status)) {
CmBattPrint(
(CMBATT_ERROR | CMBATT_CM_EXE | CMBATT_BIOS),
("CmBattGetBstData: Failed to get RemainingCapacity\n")
);
goto CmBattGetBstDataExit;
}
argument = ACPI_METHOD_NEXT_ARGUMENT( argument );
status = GetDwordElement (argument, &BstBuf->PresentVoltage);
if (!NT_SUCCESS (status)) {
CmBattPrint(
(CMBATT_ERROR | CMBATT_CM_EXE | CMBATT_BIOS),
("CmBattGetBstData: Failed to get PresentVoltage\n")
);
goto CmBattGetBstDataExit;
}
CmBattPrint ((CMBATT_TRACE | CMBATT_DATA | CMBATT_BIOS),
("CmBattGetBstData: (BST) State=%x Rate=%x Capacity=%x Volts=%x\n",
BstBuf->BatteryState, BstBuf->PresentRate,
BstBuf->RemainingCapacity, BstBuf->PresentVoltage));
//
// Done --- cleanup
//
CmBattGetBstDataExit:
ExFreePool( outputBuffer );
return status;
}
NTSTATUS
GetDwordElement (
IN PACPI_METHOD_ARGUMENT Argument,
OUT PULONG PDword
)
/*++
Routine Description:
This routine cracks the integer value from the argument and stores it
in the supplied pointer to a ULONG
Arguments:
Argument - Points to the argument to parse
PDword - Where to store the argument
Return Value:
NT Status of the operation
--*/
{
//
// Check to see if we have the right type of data
//
if (Argument->Type != ACPI_METHOD_ARGUMENT_INTEGER) {
CmBattPrint(
(CMBATT_ERROR | CMBATT_CM_EXE),
("GetDwordElement: Object contained wrong data type - %d\n",
Argument->Type)
);
return STATUS_ACPI_INVALID_DATA;
}
//
// Copy the DWORD
//
*PDword = Argument->Argument;
//
// Success!
//
return STATUS_SUCCESS;
}
NTSTATUS
GetStringElement (
IN PACPI_METHOD_ARGUMENT Argument,
OUT PUCHAR PBuffer
)
/*++
Routine Description:
This routine cracks the string from the argument and stroes it in the
supplied pointer to a PUCHAR
Note: A buffer is allowed as well.
Arguments:
Argument - Points to the argument to parse
PBuffer - Pointer to storage for the string
Return Value:
NT Status of the operation
--*/
{
//
// Check to see if we have the right type of data
//
if (Argument->Type != ACPI_METHOD_ARGUMENT_STRING &&
Argument->Type != ACPI_METHOD_ARGUMENT_BUFFER) {
CmBattPrint(
(CMBATT_ERROR | CMBATT_CM_EXE),
("GetStringElement: Object contained wrong data type - %d\n",
Argument->Type)
);
return STATUS_ACPI_INVALID_DATA;
}
//
// Check to see if the return buffer is long enough
//
if (Argument->DataLength >= CM_MAX_STRING_LENGTH) {
CmBattPrint(
(CMBATT_ERROR | CMBATT_CM_EXE),
("GetStringElement: return buffer not big enough - %d\n",
Argument->DataLength)
);
return STATUS_BUFFER_TOO_SMALL;
}
//
// Copy the string
//
RtlCopyMemory (PBuffer, Argument->Data, Argument->DataLength);
//
// Success
//
return STATUS_SUCCESS;
}