Better use user_memcpy() to return battery [extended] info to userland caller.
Also add some paranoid checks: ACPI BIOSes implementation can be... wild. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32584 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -51,16 +51,25 @@ ReadBatteryStatus(battery_driver_cookie* cookie, acpi_battery_info* batteryStatu
|
|||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
object = (acpi_object_type*)buffer.pointer;
|
object = (acpi_object_type*)buffer.pointer;
|
||||||
|
if (object->object_type != ACPI_TYPE_PACKAGE ||
|
||||||
|
object->data.package.count < 4) {
|
||||||
|
status = B_ERROR;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
pointer = object->data.package.objects;
|
pointer = object->data.package.objects;
|
||||||
|
|
||||||
batteryStatus->state = pointer->data.integer;
|
batteryStatus->state = (pointer->object_type == ACPI_TYPE_INTEGER) ?
|
||||||
|
pointer->data.integer : -1;
|
||||||
pointer++;
|
pointer++;
|
||||||
batteryStatus->current_rate = pointer->data.integer;
|
batteryStatus->current_rate = (pointer->object_type == ACPI_TYPE_INTEGER) ?
|
||||||
|
pointer->data.integer : -1;
|
||||||
pointer++;
|
pointer++;
|
||||||
batteryStatus->capacity = pointer->data.integer;
|
batteryStatus->capacity = (pointer->object_type == ACPI_TYPE_INTEGER) ?
|
||||||
|
pointer->data.integer : -1;
|
||||||
pointer++;
|
pointer++;
|
||||||
batteryStatus->voltage = pointer->data.integer;
|
batteryStatus->voltage = (pointer->object_type == ACPI_TYPE_INTEGER) ?
|
||||||
|
pointer->data.integer : -1;
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
free(buffer.pointer);
|
free(buffer.pointer);
|
||||||
@@ -87,36 +96,51 @@ ReadBatteryInfo(battery_driver_cookie* cookie,
|
|||||||
|
|
||||||
object = (acpi_object_type*)buffer.pointer;
|
object = (acpi_object_type*)buffer.pointer;
|
||||||
if (object->object_type != ACPI_TYPE_PACKAGE ||
|
if (object->object_type != ACPI_TYPE_PACKAGE ||
|
||||||
object->data.package.count < 13)
|
object->data.package.count < 13) {
|
||||||
|
status = B_ERROR;
|
||||||
goto exit;
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
pointer = object->data.package.objects;
|
pointer = object->data.package.objects;
|
||||||
|
|
||||||
batteryInfo->power_unit = pointer->data.integer;
|
batteryInfo->power_unit = (pointer->object_type == ACPI_TYPE_INTEGER) ?
|
||||||
pointer ++;
|
pointer->data.integer : -1;
|
||||||
batteryInfo->design_capacity = pointer->data.integer;
|
pointer++;
|
||||||
pointer ++;
|
batteryInfo->design_capacity = (pointer->object_type == ACPI_TYPE_INTEGER) ?
|
||||||
batteryInfo->last_full_charge = pointer->data.integer;
|
pointer->data.integer : -1;
|
||||||
pointer ++;
|
pointer++;
|
||||||
batteryInfo->technology = pointer->data.integer;
|
batteryInfo->last_full_charge = (pointer->object_type == ACPI_TYPE_INTEGER) ?
|
||||||
pointer ++;
|
pointer->data.integer : -1;
|
||||||
batteryInfo->design_voltage = pointer->data.integer;
|
pointer++;
|
||||||
pointer ++;
|
batteryInfo->technology = (pointer->object_type == ACPI_TYPE_INTEGER) ?
|
||||||
batteryInfo->design_capacity_warning = pointer->data.integer;
|
pointer->data.integer : -1;
|
||||||
pointer ++;
|
pointer++;
|
||||||
batteryInfo->design_capacity_low = pointer->data.integer;
|
batteryInfo->design_voltage = (pointer->object_type == ACPI_TYPE_INTEGER) ?
|
||||||
pointer ++;
|
pointer->data.integer : -1;
|
||||||
batteryInfo->capacity_granularity_1 = pointer->data.integer;
|
pointer++;
|
||||||
pointer ++;
|
batteryInfo->design_capacity_warning = (pointer->object_type == ACPI_TYPE_INTEGER) ?
|
||||||
batteryInfo->capacity_granularity_2 = pointer->data.integer;
|
pointer->data.integer : -1;
|
||||||
pointer ++;
|
pointer++;
|
||||||
strcpy(batteryInfo->model_number, pointer->data.string.string);
|
batteryInfo->design_capacity_low = (pointer->object_type == ACPI_TYPE_INTEGER) ?
|
||||||
pointer ++;
|
pointer->data.integer : -1;
|
||||||
strcpy(batteryInfo->serial_number, pointer->data.string.string);
|
pointer++;
|
||||||
pointer ++;
|
batteryInfo->capacity_granularity_1 = (pointer->object_type == ACPI_TYPE_INTEGER) ?
|
||||||
strcpy(batteryInfo->type, pointer->data.string.string);
|
pointer->data.integer : -1;
|
||||||
pointer ++;
|
pointer++;
|
||||||
strcpy(batteryInfo->oem_info, pointer->data.string.string);
|
batteryInfo->capacity_granularity_2 = (pointer->object_type == ACPI_TYPE_INTEGER) ?
|
||||||
|
pointer->data.integer : -1;
|
||||||
|
pointer++;
|
||||||
|
strlcpy(batteryInfo->model_number, (pointer->object_type == ACPI_TYPE_STRING) ?
|
||||||
|
pointer->data.string.string : "", sizeof(batteryInfo->model_number));
|
||||||
|
pointer++;
|
||||||
|
strlcpy(batteryInfo->serial_number, (pointer->object_type == ACPI_TYPE_STRING) ?
|
||||||
|
pointer->data.string.string : "", sizeof(batteryInfo->serial_number));
|
||||||
|
pointer++;
|
||||||
|
strlcpy(batteryInfo->type, (pointer->object_type == ACPI_TYPE_STRING) ?
|
||||||
|
pointer->data.string.string : "", sizeof(batteryInfo->type));
|
||||||
|
pointer++;
|
||||||
|
strlcpy(batteryInfo->oem_info, (pointer->object_type == ACPI_TYPE_STRING) ?
|
||||||
|
pointer->data.string.string : "", sizeof(batteryInfo->oem_info));
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
free(buffer.pointer);
|
free(buffer.pointer);
|
||||||
@@ -285,50 +309,54 @@ status_t
|
|||||||
acpi_battery_control(void* _cookie, uint32 op, void* arg, size_t len)
|
acpi_battery_control(void* _cookie, uint32 op, void* arg, size_t len)
|
||||||
{
|
{
|
||||||
battery_device_cookie* device = (battery_device_cookie*)_cookie;
|
battery_device_cookie* device = (battery_device_cookie*)_cookie;
|
||||||
status_t err = B_ERROR;
|
status_t err;
|
||||||
|
|
||||||
uint32* magicId;
|
|
||||||
acpi_battery_info* batteryInfo;
|
|
||||||
acpi_extended_battery_info* extBatteryInfo;
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case IDENTIFY_DEVICE:
|
case IDENTIFY_DEVICE: {
|
||||||
if (len < sizeof(uint32))
|
if (len < sizeof(uint32))
|
||||||
return B_IO_ERROR;
|
return B_BAD_VALUE;
|
||||||
magicId = (uint32*)arg;
|
|
||||||
*magicId = kMagicACPIBatteryID;
|
|
||||||
err = B_OK;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GET_BATTERY_INFO:
|
uint32 magicId = kMagicACPIBatteryID;
|
||||||
|
return user_memcpy(arg, &magicId, sizeof(magicId));
|
||||||
|
}
|
||||||
|
|
||||||
|
case GET_BATTERY_INFO: {
|
||||||
if (len < sizeof(acpi_battery_info))
|
if (len < sizeof(acpi_battery_info))
|
||||||
return B_IO_ERROR;
|
return B_BAD_VALUE;
|
||||||
batteryInfo = (acpi_battery_info*)arg;
|
|
||||||
err = ReadBatteryStatus(device->driver_cookie, batteryInfo);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GET_EXTENDED_BATTERY_INFO:
|
acpi_battery_info batteryInfo;
|
||||||
|
err = ReadBatteryStatus(device->driver_cookie, &batteryInfo);
|
||||||
|
if (err != B_OK)
|
||||||
|
return err;
|
||||||
|
return user_memcpy(arg, &batteryInfo, sizeof(batteryInfo));
|
||||||
|
}
|
||||||
|
|
||||||
|
case GET_EXTENDED_BATTERY_INFO: {
|
||||||
if (len < sizeof(acpi_extended_battery_info))
|
if (len < sizeof(acpi_extended_battery_info))
|
||||||
return B_IO_ERROR;
|
return B_BAD_VALUE;
|
||||||
extBatteryInfo = (acpi_extended_battery_info*)arg;
|
|
||||||
err = ReadBatteryInfo(device->driver_cookie, extBatteryInfo);
|
acpi_extended_battery_info extBatteryInfo;
|
||||||
break;
|
err = ReadBatteryInfo(device->driver_cookie, &extBatteryInfo);
|
||||||
|
if (err != B_OK)
|
||||||
|
return err;
|
||||||
|
return user_memcpy(arg, &extBatteryInfo, sizeof(extBatteryInfo));
|
||||||
|
}
|
||||||
|
|
||||||
case WATCH_BATTERY:
|
case WATCH_BATTERY:
|
||||||
sBatteryCondition.Wait();
|
sBatteryCondition.Wait();
|
||||||
if (atomic_get(&(device->stop_watching))) {
|
if (atomic_get(&(device->stop_watching))) {
|
||||||
atomic_set(&(device->stop_watching), 0);
|
atomic_set(&(device->stop_watching), 0);
|
||||||
err = B_ERROR;
|
return B_ERROR;
|
||||||
} else
|
}
|
||||||
err = B_OK;
|
return B_OK;
|
||||||
break;
|
|
||||||
|
|
||||||
case STOP_WATCHING_BATTERY:
|
case STOP_WATCHING_BATTERY:
|
||||||
atomic_set(&(device->stop_watching), 1);
|
atomic_set(&(device->stop_watching), 1);
|
||||||
sBatteryCondition.NotifyAll();
|
sBatteryCondition.NotifyAll();
|
||||||
err = B_OK;
|
return B_OK;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
return err;
|
|
||||||
|
return B_DEV_INVALID_IOCTL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user