mirror of
https://github.com/reactos/reactos.git
synced 2025-01-04 05:20:54 +00:00
[CMBATT]: Implement CmBattPowerCallback and CmBattWakeDpc to handle S0 entry/exit transitions which determine if we delay ACPI battery notifications to avoid wake, and the queuing of a DPC to handle processing the delayed ARs when we return to S0.
svn path=/trunk/; revision=46324
This commit is contained in:
parent
37d10b143e
commit
3e76f1bac8
1 changed files with 102 additions and 8 deletions
|
@ -19,26 +19,120 @@ UNICODE_STRING GlobalRegistryPath;
|
|||
KTIMER CmBattWakeDpcTimerObject;
|
||||
KDPC CmBattWakeDpcObject;
|
||||
PDEVICE_OBJECT AcAdapterPdo;
|
||||
LARGE_INTEGER CmBattWakeDpcDelay;
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
CmBattPowerCallBack(PCMBATT_DEVICE_EXTENSION DeviceExtension,
|
||||
PVOID Argument1,
|
||||
PVOID Argument2)
|
||||
CmBattPowerCallBack(IN PCMBATT_DEVICE_EXTENSION DeviceExtension,
|
||||
IN ULONG Action,
|
||||
IN ULONG Value)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
BOOLEAN Cancelled;
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
if (CmBattDebug & 0x10)
|
||||
DbgPrint("CmBattPowerCallBack: action: %d, value: %d \n", Action, Value);
|
||||
|
||||
/* Check if a transition is going to happen */
|
||||
if (Action == PO_CB_SYSTEM_STATE_LOCK)
|
||||
{
|
||||
/* We have just re-entered S0: call the wake DPC in 10 seconds */
|
||||
if (Value == 0)
|
||||
{
|
||||
if (CmBattDebug & 0x10)
|
||||
DbgPrint("CmBattPowerCallBack: Calling CmBattWakeDpc after 10 seconds.\n");
|
||||
Cancelled = KeSetTimer(&CmBattWakeDpcTimerObject, CmBattWakeDpcDelay, &CmBattWakeDpcObject);
|
||||
if (CmBattDebug & 0x10)
|
||||
DbgPrint("CmBattPowerCallBack: timerCanceled = %d.\n", Cancelled);
|
||||
}
|
||||
else if (Value == 0)
|
||||
{
|
||||
/* We are exiting the S0 state: loop all devices to set the delay flag */
|
||||
if (CmBattDebug & 0x10)
|
||||
DbgPrint("CmBattPowerCallBack: Delaying Notifications\n");
|
||||
for (DeviceObject = DeviceExtension->DeviceObject;
|
||||
DeviceObject;
|
||||
DeviceObject = DeviceObject->NextDevice)
|
||||
{
|
||||
/* Set the delay flag */
|
||||
DeviceExtension = DeviceObject->DeviceExtension;
|
||||
DeviceExtension->DelayNotification = TRUE;
|
||||
}
|
||||
}
|
||||
else if (CmBattDebug & 0x10)
|
||||
{
|
||||
/* Unknown value */
|
||||
DbgPrint("CmBattPowerCallBack: unknown argument2 = %08x\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
CmBattWakeDpc(PKDPC Dpc,
|
||||
PCMBATT_DEVICE_EXTENSION FdoExtension,
|
||||
PVOID SystemArgument1,
|
||||
PVOID SystemArgument2)
|
||||
CmBattWakeDpc(IN PKDPC Dpc,
|
||||
IN PCMBATT_DEVICE_EXTENSION FdoExtension,
|
||||
IN PVOID SystemArgument1,
|
||||
IN PVOID SystemArgument2)
|
||||
{
|
||||
PDEVICE_OBJECT CurrentObject;
|
||||
BOOLEAN AcNotify = FALSE;
|
||||
PCMBATT_DEVICE_EXTENSION DeviceExtension;
|
||||
ULONG ArFlag;
|
||||
if (CmBattDebug & 2) DbgPrint("CmBattWakeDpc: Entered.\n");
|
||||
|
||||
/* Loop all device objects */
|
||||
for (CurrentObject = FdoExtension->DeviceObject;
|
||||
CurrentObject;
|
||||
CurrentObject = CurrentObject->NextDevice)
|
||||
{
|
||||
/* Turn delay flag off, we're back in S0 */
|
||||
DeviceExtension = CurrentObject->DeviceExtension;
|
||||
DeviceExtension->DelayNotification = 0;
|
||||
|
||||
/* Check if this is an AC adapter */
|
||||
if (DeviceExtension->FdoType == CmBattAcAdapter)
|
||||
{
|
||||
/* Was there a pending notify? */
|
||||
if (DeviceExtension->ArFlag & CMBATT_AR_NOTIFY)
|
||||
{
|
||||
/* We'll send a notify on the next pass */
|
||||
AcNotify = TRUE;
|
||||
DeviceExtension->ArFlag = 0;
|
||||
if (CmBattDebug & 0x20)
|
||||
DbgPrint("CmBattWakeDpc: AC adapter notified\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Loop the device objects again */
|
||||
for (CurrentObject = FdoExtension->DeviceObject;
|
||||
CurrentObject;
|
||||
CurrentObject = CurrentObject->NextDevice)
|
||||
{
|
||||
/* Check if this is a battery */
|
||||
DeviceExtension = CurrentObject->DeviceExtension;
|
||||
if (DeviceExtension->FdoType == CmBattBattery)
|
||||
{
|
||||
/* Check what ARs are pending */
|
||||
ArFlag = DeviceExtension->ArFlag;
|
||||
if (CmBattDebug & 0x20)
|
||||
DbgPrint("CmBattWakeDpc: Performing delayed ARs: %01x\n", ArFlag);
|
||||
|
||||
/* Insert notification, clear the lock value */
|
||||
if (ArFlag & CMBATT_AR_INSERT) InterlockedExchange(&DeviceExtension->ArLockValue, 0);
|
||||
|
||||
/* Removal, clear the battery tag */
|
||||
if (ArFlag & CMBATT_AR_REMOVE) DeviceExtension->Tag = 0;
|
||||
|
||||
/* Notification (or AC/DC adapter change from first pass above) */
|
||||
if ((ArFlag & CMBATT_AR_NOTIFY) || (AcNotify))
|
||||
{
|
||||
/* Notify the class driver */
|
||||
BatteryClassStatusNotify(DeviceExtension->ClassData);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
|
|
Loading…
Reference in a new issue