mirror of
https://github.com/reactos/reactos.git
synced 2024-08-13 22:56:37 +00:00
[CMBATT]: Implement CmBattQueryTag and CmBattNotifyHandler for getting ACPI Battery notifications, as per ACPI Spec and http://www.microsoft.com/whdc/archive/ACPInotify.mspx.
svn path=/trunk/; revision=46309
This commit is contained in:
parent
c825e8a684
commit
22bb1901b6
|
@ -43,10 +43,117 @@ CmBattWakeDpc(PKDPC Dpc,
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
CmBattNotifyHandler(PCMBATT_DEVICE_EXTENSION DeviceExtension,
|
CmBattNotifyHandler(IN PCMBATT_DEVICE_EXTENSION DeviceExtension,
|
||||||
ULONG NotifyValue)
|
IN ULONG NotifyValue)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
ULONG ArFlag;
|
||||||
|
PCMBATT_DEVICE_EXTENSION FdoExtension;
|
||||||
|
PDEVICE_OBJECT DeviceObject;
|
||||||
|
|
||||||
|
if (CmBattDebug & (CMBATT_ACPI_ASSERT | CMBATT_PNP_INFO))
|
||||||
|
DbgPrint("CmBattNotifyHandler: CmBatt 0x%08x Type %d Number %d Notify Value: %x\n",
|
||||||
|
DeviceExtension,
|
||||||
|
DeviceExtension->FdoType,
|
||||||
|
DeviceExtension->DeviceId,
|
||||||
|
NotifyValue);
|
||||||
|
|
||||||
|
/* Check what kind of notification was received */
|
||||||
|
switch (NotifyValue)
|
||||||
|
{
|
||||||
|
/* ACPI Specification says is sends a "Bus Check" when power source changes */
|
||||||
|
case ACPI_BUS_CHECK:
|
||||||
|
|
||||||
|
/* We treat it as possible physical change */
|
||||||
|
DeviceExtension->ArFlag |= (CMBATT_AR_NOTIFY | CMBATT_AR_INSERT);
|
||||||
|
if ((DeviceExtension->Tag) &&
|
||||||
|
(CmBattDebug & (CMBATT_ACPI_WARNING | CMBATT_GENERIC_WARNING)))
|
||||||
|
DbgPrint("CmBattNotifyHandler: Received battery #%x insertion, but tag was not invalid.\n",
|
||||||
|
DeviceExtension->DeviceId);
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Status of the battery has changed */
|
||||||
|
case ACPI_BATT_NOTIFY_STATUS:
|
||||||
|
|
||||||
|
/* All we'll do is notify the class driver */
|
||||||
|
DeviceExtension->ArFlag |= CMBATT_AR_NOTIFY;
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Information on the battery has changed, such as physical presence */
|
||||||
|
case ACPI_DEVICE_CHECK:
|
||||||
|
case ACPI_BATT_NOTIFY_INFO:
|
||||||
|
|
||||||
|
/* Reset all state and let the class driver re-evaluate it all */
|
||||||
|
DeviceExtension->ArFlag |= (CMBATT_AR_NOTIFY |
|
||||||
|
CMBATT_AR_INSERT |
|
||||||
|
CMBATT_AR_REMOVE);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
|
||||||
|
if (CmBattDebug & CMBATT_PNP_INFO)
|
||||||
|
DbgPrint("CmBattNotifyHandler: Unknown Notify Value: %x\n", NotifyValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if we're supposed to delay the notification till later */
|
||||||
|
if (DeviceExtension->DelayNotification)
|
||||||
|
{
|
||||||
|
/* We'll handle this when we get a status query later on */
|
||||||
|
if (CmBattDebug & CMBATT_PNP_INFO)
|
||||||
|
DbgPrint("CmBattNotifyHandler: Notification delayed: ARs = %01x\n",
|
||||||
|
DeviceExtension->ArFlag);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We're going to handle this now */
|
||||||
|
if (CmBattDebug & CMBATT_PNP_INFO)
|
||||||
|
DbgPrint("CmBattNotifyHandler: Performing ARs: %01x\n", DeviceExtension->ArFlag);
|
||||||
|
|
||||||
|
/* Check if this is a battery or AC adapter notification */
|
||||||
|
if (DeviceExtension->FdoType == CmBattBattery)
|
||||||
|
{
|
||||||
|
/* Reset the current trip point */
|
||||||
|
DeviceExtension->TripPointValue = 0xFFFFFFFF;
|
||||||
|
|
||||||
|
/* Check what ARs have to be done */
|
||||||
|
ArFlag = DeviceExtension->ArFlag;
|
||||||
|
|
||||||
|
/* New battery inserted, reset lock value */
|
||||||
|
if (ArFlag & CMBATT_AR_INSERT) InterlockedExchange(&DeviceExtension->ArLockValue, 0);
|
||||||
|
|
||||||
|
/* Check if the battery may have been removed */
|
||||||
|
if (ArFlag & CMBATT_AR_REMOVE) DeviceExtension->Tag = 0;
|
||||||
|
|
||||||
|
/* Check if there's been any sort of change to the battery */
|
||||||
|
if (ArFlag & CMBATT_AR_NOTIFY)
|
||||||
|
{
|
||||||
|
/* We'll probably end up re-evaluating _BIF and _BST */
|
||||||
|
DeviceExtension->NotifySent = TRUE;
|
||||||
|
BatteryClassStatusNotify(DeviceExtension->ClassData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* The only known notification is AC/DC change */
|
||||||
|
if (DeviceExtension->ArFlag & CMBATT_AR_NOTIFY)
|
||||||
|
{
|
||||||
|
for (DeviceObject = DeviceExtension->FdoDeviceObject->DriverObject->DeviceObject;
|
||||||
|
DeviceObject;
|
||||||
|
DeviceObject = DeviceObject->NextDevice)
|
||||||
|
{
|
||||||
|
/* Is this a battery? */
|
||||||
|
FdoExtension = DeviceObject->DeviceExtension;
|
||||||
|
if (FdoExtension->FdoType == CmBattBattery)
|
||||||
|
{
|
||||||
|
/* Send a notification to the class driver */
|
||||||
|
FdoExtension->NotifySent = TRUE;
|
||||||
|
BatteryClassStatusNotify(FdoExtension->ClassData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ARs have been processed */
|
||||||
|
DeviceExtension->ArFlag = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
@ -156,11 +263,61 @@ CmBattIoctl(PDEVICE_OBJECT DeviceObject,
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
CmBattQueryTag(PCMBATT_DEVICE_EXTENSION DeviceExtension,
|
CmBattQueryTag(IN PCMBATT_DEVICE_EXTENSION DeviceExtension,
|
||||||
PULONG BatteryTag)
|
OUT PULONG Tag)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
PDEVICE_OBJECT PdoDevice;
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
ULONG StaData;
|
||||||
|
ULONG NewTag;
|
||||||
|
NTSTATUS Status;
|
||||||
|
PAGED_CODE();
|
||||||
|
if (CmBattDebug & (CMBATT_ACPI_WARNING | CMBATT_GENERIC_INFO))
|
||||||
|
DbgPrint("CmBattQueryTag - Tag (%d), Battery %x, Device %d\n",
|
||||||
|
*Tag, DeviceExtension, DeviceExtension->DeviceId);
|
||||||
|
|
||||||
|
/* Get PDO and clear notification flag */
|
||||||
|
PdoDevice = DeviceExtension->PdoDeviceObject;
|
||||||
|
DeviceExtension->NotifySent = 0;
|
||||||
|
|
||||||
|
/* Get _STA from PDO (we need the machine status, not the battery status) */
|
||||||
|
Status = CmBattGetStaData(PdoDevice, &StaData);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Is a battery present? */
|
||||||
|
if (StaData & ACPI_STA_BATTERY_PRESENT)
|
||||||
|
{
|
||||||
|
/* Do we not have a tag yet? */
|
||||||
|
if (!DeviceExtension->Tag)
|
||||||
|
{
|
||||||
|
/* Set the new tag value, reset tags if we reached the maximum */
|
||||||
|
NewTag = DeviceExtension->TagData;
|
||||||
|
if (DeviceExtension->TagData++ == 0xFFFFFFFF) NewTag = 1;
|
||||||
|
DeviceExtension->Tag = NewTag;
|
||||||
|
if (CmBattDebug & CMBATT_GENERIC_INFO)
|
||||||
|
DbgPrint("CmBattQueryTag - New Tag: (%d)\n", DeviceExtension->Tag);
|
||||||
|
|
||||||
|
/* Reset trip point data */
|
||||||
|
DeviceExtension->TripPointOld = 0;
|
||||||
|
DeviceExtension->TripPointValue = 0xFFFFFFFF;
|
||||||
|
|
||||||
|
/* Clear AR lock and set new interrupt time */
|
||||||
|
InterlockedExchange(&DeviceExtension->ArLockValue, 0);
|
||||||
|
DeviceExtension->InterruptTime = KeQueryInterruptTime();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* No battery, so no tag */
|
||||||
|
DeviceExtension->Tag = 0;
|
||||||
|
Status = STATUS_NO_SUCH_DEVICE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the tag and status result */
|
||||||
|
*Tag = DeviceExtension->Tag;
|
||||||
|
if (CmBattDebug & CMBATT_ACPI_WARNING)
|
||||||
|
DbgPrint("CmBattQueryTag: Returning Tag: 0x%x, status 0x%x\n", *Tag, Status);
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
|
|
@ -29,6 +29,15 @@ typedef enum _CMBATT_EXTENSION_TYPE
|
||||||
CmBattBattery
|
CmBattBattery
|
||||||
} CMBATT_EXTENSION_TYPE;
|
} CMBATT_EXTENSION_TYPE;
|
||||||
|
|
||||||
|
#define ACPI_BUS_CHECK 0x00
|
||||||
|
#define ACPI_DEVICE_CHECK 0x01
|
||||||
|
|
||||||
|
#define ACPI_STA_PRESENT 0x01
|
||||||
|
#define ACPI_STA_ENABLED 0x02
|
||||||
|
#define ACPI_STA_SHOW_UI 0x04
|
||||||
|
#define ACPI_STA_FUNCTIONAL 0x08
|
||||||
|
#define ACPI_STA_BATTERY_PRESENT 0x10
|
||||||
|
|
||||||
#define ACPI_BATT_NOTIFY_STATUS 0x80
|
#define ACPI_BATT_NOTIFY_STATUS 0x80
|
||||||
#define ACPI_BATT_NOTIFY_INFO 0x81
|
#define ACPI_BATT_NOTIFY_INFO 0x81
|
||||||
|
|
||||||
|
@ -67,6 +76,10 @@ typedef struct _ACPI_BIF_DATA
|
||||||
CHAR OemInfo[256];
|
CHAR OemInfo[256];
|
||||||
} ACPI_BIF_DATA, *PACPI_BIF_DATA;
|
} ACPI_BIF_DATA, *PACPI_BIF_DATA;
|
||||||
|
|
||||||
|
#define CMBATT_AR_NOTIFY 0x01
|
||||||
|
#define CMBATT_AR_INSERT 0x02
|
||||||
|
#define CMBATT_AR_REMOVE 0x04
|
||||||
|
|
||||||
typedef struct _CMBATT_DEVICE_EXTENSION
|
typedef struct _CMBATT_DEVICE_EXTENSION
|
||||||
{
|
{
|
||||||
CMBATT_EXTENSION_TYPE FdoType;
|
CMBATT_EXTENSION_TYPE FdoType;
|
||||||
|
@ -85,11 +98,11 @@ typedef struct _CMBATT_DEVICE_EXTENSION
|
||||||
ULONG DeviceId;
|
ULONG DeviceId;
|
||||||
PUNICODE_STRING DeviceName;
|
PUNICODE_STRING DeviceName;
|
||||||
ACPI_INTERFACE_STANDARD2 AcpiInterface;
|
ACPI_INTERFACE_STANDARD2 AcpiInterface;
|
||||||
BOOLEAN DelayAr;
|
BOOLEAN DelayNotification;
|
||||||
BOOLEAN DelayedArFlag;
|
BOOLEAN ArFlag;
|
||||||
PVOID ClassData;
|
PVOID ClassData;
|
||||||
BOOLEAN Started;
|
BOOLEAN Started;
|
||||||
BOOLEAN DelayNotification;
|
BOOLEAN NotifySent;
|
||||||
LONG ArLockValue;
|
LONG ArLockValue;
|
||||||
ULONG TagData;
|
ULONG TagData;
|
||||||
ULONG Tag;
|
ULONG Tag;
|
||||||
|
@ -157,4 +170,11 @@ CmBattGetPsrData(
|
||||||
PULONG PsrData
|
PULONG PsrData
|
||||||
);
|
);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
CmBattGetStaData(
|
||||||
|
PDEVICE_OBJECT DeviceObject,
|
||||||
|
PULONG StaData
|
||||||
|
);
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
Loading…
Reference in a new issue