Exemplo n.º 1
0
IOReturn
IOI2CDevice::InitializePowerManagement(void)
{
	IOReturn	status;
	static const IOPMPowerState ourPowerStates[kIOI2CPowerState_COUNT] = 
	{
	//	version	capabilityFlags			outputPowerCharacter	inputPowerRequirement
		{1,		0,						0,						0,				0, 0, 0, 0, 0, 0, 0, 0},
		{1,		kIOPMSleepCapability,	kIOPMSleep,				kIOPMSleep,		0, 0, 0, 0, 0, 0, 0, 0},
		{1,		kIOPMDeviceUsable,		kIOPMDoze,				kIOPMDoze,		0, 0, 0, 0, 0, 0, 0, 0},
		{1,		kIOPMDeviceUsable,		kIOPMPowerOn,			kIOPMPowerOn,	0, 0, 0, 0, 0, 0, 0, 0}
	};

	DLOG("IOI2CDevice@%lx::InitializePowerManagement\n", fI2CAddress);

	// Initialize Power Management superclass variables from IOService.h
	PMinit();
	fStateFlags |= kStateFlags_PMInit;

	// Join the Power Management tree from IOService.h
	fProvider->joinPMtree( this);

	if (0 == (fPowerStateThreadCall = thread_call_allocate(&IOI2CDevice::sPowerStateThreadCall, (thread_call_param_t) this)))
	{
		ERRLOG("IOI2CDevice Failed to allocate threadcall.\n");
		return kIOReturnNoResources;
	}

	// Register ourselves for power state interest notifications from the controller.
	if (kIOReturnSuccess != (status = fProvider->callPlatformFunction("IOI2CPowerStateInterest", FALSE, (void *)this, (void *)true, NULL, NULL)))
	{
		ERRLOG("IOI2CDevice register IOI2CPowerStateInterest falied\n");
		return status;
	}

	// Register ourselves as the power controller.
	if (kIOReturnSuccess != (status = registerPowerDriver( this, (IOPMPowerState *) ourPowerStates, kIOI2CPowerState_COUNT )))
	{
		ERRLOG("IOI2CDevice Failed to registerPowerDriver.\n");
		return status;
	}

	return status;
}
bool info_ennowelbers_proxyframebuffer_driver::start(IOService *provider)
{
	bool res=super::start(provider);
	if(res)
	{
		//in order to get a framebuffer up and working, we need to correctly configure powermanagement.
		//we're setting up three power states: off, on and usable.
		PMinit();
		getProvider()->joinPMtree(this);
		static IOPMPowerState myPowerStates[3];
		myPowerStates[0].version=1;
		myPowerStates[0].capabilityFlags=0;
		myPowerStates[0].outputPowerCharacter=0;
		myPowerStates[0].inputPowerRequirement=0;
		myPowerStates[1].version=1;
		myPowerStates[1].capabilityFlags=0;
		myPowerStates[1].outputPowerCharacter=0;
		myPowerStates[1].inputPowerRequirement=IOPMPowerOn;
		myPowerStates[2].version=1;
		myPowerStates[2].capabilityFlags=IOPMDeviceUsable;
		myPowerStates[2].outputPowerCharacter=IOPMPowerOn;
		myPowerStates[2].inputPowerRequirement=IOPMPowerOn;
		registerPowerDriver(this, myPowerStates, 3);
		//and we're switching to power state USABLE
		changePowerStateTo(2);
		//you need to to this AFTER setting power configuration.
		//at least that's what i recall
		registerService();
		IOLog("EWProxyFrameBuffer: start with maximum resolution %dx%d\n",getMaxWidth(),getMaxHeight());
		if(shouldInitFB())
		{
			IOLog("EWProxyFrameBuffer: Initializing Framebuffer. Unload from this point is impossible.\n");
			initFB();
		}
		else
		{
			IOLog("EWProxyFrameBuffer: Framebuffer initialization deactivated.\n");
		}
		//StartFramebuffer(640, 480);
	}
	//IOLog("Starting\n");
	return res;
}
Exemplo n.º 3
0
void Insomnia::startPM(IOService *provider)
{
	static const int kMyNumberOfStates = 2;
	static IOPMPowerState myPowerStates[kMyNumberOfStates] = {
		{kIOPMPowerStateVersion1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
		{kIOPMPowerStateVersion1, kIOPMPowerOn, kIOPMPowerOn, kIOPMPowerOn, 0, 0, 0, 0, 0, 0, 0, 0}
	};

	PMinit();
	provider->joinPMtree(this);
	registerPowerDriver(this, myPowerStates, kMyNumberOfStates);

	if (OSDictionary *tmpDict = serviceMatching("IOPMPowerSource"))
	{
		addMatchingNotification(gIOFirstPublishNotification, tmpDict,
                                &Insomnia::_power_source_published, this);

		tmpDict->release();
	}
}
Exemplo n.º 4
0
// --------------------------------------------------------------------------
//
// Method: initForPM
//                       
// Purpose:
//          sets up the conditions for the power managment (or, better power
//          behavior since there is no power control in this driver).
bool
AppleMediaBay::initForPM(IOService *provider)
{
    
    PMinit();                   // initialize superclass variables
    provider->joinPMtree(this); // attach into the power management hierarchy

    // were we able to init the power manager for this driver ? 
    if (pm_vars == NULL)
        return false;

    #define number_of_power_states 2
    static IOPMPowerState ourPowerStates[number_of_power_states] = {
    {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 ourselves with ourself as policy-maker        
    registerPowerDriver(this, ourPowerStates, number_of_power_states);

    return true;
}
bool AppleSmartBatteryManager::start(IOService *provider)
{
    DEBUG_LOG("AppleSmartBatteryManager::start: called\n");
    
    fProvider = OSDynamicCast(IOACPIPlatformDevice, provider);

    if (!fProvider || !super::start(provider)) {
        return false;
    }

    IOWorkLoop *wl = getWorkLoop();
    if (!wl) {
        return false;
    }

    // Join power management so that we can get a notification early during
    // wakeup to re-sample our battery data. We don't actually power manage
    // any devices.
	
	PMinit();
    registerPowerDriver(this, myTwoStates, 2);
    provider->joinPMtree(this);

    //rehabman: updated version
	IOLog("AppleSmartBatteryManager: Version 1.41 starting\n");

	int value = getPlatform()->numBatteriesSupported();
	DEBUG_LOG("AppleSmartBatteryManager: Battery Supported Count(s) %d.\n", value);

    // TODO: Create battery array to hold battery objects if more than one battery in the system
    
	if (value > 1) 
    { 
		if (kIOReturnSuccess == fProvider->evaluateInteger("_STA", &fBatterySTA)) {
			if (fBatterySTA & BATTERY_PRESENT) {
				goto populateBattery;
			} else {
				goto skipBattery;
			}
		}
	}

populateBattery:

	fBattery = AppleSmartBattery::smartBattery();

	if(!fBattery) 
		return false;

	fBattery->attach(this);

	fBattery->start(this);

    // Command gate for ACPIBatteryManager
    fManagerGate = IOCommandGate::commandGate(this);
    if (!fManagerGate) {
        return false;
    }
    wl->addEventSource(fManagerGate);

    // Command gate for ACPIBattery
    fBatteryGate = IOCommandGate::commandGate(fBattery);
    if (!fBatteryGate) {
        return false;
    }
    wl->addEventSource(fBatteryGate);

	fBattery->registerService(0);

skipBattery:

    this->setName("AppleSmartBatteryManager");
	this->registerService(0);

    return true;
}
Exemplo n.º 6
0
bool AppleLM8x::start(IOService *provider)
{
	mach_timespec_t		WaitTimeOut;
	OSData				*t;
	int					*reg;
    IOReturn 			status;

	// Proper etiquette
	if ( !(super::start(provider)) )
		return false;
	
	// Set flag to reflect non-restart state
	systemIsRestarting = FALSE;
	
	// Try and get the reg property
	if ( !(t = OSDynamicCast(OSData, provider->getProperty("reg"))) )
	{
		IOLog( "AppleLM8x::start couldn't find 'reg' property in registry.\n");
		return false;
	}
	
	// We have the reg property, lets make local copy
	if ( !(reg = (int*)t->getBytesNoCopy()) )
	{
		IOLog( "AppleLM8x::start 'reg' property is present but empty.\n");
		return false;
	}
	
	kLM8xBus = (UInt8)(*reg >> 8); // Determine I2C bus
	kLM8xAddr = (UInt8)(*reg >> 1); // Determine true address of device
	
	// Use a 30 second timeout when calling waitForService()
	WaitTimeOut.tv_sec = 30;
	WaitTimeOut.tv_nsec = 0;
	
	// Create some symbols for later use
	sOpenI2Cbus = OSSymbol::withCStringNoCopy(kOpenI2Cbus);
	sCloseI2Cbus = OSSymbol::withCStringNoCopy(kCloseI2Cbus);
	sSetPollingMode = OSSymbol::withCStringNoCopy(kSetPollingMode);
	sSetStandardSubMode = OSSymbol::withCStringNoCopy(kSetStandardSubMode);
	sSetCombinedMode = OSSymbol::withCStringNoCopy(kSetCombinedMode);
	sWriteI2Cbus = OSSymbol::withCStringNoCopy(kWriteI2Cbus);
	sReadI2Cbus = OSSymbol::withCStringNoCopy(kReadI2Cbus);
	sGetSensorValueSym = OSSymbol::withCString("getSensorValue");
	
	interface = OSDynamicCast(IOService, provider->getParentEntry(gIOServicePlane));
	if(interface == NULL)
	{
		IOLog("AppleLM8x::start(0x%x) failed to get i2c interface\n", kLM8xAddr<<1);
		return(false);
	}
	
	DLOG("AppleLM8x::start(0x%x) got i2c interface %s\n", kLM8xAddr<<1, interface->getName());
	
	// Configure the LM87
	if( initHW(provider) != kIOReturnSuccess )
	{
		IOLog("AppleLM8x::start(0x%x) failed to initialize sensor.\n", kLM8xAddr<<1);
		return false;
	}

	// Save registers for PM
	if ( saveRegisters() != kIOReturnSuccess )
		IOLog("AppleLM8x::powerStateWillChangeTo(0x%x) failed to save registers.\n", kLM8xAddr<<1);

	// Initialize Power Management superclass variables from IOService.h
    PMinit();

	// Register as controlling driver from IOService.h
    status = registerPowerDriver( this, (IOPMPowerState *) ourPowerStates, kLM8xNumStates );
	if (status != kIOReturnSuccess)
	{
		IOLog("%s: Failed to registerPowerDriver.\n", getName());
	}

	// Join the Power Management tree from IOService.h
	provider->joinPMtree( this);
	
	// Install power change handler (for restart notification)
	registerPrioritySleepWakeInterest(&sysPowerDownHandler, this, 0);
		
	// Register so others can find us with a waitForService()
	registerService();
	
	// Parse sensor properties and create nubs
	publishChildren(provider);

	return true;
}
Exemplo n.º 7
0
bool FileNVRAM::start(IOService *provider)
{
	bool earlyInit = false;

	LOG(NOTICE, "start() called (%d)\n", mInitComplete);

	//start is called upon wake for some reason.
	if (mInitComplete)
	{
		return true;
	}

	if (!super::start(provider))
	{
		return false;
	}
	
	LOG(NOTICE, "start() called (%d)\n", mInitComplete);

	// mFilePath		= NULL;			// no know file
	mLoggingLevel   = NOTICE;		// start with logging disabled, can be update for debug
	mInitComplete   = false;		// Don't resync anything that's already in the file system.
	mSafeToSync     = false;		// Don't sync untill later

	// We should be root right now... cache this for later.
	mCtx            = vfs_context_current();

	// Register Power modes
	PMinit();
	registerPowerDriver(this, sPowerStates, sizeof(sPowerStates) / sizeof(IOPMPowerState));
	provider->joinPMtree(this);

	IORegistryEntry* bootnvram = IORegistryEntry::fromPath(NVRAM_FILE_DT_LOCATION, gIODTPlane);
	IORegistryEntry* root = IORegistryEntry::fromPath("/", gIODTPlane);

	// Create the command gate.
	mCommandGate = IOCommandGate::commandGate( this, dispatchCommand);
	getWorkLoop()->addEventSource( mCommandGate );

	// Replace the IOService dicionary with an empty one, clean out variables we don't want.
	OSDictionary* dict = OSDictionary::withCapacity(1);

	if (!dict)
	{
		return false;
	}

	setPropertyTable(dict);

	if (bootnvram)
	{
		copyEntryProperties(NULL, bootnvram);
		bootnvram->detachFromParent(root, gIODTPlane);
	}
	else
	{
		IOTimerEventSource* mTimer = IOTimerEventSource::timerEventSource(this, timeoutOccurred);

		if (mTimer)
		{
			getWorkLoop()->addEventSource( mTimer);
			mTimer->setTimeoutMS(50); // callback isn't being setup right, causes a panic
			mSafeToSync = false;
		}
		else
		{
			earlyInit = true;
		}
	}

	// We don't have initial NVRAM data from the bootloader, or we couldn't schedule a
	// timer to read in /Extra/NVRAM/nvram.plist, so start up immediately.
	if (earlyInit == true)
	{
		mSafeToSync = true;
		registerNVRAM();
	}

	mInitComplete = true;

	return true;
}
Exemplo n.º 8
0
/******************************************************************************
 * CodecCommander::start - start kernel extension and init PM
 ******************************************************************************/
bool CodecCommander::start(IOService *provider)
{
    DEBUG_LOG("CodecCommander: cc: commander version 2.1.1 starting\n");

    if(!provider || !super::start( provider ))
	{
		DEBUG_LOG("CodecCommander: cc: error loading kext\n");
		return false;
	}
    
    // notify about extra feature requests
    if (generatePop && checkInfinite) {
        DEBUG_LOG("CodecCommander: cc: stream requested, will *pop* upon wake or fugue-wake\n");
    }
    if (checkInfinite) {
        DEBUG_LOG("CodecCommander: cc: infinite workloop requested, will start now!\n");
    }
    if (generatePop && !checkInfinite) {
        DEBUG_LOG("CodecCommander: cc: stream requested, will *pop* upon wake\n");
    }
    
    // start virtual keyboard device
    _keyboardDevice = new CCHIDKeyboardDevice;
    
    if ( !_keyboardDevice              ||
        !_keyboardDevice->init()       ||
        !_keyboardDevice->attach(this) )
    {
        _keyboardDevice->release();
        DEBUG_LOG("CodecCommander: hi: unable to create keyboard device\n");
    }
    else
    {
        DEBUG_LOG("CodecCommander: hi: keyboard device created\n");
        _keyboardDevice->registerService();
    }
    
    // determine HDEF ACPI device path in IORegistry
    IORegistryEntry *hdaDeviceEntry = IORegistryEntry::fromPath(hdaDevicePath);
    if (hdaDeviceEntry != NULL) {
        IOService *service = OSDynamicCast(IOService, hdaDeviceEntry);
        
        // get address field from IODeviceMemory
        if (service != NULL && service->getDeviceMemoryCount() != 0) {
            ioregEntry = service->getDeviceMemoryWithIndex(0);
            
        }
        hdaDeviceEntry->release();
    }
    else {
        DEBUG_LOG("CodecCommander: %s is unreachable\n",hdaDevicePath);
        return false;
    }
    
    // init power state management & set state as PowerOn
    PMinit();
    registerPowerDriver(this, powerStateArray, kPowerStateCount);
	provider->joinPMtree(this);
    
    // setup workloop and timer
    fWorkLoop = IOWorkLoop::workLoop();
    fTimer = IOTimerEventSource::timerEventSource(this,
                                                          OSMemberFunctionCast(IOTimerEventSource::Action, this,
                                                                               &CodecCommander::onTimerAction));
    if (!fWorkLoop || !fTimer)
        stop(provider);;
    
    if (fWorkLoop->addEventSource(fTimer) != kIOReturnSuccess)
        stop(provider);
    
	this->registerService(0);
    return true;
}
Exemplo n.º 9
0
bool LPCSensors::start(IOService *provider)
{
	if (!super::start(provider))
        return false;

    OSNumber *number = OSDynamicCast(OSNumber, provider->getProperty(kSuperIOHWMAddress));

    if (!number || !(address = number->unsigned16BitValue())) {
        HWSensorsFatalLog("wrong address provided");
        return false;
    }

    number = OSDynamicCast(OSNumber, provider->getProperty(kSuperIOControlPort));

    if (!number || !(port = number->unsigned8BitValue())) {
        HWSensorsFatalLog("wrong port provided");
        return false;
    }

    number = OSDynamicCast(OSNumber, provider->getProperty(kSuperIOModelValue));

    if (!number || !(model = number->unsigned16BitValue())) {
        HWSensorsFatalLog("wrong model provided");
        return false;
    }

    OSString *string = OSDynamicCast(OSString, provider->getProperty(kSuperIOModelName));

    if (!string || !(modelName = string->getCStringNoCopy())) {
        HWSensorsFatalLog("wrong model name provided");
        return false;
    }

    string = OSDynamicCast(OSString, provider->getProperty(kSuperIOVendorName));

    if (!string || !(vendorName = string->getCStringNoCopy())) {
        HWSensorsFatalLog("wrong vendor name provided");
        return false;
    }

    if (!initialize())
        return false;

    OSString *modelString = OSString::withCString(modelName);

	if (OSDictionary *configuration = getConfigurationNode(modelString))
    {
        addTemperatureSensors(configuration);
        addVoltageSensors(configuration);
        addTachometerSensors(configuration);
    }
    else HWSensorsWarningLog("no platform profile provided");

    OSSafeReleaseNULL(modelString);

    // woorkloop
    if (!(workloop = getWorkLoop())) {
        HWSensorsFatalLog("Failed to obtain workloop");
        return false;
    }

    if (!(timerEventSource = IOTimerEventSource::timerEventSource(this, OSMemberFunctionCast(IOTimerEventSource::Action, this, &LPCSensors::woorkloopTimerEvent)))) {
        HWSensorsFatalLog("failed to initialize timer event source");
        return false;
    }

    if (kIOReturnSuccess != workloop->addEventSource(timerEventSource))
    {
        HWSensorsFatalLog("failed to add timer event source into workloop");
        return false;
    }

    // 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();

    HWSensorsInfoLog("started");

	return true;
}
bool AppleSmartBatteryManager::start(IOService *provider)
{
    IOCommandGate * gate;
    IOWorkLoop *    wl;

    if(!super::start(provider)) {
        return false;
    }

    fProvider = OSDynamicCast(IOSMBusController, provider);
    if(!fProvider) {
        return false;
    }
    
    const OSSymbol *ucClassName = 
            OSSymbol::withCStringNoCopy("AppleSmartBatteryManagerUserClient");
    setProperty(gIOUserClientClassKey, (OSObject *) ucClassName);
    ucClassName->release();
    
    wl = getWorkLoop();
    if (!wl) {
        return false;
    }

    // Join power management so that we can get a notification early during
    // wakeup to re-sample our battery data. We don't actually power manage
    // any devices.
    PMinit();
    registerPowerDriver(this, myTwoStates, 2);
    provider->joinPMtree(this);
        
    fBattery = AppleSmartBattery::smartBattery();

    if(!fBattery) return false;
    
    fBattery->attach(this);

    fBattery->start(this);

    // Command gate for SmartBatteryManager
    fManagerGate = IOCommandGate::commandGate(this);
    if (!fManagerGate) {
        return false;
    }
    wl->addEventSource(fManagerGate);
    
    // Command gate for SmartBattery
    gate = IOCommandGate::commandGate(fBattery);
    if (!gate) {
        return false;
    }
    wl->addEventSource(gate);
    fBatteryGate = gate;      // enable messages

    // Track UserClient exclusive access to smartbattery
    fExclusiveUserClient = false;

    fBattery->registerService(0);

    this->registerService(0);

    return true;
}
/******************************************************************************
 * CodecCommander::start - start kernel extension and init PM
 ******************************************************************************/
bool CodecCommander::start(IOService *provider)
{
    IOLog("CodecCommander: Version 2.2.1 starting.\n");

    if (!provider || !super::start(provider))
	{
		DEBUG_LOG("CodecCommander: Error loading kernel extension.\n");
		return false;
	}
    
    // Retrieve HDEF device from IORegistry
	IORegistryEntry *hdaDeviceEntry = IORegistryEntry::fromPath(mConfiguration->getHDADevicePath());
	
    if (hdaDeviceEntry != NULL)
    {
		mIntelHDA = new IntelHDA(hdaDeviceEntry, PIO, mConfiguration->getCodecNumber());
		OSSafeRelease(hdaDeviceEntry);
    }
    else
    {
        DEBUG_LOG("CodecCommander: Device \"%s\" is unreachable, start aborted.\n", mConfiguration->getHDADevicePath());
        return false;
    }
	
	if (mConfiguration->getUpdateNodes())
	{
		IOSleep(mConfiguration->getSendDelay()); // need to wait a bit until codec can actually respond to immediate verbs
		int k = 0; // array index
	
		// Fetch Pin Capabilities from the range of nodes
		DEBUG_LOG("CodecCommander: Getting EAPD supported node list (limited to %d)\n", MAX_EAPD_NODES);
	
		for (int nodeId = mIntelHDA->getStartingNode(); nodeId <= mIntelHDA->getTotalNodes(); nodeId++)
		{
			UInt32 response = mIntelHDA->sendCommand(nodeId, HDA_VERB_GET_PARAM, HDA_PARM_PINCAP);
		
			if (response == -1)
			{
				DEBUG_LOG("CodecCommander: Failed to retrieve pin capabilities for node 0x%02x.\n", nodeId);
				continue;
			}

			// if bit 16 is set in pincap - node supports EAPD
			if (HDA_PINCAP_IS_EAPD_CAPABLE(response))
			{
				eapdCapableNodes[k] = nodeId;
				k++;
				IOLog("CodecCommander: NID=0x%02x supports EAPD, will update state after sleep\n", nodeId);
			}
		}
	
/*
		IOLog("CodecCommander:: Set 0x0A result: 0x%08x\n", mIntelHDA->sendCommand(0x0A, HDA_VERB_SET_AMP_GAIN, HDA_PARM_AMP_GAIN_SET(0x80, 0, 1, 1, 1, 0, 1)));
		IOLog("CodecCommander:: Set 0x0B result: 0x%08x\n", mIntelHDA->sendCommand(0x0B, HDA_VERB_SET_AMP_GAIN, HDA_PARM_AMP_GAIN_SET(0x80, 0, 1, 1, 1, 0, 1)));
		IOLog("CodecCommander:: Set 0x0C result: 0x%08x\n", mIntelHDA->sendCommand(0x0C, HDA_VERB_SET_AMP_GAIN, HDA_PARM_AMP_GAIN_SET(0x80, 0, 1, 1, 1, 0, 1)));
	
		for (int nodeId = mIntelHDA->getStartingNode(); nodeId <= mIntelHDA->getTotalNodes(); nodeId++)
		{
			UInt16 payload = HDA_PARM_AMP_GAIN_GET(0, 1, 1);//AC_AMP_GET_OUTPUT | AC_AMP_GET_LEFT;
			UInt32 response = mIntelHDA->sendCommand(nodeId, HDA_VERB_GET_AMP_GAIN, payload);
		
			if (response == -1)
			{
				DEBUG_LOG("Failed to retrieve amp gain settings for node 0x%02x.\n", nodeId);
				continue;
			}
		
			IOLog("CodecCommander:: [Amp Gain] Node: 0x%04x, Response: 0x%08x\n", nodeId, response);
		}
 */
	}
	
	// Execute any custom commands registered for initialization
	handleStateChange(kStateInit);
	
    // notify about extra feature requests
    if (mConfiguration->getCheckInfinite())
        DEBUG_LOG("CodecCommander: Infinite workloop requested, will start now!\n");
    
    // init power state management & set state as PowerOn
    PMinit();
    registerPowerDriver(this, powerStateArray, kPowerStateCount);
	provider->joinPMtree(this);
    
    // setup workloop and timer
    mWorkLoop = IOWorkLoop::workLoop();
    mTimer = IOTimerEventSource::timerEventSource(this,
                                                  OSMemberFunctionCast(IOTimerEventSource::Action, this,
                                                  &CodecCommander::onTimerAction));
    if (!mWorkLoop || !mTimer)
        stop(provider);;
    
    if (mWorkLoop->addEventSource(mTimer) != kIOReturnSuccess)
        stop(provider);
    
	this->registerService(0);
    return true;
}
Exemplo n.º 12
0
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;
}