Changeset 414


Ignore:
Timestamp:
Feb 26, 2013, 3:44:10 AM (12 years ago)
Author:
pr
Message:

ACPI sleep mods. from Steven.

Files:
4 edited

Legend:

Unmodified
Added
Removed
  • branches/branch-1-0/include/helpers/acpih.h

    r406 r414  
    1111 */
    1212
    13 /*      Copyright (C) 2006 Paul Ratcliffe.
     13/*      Copyright (C) 2006-2013 Paul Ratcliffe.
    1414 *      This file is part of the "XWorkplace helpers" source package.
    1515 *      This is free software; you can redistribute it and/or modify
     
    4040     */
    4141
    42     APIRET APIENTRY AcpiStartApi(ACPI_API_HANDLE *);
     42    // Extracted from acpi.h actype.h etc.
    4343    typedef APIRET APIENTRY ACPISTARTAPI(ACPI_API_HANDLE *);
    4444    typedef ACPISTARTAPI *PACPISTARTAPI;
    4545
    46     APIRET APIENTRY AcpiEndApi(ACPI_API_HANDLE *);
    4746    typedef APIRET APIENTRY ACPIENDAPI(ACPI_API_HANDLE *);
    4847    typedef ACPIENDAPI *PACPIENDAPI;
    4948
    50     APIRET APIENTRY AcpiGoToSleep(ACPI_API_HANDLE *, UCHAR);
    5149    typedef APIRET APIENTRY ACPIGOTOSLEEP(ACPI_API_HANDLE *, UCHAR);
    5250    typedef ACPIGOTOSLEEP *PACPIGOTOSLEEP;
     51
     52    // @@added V1.0.9 (2012-12-10) [slevine]: sync with current ACPI toolkit
     53    typedef ACPI_STATUS APIENTRY ACPITKPREPARETOSLEEP(UINT8);
     54    typedef ACPITKPREPARETOSLEEP *PACPITKPREPARETOSLEEP;
    5355
    5456    typedef APIRET APIENTRY ACPITKGETOBJECTINFOALLOC(ACPI_HANDLE *, PVOID);
     
    8082    #define ORD_ACPITKWALKNAMESPACE 56
    8183    #define ORD_ACPITKEVALUATEOBJECT 50
     84    // @@added V1.0.9 (2012-12-10) [slevine]: sync with current ACPI toolkit
     85    #define ORD_ACPITKPREPARETOSLEEP 89
    8286
    8387#endif
  • branches/branch-1-0/src/helpers/acpih.c

    r410 r414  
    1717
    1818/*
    19  *      Copyright (C) 2006-2012 Paul Ratcliffe.
     19 *      Copyright (C) 2006-2013 Paul Ratcliffe.
    2020 *      This file is part of the "XWorkplace helpers" source package.
    2121 *      This is free software; you can redistribute it and/or modify
     
    6868ACPITKWALKNAMESPACE *pAcpiTkWalkNamespace = NULL;
    6969ACPITKEVALUATEOBJECT *pAcpiTkEvaluateObject = NULL;
     70// @@added V1.0.9 (2012-12-10) [slevine]: additional ACPI support
     71ACPITKPREPARETOSLEEP *pAcpiTkPrepareToSleep = NULL;
    7072
    7173/*
     
    126128            DosQueryProcAddr(G_hmodACPI, ORD_ACPITKEVALUATEOBJECT,
    127129                             NULL, (PFN *) &pAcpiTkEvaluateObject);
     130            // @@added V1.0.9 (2012-12-10) [slevine]: additional ACPI support
     131            DosQueryProcAddr(G_hmodACPI, ORD_ACPITKPREPARETOSLEEP,
     132                             NULL, (PFN *) &pAcpiTkPrepareToSleep);
    128133        }
    129134    }
     
    133138    else
    134139    {
    135         char cTmp;                      // Required to ensure code not optimized away
    136         ULONG ulMemSize, ulMemFlags;
    137 
    138140        G_ulCount++;
    139         /* Force the shutdown function to be in memory.
    140          * This is probably not the best place to do this, but it is the easiest.
    141          * The function code may or may not cross page boundary and older versions
    142          * of acpi32.dll placed the function as the last function in the DLL,
    143          * so we need to check if the page exists before attempting to force it
    144          * into memory.
    145          * @@added V1.0.9 (2012-02-23) [dazarewicz]: additional ACPI support
     141
     142        // @@added V1.0.9 (2012-12-10) [slevine]: use AcpiTkPrepareToSleep rather than workaround
     143        /* This function does not exist in older versions of acpi
     144         * As a result the shutdown attempt will usually hang because
     145         * the required code has not been committed into memory.
    146146         */
    147         cTmp = *((volatile char *)pAcpiGoToSleep); /* Ensure paged in */
    148 
    149         ulMemSize = 1;
    150         if (DosQueryMem(((char *)pAcpiGoToSleep) + 4096, &ulMemSize, &ulMemFlags) == NO_ERROR)
    151         {
    152             if (ulMemFlags & PAG_COMMIT)
    153                 cTmp = *(((volatile char *)pAcpiGoToSleep) + 4096);     /* Ensure paged in */
    154         }
     147        if (pAcpiTkPrepareToSleep)
     148            pAcpiTkPrepareToSleep(ACPI_STATE_S5);
    155149
    156150        return(pAcpiStartApi(phACPI));
     
    178172        pAcpiEndApi = NULL;
    179173        pAcpiGoToSleep = NULL;
     174        // @@added V1.0.9 (2012-12-10) [slevine]: additional ACPI support
     175        pAcpiTkPrepareToSleep = NULL;
    180176    }
    181177}
     
    251247 *@@added V1.0.9 (2012-02-20) [slevine]: code from David Azarewicz
    252248 */
     249
    253250APIRET acpihGetPowerStatus(PAPM pApm, PBOOL pfChanged)
    254251{
     
    260257    BOOL fChanged;
    261258
    262     if (pAcpiTkWalkNamespace == NULL)
    263         return 1;
    264 
    265     if (pApm == NULL)
     259    /* Make sure all the functions we need have valid pointers.
     260     * @@added V1.0.9 (2012-02-25) [dazarewicz]: additional ACPI support
     261     */
     262    if (   (pAcpiTkWalkNamespace == NULL)
     263        || (pAcpiTkGetObjectInfoAlloc == NULL)
     264        || (pAcpiTkGetHandle == NULL)
     265        || (pAcpiTkOsFree == NULL)
     266        || (pAcpiTkEvaluateObject == NULL)
     267        || (pApm == NULL)
     268       )
    266269        return 1;
    267270
     
    292295        Status = pAcpiTkEvaluateObject(G_ahAC, NULL, NULL, &Result);
    293296        if (Status != AE_OK)
    294             ulTmp = 2;
    295         else
    296             if (Object[0].Type != ACPI_TYPE_INTEGER)
    297                 ulTmp = 2;
     297            ulTmp = 2;                  // assume on backup power
     298        else if (Object[0].Type != ACPI_TYPE_INTEGER)
     299            ulTmp = 2;                  // assume on backup power
    298300            else
    299301                ulTmp = (UINT32)OBJECT_VALUE(0);
     
    313315        Result.Length = sizeof(Object);
    314316        Result.Pointer = Object;
     317        // Get battery info
    315318        Status = pAcpiTkEvaluateObject(G_ahBat[uiI], "_BIF", NULL, &Result);
    316319        if (Status != AE_OK)
     
    321324
    322325        Obj = Result.Pointer;
    323         Obj = (ACPI_OBJECT *)Obj[0].Package.Elements;   // _BIF package
     326        Obj = (ACPI_OBJECT *)Obj[0].Package.Elements;   // Battery info package
    324327        LastFull = (UINT32)OBJ_VALUE(2);
    325328        if (LastFull == 0xffffffff)
     
    331334        Result.Length = sizeof(Object);
    332335        Result.Pointer = Object;
     336        // Get battery status
    333337        Status = pAcpiTkEvaluateObject(G_ahBat[uiI], "_BST", NULL, &Result);
    334338        if (Status != AE_OK)
     
    346350
    347351        // If battery units are mWh or mAh
     352        // If not, it is a percentage
    348353        if ((UINT32)OBJ_VALUE(0) != 0xffffffff)
    349354        {
  • trunk/include/helpers/acpih.h

    r323 r414  
    1111 */
    1212
    13 /*      Copyright (C) 2006 Paul Ratcliffe.
     13/*      Copyright (C) 2006-2013 Paul Ratcliffe.
    1414 *      This file is part of the "XWorkplace helpers" source package.
    1515 *      This is free software; you can redistribute it and/or modify
     
    2727#endif
    2828
     29// @@changed V1.0.9 (2012-02-20) [slevine]: sync with current ACPI toolkit, code by David Azarewicz
     30
    2931#ifndef ACPIH_HEADER_INCLUDED
    3032    #define ACPIH_HEADER_INCLUDED
    3133
     34    #pragma pack(4)
     35    #include <acpi.h>
     36    #include <acpiapi.h>
     37    #pragma pack()
    3238    /*
    3339     * Power state values
    3440     */
    3541
    36     #define ACPI_STATE_UNKNOWN              (UCHAR) 0xFF
    37 
    38     #define ACPI_STATE_S0                   (UCHAR) 0
    39     #define ACPI_STATE_S1                   (UCHAR) 1
    40     #define ACPI_STATE_S2                   (UCHAR) 2
    41     #define ACPI_STATE_S3                   (UCHAR) 3
    42     #define ACPI_STATE_S4                   (UCHAR) 4
    43     #define ACPI_STATE_S5                   (UCHAR) 5
    44     #define ACPI_S_STATES_MAX               ACPI_STATE_S5
    45     #define ACPI_S_STATE_COUNT              6
    46 
    47     #pragma pack(1)
    48 
    49     typedef struct _VersionAcpi_
    50     {
    51         ULONG  Major;
    52         ULONG  Minor;
    53     } ACPI_VERSION;
    54 
    55     typedef struct _AcpiApiHandle_
    56     {
    57         HFILE           AcpiDrv;                 // Handle to ACPICA driver
    58         ACPI_VERSION    PSD;                     // Version PSD
    59         ACPI_VERSION    Driver;                  // Version ACPICA driver
    60         ACPI_VERSION    DLL;                     // Version acpi32.dll
    61         ULONG           StartAddrPSD;            // Start address PSD (for testcase)
    62         ULONG           AddrCommApp;             // Address DosCommApp from PSD (which not write IBM)
    63         ULONG           StartAddrDriver;         // Start address ACPICA (for testcase)
    64         ULONG           AddrFindPSD;             // Address function for find PSD (find CommApp)
    65         ULONG           IRQNumber;               // Number use IRQ
    66         void            *Internal;               // For internal DLL use
    67     } ACPI_API_HANDLE, *PACPI_API_HANDLE;
    68 
    69     /* ******************************************************************
    70      *
    71      *   ACPI helper APIs
    72      *
    73      ********************************************************************/
    74 
    75     #pragma pack()
    76 
    77     APIRET APIENTRY AcpiStartApi(ACPI_API_HANDLE *);
     42    // Extracted from acpi.h actype.h etc.
    7843    typedef APIRET APIENTRY ACPISTARTAPI(ACPI_API_HANDLE *);
    7944    typedef ACPISTARTAPI *PACPISTARTAPI;
    8045
    81     APIRET APIENTRY AcpiEndApi(ACPI_API_HANDLE *);
    8246    typedef APIRET APIENTRY ACPIENDAPI(ACPI_API_HANDLE *);
    8347    typedef ACPIENDAPI *PACPIENDAPI;
    8448
    85     APIRET APIENTRY AcpiGoToSleep(ACPI_API_HANDLE *, UCHAR);
    8649    typedef APIRET APIENTRY ACPIGOTOSLEEP(ACPI_API_HANDLE *, UCHAR);
    8750    typedef ACPIGOTOSLEEP *PACPIGOTOSLEEP;
    8851
     52    // @@added V1.0.9 (2012-12-10) [slevine]: sync with current ACPI toolkit
     53    typedef ACPI_STATUS APIENTRY ACPITKPREPARETOSLEEP(UINT8);
     54    typedef ACPITKPREPARETOSLEEP *PACPITKPREPARETOSLEEP;
     55
     56    typedef APIRET APIENTRY ACPITKGETOBJECTINFOALLOC(ACPI_HANDLE *, PVOID);
     57    typedef APIRET APIENTRY ACPITKGETHANDLE(ACPI_HANDLE, ACPI_STRING, ACPI_HANDLE *);
     58    typedef APIRET APIENTRY ACPITKOSFREE(PVOID);
     59    typedef APIRET APIENTRY ACPITKWALKNAMESPACE(ACPI_OBJECT_TYPE, ACPI_HANDLE, UINT32,ACPI_WALK_CALLBACK, PVOID, void **);
     60    typedef APIRET APIENTRY ACPITKEVALUATEOBJECT(ACPI_HANDLE, ACPI_STRING, ACPI_OBJECT_LIST *, ACPI_BUFFER *);
     61
    8962    APIRET APIENTRY acpihOpen(ACPI_API_HANDLE *phACPI);
     63    typedef APIRET APIENTRY ACPIHOPEN(ACPI_API_HANDLE *);
     64    typedef ACPIHOPEN *PACPIHOPEN;
    9065
    9166    VOID APIENTRY acpihClose(ACPI_API_HANDLE *phACPI);
     
    9368    APIRET APIENTRY acpihGoToSleep(ACPI_API_HANDLE *phACPI, UCHAR ucState);
    9469
     70    APIRET APIENTRY acpihGetPowerStatus(PAPM, PBOOL);
     71    typedef APIRET APIENTRY ACPIHGETPOWERSTATUS(PAPM, PBOOL);
     72    typedef ACPIHGETPOWERSTATUS *PACPIHGETPOWERSTATUS;
     73
     74    BOOL acpihHasBattery(VOID);
     75
    9576    #define ORD_ACPISTARTAPI    16
    9677    #define ORD_ACPIENDAPI      17
    9778    #define ORD_ACPIGOTOSLEEP   19
     79    #define ORD_ACPITKGETOBJECTINFOALLOC 85
     80    #define ORD_ACPITKGETHANDLE 65
     81    #define ORD_ACPITKOSFREE 66
     82    #define ORD_ACPITKWALKNAMESPACE 56
     83    #define ORD_ACPITKEVALUATEOBJECT 50
     84    // @@added V1.0.9 (2012-12-10) [slevine]: sync with current ACPI toolkit
     85    #define ORD_ACPITKPREPARETOSLEEP 89
    9886
    9987#endif
  • trunk/src/helpers/acpih.c

    r380 r414  
    1717
    1818/*
    19  *      Copyright (C) 2006-2009 Paul Ratcliffe.
     19 *      Copyright (C) 2006-2013 Paul Ratcliffe.
    2020 *      This file is part of the "XWorkplace helpers" source package.
    2121 *      This is free software; you can redistribute it and/or modify
     
    4040#include "setup.h"                      // code generation and debugging options
    4141
     42#include "helpers\apmh.h"               // @@added V1.0.9 (2012-02-20) [slevine]
    4243#include "helpers\acpih.h"
    4344#include "helpers\standards.h"
     
    5152HMODULE       G_hmodACPI = NULLHANDLE;
    5253ULONG         G_ulCount = 0;
     54// @@added V1.0.9 (2012-02-20) [slevine]: additional ACPI support, code from David Azarewicz
     55ACPI_HANDLE   G_ahAC = 0;
     56#define MAX_BATTERY_COUNT 4
     57ACPI_HANDLE   G_ahBat[MAX_BATTERY_COUNT];
     58ULONG         G_uiBatteryCount = 0;
     59ULONG         G_uiAlreadyWalked = 0;
    5360
    5461ACPISTARTAPI  *pAcpiStartApi = NULL;
     
    5663ACPIGOTOSLEEP *pAcpiGoToSleep = NULL;
    5764
     65ACPITKGETOBJECTINFOALLOC *pAcpiTkGetObjectInfoAlloc = NULL;
     66ACPITKGETHANDLE *pAcpiTkGetHandle = NULL;
     67ACPITKOSFREE *pAcpiTkOsFree = NULL;
     68ACPITKWALKNAMESPACE *pAcpiTkWalkNamespace = NULL;
     69ACPITKEVALUATEOBJECT *pAcpiTkEvaluateObject = NULL;
     70// @@added V1.0.9 (2012-12-10) [slevine]: additional ACPI support
     71ACPITKPREPARETOSLEEP *pAcpiTkPrepareToSleep = NULL;
     72
    5873/*
    5974 *@@category: Helpers\Control program helpers\ACPI
     
    7186
    7287    if (!G_hmodACPI)
     88    {
    7389        if (!(arc = DosLoadModule(NULL,
    7490                                  0,
     
    8298            if (!arc)
    8399                arc = DosQueryProcAddr(G_hmodACPI,
    84                                    ORD_ACPIENDAPI,
    85                                    NULL,
    86                                    (PFN *) &pAcpiEndApi);
     100                                       ORD_ACPIENDAPI,
     101                                       NULL,
     102                                       (PFN *) &pAcpiEndApi);
    87103
    88104            if (!arc)
    89105                arc = DosQueryProcAddr(G_hmodACPI,
    90                                    ORD_ACPIGOTOSLEEP,
    91                                    NULL,
    92                                    (PFN *) &pAcpiGoToSleep);
     106                                       ORD_ACPIGOTOSLEEP,
     107                                       NULL,
     108                                       (PFN *) &pAcpiGoToSleep);
    93109            if (arc)
    94110            {
     
    100116                return(arc);
    101117            }
    102         }
     118
     119            // @@added V1.0.9 (2012-02-20) [slevine]: additional ACPI support, code from David Azarewicz
     120            DosQueryProcAddr(G_hmodACPI, ORD_ACPITKGETOBJECTINFOALLOC,
     121                             NULL, (PFN *) &pAcpiTkGetObjectInfoAlloc);
     122            DosQueryProcAddr(G_hmodACPI, ORD_ACPITKGETHANDLE,
     123                             NULL, (PFN *) &pAcpiTkGetHandle);
     124            DosQueryProcAddr(G_hmodACPI, ORD_ACPITKOSFREE,
     125                             NULL, (PFN *) &pAcpiTkOsFree);
     126            DosQueryProcAddr(G_hmodACPI, ORD_ACPITKWALKNAMESPACE,
     127                             NULL, (PFN *) &pAcpiTkWalkNamespace);
     128            DosQueryProcAddr(G_hmodACPI, ORD_ACPITKEVALUATEOBJECT,
     129                             NULL, (PFN *) &pAcpiTkEvaluateObject);
     130            // @@added V1.0.9 (2012-12-10) [slevine]: additional ACPI support
     131            DosQueryProcAddr(G_hmodACPI, ORD_ACPITKPREPARETOSLEEP,
     132                             NULL, (PFN *) &pAcpiTkPrepareToSleep);
     133        }
     134    }
    103135
    104136    if (arc)
     
    107139    {
    108140        G_ulCount++;
     141
     142        // @@added V1.0.9 (2012-12-10) [slevine]: use AcpiTkPrepareToSleep rather than workaround
     143        /* This function does not exist in older versions of acpi
     144         * As a result the shutdown attempt will usually hang because
     145         * the required code has not been committed into memory.
     146         */
     147        if (pAcpiTkPrepareToSleep)
     148            pAcpiTkPrepareToSleep(ACPI_STATE_S5);
     149
    109150        return(pAcpiStartApi(phACPI));
    110151    }
     
    131172        pAcpiEndApi = NULL;
    132173        pAcpiGoToSleep = NULL;
     174        // @@added V1.0.9 (2012-12-10) [slevine]: additional ACPI support
     175        pAcpiTkPrepareToSleep = NULL;
    133176    }
    134177}
     
    147190}
    148191
     192
     193/**
     194 *@@ AcpiCallbackWidget:
     195 *      ACPI callback helper for battery and power status queries.
     196 *      Code provided by David Azarewicz
     197 *@@added V1.0.9 (2012-02-20) [slevine]: code from David Azarewicz
     198 */
     199
     200#define AE_DEPTH AE_OK
     201
     202ACPI_STATUS AcpiCallbackWidget( ACPI_HANDLE ObjHandle, UINT32 NestingLevel, void *Context, void **ReturnValue )
     203{
     204    ACPI_DEVICE_INFO *pDevInfo = NULL;
     205    ACPI_STATUS Status = pAcpiTkGetObjectInfoAlloc(ObjHandle, &pDevInfo);
     206
     207    if (Status == AE_OK)
     208    {
     209        if (pDevInfo->Type != ACPI_TYPE_DEVICE)
     210            return AE_DEPTH;
     211
     212        if (!(pDevInfo->Valid & ACPI_VALID_HID))
     213            return AE_DEPTH;
     214
     215        if (!pDevInfo->HardwareId.String)
     216            return AE_DEPTH;
     217
     218        if (strncmp(pDevInfo->HardwareId.String, "ACPI0003", 8) == 0)
     219        { /* AC Power */
     220            Status = pAcpiTkGetHandle(ObjHandle, "_PSR", &G_ahAC);
     221            if (Status)
     222                G_ahAC = 0;
     223
     224            return AE_DEPTH;
     225        }
     226
     227        if (strncmp(pDevInfo->HardwareId.String, "PNP0C0A", 7) == 0)
     228        { /* Smart battery */
     229            if (G_uiBatteryCount < MAX_BATTERY_COUNT)
     230                G_ahBat[G_uiBatteryCount++] = ObjHandle;
     231
     232            return AE_DEPTH;
     233        }
     234    }
     235
     236    if (pDevInfo)
     237        pAcpiTkOsFree(pDevInfo);
     238
     239    return AE_OK;
     240}
     241
     242/**
     243 *@@ acpihGetPowerStatus:
     244 *      Returns power and battery status in caller provided buffers.
     245 *      Returns zero if success, non-zero if fail.
     246 *      Code provided by David Azarewicz
     247 *@@added V1.0.9 (2012-02-20) [slevine]: code from David Azarewicz
     248 */
     249
     250APIRET acpihGetPowerStatus(PAPM pApm, PBOOL pfChanged)
     251{
     252    ACPI_STATUS Status;
     253    ACPI_BUFFER Result;
     254    ACPI_OBJECT *Obj, Object[20];
     255    UINT32 uiI;
     256    ULONG ulTmp, BRemaining, LastFull;
     257    BOOL fChanged;
     258
     259    /* Make sure all the functions we need have valid pointers.
     260     * @@added V1.0.9 (2012-02-25) [dazarewicz]: additional ACPI support
     261     */
     262    if (   (pAcpiTkWalkNamespace == NULL)
     263        || (pAcpiTkGetObjectInfoAlloc == NULL)
     264        || (pAcpiTkGetHandle == NULL)
     265        || (pAcpiTkOsFree == NULL)
     266        || (pAcpiTkEvaluateObject == NULL)
     267        || (pApm == NULL)
     268       )
     269        return 1;
     270
     271    if (!G_uiAlreadyWalked)
     272    {
     273        Status = pAcpiTkWalkNamespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
     274                                      ACPI_UINT32_MAX, AcpiCallbackWidget,
     275                                      pApm, NULL);
     276        G_uiAlreadyWalked = 1;
     277    }
     278
     279    fChanged = FALSE;
     280
     281    // VAC 3.08 long long compatibility support
     282#ifdef INCL_LONGLONG // VAC 3.6.5 - compiler supports long long
     283#define OBJECT_VALUE(index)  (Object[index].Integer.Value)
     284#define OBJ_VALUE(index)  (Obj[index].Integer.Value)
     285#else // VAC 3.08 - compiler does not support long long
     286#define OBJECT_VALUE(index)  (Object[index].Integer.Value.ulLo)
     287#define OBJ_VALUE(index)  (Obj[index].Integer.Value.ulLo)
     288#endif
     289
     290    if (G_ahAC)
     291    {
     292        // Have _PSR
     293        Result.Length = sizeof(Object);
     294        Result.Pointer = Object;
     295        Status = pAcpiTkEvaluateObject(G_ahAC, NULL, NULL, &Result);
     296        if (Status != AE_OK)
     297            ulTmp = 2;                  // assume on backup power
     298        else if (Object[0].Type != ACPI_TYPE_INTEGER)
     299            ulTmp = 2;                  // assume on backup power
     300            else
     301                ulTmp = (UINT32)OBJECT_VALUE(0);
     302
     303        if (pApm->fUsingAC != (BYTE) ulTmp)
     304        {
     305            pApm->fUsingAC = (BYTE) ulTmp;
     306            fChanged = TRUE;
     307        }
     308    }
     309
     310    for (uiI=0; uiI < G_uiBatteryCount; uiI++)
     311    {
     312        if (G_ahBat[uiI] == 0)
     313            continue;
     314
     315        Result.Length = sizeof(Object);
     316        Result.Pointer = Object;
     317        // Get battery info
     318        Status = pAcpiTkEvaluateObject(G_ahBat[uiI], "_BIF", NULL, &Result);
     319        if (Status != AE_OK)
     320        {
     321            G_ahBat[uiI] = 0;
     322            continue;
     323        }
     324
     325        Obj = Result.Pointer;
     326        Obj = (ACPI_OBJECT *)Obj[0].Package.Elements;   // Battery info package
     327        LastFull = (UINT32)OBJ_VALUE(2);
     328        if (LastFull == 0xffffffff)
     329        {
     330            G_ahBat[uiI] = 0;
     331            continue;
     332        }
     333
     334        Result.Length = sizeof(Object);
     335        Result.Pointer = Object;
     336        // Get battery status
     337        Status = pAcpiTkEvaluateObject(G_ahBat[uiI], "_BST", NULL, &Result);
     338        if (Status != AE_OK)
     339        {
     340            G_ahBat[uiI] = 0;
     341            continue;
     342        }
     343
     344        Obj = Result.Pointer;
     345        Obj = (ACPI_OBJECT *)Obj[0].Package.Elements;   // Battery status package
     346
     347        // If voltage known
     348        if ((UINT32)OBJ_VALUE(2) != 0xffffffff)
     349            BRemaining = (UINT32)OBJ_VALUE(2);
     350
     351        // If battery units are mWh or mAh
     352        // If not, it is a percentage
     353        if ((UINT32)OBJ_VALUE(0) != 0xffffffff)
     354        {
     355            if (BRemaining > (LastFull >> 1)) // > 50% is high. < 50% is low
     356                ulTmp = 1; // High
     357            else
     358                ulTmp = 2; // Low
     359
     360            if (OBJ_VALUE(0) & 4)
     361                ulTmp = 2; // Critical
     362
     363            // If battery charging - it can't be critical
     364            if (OBJ_VALUE(0) & 2)
     365                ulTmp = 3; // Charging
     366
     367            if (pApm->bBatteryStatus != ulTmp)
     368            {
     369                pApm->bBatteryStatus = (BYTE)ulTmp;
     370                fChanged = TRUE;
     371            }
     372        }
     373
     374        ulTmp = (BRemaining*100) / LastFull;
     375        if (ulTmp > 100)
     376            ulTmp = 100;
     377
     378        if (pApm->bBatteryLife != ulTmp)
     379        {
     380            pApm->bBatteryLife = (BYTE) ulTmp;
     381            fChanged = TRUE;
     382        }
     383    }
     384
     385    if (pfChanged)
     386        *pfChanged = fChanged;
     387
     388    pApm->fAlreadyRead = FALSE;
     389    return 0;
     390
     391#undef OBJECT_VALUE
     392#undef OBJ_VALUE
     393}
     394
     395/*
     396 *@@ acpihHasBattery:
     397 *      quick'n'dirty helper which returns TRUE only
     398 *      if ACPI is supported on the system and the
     399 *      system actually has a battery (i.e. is a laptop).
     400 *      Code provided by David Azarewicz.
     401 * @@added V1.0.9 (2012-02-20) [slevine]: code from David Azarewicz
     402 */
     403BOOL acpihHasBattery(VOID)
     404{
     405    BOOL brc = FALSE;
     406    ACPI_API_HANDLE hACPI;
     407    APM Apm;
     408
     409    if (!acpihOpen(&hACPI))
     410    {
     411        Apm.bBatteryStatus = 0xff;
     412        if (!acpihGetPowerStatus(&Apm, NULL))
     413            brc = (Apm.bBatteryStatus != 0xFF);
     414
     415        acpihClose(&hACPI);
     416    }
     417
     418    return brc;
     419}
     420
Note: See TracChangeset for help on using the changeset viewer.