{
NTSTATUSStatus;
ACPI_BST_DATA BstData;
ULONG Capacity, NewTripPoint, TripPoint, DesignVoltage;
BOOLEAN Charging;
PAGED_CODE();
if (CmBattDebug & (CMBATT_ACPI_WARNING | CMBATT_GENERIC_INFO))
DbgPrint("CmBattSetStatusNotify: Tag (%d) Target(0x%x)\n",
BatteryTag, BatteryNotify->LowCapacity);
/* Update any ACPI evaluations */
Status = CmBattVerifyStaticInfo(DeviceExtension, BatteryTag);
if (!NT_SUCCESS(Status)) returnStatus;
/* Trip point not supported, fail */if (!DeviceExtension->TripPointSet) returnSTATUS_OBJECT_NAME_NOT_FOUND;
/* Are both capacities known? */if ((BatteryNotify->HighCapacity == BATTERY_UNKNOWN_CAPACITY) ||
(BatteryNotify->LowCapacity == BATTERY_UNKNOWN_CAPACITY))
{
/* We can't set trip points without these */if (CmBattDebug & CMBATT_GENERIC_WARNING)
DbgPrint("CmBattSetStatusNotify: Failing request because of BATTERY_UNKNOWN_CAPACITY.\n");
returnSTATUS_NOT_SUPPORTED;
}
/* Is the battery charging? */
Charging = DeviceExtension->BstData.State & ACPI_BATT_STAT_CHARGING;
if (Charging)
{
/* Then the trip point is when we hit the cap */
Capacity = BatteryNotify->HighCapacity;
NewTripPoint = BatteryNotify->HighCapacity;
}
else
{
/* Otherwise it's when we discharge to the bottom */
Capacity = BatteryNotify->LowCapacity;
NewTripPoint = BatteryNotify->LowCapacity;
}
/* Do we have data in Amps or Watts? */if (DeviceExtension->BifData.PowerUnit == ACPI_BATT_POWER_UNIT_AMPS)
{
/* We need the voltage to do the conversion */
DesignVoltage = DeviceExtension->BifData.DesignVoltage;
if ((DesignVoltage != BATTERY_UNKNOWN_VOLTAGE) && (DesignVoltage))
{
/* Convert from mAh into Ah */
TripPoint = 1000 * NewTripPoint;
if (Charging)
{
/* Scale the high trip point */
NewTripPoint = (TripPoint + 500) / DesignVoltage + ((TripPoint + 500) % DesignVoltage != 0);
}
else
{
/* Scale the low trip point */
NewTripPoint = (TripPoint - 500) / DesignVoltage - ((TripPoint - 500) % DesignVoltage == 0);
}
}
else
{
/* Without knowing the voltage, Amps are not enough data on consumption */
Status = STATUS_NOT_SUPPORTED;
if (CmBattDebug & CMBATT_ACPI_WARNING)
DbgPrint("CmBattSetStatusNotify: Can't calculate BTP, DesignVoltage = 0x%08x\n",
DesignVoltage);
}
}
elseif (Charging)
{
/* Make it trip just one past the charge cap */
++NewTripPoint;
}
elseif (NewTripPoint > 0)
{
/* Make it trip just one below the drain cap */
--NewTripPoint;
}
/* Do we actually have a new trip point? */if (NewTripPoint == DeviceExtension->TripPointValue)
{
/* No, so there is no work to be done */if (CmBattDebug & CMBATT_GENERIC_STATUS)
DbgPrint("CmBattSetStatusNotify: Keeping original setting: %X\n", DeviceExtension->TripPointValue);
returnSTATUS_SUCCESS;
}
/* Set the trip point with ACPI and check for success */
DeviceExtension->TripPointValue = NewTripPoint;
Status = CmBattSetTripPpoint(DeviceExtension, NewTripPoint);
if (!(NewTripPoint) && (Capacity)) Status = STATUS_NOT_SUPPORTED;
if (!NT_SUCCESS(Status))
{
/* We failed to set the trip point, or there wasn't one settable */
DeviceExtension->TripPointValue = BATTERY_UNKNOWN_CAPACITY;
if (CmBattDebug & (CMBATT_GENERIC_WARNING | CMBATT_ACPI_WARNING))
DbgPrint("CmBattSetStatusNotify: SetTripPoint failed - %x\n", Status);
returnStatus;
}
/* Read the new BST data to see the latest state */
Status = CmBattGetBstData(DeviceExtension, &BstData);
if (!NT_SUCCESS(Status))
{
/* We'll return failure to the caller */if (CmBattDebug & (CMBATT_GENERIC_WARNING | CMBATT_ACPI_WARNING))
DbgPrint("CmBattSetStatusNotify: GetBstData - %x\n", Status);
}
elseif ((Charging) && (BstData.RemainingCapacity >= NewTripPoint))
{
/* We are charging and our capacity is past the trip point, so trip now */if (CmBattDebug & CMBATT_GENERIC_WARNING)
DbgPrint("CmBattSetStatusNotify: Trip point already crossed (1): TP = %08x, remaining capacity = %08x\n",
NewTripPoint, BstData.RemainingCapacity);
CmBattNotifyHandler(DeviceExtension, ACPI_BATT_NOTIFY_STATUS);
}
elseif ((BstData.RemainingCapacity) && (Capacity))
{
/* We are discharging, and our capacity is below the trip point, trip now */if (CmBattDebug & CMBATT_GENERIC_WARNING)
DbgPrint("CmBattSetStatusNotify: Trip point already crossed (1): TP = %08x, remaining capacity = %08x\n",
NewTripPoint, BstData.RemainingCapacity);
CmBattNotifyHandler(DeviceExtension, ACPI_BATT_NOTIFY_STATUS);
}
/* All should've went well if we got here, unless BST failed... return! */if (CmBattDebug & CMBATT_GENERIC_STATUS)
DbgPrint("CmBattSetStatusNotify: Want %X CurrentCap %X\n",
Capacity, DeviceExtension->RemainingCapacity);
if (CmBattDebug & CMBATT_ACPI_WARNING)
DbgPrint("CmBattSetStatusNotify: Set to: [%#08lx][%#08lx][%#08lx] Status %x\n",
BatteryNotify->PowerState,
BatteryNotify->LowCapacity,
BatteryNotify->HighCapacity);
returnStatus;
}
Generated on Sun May 27 2012 05:22:57 for ReactOS by
1.7.6.1
ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.