//================================================================================================ // // ResetControllerState // //================================================================================================ // IOReturn AppleUSBOHCI::ResetControllerState(void) { USBTrace( kUSBTOHCI, KTPOHCIResetControllerState, (uintptr_t)this, 0, 0, 0); // Disable All OHCI Interrupts _pOHCIRegisters->hcInterruptDisable = HostToUSBLong(kOHCIHcInterrupt_MIE); IOSync(); // Place the USB bus into the Reset State _pOHCIRegisters->hcControl = HostToUSBLong((kOHCIFunctionalState_Reset << kOHCIHcControl_HCFSPhase)); IOSync(); // always make sure we stay in reset for at least 50 ms IOSleep(50); // Clear all Processing Registers _pOHCIRegisters->hcHCCA = 0; _pOHCIRegisters->hcControlHeadED = 0; _pOHCIRegisters->hcControlCurrentED = 0; _pOHCIRegisters->hcBulkHeadED = 0; _pOHCIRegisters->hcBulkCurrentED = 0; IOSync(); // turn off the global power OHCIRootHubPower(0 /* kOff */); // go ahead and reset the controller _pOHCIRegisters->hcCommandStatus = HostToUSBLong(kOHCIHcCommandStatus_HCR); // Reset OHCI IOSync(); IOSleep(1); // the spec says 10 microseconds return kIOReturnSuccess; }
void CodecCommander::performCodecReset() { /* Reset is created by sending two Function Group resets, potentially separated by an undefined number of idle frames, but no other valid commands. This Function Group “Double” reset shall do a full initialization and reset most settings to their power on defaults. This function can be used to reset codec on dekstop boards, for example H87-HD3, to overcome audio loss and jack sense problem after sleep with AppleHDA v2.6.0+ */ if (!coldBoot) { DEBUG_LOG("CodecCommander: cc: --> resetting codec\n"); mIntelHDA->sendCommand(1, HDA_VERB_RESET, HDA_PARM_NULL); IOSleep(100); // define smaller delays ???? mIntelHDA->sendCommand(1, HDA_VERB_RESET, HDA_PARM_NULL); IOSleep(100); // forcefully set power state to D3 mIntelHDA->sendCommand(1, HDA_VERB_SET_PSTATE, HDA_PARM_PS_D3_HOT); eapdPoweredDown = true; DEBUG_LOG("CodecCommander: cc: --> hda codec power restored\n"); } }
bool SuperIODevice::detectITEFamilyChip() { // IT87XX can enter only on port 0x2E port = 0x2E; ite_family_enter(port); id = superio_listen_port_word(port, kSuperIOChipIDRegister); HWSensorsDebugLog("probing device on 0x%x, id=0x%x", port, id); ldn = 0; vendor = ""; switch (id) { case IT8512F: case IT8712F: case IT8716F: case IT8718F: case IT8720F: case IT8721F: case IT8726F: case IT8620E: case IT8728F: case IT8752F: case IT8771E: case IT8772E: model = id; ldn = kFintekITEHardwareMonitorLDN; vendor = "ITE"; break; } if (model != 0 && ldn != 0) { HWSensorsDebugLog("detected %s %s, starting address sanity checks", vendor, superio_get_model_name(model)); superio_select_logical_device(port, ldn); IOSleep(10); address = superio_listen_port_word(port, kSuperIOBaseAddressRegister); IOSleep(10); UInt16 verify = superio_listen_port_word(port, kSuperIOBaseAddressRegister); IOSleep(10); ite_family_exit(port); if (address != verify || address < 0x100 || (address & 0xF007) != 0) return false; return true; } else ite_family_exit(port); return false; }
IOReturn AudioProj10PowerObject::setHardwarePowerOn(){ debugIOLog (3, "+ AudioProj10PowerObject::setHardwarePowerOn"); IOReturn result = kIOReturnSuccess; UInt32 progOut; IOService *keyLargo = 0; keyLargo = IOService::waitForService(IOService::serviceMatching("KeyLargo")); if(keyLargo){ long gpioOffset = kPowerObjectOffset; UInt8 value = kPowerOn; keyLargo->callPlatformFunction("keyLargo_writeRegUInt8", false, (void *)&gpioOffset, (void *)(UInt32)value, 0, 0); } IOSleep(80); progOut = audioPluginRef->sndHWGetProgOutput(); progOut &= ~kSndHWProgOutput0; audioPluginRef->sndHWSetProgOutput(progOut); IOSleep(200); if(audioPluginRef) { audioPluginRef->sndHWSetPowerState(kIOAudioDeviceActive); audioPluginRef->setDeviceDetectionActive(); } debugIOLog (3, "- AudioProj10PowerObject::setHardwarePowerOn"); return result; }
bool SuperIODevice::detectITEFamilyChip() { // IT87XX can enter only on port 0x2E port = 0x2E; ite_family_enter(port); id = superio_listen_port_word(port, kSuperIOChipIDRegister); ldn = 0; vendor = ""; switch (id) { case IT8512F: case IT8712F: case IT8716F: case IT8718F: case IT8720F: case IT8721F: case IT8726F: case IT8728F: case IT8752F: case IT8771E: case IT8772E: model = id; ldn = kFintekITEHardwareMonitorLDN; vendor = "ITE"; break; } if (model != 0 && ldn != 0) { superio_select_logical_device(port, ldn); IOSleep(10); address = superio_listen_port_word(port, kSuperIOBaseAddressRegister); IOSleep(10); UInt16 verify = superio_listen_port_word(port, kSuperIOBaseAddressRegister); IOSleep(10); ite_family_exit(port); if (address != verify || address < 0x100 || (address & 0xF007) != 0) return false; return true; } else ite_family_exit(port); return false; }
IOReturn CodecCommander::setPowerState(unsigned long powerStateOrdinal, IOService *policyMaker) { if (kPowerStateSleep == powerStateOrdinal) { DEBUG_LOG("CodecCommander: cc: --> asleep\n"); eapdPoweredDown = true; // though this probably has been determined after parsing codec power state, we set this as false again coldBoot = false; } else if (kPowerStateNormal == powerStateOrdinal) { DEBUG_LOG("CodecCommander: cc: --> awake\n"); updateCount = 0; // This operation has to be performed right at wake or codec will enter power mode 0 immediately! // ***** // set EAPD bit at wake or cold boot if (eapdPoweredDown) { DEBUG_LOG("CodecCommander: cc: --> hda codec power restored\n"); // delay setting by 100ms, otherwise immediate command won't be received IOSleep(100); setOutputs(); } // only when this is done we can stars a check workloop! // ***** // if infinite checking requested if (checkInfinite){ // if checking infinitely then make sure to delay workloop if (coldBoot) { fTimer->setTimeoutMS(20000); // create a nasty 20sec delay for AudioEngineOutput to initialize } // if we are waking it will be already initialized else { fTimer->setTimeoutMS(100); // so fire timer for workLoop almost immediately } DEBUG_LOG("CodecCommander: cc: --> workloop started\n"); } // generate audio stream at wake if requested if (!coldBoot && generatePop){ // apply delay or it will not trigger a system event IOSleep(streamDelay); createAudioStream(); } // simulate headphone jack replug simulateHedphoneJack(); } return IOPMAckImplied; }
static int bfe_wait_bit( struct bfe_softc * sc, u_int32_t reg, u_int32_t bit, u_long timeout, const int clear ) { u_long i; int use_sleep = 0; /* jliu@Apple: long timeouts polls are done using a blocking wait */ if (timeout >= 10000) { use_sleep = 1; timeout /= 1000; } for (i = 0; i < timeout; i++) { u_int32_t val = CSR_READ_4(sc, reg); if (clear && !(val & bit)) break; if (!clear && (val & bit)) break; if (use_sleep) IOSleep(10); else DELAY(10); } if (i == timeout) { DEBUG_LOG("bfe%d: BUG! Timeout waiting for bit %08x of register " "%x to %s.\n", sc->bfe_unit, bit, reg, (clear ? "clear" : "set")); return -1; } return 0; }
IOReturn AppleUSBUHCI::RHResumePortCompletion(UInt32 port) { UInt16 value; USBLog(5, "AppleUSBUHCI[%p]::RHResumePortCompletion - finishing resume on port %d", this, (int)port); if (!_rhPortBeingResumed[port-1]) { USBLog(1, "AppleUSBUHCI[%p]::RHResumePortCompletion - port %d does not appear to be resuming!", this, (int)port); USBTrace( kUSBTUHCI, kTPUHCIRHResumePortCompletion, (uintptr_t)this, (int)port, 0, kIOReturnInternalError ); return kIOReturnInternalError; } if (!_controllerAvailable) { USBLog(5, "AppleUSBEHCI[%p]::RHResumePortCompletion - cannot finish resume on port %d because the controller is unavailable", this, (int)port); _rhPortBeingResumed[port-1] = false; return kIOReturnInternalError; } value = ReadPortStatus(port-1) & kUHCI_PORTSC_MASK; value &= ~(kUHCI_PORTSC_RD | kUHCI_PORTSC_SUSPEND); USBLog(5, "AppleUSBUHCI[%p]: de-asserting resume signal by writing (%p)", this, (void*)value); WritePortStatus(port-1, value); IOSync(); IOSleep(2); // allow it to kick in _rhPortBeingResumed[port-1] = false; _portSuspendChange[port-1] = true; EnsureUsability(); return kIOReturnSuccess; }
IOReturn SATSMARTUserClient::HandleTerminate ( IOService * provider ) { IOReturn status = kIOReturnSuccess; DEBUG_LOG("%s[%p]::%s\n", getClassName(), this, __FUNCTION__); while ( fOutstandingCommands != 0 ) { IOSleep ( 10 ); } // Check if we have our provider open. if ( provider->isOpen ( this ) ) { // Yes we do, so close the connection DEBUG_LOG("%s[%p]::%s closing provider\n", getClassName(), this, __FUNCTION__); provider->close ( this, kIOATASMARTUserClientAccessMask ); } // Decouple us from the IORegistry. detach ( provider ); fProvider = NULL; DEBUG_LOG("%s[%p]::%s result %d\n", getClassName(), this, __FUNCTION__, status); return status; }
IOReturn AudioProj6PowerObject::setHardwarePowerOn(){ IOReturn result = kIOReturnSuccess; IOService *HeathRow = 0; UInt32 mask, data; UInt32 powerRegAdrr; debugIOLog (3, "+ AudioProj6PowerObject::setHardwarePowerOn"); HeathRow = IOService::waitForService(IOService::serviceMatching("Heathrow")); powerRegAdrr = kPowerObjectOffset; if(HeathRow) { mask = kPowerObjectMask; data = kPowerOn; HeathRow->callPlatformFunction(OSSymbol::withCString("heathrow_safeWriteRegUInt32"), false, (void *)powerRegAdrr, (void *)mask, (void *) data, 0); IOSleep(10); } if(audioPluginRef) { audioPluginRef->sndHWSetPowerState(kIOAudioDeviceActive); audioPluginRef->setDeviceDetectionActive(); } debugIOLog (3, "- AudioProj6PowerObject::setHardwarePowerOn, %d", kIOReturnSuccess == result); return result; }
IOReturn AudioProj10PowerObject::setHardwarePowerOff(){ IOReturn result = kIOReturnSuccess; UInt32 progOut; IOService *keyLargo = 0; debugIOLog (3, "+ AudioProj10PowerObject::setHardwarePowerOff"); // specific progOut = audioPluginRef->sndHWGetProgOutput(); progOut |= kSndHWProgOutput0; // this turns the boomer off audioPluginRef->sndHWSetProgOutput(progOut); IOSleep(200); // generic audioPluginRef->sndHWSetPowerState(kIOAudioDeviceSleep); audioPluginRef->setDeviceDetectionInActive(); // clock keyLargo = IOService::waitForService(IOService::serviceMatching("KeyLargo")); if(keyLargo){ long gpioOffset = kPowerObjectOffset; UInt8 value = kPowerOff; keyLargo->callPlatformFunction("keyLargo_writeRegUInt8", false, (void *)&gpioOffset, (void *)(UInt32)value, 0, 0); } debugIOLog (3, "- AudioProj10PowerObject::setHardwarePowerOff"); return result; }
bool IOATABlockStorageDriver::finalize ( IOOptionBits options ) { if ( fPowerManagementInitialized ) { while ( fPowerTransitionInProgress ) { IOSleep ( 1 ); } fCommandGate->commandWakeup ( &fCurrentPowerState, false ); PMstop ( ); if ( fPowerManagementThread != NULL ) { // If the power management thread is scheduled, unschedule it. thread_call_cancel ( fPowerManagementThread ); } fPowerManagementInitialized = false; } return super::finalize ( options ); }
float X3100monitor::getSensorValue(FakeSMCSensor *sensor) { if (sensor->getGroup() == kFakeSMCTemperatureSensor) { short value = 0; if (mmio_base) { OUTVID(TIC1, 3); // if ((INVID16(TSC1) & (1<<15)) && !(INVID16(TSC1) & (1<<8)))//enabled and ready for (int i=0; i<1000; i++) { //attempts to ready if (INVID16(TSS1) & (1<<10)) //valid? break; IOSleep(10); } value = INVID8(TR1); } return 150 - value; } return 0; }
bool GmaSensors::willReadSensorValue(FakeSMCSensor *sensor, float *outValue) { if (sensor->getGroup() == kFakeSMCTemperatureSensor) { short value = 0; if (mmio_base) { OUTVID(TIC1, 3); // if ((INVID16(TSC1) & (1<<15)) && !(INVID16(TSC1) & (1<<8)))//enabled and ready for (int i=0; i<1000; i++) { //attempts to ready if (INVID16(TSS1) & (1<<10)) //valid? break; IOSleep(10); } value = INVID8(TR1); } *outValue = (float)(150 - value); } return true; }
IOReturn AppleRS232Serial::setPowerState(unsigned long powerStateOrdinal, IOService *whatDevice) { bool ok; UInt32 counter = 0; ELG(0, powerStateOrdinal, "setPowerState - powerStateOrdinal"); retain(); // paranoia is your friend, make sure we're not freed fWaitForGatedCmd = true; // could do this async, but let's be sync initially ok = thread_call_enter1(fPowerThreadCall, (void *)powerStateOrdinal); // schedule work on workloop if (ok) { // if thread was already pending ... ALERT(0, 0, "setPowerState - thread already pending?"); // a 'never' in current flow release(); // don't need/want the retain, so undo it } while (fWaitForGatedCmd) { // we're being sync for now, wait for it to finish IOSleep(2); // it should be very fast counter++; } ELG(0, counter, "setPowerState - finished after N sleeps of 2ms each"); return IOPMAckImplied; // we're done }/* end setPowerState */
unsigned long msleep_interruptible(unsigned int msecs) { // FIXME, make into interruptable sleep // Sleep the calling thread for a number of milliseconds IOSleep(msecs); return(0); }
IOReturn AttansicL2Ethernet::disable(IONetworkInterface *netif) { DbgPrint("disable()\n"); at_adapter *adapter=&adapter_; setLinkStatus(kIONetworkLinkValid, 0); transmitQueue_->flush(); transmitQueue_->stop(); transmitQueue_->setCapacity(0); at_reset_hw(adapter); IOSleep(1); at_irq_disable(adapter); adapter->link_speed = SPEED_0; adapter->link_duplex = -1; // pretty wrong place for DMA stuff cleaning, eh? if (adapter->pdev && adapter->pdev->isOpen () ) adapter->pdev->close(this); return kIOReturnSuccess; }
IOReturn AtherosL1Ethernet::getHardwareAddress(IOEthernetAddress *addr) { DbgPrint("getHardwareAddress()\n"); IOSleep(1000); if (is_valid_ether_addr(adapter_.hw.mac_addr)) { memcpy(addr->bytes, adapter_.hw.mac_addr, NODE_ADDRESS_SIZE); return kIOReturnSuccess; } if (get_permanent_address(&adapter_.hw) == 0) { if (is_valid_ether_addr(adapter_.hw.perm_mac_addr)) { memcpy(adapter_.hw.mac_addr, adapter_.hw.perm_mac_addr, NODE_ADDRESS_SIZE); memcpy(addr->bytes, adapter_.hw.mac_addr, NODE_ADDRESS_SIZE); } else { ErrPrint("Invalid mac address\n"); return kIOReturnUnsupported; } return kIOReturnSuccess; } else { DbgPrint("Couldn't get device mac address\n"); memcpy(adapter_.hw.mac_addr, addr->bytes, NODE_ADDRESS_SIZE); //return kIOReturnUnsupported; return kIOReturnSuccess; } }
void darwin_iwi4965::setPowerStateOn() { // IOSleep(2); // _cardGone = false; // wakeUp(); if ( pmPCICapPtr ) { fPCIDevice->saveDeviceState(); fPCIDevice->configWrite16( kPCIPMCSR, 0x8000 ); IOSleep(10); // wait for internal reset completion fPCIDevice->restoreDeviceState(); } // Since the driver returned a non-acknowledgement when called at // setPowerState(), it sends an ACK to the policy-maker here to // indicate that our power state transition is complete. _pmPowerState = kWiFiControllerPowerStateOn; _pmPolicyMaker->acknowledgeSetPowerState(); // With power restored, all clients will be notified that the driver // has became "usable". If a client wishes to use the driver, then the // driver can expect a call to its enable() method to start things off. }
/****************************************************************************** * CodecCommander::simulateHeadphoneJack - plug and unplug headphones virtually ******************************************************************************/ void CodecCommander::simulateHedphoneJack() { DEBUG_LOG("CodecCommander: cc: --> simulate headphone jack event\n"); setStatus(shpCommandEnable); // H-Phn PinCap Enable IOSleep(100); setStatus(shpCommandDisable); // H-Phn PinCap Disable }
bool FakeSMCPlugin::releaseGPUIndex(UInt8 index) { SYNCLOCK; for (int i = 0; i < 3; i++) { IOReturn resut = storageProvider->callPlatformFunction(kFakeSMCReleaseGPUIndex, true, (void *)&index, 0, 0, 0); switch (resut) { case kIOReturnSuccess: SYNCUNLOCK; return true; case kIOReturnBadArgument: SYNCUNLOCK; return false; default: break; } IOSleep(10); } SYNCUNLOCK; return false; }
static void checkACStatusThread(thread_call_param_t param0, thread_call_param_t param1) { int i=0; const int retryTimes = 10; while (!isStatusThreadCanCancel && i<retryTimes) { if(NULL == commmonBatteryDevice) { IOLog("Can't find battery device, retry %d...\n", retryTimes-i); commmonBatteryDevice = getBatteryDevice(); IOSleep(3000); i++; continue; } OSObject * obj = commmonBatteryDevice->getProperty("ExternalConnected"); OSBoolean * status = OSDynamicCast(OSBoolean, obj); if (!status) { IOLog("Battery status get failed.\n"); break; } if(ACStatusChangedCallback) { bool batStatus = status->getValue(); if(batStatus != ACStatus) { //IOLog("Battery status changed.\n"); ACStatus = batStatus; ACStatusChangedCallback(batStatus); } } else ACStatus = status->getValue(); IOSleep(ACStatus?1000:5000);//1s=1000ms } if(i == 10) IOLog("Can't find battery device, exit.\n"); else IOLog("Battery thread cancelled.\n"); isStatusThreadCancelled = true; }
/****************************************************************************** * CodecCommander::setOutputs - set EAPD status bit on SP/HP ******************************************************************************/ void CodecCommander::setEAPD(UInt8 logicLevel) { // delay by at least 100ms, otherwise first immediate command won't be received // some codecs will produce loud pop when EAPD is enabled too soon, need custom delay until codec inits if (mConfiguration->getSendDelay() < 100) IOSleep(100); else IOSleep(mConfiguration->getSendDelay()); // for nodes supporting EAPD bit 1 in logicLevel defines EAPD logic state: 1 - enable, 0 - disable for (int i = 0; i < MAX_EAPD_NODES; i++) { if (eapdCapableNodes[i] != 0) mIntelHDA->sendCommand(eapdCapableNodes[i], HDA_VERB_EAPDBTL_SET, logicLevel); } eapdPoweredDown = false; }
IOReturn FakeSMCDevice::setProperties(OSObject * properties) { KEYSLOCK; IOReturn result = kIOReturnUnsupported; if (OSDictionary * msg = OSDynamicCast(OSDictionary, properties)) { if (OSString * name = OSDynamicCast(OSString, msg->getObject(kFakeSMCDeviceUpdateKeyValue))) { if (FakeSMCKey * key = getKey(name->getCStringNoCopy())) { OSArray *info = OSArray::withCapacity(2); info->setObject(OSString::withCString(key->getType())); info->setObject(OSData::withBytes(key->getValue(), key->getSize())); exposedValues->setObject(key->getKey(), info); OSDictionary *values = OSDictionary::withDictionary(exposedValues); this->setProperty(kFakeSMCDeviceValues, values); OSSafeRelease(values); result = kIOReturnSuccess; } } else if (OSArray* array = OSDynamicCast(OSArray, msg->getObject(kFakeSMCDevicePopulateValues))) { if (OSIterator* iterator = OSCollectionIterator::withCollection(array)) { while (OSString *keyName = OSDynamicCast(OSString, iterator->getNextObject())) if (FakeSMCKey * key = getKey(keyName->getCStringNoCopy())) { OSArray *info = OSArray::withCapacity(2); info->setObject(OSString::withCString(key->getType())); info->setObject(OSData::withBytes(key->getValue(), key->getSize())); exposedValues->setObject(key->getKey(), info); IOSleep(10); //REVIEW: what is this for? } OSDictionary *values = OSDictionary::withDictionary(exposedValues); this->setProperty(kFakeSMCDeviceValues, values); OSSafeRelease(values); OSSafeRelease(iterator); result = kIOReturnSuccess; } } } KEYSUNLOCK; return result; }
void IT87x::stop (IOService* provider) { DebugLog("stoping..."); if (kIOReturnSuccess != fakeSMC->callPlatformFunction(kFakeSMCRemoveKeyHandler, true, this, NULL, NULL, NULL)) { WarningLog("Can't remove key handler"); IOSleep(500); } super::stop(provider); }
void AutoThrottler::stop() { enabled = false; perfTimer->cancelTimeout(); perfTimer->disable(); // Settle time in case we were just stepping IOSleep(1024); if (workLoop) workLoop->removeEventSource(perfTimer); // Remove our event sources dbg("Autothrottler stopped.\n"); setupDone = false; }
IOReturn AttansicL2Ethernet::selectMedium(const IONetworkMedium *medium) { DbgPrint("selectMedium()\n"); if (medium) { switch(medium->getIndex()) { case MEDIUM_INDEX_AUTO: DbgPrint("Selected medium is autoselect\n"); adapter_.link_speed = SPEED_100; adapter_.link_duplex = FULL_DUPLEX; adapter_.hw.MediaType = MEDIA_TYPE_AUTO_SENSOR; break; case MEDIUM_INDEX_10HD: DbgPrint("Selected medium is 10HD\n"); adapter_.link_speed = SPEED_10; adapter_.link_duplex = HALF_DUPLEX; adapter_.hw.MediaType = MEDIA_TYPE_10M_HALF; break; case MEDIUM_INDEX_10FD: DbgPrint("Selected medium is 10FD\n"); adapter_.link_speed = SPEED_10; adapter_.link_duplex = FULL_DUPLEX; adapter_.hw.MediaType = MEDIA_TYPE_10M_FULL; break; case MEDIUM_INDEX_100HD: DbgPrint("Selected medium is 100HD\n"); adapter_.link_speed = SPEED_100; adapter_.link_duplex = HALF_DUPLEX; adapter_.hw.MediaType = MEDIA_TYPE_100M_HALF; break; case MEDIUM_INDEX_100FD: DbgPrint("Selected medium is 100FD\n"); adapter_.link_speed = SPEED_100; adapter_.link_duplex = FULL_DUPLEX; adapter_.hw.MediaType = MEDIA_TYPE_100M_FULL; break; } atSetupLink(); setCurrentMedium(medium); } else { DbgPrint("Selected medium is NULL\n"); return kIOReturnError; } //Refresh link status IOSleep(100*((medium->getIndex() == MEDIUM_INDEX_AUTO)? PHY_AUTO_NEG_TIME:PHY_FORCE_TIME)); atGetAndUpdateLinkStatus(); return kIOReturnSuccess; }
void driver::stop(IOService *provider) { // We have stopped driverStatus = driverOff; perfTimer->cancelTimeout(); // Settle time in case we were just stepping IOSleep(1024); if (workLoop) workLoop->removeEventSource(perfTimer); // Remove our event sources super::stop(provider); }
void GeforceSensors::stop (IOService* provider) { DebugLog("Stoping..."); sensors->flushCollection(); if (kIOReturnSuccess != fakeSMC->callPlatformFunction(kFakeSMCRemoveKeyHandler, true, this, NULL, NULL, NULL)) { WarningLog("Can't remove key handler"); IOSleep(500); } super::stop(provider); }
bool TZSensors::start(IOService * provider) { if (!super::start(provider)) return false; acpiDevice = (IOACPIPlatformDevice *)provider; if (!acpiDevice) { HWSensorsFatalLog("ACPI device not ready"); return false; } if (OSDictionary *configuration = getConfigurationNode()) { OSBoolean* disable = OSDynamicCast(OSBoolean, configuration->getObject("DisableDevice")); if (disable && disable->isTrue()) return false; } // On some computers (eg. RehabMan's ProBook 4530s), the system will hang on startup // if kernel cache is used, because of the early call to updateTemperatures and/or // updateTachometers. At least that is the case with an SSD and a valid pre-linked // kernel, along with kernel cache enabled. This 1000ms sleep seems to fix the problem, // enabling a clean boot with TZSensors enabled. // // On the ProBook this is the case with both TZSensors and PTIDSensors, although // PTIDSensors can be avoided by using DropSSDT=Yes (because PTID device is in an SSDT) // // And in the case of TZSensors it even happens (intermittently) without kernel cache. IOSleep(1000); OSObject *object = NULL; if(kIOReturnSuccess == acpiDevice->evaluateObject("_TMP", &object) && object) { for (UInt8 i = 0; i < 0xf; i++) { char key[5]; snprintf(key, 5, KEY_FORMAT_THERMALZONE_TEMPERATURE, i); if (!isKeyHandled(key)) { if (addSensor(key, TYPE_SP78, TYPE_SPXX_SIZE, kFakeSMCTemperatureSensor, 0)) { break; } } } } registerService(); HWSensorsInfoLog("started on %s", acpiDevice->getName()); return true; }