IOReturn ACPIProbe::woorkloopTimerEvent(void) { if (pollingTimeout > 0 && !startTime) startTime = ptimer_read_seconds(); double time = ptimer_read_seconds(); if (pollingTimeout == 0 || (time - startTime < pollingTimeout)) { OSDictionary *values = OSDictionary::withCapacity(0); for (unsigned int i = 0; i < methods->getCount(); i++) { if (OSString *method = (OSString*)methods->getObject(i)) { OSObject *object = NULL; IOReturn result = acpiDevice->evaluateObject(method->getCStringNoCopy(), &object); if (kIOReturnSuccess == result && object) { values->setObject(method->getCStringNoCopy(), object); if (loggingEnabled) logValue(method->getCStringNoCopy(), object); } else ACPISensorsErrorLog("failed to evaluate method \"%s\", return %d", method->getCStringNoCopy(), result); } } setProperty("Values", values); timerEventSource->setTimeoutMS((UInt32)(pollingInterval * 1000.0)); } return kIOReturnSuccess; }
IOReturn ACPIProbe::woorkloopTimerEvent(void) { double time = ptimer_read_seconds(); if (activeProfile->timeout > 0 && activeProfile->startedAt == 0) { activeProfile->startedAt = time; } if (activeProfile && (activeProfile->timeout == 0 || (time - activeProfile->startedAt < activeProfile->timeout))) { OSDictionary *values = OSDictionary::withCapacity(0); for (unsigned int i = 0; i < activeProfile->methods->getCount(); i++) { if (OSString *method = (OSString*)activeProfile->methods->getObject(i)) { OSObject *object = NULL; IOReturn result = acpiDevice->evaluateObject(method->getCStringNoCopy(), &object); if (kIOReturnSuccess == result && object) { values->setObject(method->getCStringNoCopy(), object); if (activeProfile->verbose) logValue(method->getCStringNoCopy(), object); } else { ACPISensorsErrorLog("failed to evaluate method \"%s\", return %d", method->getCStringNoCopy(), result); } } } setProperty("Values", values); timerEventSource->setTimeoutMS(activeProfile->interval); } return kIOReturnSuccess; }
bool ACPIProbe::start(IOService * provider) { ACPISensorsDebugLog("starting..."); if (!super::start(provider)) return false; if (!(acpiDevice = OSDynamicCast(IOACPIPlatformDevice, provider))) { ACPISensorsFatalLog("ACPI device not ready"); return false; } methods = OSArray::withCapacity(0); OSNumber *interval = NULL; OSNumber *timeout = NULL; OSBoolean *logging = NULL; OSArray *list = NULL; // Try to load configuration from info.plist first if (OSDictionary *configuration = getConfigurationNode()) { OSBoolean* disable = OSDynamicCast(OSBoolean, configuration->getObject("DisableDevice")); if (disable && disable->isTrue()) return false; interval = OSDynamicCast(OSNumber, configuration->getObject("PollingInterval")); timeout = OSDynamicCast(OSNumber, configuration->getObject("PollingTimeout")); logging = OSDynamicCast(OSBoolean, configuration->getObject("LoggingEnabled")); list = OSDynamicCast(OSArray, configuration->getObject("Methods")); } // Try to load configuration provided by ACPI device else { OSObject *object = NULL; if (kIOReturnSuccess == acpiDevice->evaluateObject("INVL", &object) && object) interval = OSDynamicCast(OSNumber, object); if (kIOReturnSuccess == acpiDevice->evaluateObject("TOUT", &object) && object) timeout = OSDynamicCast(OSNumber, object); if (kIOReturnSuccess == acpiDevice->evaluateObject("LOGG", &object) && object) { if (OSNumber *number = OSDynamicCast(OSNumber, object)) { logging = OSBoolean::withBoolean(number->unsigned8BitValue() == 1); } } if (kIOReturnSuccess == acpiDevice->evaluateObject("LIST", &object) && object) list = OSDynamicCast(OSArray, object); else ACPISensorsErrorLog("polling methods table (LIST) not found"); } if (interval) { pollingInterval = (double)interval->unsigned64BitValue() / (double)1000.0; ACPISensorsInfoLog("polling interval %lld ms", interval->unsigned64BitValue()); if (pollingInterval) { if (timeout) { pollingTimeout = (double)timeout->unsigned64BitValue() / 1000.0; ACPISensorsInfoLog("polling timeout %lld ms", timeout->unsigned64BitValue()); } if (logging) { loggingEnabled = logging->isTrue(); ACPISensorsInfoLog("logging %s", loggingEnabled ? "enabled" : "disabled"); } if (list) { for (unsigned int i = 0; i < list->getCount(); i++) { if (OSString *method = OSDynamicCast(OSString, list->getObject(i))) { if (method->getLength() && kIOReturnSuccess == acpiDevice->validateObject(method->getCStringNoCopy())) { methods->setObject(method); ACPISensorsInfoLog("method \"%s\" registered", method->getCStringNoCopy()); } else ACPISensorsErrorLog("unable to register method \"%s\"", method->getCStringNoCopy()); } } } } else ACPISensorsWarningLog("polling interval is set to zero, driver will be disabled"); } //REVIEW_REHABMAN: just bail if no methods to call... no need to stick around... if (!methods->getCount()) return false; if (methods->getCount()) { // woorkloop if (!(workloop = getWorkLoop())) { HWSensorsFatalLog("Failed to obtain workloop"); return false; } if (!(timerEventSource = IOTimerEventSource::timerEventSource( this, OSMemberFunctionCast(IOTimerEventSource::Action, this, &ACPIProbe::woorkloopTimerEvent)))) { ACPISensorsFatalLog("failed to initialize timer event source"); return false; } if (kIOReturnSuccess != workloop->addEventSource(timerEventSource)) { ACPISensorsFatalLog("failed to add timer event source into workloop"); return false; } timerEventSource->setTimeoutMS(100); //ACPISensorsInfoLog("%d method%s registered", methods->getCount(), methods->getCount() > 1 ? "s" : ""); } registerService(); ACPISensorsInfoLog("started"); return true; }
void ACPISensors::addSensorsFromArray(OSArray *array, FakeSMCSensorCategory category) { if (array) { UInt32 group = 0; const char *title = NULL; switch (category) { case kFakeSMCCategoryTemperature: group = kFakeSMCTemperatureSensor; title = "temperature"; break; case kFakeSMCCategoryFrequency: group = kFakeSMCFrequencySensor; title = "frequency"; break; case kFakeSMCCategoryVoltage: group = kFakeSMCVoltageSensor; title = "voltage"; break; case kFakeSMCCategoryCurrent: group = kFakeSMCCurrentSensor; title = "amperage"; break; case kFakeSMCCategoryPower: group = kFakeSMCPowerSensor; title = "power"; break; case kFakeSMCCategoryFan: group = kFakeSMCTachometerSensor; title = "tachometer"; break; default: return; } for (UInt32 index = 0; index + 1 < array->getCount(); index += 2) { if (OSString *key = OSDynamicCast(OSString, array->getObject(index))) { if (OSString *method = OSDynamicCast(OSString, array->getObject(index + 1))) { FakeSMCSensor *sensor = NULL; if (category == kFakeSMCCategoryFan) { sensor = addTachometer(methods->getCount(), key->getCStringNoCopy()); } else { sensor = addSensorFromNode(key, category, group, methods->getCount()); } if (sensor) { methods->setObject(method);//sensor->getKey(), method); } else { ACPISensorsErrorLog("Failed to register %s sensor \"%s\" for method \"%s\"", title, key->getCStringNoCopy(), method->getCStringNoCopy()); } } } } } }
void ACPISensors::addSensorsFromDictionary(OSDictionary *dictionary, FakeSMCSensorCategory category) { if (dictionary) { UInt32 group = 0; const char *title = NULL; switch (category) { case kFakeSMCCategoryTemperature: group = kFakeSMCTemperatureSensor; title = "temperature"; break; case kFakeSMCCategoryFrequency: group = kFakeSMCFrequencySensor; title = "frequency"; break; case kFakeSMCCategoryVoltage: group = kFakeSMCVoltageSensor; title = "voltage"; break; case kFakeSMCCategoryCurrent: group = kFakeSMCCurrentSensor; title = "amperage"; break; case kFakeSMCCategoryPower: group = kFakeSMCPowerSensor; title = "power"; break; case kFakeSMCCategoryFan: group = kFakeSMCTachometerSensor; title = "tachometer"; break; default: return; } OSCollectionIterator *iterator = OSCollectionIterator::withCollection(dictionary); while (OSString *key = OSDynamicCast(OSString, iterator->getNextObject())) { OSString *method = OSDynamicCast(OSString, dictionary->getObject(key)); if (method && kIOReturnSuccess == acpiDevice->validateObject(method->getCStringNoCopy())) { FakeSMCSensor *sensor = NULL; if (category == kFakeSMCCategoryFan) { sensor = addTachometer(methods->getCount(), key->getCStringNoCopy()); } else { sensor = addSensorFromNode(key, category, group, methods->getCount()); } if (sensor) { methods->setObject(method);//sensor->getKey(), method); } else { ACPISensorsErrorLog("Failed to register %s sensor \"%s\" for method \"%s\"", title, key->getCStringNoCopy(), method->getCStringNoCopy()); } } } } }
bool ACPIProbe::start(IOService * provider) { ACPISensorsDebugLog("starting..."); if (!super::start(provider)) return false; if (!(acpiDevice = OSDynamicCast(IOACPIPlatformDevice, provider))) { ACPISensorsFatalLog("ACPI device not ready"); return false; } profiles = OSDictionary::withCapacity(0); profileList = OSArray::withCapacity(0); OSObject *object = NULL; // Try to load configuration provided by ACPI device if (kIOReturnSuccess == acpiDevice->evaluateObject("LIST", &object) && object) { if (OSArray *list = OSDynamicCast(OSArray, object)) { for (unsigned int i = 0; i < list->getCount(); i++) { if (OSString *method = OSDynamicCast(OSString, list->getObject(i))) { if (kIOReturnSuccess == acpiDevice->evaluateObject(method->getCStringNoCopy(), &object) && object) { if (OSArray *config = OSDynamicCast(OSArray, object)) { if (config->getCount() > 4) { OSString *pName = OSDynamicCast(OSString, config->getObject(0)); OSNumber *pInterval = OSDynamicCast(OSNumber, config->getObject(1)); OSNumber *pTimeout = OSDynamicCast(OSNumber, config->getObject(2)); OSNumber *pVerbose = OSDynamicCast(OSNumber, config->getObject(3)); OSArray *pMethods = OSArray::withCapacity(config->getCount() - 4); for (unsigned int offset = 4; offset < config->getCount(); offset++) { if (OSString *methodName = OSDynamicCast(OSString, config->getObject(offset))) { pMethods->setObject(methodName); } } addProfile(pName, pMethods, pInterval, pTimeout, pVerbose); } } OSSafeRelease(object); } } } OSSafeRelease(list); } } else { ACPISensorsErrorLog("profile definition table (LIST) not found"); } // Try to load configuration from info.plist if (profiles->getCount() == 0) { if (OSDictionary *configuration = getConfigurationNode()) { OSString *pName = OSDynamicCast(OSString, configuration->getObject("ProfileName")); OSNumber *pInterval = OSDynamicCast(OSNumber, configuration->getObject("PollingInterval")); OSNumber *pTimeout = OSDynamicCast(OSNumber, configuration->getObject("PollingTimeout")); OSBoolean *pVerboseBool = OSDynamicCast(OSBoolean, configuration->getObject("VerboseLog")); OSNumber *pVerbose = OSNumber::withNumber(pVerboseBool->getValue() ? 1 : 0, 8); OSArray *pMethods = OSDynamicCast(OSArray, configuration->getObject("MethodsToPoll")); addProfile(pName, pMethods, pInterval, pTimeout, pVerbose); } } if (this->profiles->getCount()) { // Parse active profile if (kIOReturnSuccess == acpiDevice->evaluateObject("ACTV", &object) && object) { if (OSString *method = OSDynamicCast(OSString, object)) { if (kIOReturnSuccess == acpiDevice->evaluateObject(method->getCStringNoCopy(), &object) && object) { if (OSArray *config = OSDynamicCast(OSArray, object)) { if (config->getCount() > 4) { if (OSString *profile = OSDynamicCast(OSString, config->getObject(0))) { if (!(activeProfile = (ACPIProbeProfile *)profiles->getObject(profile))) { activeProfile = (ACPIProbeProfile *)profileList->getObject(0); } } } } OSSafeRelease(object); } OSSafeRelease(method); } } // woorkloop if (!(workloop = getWorkLoop())) { HWSensorsFatalLog("Failed to obtain workloop"); return false; } if (!(timerEventSource = IOTimerEventSource::timerEventSource( this, OSMemberFunctionCast(IOTimerEventSource::Action, this, &ACPIProbe::woorkloopTimerEvent)))) { ACPISensorsFatalLog("failed to initialize timer event source"); return false; } if (kIOReturnSuccess != workloop->addEventSource(timerEventSource)) { ACPISensorsFatalLog("failed to add timer event source into workloop"); return false; } timerEventSource->setTimeoutMS(100); //ACPISensorsInfoLog("%d method%s registered", methods->getCount(), methods->getCount() > 1 ? "s" : ""); } // two power states - off and on static const IOPMPowerState powerStates[2] = { { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 1, IOPMDeviceUsable, IOPMPowerOn, IOPMPowerOn, 0, 0, 0, 0, 0, 0, 0, 0 } }; // register interest in power state changes PMinit(); provider->joinPMtree(this); registerPowerDriver(this, (IOPMPowerState *)powerStates, 2); registerService(); ACPISensorsInfoLog("started"); return true; }