DrvACPI.cpp revision 1c94c0a63ba68be1a7b2c640e70d7a06464e4fca
/** $Id$ */
/** @file
* ACPI Host Driver.
*/
/*
* Copyright (C) 2006-2007 Sun Microsystems, Inc.
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
* Clara, CA 95054 USA or visit http://www.sun.com if you need
* additional information or have any questions.
*/
/*******************************************************************************
* Header Files *
*******************************************************************************/
#define LOG_GROUP LOG_GROUP_DRV_ACPI
#ifdef RT_OS_WINDOWS
# include <windows.h>
#endif
#ifdef RT_OS_LINUX
# include <dirent.h>
# include <stdio.h>
#endif
#include "Builtins.h"
/*******************************************************************************
* Structures and Typedefs *
*******************************************************************************/
/**
* ACPI driver instance data.
*/
typedef struct DRVACPI
{
/** The ACPI interface. */
/** The ACPI port interface. */
/** Pointer to the driver instance. */
/**
* Queries an interface to the driver.
*
* @returns Pointer to interface.
* @returns NULL if the interface was not supported by the driver.
* @param pInterface Pointer to this interface structure.
* @param enmInterface The requested interface identification.
* @thread Any thread.
*/
{
switch (enmInterface)
{
case PDMINTERFACE_BASE:
return &pData->IACPIConnector;
default:
return NULL;
}
}
/**
* Get the current power source of the host system.
*
* @returns status code
* @param pInterface Pointer to the interface structure containing the called function pointer.
* @param pPowerSource Pointer to the power source result variable.
*/
{
#if defined(RT_OS_WINDOWS)
if (GetSystemPowerStatus(&powerStatus))
{
/* running on battery? */
if ( (powerStatus.ACLineStatus == 0)
{
}
/* running on AC link? */
{
}
else
/* what the hell we're running on? */
{
}
}
else
{
AssertMsgFailed(("Could not determine system power status, error: 0x%x\n",
GetLastError()));
}
/* start with no result */
if (dfd)
{
for (;;)
{
if (dp == 0)
break;
continue;
/* there's another possible name for this file */
if (!statusFile)
{
}
if (statusFile)
break;
}
}
if (statusFile)
{
for (;;)
{
char buff2[1024];
break;
{
else
}
}
}
#else /* !RT_OS_LINUX either - what could this be? */
#endif /* !RT_OS_WINDOWS */
return VINF_SUCCESS;
}
/**
* @copydoc PDMIACPICONNECTOR::pfnQueryBatteryStatus
*/
{
/* default return values for all architectures */
*pfPresent = false; /* no battery present */
*pu32PresentRate = ~0; /* present rate is unknown */
#if defined(RT_OS_WINDOWS)
if (GetSystemPowerStatus(&powerStatus))
{
/* 128 means no battery present */
/* just forward the value directly */
/* we assume that we are discharging the battery if we are not on-line and
* not charge the battery */
/* on Windows it is difficult to request the present charging/discharging rate */
}
else
{
AssertMsgFailed(("Could not determine system power status, error: 0x%x\n",
GetLastError()));
}
#elif defined(RT_OS_LINUX)
/* the summed up maximum capacity */
int maxCapacityTotal = ~0;
/* the summed up total capacity */
int currentCapacityTotal = ~0;
int presentRate = 0;
int presentRateTotal = 0;
if (dfd)
{
for (;;)
{
if (dp == 0)
break;
continue;
/* there is a 2nd variant of that file */
if (!statusFile)
{
}
/* we need both files */
if (!statusFile || !infoFile)
{
if (statusFile)
if (infoFile)
break;
}
/* get 'present' status from the info file */
for (;;)
{
char buff2[1024];
break;
{
fBatteryPresent = true;
}
}
/* move file pointer back to start of file */
if (fBatteryPresent)
{
/* get the maximum capacity from the info file */
for (;;)
{
char buff2[1024];
int maxCapacity = ~0;
break;
{
maxCapacity = ~0;
/* did we get a valid capacity and it's the first value we got? */
if (maxCapacityTotal < 0 && maxCapacity > 0)
{
/* take this as the maximum capacity */
}
else
{
/* sum up the maximum capacity */
if (maxCapacityTotal > 0 && maxCapacity > 0)
}
/* we got all we need */
break;
}
}
bool gotRemainingCapacity=false, gotBatteryState=false,
gotCapacityState=false, gotPresentRate=false;
while (!gotRemainingCapacity || !gotBatteryState ||
{
char buff2[1024];
int currentCapacity = ~0;
break;
{
currentCapacity = ~0;
/* is this the first valid value we see? If so, take it! */
if (currentCapacityTotal < 0 && currentCapacity >= 0)
{
}
else
{
/* just sum up the current value */
if (currentCapacityTotal > 0 && currentCapacity > 0)
}
gotRemainingCapacity = true;
}
{
fDischarging = true;
fCharging = true;
gotBatteryState = true;
}
{
fCritical = true;
gotCapacityState = true;
}
{
presentRate = 0;
gotPresentRate = true;
}
}
}
if (presentRate)
{
if (fDischarging)
else
}
if (statusFile)
if (infoFile)
}
}
/* charging/discharging bits are mutual exclusive */
if (fDischarging)
else if (fCharging)
if (fCritical)
if (presentRateTotal < 0)
if (maxCapacityTotal > 0 && currentCapacityTotal > 0)
{
/* calculate the percentage */
*penmRemainingCapacity = (PDMACPIBATCAPACITY)(((float)currentCapacityTotal / (float)maxCapacityTotal)
}
#endif /* RT_OS_LINUX */
return VINF_SUCCESS;
}
/**
* Destruct a driver instance.
*
* Most VM resources are freed by the VM. This callback is provided so that any non-VM
* resources can be freed correctly.
*
* @param pDrvIns The driver instance data.
*/
{
LogFlow(("drvACPIDestruct\n"));
}
/**
* Construct an ACPI driver instance.
*
* @returns VBox status.
* @param pDrvIns The driver instance data.
* If the registration structure is needed, pDrvIns->pDrvReg points to it.
* @param pCfgHandle Configuration node handle for the driver. Use this to obtain the configuration
* of the driver instance. It's also found in pDrvIns->pCfgHandle, but like
* iInstance it's expected to be used a bit in this function.
*/
{
/*
* Init the static parts.
*/
/* IBase */
/* IACPIConnector */
/*
* Validate the config.
*/
/*
* Check that no-one is attached to us.
*/
if (rc != VERR_PDM_NO_ATTACHED_DRIVER)
{
AssertMsgFailed(("Configuration error: Cannot attach drivers to the ACPI driver!\n"));
return VERR_PDM_DRVINS_NO_ATTACH;
}
/*
* Query the ACPI port interface.
*/
{
AssertMsgFailed(("Configuration error: "
return VERR_PDM_MISSING_INTERFACE_ABOVE;
}
return VINF_SUCCESS;
}
/**
* ACPI driver registration record.
*/
{
/* u32Version */
/* szDriverName */
"ACPIHost",
/* pszDescription */
"ACPI Host Driver",
/* fFlags */
/* fClass. */
/* cMaxInstances */
~0,
/* cbInstance */
sizeof(DRVACPI),
/* pfnConstruct */
/* pfnDestruct */
/* pfnIOCtl */
NULL,
/* pfnPowerOn */
NULL,
/* pfnReset */
NULL,
/* pfnSuspend */
NULL,
/* pfnResume */
NULL,
/* pfnDetach */
NULL,
/* pfnPowerOff */
};