From a97fcf19ecd2d73def84fc60d206372883599631 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?George=20Bi=C8=99oc?= Date: Fri, 10 Jan 2025 22:23:23 +0100 Subject: [PATCH] [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 --- drivers/bus/acpi/cmbatt/cmbatt.c | 21 ++++++++++++++++----- drivers/bus/acpi/cmbatt/cmbatt.h | 12 ++++++++++++ 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/drivers/bus/acpi/cmbatt/cmbatt.c b/drivers/bus/acpi/cmbatt/cmbatt.c index 407fa149572..dd01f8b22be 100644 --- a/drivers/bus/acpi/cmbatt/cmbatt.c +++ b/drivers/bus/acpi/cmbatt/cmbatt.c @@ -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; diff --git a/drivers/bus/acpi/cmbatt/cmbatt.h b/drivers/bus/acpi/cmbatt/cmbatt.h index e6ab5f029bd..4a2ec81acd3 100644 --- a/drivers/bus/acpi/cmbatt/cmbatt.h +++ b/drivers/bus/acpi/cmbatt/cmbatt.h @@ -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,