IOPlatformTableCtrlLoop.cpp [plain text]
#include "IOPlatformPlugin.h"
#include "IOPlatformPluginDefs.h"
#include "IOPlatformPluginSymbols.h"
#include "IOPlatformStateSensor.h"
#include "IOPlatformControl.h"
#include "IOPlatformTableCtrlLoop.h"
#define super IOPlatformCtrlLoop
OSDefineMetaClassAndStructors( IOPlatformTableCtrlLoop, IOPlatformCtrlLoop )
bool IOPlatformTableCtrlLoop::init( void )
{
if (!super::init()) return(false);
inputSensor = NULL;
outputControl = NULL;
return(true);
}
void IOPlatformTableCtrlLoop::free( void )
{
if (inputSensor) { inputSensor->release(); inputSensor = NULL; }
if (outputControl) { outputControl->release(); outputControl = NULL; }
super::free();
}
IOReturn IOPlatformTableCtrlLoop::initPlatformCtrlLoop( const OSDictionary *dict)
{
IOReturn status;
OSArray * array;
status = super::initPlatformCtrlLoop(dict);
if ((array = OSDynamicCast(OSArray, dict->getObject(kIOPPluginThermalControlIDsKey))) == NULL ||
(outputControl = platformPlugin->lookupControlByID( OSDynamicCast(OSNumber, array->getObject(0)) )) == NULL)
{
CTRLLOOP_DLOG("IOPlatformTableCtrlLoop::initPlatformCtrlLoop no control ID!!\n");
goto failNoControl;
}
outputControl->retain();
addControl( outputControl );
if ((array = OSDynamicCast(OSArray, dict->getObject(kIOPPluginThermalSensorIDsKey))) == NULL ||
(inputSensor = OSDynamicCast(IOPlatformStateSensor, platformPlugin->lookupSensorByID( OSDynamicCast(OSNumber, array->getObject(0)) ))) == NULL)
{
CTRLLOOP_DLOG("IOPlatformTableCtrlLoop::initPlatformCtrlLoop no sensor ID!!\n");
goto failNoSensor;
}
inputSensor->retain();
addSensor( inputSensor );
if (!updateMetaState())
{
CTRLLOOP_DLOG("IOPlatformTableCtrlLoop::initPlatformCtrlLoop NO VALID META STATES!!\n");
status = kIOReturnBadArgument;
}
return status;
failNoSensor:
removeControl( outputControl );
outputControl->release();
failNoControl:
return(kIOReturnError);
}
bool IOPlatformTableCtrlLoop::updateMetaState( void )
{
const OSArray * metaStateArray;
const OSNumber * newMetaState;
OSDictionary * metaStateDict;
if ((metaStateArray = OSDynamicCast(OSArray, infoDict->getObject(gIOPPluginThermalMetaStatesKey))) == NULL)
{
CTRLLOOP_DLOG("IOPlatformTableCtrlLoop::updateMetaState NO META STATE ARRAY!!\n");
return(false);
}
if (platformPlugin->envArrayCondIsTrue(gIOPPluginEnvExternalOvertemp))
{
CTRLLOOP_DLOG("IOPlatformTableCtrlLoop::updateMetaState Entering Overtemp Mode\n");
if ((metaStateDict = OSDynamicCast(OSDictionary, metaStateArray->getObject(1))) != NULL &&
(lookupTable = OSDynamicCast(OSArray, metaStateDict->getObject(kIOPTCLLookupTableKey))) != NULL)
{
setMetaState( gIOPPluginOne );
return(true);
}
else
{
CTRLLOOP_DLOG("IOPlatformTableCtrlLoop::updateMetaState Overtemp Mode Failed!\n");
}
}
if ((metaStateDict = OSDynamicCast(OSDictionary, infoDict->getObject(gIOPPluginForceCtrlLoopMetaStateKey))) != NULL)
{
if ((lookupTable = OSDynamicCast(OSArray, metaStateDict->getObject(kIOPTCLLookupTableKey))) != NULL)
{
CTRLLOOP_DLOG("IOPlatformTableCtrlLoop::updateMetaState using forced meta state\n");
newMetaState = OSNumber::withNumber( 0xFFFFFFFF, 32 );
setMetaState( newMetaState );
newMetaState->release();
return(true);
}
else
{
CTRLLOOP_DLOG("IOPlatformTableCtrlLoop::updateMetaState forced meta state is invalid, removing...\n");
infoDict->removeObject(gIOPPluginForceCtrlLoopMetaStateKey);
}
}
if ((metaStateDict = OSDynamicCast(OSDictionary, metaStateArray->getObject(0))) != NULL &&
(lookupTable = OSDynamicCast(OSArray, metaStateDict->getObject(kIOPTCLLookupTableKey))) != NULL)
{
setMetaState( gIOPPluginZero );
return(true);
}
else
{
CTRLLOOP_DLOG("IOPlatformTableCtrlLoop::updateMetaState no valid meta states!\n");
return(false);
}
}
void IOPlatformTableCtrlLoop::adjustControls( void )
{
const OSNumber * state, * newTargetNum;
ControlValue newTarget;
if (ctrlloopState == kIOPCtrlLoopNotReady)
{
CTRLLOOP_DLOG("IOPlatformTableCtrlLoop::adjustControls some entities not yet registered\n");
return;
}
if ((state = inputSensor->getSensorState()) == NULL)
{
CTRLLOOP_DLOG("IOPlatformTableCtrlLoop::adjustControls sensor current state unknown\n");
return;
}
if ((newTargetNum = OSDynamicCast(OSNumber, lookupTable->getObject( state->unsigned32BitValue() ))) == NULL)
{
CTRLLOOP_DLOG("IOPlatformTableCtrlLoop::adjustControls no target for state %u\n", state->unsigned32BitValue() );
return;
}
newTarget = newTargetNum->unsigned32BitValue();
if (ctrlloopState == kIOPCtrlLoopFirstAdjustment ||
ctrlloopState == kIOPCtrlLoopDidWake ||
newTarget != outputControl->getTargetValue() )
{
if (outputControl->sendTargetValue( newTarget ))
{
outputControl->setTargetValue(newTarget);
ctrlloopState = kIOPCtrlLoopAllRegistered;
}
else
{
CTRLLOOP_DLOG("IOPlatformTableCtrlLoop::adjustControls failed to send target value\n");
}
}
}
void IOPlatformTableCtrlLoop::sensorRegistered( IOPlatformSensor * aSensor )
{
if (aSensor == inputSensor &&
outputControl->isRegistered() == kOSBooleanTrue)
{
ctrlloopState = kIOPCtrlLoopFirstAdjustment;
adjustControls();
}
}
void IOPlatformTableCtrlLoop::controlRegistered( IOPlatformControl * aControl )
{
if (aControl == outputControl &&
inputSensor->isRegistered() == kOSBooleanTrue)
{
ctrlloopState = kIOPCtrlLoopFirstAdjustment;
adjustControls();
}
}