[CMBATT] Minor improvements to estimated battery time code

- Declare CMBATT_DISCHARGE_TIME and CMBATT_CAPACITY_BOGUS constructs
- Determine if the battery was already discharging and if not, update the time when it's being discharged
- Fix the condition where it checks if the battery has been discharging for quite some time
- Default the time to BATTERY_UNKNOWN_TIME if querying the estimated battery time request fails or if the battery has just started discharging not over 15 seconds

CORE-18969
CORE-19452
This commit is contained in:
George Bișoc 2025-01-10 22:23:23 +01:00
parent 37b0646e76
commit a97fcf19ec
No known key found for this signature in database
GPG key ID: 688C4FBE25D7DEF6
2 changed files with 28 additions and 5 deletions

View file

@ -1085,6 +1085,7 @@ CmBattGetBatteryStatus(IN PCMBATT_DEVICE_EXTENSION DeviceExtension,
{
ULONG PsrData = 0;
NTSTATUS Status;
BOOLEAN WasDischarging;
ULONG BstState;
ULONG PowerUnit;
ULONG DesignVoltage, PresentRate, RemainingCapacity;
@ -1113,6 +1114,9 @@ CmBattGetBatteryStatus(IN PCMBATT_DEVICE_EXTENSION DeviceExtension,
return Status;
}
/* Remember if the battery was discharging at the time of querying new status */
WasDischarging = !!(DeviceExtension->State & BATTERY_DISCHARGING);
/* Clear current BST information */
DeviceExtension->State = 0;
DeviceExtension->RemainingCapacity = 0;
@ -1135,9 +1139,9 @@ CmBattGetBatteryStatus(IN PCMBATT_DEVICE_EXTENSION DeviceExtension,
{
/* Set power state and check if it just started discharging now */
DeviceExtension->State |= BATTERY_DISCHARGING;
if (!(DeviceExtension->State & ACPI_BATT_STAT_DISCHARG))
if (!WasDischarging)
{
/* Remember the time when the state changed */
/* The battery is discharging now and not before, remember the time when the state changed */
DeviceExtension->InterruptTime = KeQueryInterruptTime();
}
}
@ -1363,8 +1367,8 @@ CmBattQueryInformation(IN PCMBATT_DEVICE_EXTENSION FdoExtension,
case BatteryEstimatedTime:
/* Check if it's been more than 2 1/2 minutes since the last change */
if ((KeQueryInterruptTime() - 150000000) > (FdoExtension->InterruptTime))
/* Check if it's been more than 15 seconds since the last change */
if (KeQueryInterruptTime() > (FdoExtension->InterruptTime + CMBATT_DISCHARGE_TIME))
{
/* Get new battery status */
CmBattGetBatteryStatus(FdoExtension, FdoExtension->Tag);
@ -1379,6 +1383,9 @@ CmBattQueryInformation(IN PCMBATT_DEVICE_EXTENSION FdoExtension,
/* Grab the remaining capacity */
RemainingCapacity = FdoExtension->RemainingCapacity;
/* Default time to unknown if we fail the request later */
RemainingTime = BATTERY_UNKNOWN_TIME;
/* See if we don't know one or the other */
if ((Rate == BATTERY_UNKNOWN_RATE) ||
(RemainingCapacity == BATTERY_UNKNOWN_CAPACITY))
@ -1410,7 +1417,7 @@ CmBattQueryInformation(IN PCMBATT_DEVICE_EXTENSION FdoExtension,
else
{
/* We have data, but is it valid? */
if (RemainingCapacity > 0x123456)
if (RemainingCapacity > CMBATT_CAPACITY_BOGUS)
{
/* The capacity seems bogus, so don't use it */
if (CmBattDebug & CMBATT_ACPI_WARNING)
@ -1423,6 +1430,10 @@ CmBattQueryInformation(IN PCMBATT_DEVICE_EXTENSION FdoExtension,
}
}
}
else
{
RemainingTime = BATTERY_UNKNOWN_TIME;
}
/* Return the remaining time */
QueryData = &RemainingTime;

View file

@ -42,6 +42,18 @@
#define CMBATT_PNP_ENTRY_EXIT 0x200
#define CMBATT_ACPI_ASSERT 0x400
//
// Constant used to determine if the battery was discharging
// for over 15 seconds since last time the AC adapter got unplugged.
//
#define CMBATT_DISCHARGE_TIME 150000000
//
// Bogus constant used to determine if the remaining battery capacity
// overflows which is returned by the hardware.
//
#define CMBATT_CAPACITY_BOGUS 0x100000
typedef enum _CMBATT_EXTENSION_TYPE
{
CmBattAcAdapter,