Author: sir_richard
Date: Sat Mar 20 22:25:40 2010
New Revision: 46288
URL:
http://svn.reactos.org/svn/reactos?rev=46288&view=rev
Log:
[CMBATT]: Implement CmBattQueryInformation and CmBattQueryStatus.
Modified:
trunk/reactos/drivers/bus/acpi/cmbatt/cmbatt.c
trunk/reactos/drivers/bus/acpi/cmbatt/cmbatt.h
Modified: trunk/reactos/drivers/bus/acpi/cmbatt/cmbatt.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/bus/acpi/cmbatt/cm…
==============================================================================
--- trunk/reactos/drivers/bus/acpi/cmbatt/cmbatt.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/bus/acpi/cmbatt/cmbatt.c [iso-8859-1] Sat Mar 20 22:25:40 2010
@@ -74,7 +74,7 @@
NTSTATUS
NTAPI
-CmBattVerifyStaticInfo(ULONG StaData,
+CmBattVerifyStaticInfo(PCMBATT_DEVICE_EXTENSION DeviceExtension,
ULONG BatteryTag)
{
UNIMPLEMENTED;
@@ -191,26 +191,246 @@
NTSTATUS
NTAPI
-CmBattQueryInformation(PCMBATT_DEVICE_EXTENSION DeviceExtension,
- ULONG BatteryTag,
- BATTERY_QUERY_INFORMATION_LEVEL Level,
- OPTIONAL LONG AtRate,
- PVOID Buffer,
- ULONG BufferLength,
- PULONG ReturnedLength)
-{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
-}
-
-NTSTATUS
-NTAPI
-CmBattQueryStatus(PCMBATT_DEVICE_EXTENSION DeviceExtension,
- ULONG BatteryTag,
- PBATTERY_STATUS BatteryStatus)
-{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+CmBattQueryInformation(IN PCMBATT_DEVICE_EXTENSION FdoExtension,
+ IN ULONG Tag,
+ IN BATTERY_QUERY_INFORMATION_LEVEL InfoLevel,
+ IN OPTIONAL LONG AtRate,
+ IN PVOID Buffer,
+ IN ULONG BufferLength,
+ OUT PULONG ReturnedLength)
+{
+ NTSTATUS Status;
+ PVOID QueryData = NULL;
+ ULONG QueryLength = 0;
+ ULONG RemainingTime = 0;
+ ANSI_STRING TempString;
+ UNICODE_STRING TempString2;
+ WCHAR InfoBuffer[256];
+ WCHAR TempBuffer[256];
+ UNICODE_STRING InfoString;
+ ULONG RemainingCapacity;
+ BATTERY_REPORTING_SCALE BatteryReportingScale[2];
+ LONG Rate;
+ PAGED_CODE();
+ if (CmBattDebug & (CMBATT_ACPI_WARNING | CMBATT_GENERIC_INFO))
+ DbgPrint("CmBattQueryInformation - Tag (%d) Device %d, Informationlevel
%d\n",
+ Tag,
+ FdoExtension->DeviceId,
+ InfoLevel);
+
+ /* Check ACPI Data */
+ Status = CmBattVerifyStaticInfo(FdoExtension, Tag);
+ if (!NT_SUCCESS(Status)) return Status;
+
+ /* Check what caller wants */
+ switch (InfoLevel)
+ {
+ case BatteryInformation:
+ /* Just return our static information */
+ QueryData = &FdoExtension->BatteryInformation;
+ QueryLength = sizeof(BATTERY_INFORMATION);
+ break;
+
+ case BatteryGranularityInformation:
+
+ /* Return our static information, we have two scales */
+ BatteryReportingScale[0].Granularity =
FdoExtension->BatteryCapacityGranularity1;
+ BatteryReportingScale[0].Capacity =
FdoExtension->BatteryInformation.DefaultAlert1;
+ BatteryReportingScale[1].Granularity =
FdoExtension->BatteryCapacityGranularity2;
+ BatteryReportingScale[1].Capacity =
FdoExtension->BatteryInformation.DesignedCapacity;
+ QueryData = BatteryReportingScale;
+ QueryLength = sizeof(BATTERY_REPORTING_SCALE) * 2;
+ break;
+
+ case BatteryEstimatedTime:
+
+ /* Check if it's been more than 2 1/2 minutes since the last change */
+ if ((KeQueryInterruptTime() - 150000000) >
(FdoExtension->InterruptTime))
+ {
+ /* Get new battery status */
+ CmBattGetBatteryStatus(FdoExtension, FdoExtension->Tag);
+
+ /* If the caller didn't specify a rate, use our static one */
+ Rate = AtRate;
+ if (!Rate) Rate = FdoExtension->Rate;
+
+ /* If we don't have a valid negative rate, use unknown value */
+ if (Rate >= 0) Rate = BATTERY_UNKNOWN_RATE;
+
+ /* Grab the remaining capacity */
+ RemainingCapacity = FdoExtension->RemainingCapacity;
+
+ /* See if we don't know one or the other */
+ if ((Rate == BATTERY_UNKNOWN_RATE) ||
+ (RemainingCapacity == BATTERY_UNKNOWN_CAPACITY))
+ {
+ /* If the battery is discharging, we can't give out a time */
+ if ((FdoExtension->BstData.State & ACPI_BATT_STAT_DISCHARG)
&&
+ (CmBattDebug & CMBATT_GENERIC_WARNING))
+ DbgPrint("CmBattQueryInformation: Can't calculate
EstimatedTime.\n");
+
+ /* Check if we don't have a rate and capacity is going down */
+ if ((FdoExtension->Rate == BATTERY_UNKNOWN_RATE) &&
+ (FdoExtension->BstData.State & ACPI_BATT_STAT_DISCHARG))
+ {
+ /* We have to fail, since we lack data */
+ Status = STATUS_INVALID_DEVICE_REQUEST;
+ if (CmBattDebug & CMBATT_GENERIC_WARNING)
+ DbgPrint("---------------------- PresentRate =
BATTERY_UNKNOWN_RATE\n");
+ }
+
+ /* If we don't have capacity, the rate is useless */
+ if (RemainingCapacity == BATTERY_UNKNOWN_CAPACITY)
+ {
+ /* We have to fail the request */
+ Status = STATUS_INVALID_DEVICE_REQUEST;
+ if (CmBattDebug & CMBATT_GENERIC_WARNING)
+ DbgPrint("---------------------- RemainingCapacity =
BATTERY_UNKNOWN_CAPACITY\n");
+ }
+ }
+ else
+ {
+ /* We have data, but is it valid? */
+ if (RemainingCapacity > 0x123456)
+ {
+ /* The capacity seems bogus, so don't use it */
+ if (CmBattDebug & CMBATT_ACPI_WARNING)
+ DbgPrint("CmBattQueryInformation: Data Overflow in
calculating Remaining Capacity.\n");
+ }
+ else
+ {
+ /* Compute the remaining time in seconds, based on rate */
+ RemainingTime = (RemainingCapacity * 3600) / -Rate;
+ }
+ }
+ }
+
+ /* Return the remaining time */
+ QueryData = &RemainingTime;
+ QueryLength = sizeof(ULONG);
+ break;
+
+ case BatteryDeviceName:
+
+ /* Build the model number string */
+ RtlInitAnsiString(&TempString, FdoExtension->ModelNumber);
+
+ /* Convert it to Unicode */
+ InfoString.Buffer = InfoBuffer;
+ InfoString.MaximumLength = sizeof(InfoBuffer);
+ Status = RtlAnsiStringToUnicodeString(&InfoString, &TempString, 0);
+
+ /* Return the unicode buffer */
+ QueryData = InfoString.Buffer;
+ QueryLength = InfoString.Length;
+ break;
+
+ case BatteryTemperature:
+ case BatteryManufactureDate:
+
+ /* We don't support these */
+ Status = STATUS_INVALID_DEVICE_REQUEST;
+ break;
+
+ case BatteryManufactureName:
+
+ /* Build the OEM info string */
+ RtlInitAnsiString(&TempString, FdoExtension->OemInfo);
+
+ /* Convert it to Unicode */
+ InfoString.Buffer = InfoBuffer;
+ InfoString.MaximumLength = sizeof(InfoBuffer);
+ Status = RtlAnsiStringToUnicodeString(&InfoString, &TempString, 0);
+
+ /* Return the unicode buffer */
+ QueryData = InfoString.Buffer;
+ QueryLength = InfoString.Length;
+ break;
+
+ case BatteryUniqueID:
+
+ /* Build the serial number string */
+ RtlInitAnsiString(&TempString, FdoExtension->SerialNumber);
+
+ /* Convert it to Unicode */
+ InfoString.Buffer = InfoBuffer;
+ InfoString.MaximumLength = sizeof(InfoBuffer);
+ RtlAnsiStringToUnicodeString(&InfoString, &TempString, 0);
+
+ /* Setup a temporary string for concatenation */
+ TempString2.Buffer = TempBuffer;
+ TempString2.MaximumLength = sizeof(TempBuffer);
+
+ /* Check if there's an OEM string */
+ if (FdoExtension->OemInfo[0])
+ {
+ /* Build the OEM info string */
+ RtlInitAnsiString(&TempString, FdoExtension->OemInfo);
+
+ /* Convert it to Unicode and append it */
+ RtlAnsiStringToUnicodeString(&TempString2, &TempString, 0);
+ RtlAppendUnicodeStringToString(&InfoString, &TempString2);
+ }
+
+ /* Build the model number string */
+ RtlInitAnsiString(&TempString, FdoExtension->ModelNumber);
+
+ /* Convert it to Unicode and append it */
+ RtlAnsiStringToUnicodeString(&TempString2, &TempString, 0);
+ RtlAppendUnicodeStringToString(&InfoString, &TempString2);
+
+ /* Return the final appended string */
+ QueryData = InfoString.Buffer;
+ QueryLength = InfoString.Length;
+ break;
+
+ default:
+
+ /* Everything else is unknown */
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ /* Return the required length and check if the caller supplied enough */
+ *ReturnedLength = QueryLength;
+ if (BufferLength < QueryLength) Status = STATUS_BUFFER_TOO_SMALL;
+
+ /* Copy the data if there's enough space and it exists */
+ if ((NT_SUCCESS(Status)) && (QueryData)) RtlCopyMemory(Buffer, QueryData,
QueryLength);
+
+ /* Return function result */
+ return Status;
+}
+
+NTSTATUS
+NTAPI
+CmBattQueryStatus(IN PCMBATT_DEVICE_EXTENSION DeviceExtension,
+ IN ULONG Tag,
+ IN PBATTERY_STATUS BatteryStatus)
+{
+ NTSTATUS Status;
+ PAGED_CODE();
+ if (CmBattDebug & (CMBATT_ACPI_WARNING | CMBATT_GENERIC_INFO))
+ DbgPrint("CmBattQueryStatus - Tag (%d) Device %x\n", Tag,
DeviceExtension->DeviceId);
+
+ /* Query ACPI information */
+ Status = CmBattGetBatteryStatus(DeviceExtension, Tag);
+ if (NT_SUCCESS(Status))
+ {
+ BatteryStatus->PowerState = DeviceExtension->State;
+ BatteryStatus->Capacity = DeviceExtension->RemainingCapacity;
+ BatteryStatus->Voltage = DeviceExtension->PresentVoltage;
+ BatteryStatus->Rate = DeviceExtension->Rate;
+ }
+
+ /* Return status */
+ if (CmBattDebug & (CMBATT_GENERIC_INFO))
+ DbgPrint("CmBattQueryStatus: Returning
[%#08lx][%#08lx][%#08lx][%#08lx]\n",
+ BatteryStatus->PowerState,
+ BatteryStatus->Capacity,
+ BatteryStatus->Voltage,
+ BatteryStatus->Rate);
+ return Status;
}
NTSTATUS
@@ -233,20 +453,16 @@
{
/* Fail if we're out of memory this early */
if (CmBattDebug & CMBATT_GENERIC_WARNING)
- {
DbgPrint("CmBatt: Couldn't allocate pool for registry path.");
- }
return STATUS_INSUFFICIENT_RESOURCES;
}
/* Buffer allocated, copy the string */
RtlCopyUnicodeString(&GlobalRegistryPath, RegistryPath);
if (CmBattDebug & CMBATT_GENERIC_INFO)
- {
DbgPrint("CmBatt DriverEntry - Obj (%08x) Path \"%ws\"\n",
DriverObject,
RegistryPath->Buffer);
- }
/* Setup the major dispatchers */
DriverObject->MajorFunction[0] = CmBattOpenClose;
@@ -276,9 +492,7 @@
/* No callback, fail */
CmBattPowerCallBackObject = 0;
if (CmBattDebug & CMBATT_GENERIC_WARNING)
- {
DbgPrint("CmBattRegisterPowerCallBack: failed status=0x%08x\n",
Status);
- }
}
else
{
@@ -296,9 +510,7 @@
{
ObfDereferenceObject(CmBattPowerCallBackObject);
if (CmBattDebug & CMBATT_GENERIC_WARNING)
- {
DbgPrint("CmBattRegisterPowerCallBack: ExRegisterCallback
failed.\n");
- }
}
/* All good */
Modified: trunk/reactos/drivers/bus/acpi/cmbatt/cmbatt.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/bus/acpi/cmbatt/cm…
==============================================================================
--- trunk/reactos/drivers/bus/acpi/cmbatt/cmbatt.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/bus/acpi/cmbatt/cmbatt.h [iso-8859-1] Sat Mar 20 22:25:40 2010
@@ -28,6 +28,12 @@
CmBattAcAdapter,
CmBattBattery
} CMBATT_EXTENSION_TYPE;
+
+#define ACPI_BATT_STAT_DISCHARG 0x0001
+#define ACPI_BATT_STAT_CHARGING 0x0002
+#define ACPI_BATT_STAT_CRITICAL 0x0004
+#define ACPI_BATT_STAT_NOT_PRESENT 0x0007
+#define ACPI_BATT_STAT_MAX 0x0007
typedef struct _ACPI_BST_DATA
{
@@ -93,7 +99,7 @@
ULONG RemainingCapacity;
ULONG PresentVoltage;
ULONG Rate;
- BATTERY_INFORMATION StaticBatteryInformation;
+ BATTERY_INFORMATION BatteryInformation;
ULONG BatteryCapacityGranularity1;
ULONG BatteryCapacityGranularity2;
BOOLEAN TripPointSet;