aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/battery.c
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2010-10-23 13:35:15 -0400
committerLen Brown <len.brown@intel.com>2010-10-23 14:05:03 -0400
commita1b4bd694a803eba49d637de32bb249638ceadb4 (patch)
tree30b3b4efbf394b8cd500b694c80485561a6827ab /drivers/acpi/battery.c
parentf6f94e2ab1b33f0082ac22d71f66385a60d8157f (diff)
ACPI / Battery: Return -ENODEV for unknown values in get_property()
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()). Reported-and-tested-by: Sitsofe Wheeler <sitsofe@yahoo.com> Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/battery.c')
-rw-r--r--drivers/acpi/battery.c35
1 files changed, 27 insertions, 8 deletions
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 98417201e9ce..ac74a7ddaaa4 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -186,6 +186,7 @@ static int acpi_battery_get_property(struct power_supply *psy,
186 enum power_supply_property psp, 186 enum power_supply_property psp,
187 union power_supply_propval *val) 187 union power_supply_propval *val)
188{ 188{
189 int ret = 0;
189 struct acpi_battery *battery = to_acpi_battery(psy); 190 struct acpi_battery *battery = to_acpi_battery(psy);
190 191
191 if (acpi_battery_present(battery)) { 192 if (acpi_battery_present(battery)) {
@@ -214,26 +215,44 @@ static int acpi_battery_get_property(struct power_supply *psy,
214 val->intval = battery->cycle_count; 215 val->intval = battery->cycle_count;
215 break; 216 break;
216 case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: 217 case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
217 val->intval = battery->design_voltage * 1000; 218 if (battery->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN)
219 ret = -ENODEV;
220 else
221 val->intval = battery->design_voltage * 1000;
218 break; 222 break;
219 case POWER_SUPPLY_PROP_VOLTAGE_NOW: 223 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
220 val->intval = battery->voltage_now * 1000; 224 if (battery->voltage_now == ACPI_BATTERY_VALUE_UNKNOWN)
225 ret = -ENODEV;
226 else
227 val->intval = battery->voltage_now * 1000;
221 break; 228 break;
222 case POWER_SUPPLY_PROP_CURRENT_NOW: 229 case POWER_SUPPLY_PROP_CURRENT_NOW:
223 case POWER_SUPPLY_PROP_POWER_NOW: 230 case POWER_SUPPLY_PROP_POWER_NOW:
224 val->intval = battery->rate_now * 1000; 231 if (battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN)
232 ret = -ENODEV;
233 else
234 val->intval = battery->rate_now * 1000;
225 break; 235 break;
226 case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: 236 case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
227 case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN: 237 case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
228 val->intval = battery->design_capacity * 1000; 238 if (battery->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
239 ret = -ENODEV;
240 else
241 val->intval = battery->design_capacity * 1000;
229 break; 242 break;
230 case POWER_SUPPLY_PROP_CHARGE_FULL: 243 case POWER_SUPPLY_PROP_CHARGE_FULL:
231 case POWER_SUPPLY_PROP_ENERGY_FULL: 244 case POWER_SUPPLY_PROP_ENERGY_FULL:
232 val->intval = battery->full_charge_capacity * 1000; 245 if (battery->full_charge_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
246 ret = -ENODEV;
247 else
248 val->intval = battery->full_charge_capacity * 1000;
233 break; 249 break;
234 case POWER_SUPPLY_PROP_CHARGE_NOW: 250 case POWER_SUPPLY_PROP_CHARGE_NOW:
235 case POWER_SUPPLY_PROP_ENERGY_NOW: 251 case POWER_SUPPLY_PROP_ENERGY_NOW:
236 val->intval = battery->capacity_now * 1000; 252 if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN)
253 ret = -ENODEV;
254 else
255 val->intval = battery->capacity_now * 1000;
237 break; 256 break;
238 case POWER_SUPPLY_PROP_MODEL_NAME: 257 case POWER_SUPPLY_PROP_MODEL_NAME:
239 val->strval = battery->model_number; 258 val->strval = battery->model_number;
@@ -245,9 +264,9 @@ static int acpi_battery_get_property(struct power_supply *psy,
245 val->strval = battery->serial_number; 264 val->strval = battery->serial_number;
246 break; 265 break;
247 default: 266 default:
248 return -EINVAL; 267 ret = -EINVAL;
249 } 268 }
250 return 0; 269 return ret;
251} 270}
252 271
253static enum power_supply_property charge_battery_props[] = { 272static enum power_supply_property charge_battery_props[] = {