[CMBATT] Implement support for the _BIX method

_BIX is basically _BIF but with more information added, such as cycle count, measurement capacity accuracy and whatnot.
Starting with ACPI 4.0 _BIF is rendered obsolete and as a matter of fact a lot of modern hardware fill their ACPI machine data to _BIX.

ReactOS must go forward and beyond, compatibility with _BIF is kept. NOTE that a machine can ONLY support one battery static information method!

CORE-18969
CORE-19452
This commit is contained in:
George Bișoc 2024-12-17 23:22:39 +01:00
parent 205eadcb84
commit faf6123150
No known key found for this signature in database
GPG key ID: 688C4FBE25D7DEF6
3 changed files with 469 additions and 74 deletions

View file

@ -273,71 +273,276 @@ CmBattUnload(IN PDRIVER_OBJECT DriverObject)
}
}
/**
* @brief
* Retrieves the static information of the battery.
*
* @param[in] DeviceExtension
* A pointer to a Control Method (CM) battery device extension.
* It is used for debugging purposes.
*
* @param[out] UseBix
* A pointer to a boolean value, returned to caller. This can return
* TRUE if this machine supports the _BIX method, FALSE otherwise.
*
* @param[out] BattInfo
* A pointer to a structure that contains the static info of the
* battery. ONLY ONE type of information is filled. See Remarks.
*
* @return
* Returns STATUS_INSUFFICIENT_RESOURCES if there is no enough
* memory to allocate for the static info buffer. Returns
* STATUS_SUCCESS if the operation has succeeded. Otherwise an
* error NTSTATUS code is returned.
*
* @remarks
* It is important to note that a machine can only support one method,
* _BIX or _BIF. Starting with ACPI 4.0, _BIF has become deprecated.
* The caller MUST INSPECT the boolean value, ExtendedData, in order
* to determine if the machine has returned the extended information
* data or not.
*/
static
NTSTATUS
CmBattGetBattStaticInfo(
_In_ PCMBATT_DEVICE_EXTENSION DeviceExtension,
_Out_ PBOOLEAN UseBix,
_Outptr_ PACPI_BATT_STATIC_INFO *BattInfo)
{
NTSTATUS Status;
ACPI_BIF_DATA BifData;
ACPI_BIX_DATA BixData;
PACPI_BATT_STATIC_INFO Info;
/* Allocate pool space for the static information */
Info = ExAllocatePoolZero(PagedPool,
sizeof(*Info),
CMBATT_BATT_STATIC_INFO_TAG);
if (Info == NULL)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
/* Assume this machine supports the _BIX method */
*UseBix = TRUE;
/* Retrieve extended battery static info from _BIX method */
Status = CmBattGetBixData(DeviceExtension, &BixData);
if (!NT_SUCCESS(Status))
{
/*
* It failed. This can be expected because not every machine supports
* _BIX, especially the older machines which do not support ACPI 4.0.
* Fallback to _BIF at this point.
*/
Status = CmBattGetBifData(DeviceExtension, &BifData);
if (!NT_SUCCESS(Status))
{
/* That failed too, time to punt */
ExFreePoolWithTag(Info, CMBATT_BATT_STATIC_INFO_TAG);
return Status;
}
/* Acknowledge the caller it will be going to use _BIF */
*UseBix = FALSE;
Info->BifData = BifData;
}
else
{
Info->BixData = BixData;
}
/* Return the battery static info to caller */
Info->ExtendedData = *UseBix;
*BattInfo = Info;
return Status;
}
/**
* @brief
* Verifies the extended battery information (_BIX) and translates
* such data to the BATTERY_INFORMATION structure.
*
* @param[in] DeviceExtension
* A pointer to a Control Method (CM) battery device extension.
* It is used to gather _BIX data.
*
* @param[in,out] Info
* A pointer to a structure of which this function fills in
* battery information that can be by other battery miniport
* drivers, such as the Composite Battery driver.
*/
static
VOID
CmBattVerifyBixData(
_In_ PCMBATT_DEVICE_EXTENSION DeviceExtension,
_Inout_ PBATTERY_INFORMATION Info)
{
ULONG DesignVoltage;
ACPI_BIX_DATA BixData = DeviceExtension->BattInfo.BixData;
/* Copy the battery info data */
Info->Technology = BixData.BatteryTechnology;
Info->CycleCount = BixData.CycleCount;
RtlCopyMemory(Info->Chemistry, BixData.BatteryType, 4);
/* Check if the power stats are reported in ampere or watts */
if (BixData.PowerUnit == ACPI_BATT_POWER_UNIT_AMPS)
{
/*
* We have got power stats in milli-ampere but ReactOS expects the values
* to be reported in milli-watts, so we have to convert them.
* In order to do so we must expect the design voltage of the battery
* is not unknown.
*/
DesignVoltage = BixData.DesignVoltage;
if ((DesignVoltage != BATTERY_UNKNOWN_VOLTAGE) && (DesignVoltage != 0))
{
/* Convert the design capacity */
Info->DesignedCapacity = CONVERT_BATT_INFO(BixData.DesignCapacity, DesignVoltage);
/* Convert the full charged capacity */
Info->FullChargedCapacity = CONVERT_BATT_INFO(BixData.LastFullCapacity, DesignVoltage);
/* Convert the low capacity alarm (DefaultAlert1) */
Info->DefaultAlert1 = CONVERT_BATT_INFO(BixData.DesignCapacityLow, DesignVoltage);
/* Convert the designed capacity warning alarm (DefaultAlert2) */
Info->DefaultAlert2 = CONVERT_BATT_INFO(BixData.DesignCapacityWarning, DesignVoltage);
}
else
{
/*
* Without knowing the nominal designed voltage of the battery
* we cannot determine the power consumption of this battery.
*/
Info->DesignedCapacity = BATTERY_UNKNOWN_CAPACITY;
Info->FullChargedCapacity = BATTERY_UNKNOWN_CAPACITY;
Info->DefaultAlert1 = BATTERY_UNKNOWN_CAPACITY;
Info->DefaultAlert2 = BATTERY_UNKNOWN_CAPACITY;
}
}
else
{
/* The stats are in milli-watts, use them directly */
Info->DesignedCapacity = BixData.DesignCapacity;
Info->FullChargedCapacity = BixData.LastFullCapacity;
Info->DefaultAlert1 = BixData.DesignCapacityLow;
Info->DefaultAlert2 = BixData.DesignCapacityWarning;
}
}
/**
* @brief
* Verifies the battery information (_BIF) and translates
* such data to the BATTERY_INFORMATION structure.
*
* @param[in] DeviceExtension
* A pointer to a Control Method (CM) battery device extension.
* It is used to gather _BIF data.
*
* @param[in,out] Info
* A pointer to a structure of which this function fills in
* battery information that can be by other battery miniport
* drivers, such as the Composite Battery driver.
*/
static
VOID
CmBattVerifyBifData(
_In_ PCMBATT_DEVICE_EXTENSION DeviceExtension,
_Inout_ PBATTERY_INFORMATION Info)
{
ULONG DesignVoltage;
ACPI_BIF_DATA BifData = DeviceExtension->BattInfo.BifData;
/* Copy the battery info data, CycleCount is not supported in _BIF */
Info->Technology = BifData.BatteryTechnology;
Info->CycleCount = 0;
RtlCopyMemory(Info->Chemistry, BifData.BatteryType, 4);
/* Check if the power stats are reported in ampere or watts */
if (BifData.PowerUnit == ACPI_BATT_POWER_UNIT_AMPS)
{
/*
* We have got power stats in milli-ampere but ReactOS expects the values
* to be reported in milli-watts, so we have to convert them.
* In order to do so we must expect the design voltage of the battery
* is not unknown.
*/
DesignVoltage = BifData.DesignVoltage;
if ((DesignVoltage != BATTERY_UNKNOWN_VOLTAGE) && (DesignVoltage != 0))
{
/* Convert the design capacity */
Info->DesignedCapacity = CONVERT_BATT_INFO(BifData.DesignCapacity, DesignVoltage);
/* Convert the full charged capacity */
Info->FullChargedCapacity = CONVERT_BATT_INFO(BifData.LastFullCapacity, DesignVoltage);
/* Convert the low capacity alarm (DefaultAlert1) */
Info->DefaultAlert1 = CONVERT_BATT_INFO(BifData.DesignCapacityLow, DesignVoltage);
/* Convert the designed capacity warning alarm (DefaultAlert2) */
Info->DefaultAlert2 = CONVERT_BATT_INFO(BifData.DesignCapacityWarning, DesignVoltage);
}
else
{
/*
* Without knowing the nominal designed voltage of the battery
* we cannot determine the power consumption of this battery.
*/
Info->DesignedCapacity = BATTERY_UNKNOWN_CAPACITY;
Info->FullChargedCapacity = BATTERY_UNKNOWN_CAPACITY;
Info->DefaultAlert1 = BATTERY_UNKNOWN_CAPACITY;
Info->DefaultAlert2 = BATTERY_UNKNOWN_CAPACITY;
}
}
else
{
/* The stats are in milli-watts, use them directly */
Info->DesignedCapacity = BifData.DesignCapacity;
Info->FullChargedCapacity = BifData.LastFullCapacity;
Info->DefaultAlert1 = BifData.DesignCapacityLow;
Info->DefaultAlert2 = BifData.DesignCapacityWarning;
}
}
NTSTATUS
NTAPI
CmBattVerifyStaticInfo(
_Inout_ PCMBATT_DEVICE_EXTENSION DeviceExtension,
_In_ ULONG BatteryTag)
{
ACPI_BIF_DATA BifData;
ULONG DesignVoltage;
PBATTERY_INFORMATION Info = &DeviceExtension->BatteryInformation;
NTSTATUS Status;
BOOLEAN UseBix;
PACPI_BATT_STATIC_INFO BattInfo;
PBATTERY_INFORMATION Info = &DeviceExtension->BatteryInformation;
Status = CmBattGetBifData(DeviceExtension, &BifData);
/* FIXME: This function is not fully implemented, more checks need to be implemented */
UNREFERENCED_PARAMETER(BatteryTag);
/* Retrieve the battery static info */
Status = CmBattGetBattStaticInfo(DeviceExtension, &UseBix, &BattInfo);
if (NT_SUCCESS(Status))
{
/* Initialize the battery information data */
RtlZeroMemory(Info, sizeof(*Info));
Info->Capabilities = BATTERY_SYSTEM_BATTERY;
Info->Technology = BifData.BatteryTechnology;
RtlCopyMemory(Info->Chemistry, BifData.BatteryType, 4);
// FIXME: take from _BIX method: Info->CycleCount
DeviceExtension->BifData = BifData;
DesignVoltage = DeviceExtension->BifData.DesignVoltage;
/* Check if the power stats are reported in ampere or watts */
if (BifData.PowerUnit == ACPI_BATT_POWER_UNIT_AMPS)
/* Copy the static information to the device extension of the battery */
RtlCopyMemory(&DeviceExtension->BattInfo, BattInfo, sizeof(*BattInfo));
/* Check if the data from _BIX has to be used or not */
if (UseBix)
{
/*
* We have got power stats in milli-ampere but ReactOS expects the values
* to be reported in milli-watts, so we have to convert them.
* In order to do so we must expect the design voltage of the battery
* is not unknown.
*/
if ((DesignVoltage != BATTERY_UNKNOWN_VOLTAGE) && (DesignVoltage != 0))
{
/* Convert the design capacity */
Info->DesignedCapacity = CONVERT_BATT_INFO(BifData.DesignCapacity, DesignVoltage);
/* Convert the full charged capacity */
Info->FullChargedCapacity = CONVERT_BATT_INFO(BifData.LastFullCapacity, DesignVoltage);
/* Convert the low capacity alarm (DefaultAlert1) */
Info->DefaultAlert1 = CONVERT_BATT_INFO(BifData.DesignCapacityLow, DesignVoltage);
/* Convert the designed capacity warning alarm (DefaultAlert2) */
Info->DefaultAlert2 = CONVERT_BATT_INFO(BifData.DesignCapacityWarning, DesignVoltage);
}
else
{
/*
* Without knowing the nominal designed voltage of the battery
* we cannot determine the power consumption of this battery.
*/
Info->DesignedCapacity = BATTERY_UNKNOWN_CAPACITY;
Info->FullChargedCapacity = BATTERY_UNKNOWN_CAPACITY;
Info->DefaultAlert1 = BATTERY_UNKNOWN_CAPACITY;
Info->DefaultAlert2 = BATTERY_UNKNOWN_CAPACITY;
}
CmBattVerifyBixData(DeviceExtension, Info);
}
else
{
/* The stats are in milli-watts, use them directly */
Info->DesignedCapacity = BifData.DesignCapacity;
Info->FullChargedCapacity = BifData.LastFullCapacity;
Info->DefaultAlert1 = BifData.DesignCapacityLow;
Info->DefaultAlert2 = BifData.DesignCapacityWarning;
CmBattVerifyBifData(DeviceExtension, Info);
}
/* Free the static information buffer as we already copied it */
ExFreePoolWithTag(BattInfo, CMBATT_BATT_STATIC_INFO_TAG);
}
return Status;
@ -530,20 +735,44 @@ CmBattIoctl(IN PDEVICE_OBJECT DeviceObject,
}
break;
case IOCTL_BATTERY_QUERY_BIF:
case IOCTL_BATTERY_QUERY_BIF_BIX:
/* Data is 1060 bytes long */
if (OutputBufferLength == sizeof(ACPI_BIF_DATA))
/* Return the battery static information to the caller depending on the supported ACPI method */
if (DeviceExtension->BattInfo.ExtendedData)
{
/* Query it */
Status = CmBattGetBifData(DeviceExtension,
Irp->AssociatedIrp.SystemBuffer);
if (NT_SUCCESS(Status)) Irp->IoStatus.Information = sizeof(ACPI_BIF_DATA);
if (OutputBufferLength == sizeof(ACPI_BIX_DATA))
{
/* Query it */
Status = CmBattGetBixData(DeviceExtension,
Irp->AssociatedIrp.SystemBuffer);
if (NT_SUCCESS(Status))
{
Irp->IoStatus.Information = sizeof(ACPI_BIX_DATA);
}
}
else
{
/* Buffer size invalid */
Status = STATUS_INVALID_BUFFER_SIZE;
}
}
else
{
/* Buffer size invalid */
Status = STATUS_INVALID_BUFFER_SIZE;
if (OutputBufferLength == sizeof(ACPI_BIF_DATA))
{
/* Query it */
Status = CmBattGetBifData(DeviceExtension,
Irp->AssociatedIrp.SystemBuffer);
if (NT_SUCCESS(Status))
{
Irp->IoStatus.Information = sizeof(ACPI_BIF_DATA);
}
}
else
{
/* Buffer size invalid */
Status = STATUS_INVALID_BUFFER_SIZE;
}
}
break;
@ -699,7 +928,7 @@ CmBattSetStatusNotify(IN PCMBATT_DEVICE_EXTENSION DeviceExtension,
{
NTSTATUS Status;
ACPI_BST_DATA BstData;
ULONG Capacity, NewTripPoint, TripPoint, DesignVoltage;
ULONG PowerUnit, Capacity, NewTripPoint, TripPoint, DesignVoltage;
BOOLEAN Charging;
PAGED_CODE();
if (CmBattDebug & (CMBATT_ACPI_WARNING | CMBATT_GENERIC_INFO))
@ -738,11 +967,22 @@ CmBattSetStatusNotify(IN PCMBATT_DEVICE_EXTENSION DeviceExtension,
NewTripPoint = BatteryNotify->LowCapacity;
}
/* Is this machine supporting _BIX or _BIF? */
if (DeviceExtension->BattInfo.ExtendedData)
{
PowerUnit = DeviceExtension->BattInfo.BixData.PowerUnit;
DesignVoltage = DeviceExtension->BattInfo.BixData.DesignVoltage;
}
else
{
PowerUnit = DeviceExtension->BattInfo.BifData.PowerUnit;
DesignVoltage = DeviceExtension->BattInfo.BifData.DesignVoltage;
}
/* Do we have data in Amps or Watts? */
if (DeviceExtension->BifData.PowerUnit == ACPI_BATT_POWER_UNIT_AMPS)
if (PowerUnit == ACPI_BATT_POWER_UNIT_AMPS)
{
/* We need the voltage to do the conversion */
DesignVoltage = DeviceExtension->BifData.DesignVoltage;
if ((DesignVoltage != BATTERY_UNKNOWN_VOLTAGE) && (DesignVoltage))
{
/* Convert from mAh into Ah */
@ -846,6 +1086,7 @@ CmBattGetBatteryStatus(IN PCMBATT_DEVICE_EXTENSION DeviceExtension,
ULONG PsrData = 0;
NTSTATUS Status;
ULONG BstState;
ULONG PowerUnit;
ULONG DesignVoltage, PresentRate, RemainingCapacity;
PAGED_CODE();
if (CmBattDebug & CMBATT_GENERIC_INFO)
@ -946,13 +1187,24 @@ CmBattGetBatteryStatus(IN PCMBATT_DEVICE_EXTENSION DeviceExtension,
DbgPrint("CmBattGetBatteryStatus: AC adapter is NOT connected\n");
}
/* Is this machine supporting _BIX or _BIF? */
if (DeviceExtension->BattInfo.ExtendedData)
{
PowerUnit = DeviceExtension->BattInfo.BixData.PowerUnit;
DesignVoltage = DeviceExtension->BattInfo.BixData.DesignVoltage;
}
else
{
PowerUnit = DeviceExtension->BattInfo.BifData.PowerUnit;
DesignVoltage = DeviceExtension->BattInfo.BifData.DesignVoltage;
}
/* Get some data we'll need */
DesignVoltage = DeviceExtension->BifData.DesignVoltage;
PresentRate = DeviceExtension->BstData.PresentRate;
RemainingCapacity = DeviceExtension->BstData.RemainingCapacity;
/* Check if we have battery data in Watts instead of Amps */
if (DeviceExtension->BifData.PowerUnit == ACPI_BATT_POWER_UNIT_WATTS)
if (PowerUnit == ACPI_BATT_POWER_UNIT_WATTS)
{
/* Get the data from the BST */
DeviceExtension->RemainingCapacity = RemainingCapacity;
@ -970,7 +1222,7 @@ CmBattGetBatteryStatus(IN PCMBATT_DEVICE_EXTENSION DeviceExtension,
}
}
}
else if ((DesignVoltage != CM_UNKNOWN_VALUE) && (DesignVoltage != 0)) // Same as doing DeviceExtension->BifData.PowerUnit == ACPI_BATT_POWER_UNIT_AMPS
else if ((DesignVoltage != CM_UNKNOWN_VALUE) && (DesignVoltage != 0)) // Same as doing PowerUnit == ACPI_BATT_POWER_UNIT_AMPS
{
/* We have voltage data, what about capacity? */
if (RemainingCapacity == CM_UNKNOWN_VALUE)
@ -1180,7 +1432,14 @@ CmBattQueryInformation(IN PCMBATT_DEVICE_EXTENSION FdoExtension,
case BatteryDeviceName:
/* Build the model number string */
RtlInitAnsiString(&TempString, FdoExtension->BifData.ModelNumber);
if (FdoExtension->BattInfo.ExtendedData)
{
RtlInitAnsiString(&TempString, FdoExtension->BattInfo.BixData.ModelNumber);
}
else
{
RtlInitAnsiString(&TempString, FdoExtension->BattInfo.BifData.ModelNumber);
}
/* Convert it to Unicode */
InfoString.Buffer = InfoBuffer;
@ -1202,7 +1461,14 @@ CmBattQueryInformation(IN PCMBATT_DEVICE_EXTENSION FdoExtension,
case BatteryManufactureName:
/* Build the OEM info string */
RtlInitAnsiString(&TempString, FdoExtension->BifData.OemInfo);
if (FdoExtension->BattInfo.ExtendedData)
{
RtlInitAnsiString(&TempString, FdoExtension->BattInfo.BixData.OemInfo);
}
else
{
RtlInitAnsiString(&TempString, FdoExtension->BattInfo.BifData.OemInfo);
}
/* Convert it to Unicode */
InfoString.Buffer = InfoBuffer;
@ -1217,7 +1483,14 @@ CmBattQueryInformation(IN PCMBATT_DEVICE_EXTENSION FdoExtension,
case BatteryUniqueID:
/* Build the serial number string */
RtlInitAnsiString(&TempString, FdoExtension->BifData.SerialNumber);
if (FdoExtension->BattInfo.ExtendedData)
{
RtlInitAnsiString(&TempString, FdoExtension->BattInfo.BixData.SerialNumber);
}
else
{
RtlInitAnsiString(&TempString, FdoExtension->BattInfo.BifData.SerialNumber);
}
/* Convert it to Unicode */
InfoString.Buffer = InfoBuffer;
@ -1229,10 +1502,18 @@ CmBattQueryInformation(IN PCMBATT_DEVICE_EXTENSION FdoExtension,
TempString2.MaximumLength = sizeof(TempBuffer);
/* Check if there's an OEM string */
if (FdoExtension->BifData.OemInfo[0])
if ((FdoExtension->BattInfo.ExtendedData && FdoExtension->BattInfo.BixData.OemInfo[0]) ||
FdoExtension->BattInfo.BifData.OemInfo[0])
{
/* Build the OEM info string */
RtlInitAnsiString(&TempString, FdoExtension->BifData.OemInfo);
if (FdoExtension->BattInfo.ExtendedData)
{
RtlInitAnsiString(&TempString, FdoExtension->BattInfo.BixData.OemInfo);
}
else
{
RtlInitAnsiString(&TempString, FdoExtension->BattInfo.BifData.OemInfo);
}
/* Convert it to Unicode and append it */
RtlAnsiStringToUnicodeString(&TempString2, &TempString, 0);
@ -1240,7 +1521,14 @@ CmBattQueryInformation(IN PCMBATT_DEVICE_EXTENSION FdoExtension,
}
/* Build the model number string */
RtlInitAnsiString(&TempString, FdoExtension->BifData.ModelNumber);
if (FdoExtension->BattInfo.ExtendedData)
{
RtlInitAnsiString(&TempString, FdoExtension->BattInfo.BixData.ModelNumber);
}
else
{
RtlInitAnsiString(&TempString, FdoExtension->BattInfo.BifData.ModelNumber);
}
/* Convert it to Unicode and append it */
RtlAnsiStringToUnicodeString(&TempString2, &TempString, 0);

View file

@ -26,7 +26,7 @@
#define IOCTL_BATTERY_SET_TRIP_POINT \
CTL_CODE(FILE_DEVICE_BATTERY, 0x104, METHOD_BUFFERED, FILE_READ_ACCESS) // 0x294410
#define IOCTL_BATTERY_QUERY_BIF \
#define IOCTL_BATTERY_QUERY_BIF_BIX \
CTL_CODE(FILE_DEVICE_BATTERY, 0x105, METHOD_BUFFERED, FILE_READ_ACCESS) // 0x294414
#define IOCTL_BATTERY_QUERY_BST \
@ -85,6 +85,8 @@ typedef struct _ACPI_BST_DATA
#define ACPI_BATT_POWER_UNIT_WATTS 0x0
#define ACPI_BATT_POWER_UNIT_AMPS 0x1
#define ASCIIZ_MAX_LENGTH 256
typedef struct _ACPI_BIF_DATA
{
ULONG PowerUnit;
@ -96,12 +98,46 @@ typedef struct _ACPI_BIF_DATA
ULONG DesignCapacityLow;
ULONG BatteryCapacityGranularity1;
ULONG BatteryCapacityGranularity2;
CHAR ModelNumber[256];
CHAR SerialNumber[256];
CHAR BatteryType[256];
CHAR OemInfo[256];
CHAR ModelNumber[ASCIIZ_MAX_LENGTH];
CHAR SerialNumber[ASCIIZ_MAX_LENGTH];
CHAR BatteryType[ASCIIZ_MAX_LENGTH];
CHAR OemInfo[ASCIIZ_MAX_LENGTH];
} ACPI_BIF_DATA, *PACPI_BIF_DATA;
typedef struct _ACPI_BIX_DATA
{
ULONG Revision;
ULONG PowerUnit;
ULONG DesignCapacity;
ULONG LastFullCapacity;
ULONG BatteryTechnology;
ULONG DesignVoltage;
ULONG DesignCapacityWarning;
ULONG DesignCapacityLow;
ULONG CycleCount;
ULONG Accuracy;
ULONG MaxSampleTime;
ULONG MinSampleTime;
ULONG MaxAverageInterval;
ULONG MinAverageInterval;
ULONG BatteryCapacityGranularity1;
ULONG BatteryCapacityGranularity2;
CHAR ModelNumber[ASCIIZ_MAX_LENGTH];
CHAR SerialNumber[ASCIIZ_MAX_LENGTH];
CHAR BatteryType[ASCIIZ_MAX_LENGTH];
CHAR OemInfo[ASCIIZ_MAX_LENGTH];
ULONG SwapCapability;
} ACPI_BIX_DATA, *PACPI_BIX_DATA;
typedef struct _ACPI_BATT_STATIC_INFO
{
ACPI_BIF_DATA BifData;
ACPI_BIX_DATA BixData;
BOOLEAN ExtendedData;
} ACPI_BATT_STATIC_INFO, *PACPI_BATT_STATIC_INFO;
#define CMBATT_BATT_STATIC_INFO_TAG 'nItS'
#define CMBATT_AR_NOTIFY 0x01
#define CMBATT_AR_INSERT 0x02
#define CMBATT_AR_REMOVE 0x04
@ -132,7 +168,7 @@ typedef struct _CMBATT_DEVICE_EXTENSION
ULONG TagData;
ULONG Tag;
ACPI_BST_DATA BstData;
ACPI_BIF_DATA BifData;
ACPI_BATT_STATIC_INFO BattInfo;
ULONG Id;
ULONG State;
ULONG RemainingCapacity;
@ -203,6 +239,13 @@ CmBattGetBifData(
PACPI_BIF_DATA BifData
);
NTSTATUS
NTAPI
CmBattGetBixData(
_In_ PCMBATT_DEVICE_EXTENSION DeviceExtension,
_Out_ PACPI_BIX_DATA BixData
);
NTSTATUS
NTAPI
CmBattSetTripPpoint(

View file

@ -445,6 +445,70 @@ CmBattGetBifData(PCMBATT_DEVICE_EXTENSION DeviceExtension,
RTL_NUMBER_OF(BifFields));
}
/**
* @brief
* Retrieves the eXtended static battery information from the
* ACPI _BIX method.
*
* @param[in] DeviceExtension
* A pointer to a Control Method (CM) battery device extension.
* It is used to send the ACPI method evaluation operation
* to the ACPI driver of which it is attached to this CM battery.
*
* @param[out] BixData
* A pointer to a structure that contains the _BIX data fields,
* returned to caller.
*
* @return
* Returns STATUS_SUCCESS if the operation has succeeded successfully,
* otherwise a failure NTSTATUS code is returned.
*/
NTSTATUS
NTAPI
CmBattGetBixData(
_In_ PCMBATT_DEVICE_EXTENSION DeviceExtension,
_Out_ PACPI_BIX_DATA BixData)
{
ACPI_PACKAGE_FIELD BixFields[] = {
{ "Revision", FALSE, &BixData->Revision },
{ "PowerUnit", FALSE, &BixData->PowerUnit },
{ "DesignCapacity", FALSE, &BixData->DesignCapacity },
{ "LastFullCapacity", FALSE, &BixData->LastFullCapacity },
{ "BatteryTechnology", FALSE, &BixData->BatteryTechnology },
{ "DesignVoltage", FALSE, &BixData->DesignVoltage },
{ "DesignCapacityWarning", FALSE, &BixData->DesignCapacityWarning },
{ "DesignCapacityLow", FALSE, &BixData->DesignCapacityLow },
{ "CycleCount", FALSE, &BixData->CycleCount },
{ "Accuracy", FALSE, &BixData->Accuracy },
{ "MaxSampleTime", FALSE, &BixData->MaxSampleTime },
{ "MinSampleTime", FALSE, &BixData->MinSampleTime },
{ "MaxAverageInterval", FALSE, &BixData->MaxAverageInterval },
{ "MinAverageInterval", FALSE, &BixData->MinAverageInterval },
{ "BatteryCapacityGranularity1", FALSE, &BixData->BatteryCapacityGranularity1 },
{ "BatteryCapacityGranularity2", FALSE, &BixData->BatteryCapacityGranularity2 },
{ "ModelNumber", TRUE, &BixData->ModelNumber },
{ "SerialNumber", TRUE, &BixData->SerialNumber },
{ "BatteryType", TRUE, &BixData->BatteryType },
{ "OemInfo", TRUE, &BixData->OemInfo },
{ "SwapCapability", FALSE, &BixData->SwapCapability },
};
PAGED_CODE();
if (CmBattDebug & CMBATT_ACPI_ENTRY_EXIT)
{
DbgPrint("CmBattGetBixData: Buffer (0x%x) Device %x Tid %x\n",
BixData, DeviceExtension->DeviceId, KeGetCurrentThread());
}
/* Request the ACPI driver to get the _BIX data for us */
return CmBattCallAcpiPackage("CmBattGetBifData",
DeviceExtension,
'XIB_',
512,
BixFields,
RTL_NUMBER_OF(BixFields));
}
NTSTATUS
NTAPI
CmBattGetBstData(PCMBATT_DEVICE_EXTENSION DeviceExtension,