ACPI / Battery: Return -ENODEV for unknown values in get_property()
PATCH RESEND 1/1 ACPI / Battery: Return -ENODEV for unknown values in get_property()
From: Rafael J. Wysocki <[email protected]>
The function acpi_battery_get_property() is called by the power supply framework's function power_supply_show_property() implementing the sysfs interface for power supply devices as the ACPI battery driver's ->get_property() callback. Thus it is supposed to return error code if the value of the given property is unknown. Unfortunately, however, it returns 0 in those cases and puts a wrong (negative) value into the intval field of the
union power_supply_propval object provided by power_supply_show_property(). In consequence, wrong negative values are read by user space from the battery's sysfs files.
Fix this by making acpi_battery_get_property() return -ENODEV for properties with unknown values (-ENODEV is returned, because power_supply_uevent() returns with error for any other error code returned by power_supply_show_property()).
--- drivers/acpi/battery.c | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-)
drivers/acpi/battery.c +27 -8
@@ -186,6 +186,7 @@ static int acpi_battery_get_property(strenum power_supply_property psp, union power_supply_propval *val) { + int ret = 0;struct acpi_battery *battery =to_acpi_battery (psy);if (acpi_battery_present (battery)) {
@@ -214,26 +215,44 @@ static int acpi_battery_get_property(str val->intval = battery->cycle_count;break ;case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN : - val->intval = battery->design_voltage *1000 ; +if (battery->design_voltage ==ACPI_BATTERY_VALUE_UNKNOWN ) + ret = -ENODEV ; +else + val->intval = battery->design_voltage *1000 ;break ;case POWER_SUPPLY_PROP_VOLTAGE_NOW : - val->intval = battery->voltage_now *1000 ; +if (battery->voltage_now ==ACPI_BATTERY_VALUE_UNKNOWN ) + ret = -ENODEV ; +else + val->intval = battery->voltage_now *1000 ;break ;case POWER_SUPPLY_PROP_CURRENT_NOW :case POWER_SUPPLY_PROP_POWER_NOW : - val->intval = battery->rate_now *1000 ; +if (battery->rate_now ==ACPI_BATTERY_VALUE_UNKNOWN ) + ret = -ENODEV ; +else + val->intval = battery->rate_now *1000 ;break ;case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN :case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN : - val->intval = battery->design_capacity *1000 ; +if (battery->design_capacity ==ACPI_BATTERY_VALUE_UNKNOWN ) + ret = -ENODEV ; +else + val->intval = battery->design_capacity *1000 ;break ;case POWER_SUPPLY_PROP_CHARGE_FULL :case POWER_SUPPLY_PROP_ENERGY_FULL : - val->intval = battery->full_charge_capacity *1000 ; +if (battery->full_charge_capacity ==ACPI_BATTERY_VALUE_UNKNOWN ) + ret = -ENODEV ; +else + val->intval = battery->full_charge_capacity *1000 ;break ;case POWER_SUPPLY_PROP_CHARGE_NOW :case POWER_SUPPLY_PROP_ENERGY_NOW : - val->intval = battery->capacity_now *1000 ; +if (battery->capacity_now ==ACPI_BATTERY_VALUE_UNKNOWN ) + ret = -ENODEV ; +else + val->intval = battery->capacity_now *1000 ;break ;case POWER_SUPPLY_PROP_MODEL_NAME : val->strval = battery->model_number;
@@ -245,9 +264,9 @@ static int acpi_battery_get_property(str val->strval = battery->serial_number;break ;default : -return -EINVAL ; + ret = -EINVAL ; } -return 0 ; +return ret; }static enum power_supply_property charge_battery_props[] = {
applied
thanks,
Len Brown, Intel Open Source Technology Center