Esempio n. 1
0
bool FakeSMCPlugin::start(IOService *provider)
{	
	if (!super::start(provider)) 
        return false;

    if (!(headingProvider = waitForService(serviceMatching(kFakeSMCService))))
		HWSensorsWarningLog("failed to locate FakeSMC service, specific OEM configurations will be unavailable");
    
	if (!(storageProvider = waitForService(serviceMatching(kFakeSMCDeviceService)))) {
		HWSensorsFatalLog("failed to locate FakeSMCDevice");
		return false;
	}
	
	return true;
}
void IOPlatformExpert::setCPUInterruptProperties(IOService *service)
{
  IOCPUInterruptController *controller;
  
  controller = OSDynamicCast(IOCPUInterruptController, waitForService(serviceMatching("IOCPUInterruptController")));
  if (controller) controller->setCPUInterruptProperties(service);
}
bool SuperIODevice::start(IOService *provider)
{
	if (!super::start(provider)) return false;

    // Gigabyte mobos usualy use ITE
    if (IOService *headingProvider = waitForService(serviceMatching(kFakeSMCService))) {
        if (OSString *manufacturer = OSDynamicCast(OSString, headingProvider->getProperty(kOEMInfoManufacturer))) {
            if (manufacturer->isEqualTo("Gigabyte")) {
                if (!detectITEFamilyChip()) {

                    UInt16 ite_id = id;
                    
                    if (!detectWinbondFamilyChip()) {
                        HWSensorsFatalLog("found unsupported chip! ITE sequence ID=0x%x, Winbond sequence ID=0x%x", ite_id, id);
                        return false;
                    }
                }
            }
        }
    }
    
    // Other vendors usualy use Winbond family chipsets
    if (model == 0) {
        if (!detectWinbondFamilyChip()) {
            
            UInt16 wnbnd_id = id;
            
            if (!detectITEFamilyChip()) {
                HWSensorsFatalLog("found unsupported chip! ITE sequence ID=0x%x, Winbond sequence ID=0x%x", id, wnbnd_id);
                return false;
            }
        }
    }
    
    HWSensorsInfoLog("found %s %s on port=0x%x address=0x%x", vendor, superio_get_model_name(model), port, address);
    
    char string[128];
    
    snprintf(string, sizeof(string), "%s,%s", vendor, superio_get_model_name(model));
    
    setName(string);
    
    //setProperty("name", &string, (UInt32)strlen(string) + 1);
    
    setProperty(kSuperIOHWMAddress, address, 16);
    setProperty(kSuperIOControlPort, port, 8);
    setProperty(kSuperIOModelValue, model, 16);
    
    setProperty(kSuperIOModelName, superio_get_model_name(model));
    setProperty(kSuperIOVendorName, vendor);
    
    setProperty(kSuperIODeviceID, OSData::withBytes(&id, sizeof(id)));
    
    registerService();
    
    return true;
}
Esempio n. 4
0
bool FakeSMCPlugin::start(IOService *provider)
{	
	if (!super::start(provider)) 
        return false;

	if (!(fakeSMC = waitForService(serviceMatching(kFakeSMCDeviceService)))) {
		HWSensorsWarningLog("can't locate FakeSMCDevice");
		return false;
	}
	
	return true;
}
Esempio n. 5
0
bool SuperIOMonitor::start(IOService *provider)
{		
	DebugLog("starting...");
	
	if (!super::start(provider)) return false;
	
	if (!(fakeSMC = waitForService(serviceMatching(kFakeSMCDeviceService)))) {
		WarningLog("can't locate fake SMC device, kext will not load");
		return false;
	}
	
	return true;
}
Esempio n. 6
0
bool FakeSMCPlugin::start(IOService *provider)
{
    DebugLog("Starting...");

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

    if (!(fakeSMC = waitForService(serviceMatching(kFakeSMCDeviceService)))) {
        WarningLog("Can't locate fake SMC device!");
        return false;
    }

    return true;
}
IOReturn IOPlatformExpert::callPlatformFunction(const OSSymbol *functionName,
						bool waitForFunction,
						void *param1, void *param2,
						void *param3, void *param4)
{
  IOService *service, *_resources;
  
  if (waitForFunction) {
    _resources = waitForService(resourceMatching(functionName));
  } else {
    _resources = resources();
  }
  if (_resources == 0) return kIOReturnUnsupported;
  
  service = OSDynamicCast(IOService, _resources->getProperty(functionName));
  if (service == 0) return kIOReturnUnsupported;
  
  return service->callPlatformFunction(functionName, waitForFunction,
				       param1, param2, param3, param4);
}
Esempio n. 8
0
bool X3100monitor::start(IOService * provider)
{
	if (!provider || !super::start(provider)) return false;
	
	if (!(fakeSMC = waitForService(serviceMatching(kFakeSMCDeviceService)))) {
		WarningLog("Can't locate fake SMC device, kext will not load");
		return false;
	}
	
	IOMemoryDescriptor *		theDescriptor;
	IOPhysicalAddress bar = (IOPhysicalAddress)((VCard->configRead32(kMCHBAR)) & ~0xf);
	DebugLog("Fx3100: register space=%08lx\n", (long unsigned int)bar);
	theDescriptor = IOMemoryDescriptor::withPhysicalAddress (bar, 0x2000, kIODirectionOutIn); // | kIOMapInhibitCache);
	if(theDescriptor != NULL)
	{
		mmio = theDescriptor->map();
		if(mmio != NULL)
		{
			mmio_base = (volatile UInt8 *)mmio->getVirtualAddress();
#if DEBUG				
			DebugLog(" MCHBAR mapped\n");
			for (int i=0; i<0x2f; i +=16) {
				DebugLog("%04lx: ", (long unsigned int)i+0x1000);
				for (int j=0; j<16; j += 1) {
					DebugLog("%02lx ", (long unsigned int)INVID8(i+j+0x1000));
				}
				DebugLog("\n");
			}
#endif				
		}
		else
		{
			InfoLog(" MCHBAR failed to map\n");
			return -1;
		}			
	}	
	
	char name[5];
	//try to find empty key
	for (int i = 0; i < 0x10; i++) {
						
		snprintf(name, 5, KEY_FORMAT_GPU_DIODE_TEMPERATURE, i); 
			
		UInt8 length = 0;
		void * data = 0;
			
		IOReturn result = fakeSMC->callPlatformFunction(kFakeSMCGetKeyValue, true, (void *)name, (void *)&length, (void *)&data, 0);
			
		if (kIOReturnSuccess == result) {
			continue;
		}
		if (addSensor(name, TYPE_SP78, 2, i)) {
			numCard = i;
			break;
		}
	}
		
	if (kIOReturnSuccess != fakeSMC->callPlatformFunction(kFakeSMCAddKeyHandler, false, (void *)name, (void *)TYPE_SP78, (void *)2, this)) {
		WarningLog("Can't add key to fake SMC device, kext will not load");
		return false;
	}
	
	return true;	
}
bool ACPIBacklightPanel::start( IOService * provider )
{
    DbgLog("%s::%s()\n", this->getName(),__FUNCTION__);

#if 0
    if (!provider)
        return false;

    _provider = provider;
    _provider->retain();
#endif

    _lock = IORecursiveLockAlloc();
    if (!_lock)
        return false;
    
    findDevices(provider);

    getDeviceControl();
    hasSaveMethod = hasSAVEMethod(backLightDevice);
    min = 0;
    max = setupIndexedLevels();
    if (min == max)
    {
        IOLog("ACPIBacklight: setupIndexedLevels failed (min==max)... aborting");
        return false;
    }

    // add interrupt source for delayed actions...
    _workSource = IOInterruptEventSource::interruptEventSource(this, OSMemberFunctionCast(IOInterruptEventAction, this, &ACPIBacklightPanel::processWorkQueue));
    if (!_workSource)
        return false;
    IOWorkLoop* workLoop = getWorkLoop();
    if (!workLoop)
    {
        _workSource->release();
        _workSource = NULL;
        return false;
    }
    workLoop->addEventSource(_workSource);
    _workPending = 0;

    // add timer for smooth fade ins
    if (_extended && !(_options & kDisableSmooth))
    {
        _smoothTimer = IOTimerEventSource::timerEventSource(this, OSMemberFunctionCast(IOTimerEventSource::Action, this, &ACPIBacklightPanel::onSmoothTimer));
        if (_smoothTimer)
            workLoop->addEventSource(_smoothTimer);
    }

    _cmdGate = IOCommandGate::commandGate(this);
    if (_cmdGate)
        workLoop->addEventSource(_cmdGate);

    // initialize from properties
    OSDictionary* dict = getPropertyTable();
    setPropertiesGated(dict);

    // write current values from smoothData
    for (int i = 0; i < countof(smoothData); i++)
    {
        char buf[kSmoothBufSize];
        snprintf(buf, sizeof(buf), kSmoothDelta, i);
        setProperty(buf, smoothData[i].delta, 32);
        snprintf(buf, sizeof(buf), kSmoothStep, i);
        setProperty(buf, smoothData[i].step, 32);
        snprintf(buf, sizeof(buf), kSmoothTimeout, i);
        setProperty(buf, smoothData[i].timeout, 32);
    }
#ifdef DEBUG
    setProperty("CycleTest", 1, 32);
    setProperty("KLVX", 1, 32);
#endif

    // make the service available for clients like 'ioio'...
    registerService();

    // load and set default brightness level
    UInt32 value = loadFromNVRAM();
    DbgLog("%s: loadFromNVRAM returns %d\n", this->getName(), value);

    // registerService above must be called before we wait for the BacklightHandler
    if (useBacklightHandler())
    {
        DbgLog("%s: Waiting for BacklightHandler\n", this->getName());
        waitForService(serviceMatching("BacklightHandler"));
    }

    // after backlight handler is in place, now we can manipulate backlight level
    UInt32 current = queryACPICurentBrightnessLevel();
    setProperty(kRawBrightness, current, 32);
#if 0
    _provider->setProperty("AppleBacklightAtBoot", current, 32);
    _provider->setProperty("AppleMaxBrightness", BCLlevels[BCLlevelsCount-1], 32);
#endif

    _committed_value = _value = _from_value = levelForValue(current);
    DbgLog("%s: current brightness: %d (%d)\n", this->getName(), _from_value, current);
    if (-1 != value)
    {
        _committed_value = value;
        DbgLog("%s: setting to value from nvram %d\n", this->getName(), value);
        setBrightnessLevelSmooth(value);
    }
    _saved_value = _committed_value;

    DbgLog("%s: min = %u, max = %u\n", this->getName(), min, max);

    // announce version
    extern kmod_info_t kmod_info;
    IOLog("ACPIBacklight: Version %s starting on OS X Darwin %d.%d.\n", kmod_info.version, version_major, version_minor);

    // place version/build info in ioreg properties RM,Build and RM,Version
    char buf[128];
    snprintf(buf, sizeof(buf), "%s %s", kmod_info.name, kmod_info.version);
    setProperty("RM,Version", buf);
#ifdef DEBUG
    setProperty("RM,Build", "Debug-" LOGNAME);
#else
    setProperty("RM,Build", "Release-" LOGNAME);
#endif

	return true;
}
Esempio n. 10
0
bool IOI2CDriveBayGPIO::start(IOService *provider)
{
	IOReturn				status;
	OSData					*data;
	mach_timespec_t			timeout;

	DLOG("IOI2CDriveBayGPIO::start\n");

	// Get our "reg" property.. I2C address.
	if (0 == (data = OSDynamicCast(OSData, provider->getProperty("reg"))))
	{
		DLOG("IOI2CDriveBayGPIO::start -- no reg property\n");
		return false;
	}
	fReg = *((UInt32 *)data->getBytesNoCopy());

	// Find the PCA9554M node. It provides our interrupt source...
	timeout.tv_sec = 30;
	timeout.tv_nsec = 0;
	if (0 == (fPCA9554M = waitForService(serviceMatching("IOI2CDriveBayMGPIO"), &timeout)))
	{
		DLOG("IOI2CDriveBayGPIO::start -- timeout waiting for IOI2CDriveBayMGPIO\n");
		return false;
	}

	fConfigReg = 0xFF;		// default to all input pins
	fPolarityReg = 0x00;	// no polarity inversion

	// find out how to program the config register
	if (data = OSDynamicCast(OSData, provider->getProperty("config-reg")))
		fConfigReg = (UInt8)*((UInt32 *)data->getBytesNoCopy());

	// find out how to program the polarity register
	if (data = OSDynamicCast(OSData, provider->getProperty("polarity-reg")))
		fPolarityReg = (UInt8)*((UInt32 *)data->getBytesNoCopy());

	DLOG("IOI2CDriveBayGPIO(%x)::start fConfigReg = %02x fPolarityReg = %02x\n", (int)fReg, fConfigReg, fPolarityReg);

	// allocate my lock
	fClientLock = IOLockAlloc();

	// Register with the combined PCA9554M
	DLOG("IOI2CDriveBayGPIO(%x)::start - register9554MInterruptClient\n", (int)fReg);
	if (kIOReturnSuccess != (status = fPCA9554M->callPlatformFunction("register9554MInterruptClient", false,
				(void *)fReg, (void *)&sProcess9554MInterrupt, (void *)this, (void *)true)))
	{
		DLOG("IOI2CDriveBayGPIO(%x)::start failed to register (%x)\n", (int)fReg, (int)status);
		return false;
	}

	// Start IOI2C services...
	if (false == super::start(provider))
	{
		DLOG("IOI2CDriveBayGPIO(%x)::start -- super::start returned error\n", (int)fReg);
		return false;
	}

	super::callPlatformFunction("IOI2CSetDebugFlags", false, (void *)kStateFlags_kprintf, (void *)true, (void *)NULL, (void *)NULL);

	if (kIOReturnSuccess != readI2C(k9554OutputPort, &fOutputReg, 1))
	{
		DLOG("IOI2CDriveBayGPIO(%x)::start -- super::start returned error\n", (int)fReg);
		freeI2CResources();
		return false;
	}

	// start matching on children
	publishChildren(provider);
	registerService();

	DLOG("IOI2CDriveBayGPIO@%lx::start succeeded\n", getI2CAddress());

	return true;
}
Esempio n. 11
0
bool SuperIODevice::start(IOService *provider)
{
	if (!super::start(provider)) return false;
    
    /*for (int i = 0; i < 2; i++) {
        i386_ioport_t port = kSuperIOPorts[i];
        
        winbond_family_enter(port);
        
        UInt16 id = superio_listen_port_word(port, kSuperIOChipIDRegister);
        
        UInt16 model = 0;
        UInt8 ldn = 0;
        const char* vendor = "";
        
        switch (id) {   
            // Fintek
            case F71858:
                model = id;
                ldn = kF71858HardwareMonitorLDN;
                vendor = "Fintek";
                break;
                
            case F71862:
            case F71868A:
            case F71869:
            case F71869A:
            case F71882:
            case F71889AD:
            case F71889ED:
            case F71889F:
            case F71808E:
                model = id;
                ldn = kFintekITEHardwareMonitorLDN;
                vendor = "Fintek";
                break;
                
            default:
                switch (id >> 8) {
                    // Winbond
                    case 0x52:
                        switch (id & 0xff) {
                            case 0x17:
                            case 0x3A:
                            case 0x41:
                                model = W83627HF;
                                ldn = kWinbondHardwareMonitorLDN;
                                vendor = "Winbond";
                                break;
                        } 
                        break;
                        
                    case 0x82:
                        switch (id & 0xf0) {
                            case 0x80:
                                model = W83627THF;
                                ldn = kWinbondHardwareMonitorLDN;
                                vendor = "Winbond";
                                break;
                        } 
                        break;
                        
                    case 0x85:
                        switch (id & 0xff) {
                            case 0x41:
                                model = W83687THF;
                                ldn = kWinbondHardwareMonitorLDN;
                                vendor = "Winbond";
                                break;
                        } 
                        break;
                        
                    case 0x88:
                        switch (id & 0xf0) {
                            case 0x50:
                            case 0x60:
                                model = W83627EHF;
                                ldn = kWinbondHardwareMonitorLDN;
                                vendor = "Winbond";
                                break;
                        } 
                        break;
                        
                    case 0xA0:
                        switch (id & 0xf0) {
                            case 0x20:
                                model = W83627DHG;
                                ldn = kWinbondHardwareMonitorLDN;
                                vendor = "Winbond";
                                break;
                        } 
                        break;
                        
                    case 0xA5:
                        switch (id & 0xf0) {
                            case 0x10:
                                model = W83667HG;
                                ldn = kWinbondHardwareMonitorLDN;
                                vendor = "Winbond";
                                break;
                        } 
                        break;
                        
                    case 0xB0:
                        switch (id & 0xf0) {
                            case 0x70:
                                model = W83627DHGP;
                                ldn = kWinbondHardwareMonitorLDN;
                                vendor = "Winbond";
                                break;
                        } 
                        break;
                        
                    case 0xB3:
                        switch (id & 0xf0) {
                            case 0x50:
                                model = W83667HGB;
                                ldn = kWinbondHardwareMonitorLDN;
                                vendor = "Winbond";
                                break;
                        } 
                        break;
                        
                    // Nuvoton 
                    case 0xB4:
                        switch (id & 0xf0) {
                            case 0x70:
                                model = NCT6771F;
                                ldn = kWinbondHardwareMonitorLDN;
                                vendor = "Nuvoton";
                                break;
                        } 
                        break;
                        
                    case 0xC3:
                        switch (id & 0xf0) {
                            case 0x30:
                                model = NCT6776F;
                                ldn = kWinbondHardwareMonitorLDN;
                                vendor = "Nuvoton";
                                break;
                        } 
                        break;
                    
                    case 0xC5:
                        switch (id & 0xf0) {
                            case 0x60:
                                model = NCT6779D;
                                ldn = kWinbondHardwareMonitorLDN;
                                vendor = "Nuvoton";
                                break;
                        } break;
                } 
                break;
        }
        
        UInt16 address = 0;
        UInt16 verify = 0;
        
        if (model != 0 && ldn != 0) {
            
            superio_select_logical_device(port, ldn);
            
            address = superio_listen_port_word(port, kSuperIOBaseAddressRegister);
            
            IOSleep(50);
            
            verify = superio_listen_port_word(port, kSuperIOBaseAddressRegister);
            
            winbond_family_exit(port);
            
            if (address != verify)
                continue;
            
            // some Fintek chips have address register offset 0x05 added already
            if ((address & 0x07) == 0x05)
                address &= 0xFFF8;
            
            if (address < 0x100 || (address & 0xF007) != 0)
                continue;
        }
        else {
            winbond_family_exit(port);
            
            IOSleep(50);
            
            // IT87XX can enter only on port 0x2E
            if (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);
                    
                    address = superio_listen_port_word(port, kSuperIOBaseAddressRegister);
                    
                    IOSleep(50);
                    
                    verify = superio_listen_port_word(port, kSuperIOBaseAddressRegister);
                    
                    ite_family_exit(port);
                    
                    if (address != verify || address < 0x100 || (address & 0xF007) != 0)
                        continue;
                }
                else {
                    ite_family_exit(port);
                    continue;
                }
            }
        }*/
    
    // Gigabyte mobos usualy use ITE
    if (IOService *headingProvider = waitForService(serviceMatching(kFakeSMCService))) {
        if (OSString *manufacturer = OSDynamicCast(OSString, headingProvider->getProperty(kOEMInfoManufacturer))) {
            if (manufacturer->isEqualTo("Gigabyte")) {
                if (!detectITEFamilyChip()) {

                    UInt16 ite_id = id;
                    
                    if (!detectWinbondFamilyChip()) {
                        HWSensorsFatalLog("found unsupported ship ITE sequence ID=0x%x, Winbond sequence ID=0x%x", ite_id, id);
                        return false;
                    }
                }
            }
        }
    }
    
    // Other vendors usualy use Winbond family chipsets
    if (model == 0) {
        if (!detectWinbondFamilyChip()) {
            
            UInt16 wnbnd_id = id;
            
            if (!detectITEFamilyChip()) {
                HWSensorsFatalLog("found unsupported ship ITE sequence ID=0x%x, Winbond sequence ID=0x%x", id, wnbnd_id);
                return false;
            }
        }
    }
    
    HWSensorsInfoLog("found %s %s on port=0x%x address=0x%x", vendor, superio_get_model_name(model), port, address);
    
    char string[128];
    
    snprintf(string, sizeof(string), "%s,%s", vendor, superio_get_model_name(model));
    
    setName(string);
    
    //setProperty("name", &string, (UInt32)strlen(string) + 1);
    
    setProperty(kSuperIOHWMAddress, address, 16);
    setProperty(kSuperIOControlPort, port, 8);
    setProperty(kSuperIOModelValue, model, 16);
    
    setProperty(kSuperIOModelName, superio_get_model_name(model));
    setProperty(kSuperIOVendorName, vendor);
    
    setProperty(kSuperIODeviceID, OSData::withBytes(&id, sizeof(id)));
    
    registerService();
    
    return true;
}
Esempio n. 12
0
/*!
 * \brief Launcher of Ros node cmd
 *
 * \param argc Number of parameters
 * \param argv The arguments
 *
 */
int main(int argc, char *argv[]) {
    // Initialize ros for this node
    ros::init(argc, argv, "pikopter_test_takeoff");

    // Struct for handling timeout
    struct timeval tv;

    // set a timeout
    tv.tv_sec = 0;
    tv.tv_usec = 100000; // 100ms

    ros::NodeHandle nh;

    ros::Subscriber state_sub = nh.subscribe<mavros_msgs::State>
                                ("mavros/state", 10, state_cb);
    ros::ServiceClient arming_client = nh.serviceClient<mavros_msgs::CommandBool>
                                       ("mavros/cmd/arming");
    ros::ServiceClient set_mode_client = nh.serviceClient<mavros_msgs::SetMode>
                                         ("mavros/set_mode");
    ros::ServiceClient tol_client = nh.serviceClient<mavros_msgs::CommandTOL>
                                    ("mavros/cmd/takeoff");

    ros::Publisher velocity_pub = nh.advertise<geometry_msgs::TwistStamped>("/mavros/setpoint_velocity/cmd_vel", 100);

    mavros_msgs::SetMode srvGuided;
    mavros_msgs::CommandTOL srvTakeOffLand;
    mavros_msgs::CommandBool srvArmed;
    geometry_msgs::TwistStamped msgMove;


    srvGuided.request.custom_mode = "GUIDED";
    srvGuided.request.base_mode = 0;
    srvTakeOffLand.request.altitude = 50;
    srvArmed.request.value = true;

    ROS_INFO("Wait for land service");
    waitForService("/mavros/cmd/land");

    ROS_INFO("Wait for set_mode service");
    waitForService("/mavros/set_mode");

    ROS_INFO("Wait for set_mode service");
    waitForService("/mavros/cmd/arming");

    ros::Rate rate(20.0);
    ros::Time last_request = ros::Time::now();
    ros::Time loop_time = ros::Time::now();

    bool takeoff = false;
    bool land = false;

    /*while(ros::ok()){
        if(current_state.mode != "GUIDED" &&
            (ros::Time::now() - last_request > ros::Duration(5.0))){
            if( set_mode_client.call(srvGuided) &&
                srvGuided.response.success){
                ROS_INFO("Guided mode enabled");
            }
            last_request = ros::Time::now();
        } else {
            if(!current_state.armed &&
                (ros::Time::now() - last_request > ros::Duration(5.0))){
                if( arming_client.call(srvArmed) &&
                    srvArmed.response.success){
                    ROS_INFO("Vehicle armed");
                }
                last_request = ros::Time::now();
            }
        }

        if(ros::Time::now() - last_request > ros::Duration(5.0) && !takeoff){
    		if(tol_client.call(srvTakeOffLand) &&
        		srvTakeOffLand.response.success){
    			takeoff = true;
        		sleep(10);
        		ROS_INFO("Vehicle has takeoff");
        	}
        	last_request = ros::Time::now();
    	}

        ros::spinOnce();
        rate.sleep();
    }

    return 0;*/

    sleep(5);

    // Set mode to GUIDED
    if(ros::service::call("/mavros/set_mode", srvGuided) && srvGuided.response.success) {
        ROS_INFO("Mode MAV_MODE_GUIDED activated.");
    }

    else {
        ROS_ERROR("Problem occured on calling set_mode service");
        exit(ERROR_ENCOUNTERED);
    }

    // Wait a little before arming
    sleep(1);

    // Arming motors
    if(ros::service::call("/mavros/cmd/arming", srvArmed) && srvArmed.response.success) {
        ROS_INFO("Arming command called.");
    }

    else {
        ROS_ERROR("Problem occured on calling arming command");
        exit(ERROR_ENCOUNTERED);
    }

    // Wait a little before taking off (need to warn everyone aroun!)
    sleep(2);

    // Calling takeoff service
    if(ros::service::call("/mavros/cmd/takeoff", srvTakeOffLand) && srvTakeOffLand.response.success) {
        ROS_INFO("Takeoff called");
    }

    else {
        ROS_ERROR("Problem occured on calling takeoff command");
        exit(ERROR_ENCOUNTERED);
    }

    sleep(5);

    msgMove.header.stamp = ros::Time::now();
    msgMove.twist.linear.x = -10;

    velocity_pub.publish(msgMove);

    ROS_INFO("Linear velocity -> x = %f, y = %f, z = %f", msgMove.twist.linear.x, msgMove.twist.linear.y, msgMove.twist.linear.z);
    // ROS_INFO("Angular velocity -> x = %f, y = %f, z = %f", msgMove.twist.angular.x, msgMove.twist.angular.y, msgMove.twist.angular.z);

    // Drone will move during 15 seconds
    sleep(15);

    msgMove.header.stamp = ros::Time::now();
    msgMove.twist.linear.x = 0;
    msgMove.twist.angular.z = 0;

    velocity_pub.publish(msgMove);

    ROS_INFO("Linear velocity -> x = %f, y = %f, z = %f", msgMove.twist.linear.x, msgMove.twist.linear.y, msgMove.twist.linear.z);
    ROS_INFO("Angular velocity -> x = %f, y = %f, z = %f", msgMove.twist.angular.x, msgMove.twist.angular.y, msgMove.twist.angular.z);

    sleep(5);

    if(ros::service::call("/mavros/cmd/land", srvTakeOffLand))
        ROS_INFO("Land called");
    else
        ROS_ERROR("Problem occured on calling land command");
    return 0;
}
Esempio n. 13
0
bool MacRISC2CPU::start(IOService *provider)
{
    kern_return_t        result;
    IORegistryEntry      *cpusRegEntry, *uniNRegEntry, *mpicRegEntry, *devicetreeRegEntry;
    OSIterator           *cpusIterator;
    OSData               *tmpData;
    IOService            *service;
    const OSSymbol       *interruptControllerName;
    OSData               *interruptData;
    OSArray              *tmpArray;
    UInt32               maxCPUs, uniNVersion, physCPU;
    ml_processor_info_t  processor_info;
    
#if enableUserClientInterface    
	DFScontMode = 0;
    fWorkLoop = 0;
    DFS_Status = false;
    GPU_Status = kGPUHigh;
	vStepped = false;
#endif

    // callPlatformFunction symbols
    mpic_getProvider = OSSymbol::withCString("mpic_getProvider");
    mpic_getIPIVector= OSSymbol::withCString("mpic_getIPIVector");
    mpic_setCurrentTaskPriority = OSSymbol::withCString("mpic_setCurrentTaskPriority");
    mpic_setUpForSleep = OSSymbol::withCString("mpic_setUpForSleep");
    mpic_dispatchIPI = OSSymbol::withCString("mpic_dispatchIPI");
    keyLargo_restoreRegisterState = OSSymbol::withCString("keyLargo_restoreRegisterState");
    keyLargo_syncTimeBase = OSSymbol::withCString("keyLargo_syncTimeBase");
    keyLargo_saveRegisterState = OSSymbol::withCString("keyLargo_saveRegisterState");
    keyLargo_turnOffIO = OSSymbol::withCString("keyLargo_turnOffIO");
    keyLargo_writeRegUInt8 = OSSymbol::withCString("keyLargo_writeRegUInt8");
    keyLargo_getHostKeyLargo = OSSymbol::withCString("keyLargo_getHostKeyLargo");
    keyLargo_setPowerSupply = OSSymbol::withCString("setPowerSupply");
    uniN_setPowerState = OSSymbol::withCString(kUniNSetPowerState);
    uniN_setAACKDelay = OSSymbol::withCString(kUniNSetAACKDelay);
	pmu_cpuReset = OSSymbol::withCString("cpuReset");
	ati_prepareDMATransaction = OSSymbol::withCString(kIOFBPrepareDMAValueKey);
    ati_performDMATransaction = OSSymbol::withCString(kIOFBPerformDMAValueKey);
    
    macRISC2PE = OSDynamicCast(MacRISC2PE, getPlatform());
    if (macRISC2PE == 0) return false;
  
    if (!super::start(provider)) return false;

    // Get the Uni-N Version.
    uniNRegEntry = fromPath("/uni-n", gIODTPlane);
    if (uniNRegEntry == 0) return false;
    tmpData = OSDynamicCast(OSData, uniNRegEntry->getProperty("device-rev"));
    if (tmpData == 0) return false;
    uniNVersion = *(long *)tmpData->getBytesNoCopy();
  
    // Find out if this is the boot CPU.
    bootCPU = false;
    tmpData = OSDynamicCast(OSData, provider->getProperty("state"));
    if (tmpData == 0) return false;
    if (!strcmp((char *)tmpData->getBytesNoCopy(), "running")) bootCPU = true;

    // Count the CPUs.
    numCPUs = 0;
    cpusRegEntry = fromPath("/cpus", gIODTPlane);
    if (cpusRegEntry == 0) return false;
    cpusIterator = cpusRegEntry->getChildIterator(gIODTPlane);
    while (cpusIterator->getNextObject()) numCPUs++;
    cpusIterator->release();
  
	// [3830950] - The bootCPU driver inits globals for all instances (like gCPUIC) so if we're not the
	// boot CPU driver we wait here for that driver to finish its initialization
	if ((numCPUs > 1) && !bootCPU)
		// Wait for bootCPU driver to say it's up and running
		(void) waitForService (resourceMatching ("BootCPU"));
		
    // Limit the number of CPUs to one if uniNVersion is 1.0.7 or less.
    if (uniNVersion < kUniNVersion107) numCPUs = 1;
  
    // Limit the number of CPUs by the cpu=# boot arg.
    if (PE_parse_boot_arg("cpus", &maxCPUs))
    {
        if (numCPUs > maxCPUs) numCPUs = maxCPUs;
    }
	
	ignoreSpeedChange = false;
	doSleep = false;
	topLevelPCIBridgeCount = 0;
  
    // Get the "flush-on-lock" property from the first cpu node.
    flushOnLock = false;
    cpusRegEntry = fromPath("/cpus/@0", gIODTPlane);
    if (cpusRegEntry == 0) return false;
    if (cpusRegEntry->getProperty("flush-on-lock") != 0) flushOnLock = true;
  
    // Set flushOnLock when numCPUs is not one.
    if (numCPUs != 1) flushOnLock = true;
  
    // If system is PowerMac3,5 (TowerG4), then set flushOnLock to disable nap
    devicetreeRegEntry = fromPath("/", gIODTPlane);
    tmpData = OSDynamicCast(OSData, devicetreeRegEntry->getProperty("model"));
    if (tmpData == 0) return false;
#if 0
    if(!strcmp((char *)tmpData->getBytesNoCopy(), "PowerMac3,5"))
        flushOnLock = true;
#endif

    // Get the physical CPU number from the "reg" property.
    tmpData = OSDynamicCast(OSData, provider->getProperty("reg"));
    if (tmpData == 0) return false;
    physCPU = *(long *)tmpData->getBytesNoCopy();
    setCPUNumber(physCPU);

    // Get the gpio offset for soft reset from the "soft-reset" property.
    tmpData = OSDynamicCast(OSData, provider->getProperty("soft-reset"));
    if (tmpData == 0) 
    {
        if (physCPU == 0)
            soft_reset_offset = 0x5B;
        else
            soft_reset_offset = 0x5C;
    }
    else
        soft_reset_offset = *(long *)tmpData->getBytesNoCopy();
   
    // Get the gpio offset for timebase enable from the "timebase-enable" property.
    tmpData = OSDynamicCast(OSData, provider->getProperty("timebase-enable"));
    if (tmpData == 0) 
        timebase_enable_offset = 0x73;
    else
        timebase_enable_offset = *(long *)tmpData->getBytesNoCopy();
  
	// See if reset is needed on wake
	resetOnWake = (provider->getProperty ("reset-on-wake") != NULL);
	
	if (resetOnWake) {
		vm_address_t reserveMem;
		

		reserveMem = (vm_address_t)IOMallocAligned (PAGE_SIZE, PAGE_SIZE);	// Get one page (which we keep forever)
		if (reserveMem) {			
			// map it
			reserveMemDesc = IOMemoryDescriptor::withAddress (reserveMem, PAGE_SIZE, kIODirectionNone, NULL);
			if (reserveMemDesc) {
				// get the physical address
				reserveMemPhys = reserveMemDesc->getPhysicalAddress();
			} 
		} 
	}

    // On machines with a 'vmin' property in the CPU Node we need to make sure to tell the kernel to 
    // ml_set_processor_voltage on needed processors.
    needVSetting = (provider->getProperty( "vmin" ) != 0);

    // While techincally the Apollo7PM machines do need AACK delay, it is already set in the bootROM
    // since we boot slow.  We don't want the machine to switch AACKdelay off when we run DFS high so
    // setting this to false will take care of the issue.
        
    needAACKDelay = false;
 
 	if (bootCPU)
    {
        gCPUIC = new IOCPUInterruptController;
        if (gCPUIC == 0) return false;
        if (gCPUIC->initCPUInterruptController(numCPUs) != kIOReturnSuccess)
            return false;
        gCPUIC->attach(this);
        gCPUIC->registerCPUInterruptController();
    }
  
    // Get the l2cr value from the property list.
    tmpData = OSDynamicCast(OSData, provider->getProperty("l2cr"));
    if (tmpData != 0)
    {
        l2crValue = *(long *)tmpData->getBytesNoCopy() & 0x7FFFFFFF;
    }
    else
    {
        l2crValue = mfl2cr() & 0x7FFFFFFF;
    }
  
    // Wait for KeyLargo to show up.
    keyLargo = waitForService(serviceMatching("KeyLargo"));
    if (keyLargo == 0) return false;
  
    keyLargo->callPlatformFunction (keyLargo_getHostKeyLargo, false, &keyLargo, 0, 0, 0);
    if (keyLargo == 0)
    {
        kprintf ("MacRISC2CPU::start - getHostKeyLargo returned nil\n");
        return false;
    }

    // Wait for MPIC to show up.
    mpic = waitForService(serviceMatching("AppleMPICInterruptController"));
    if (mpic == 0) return false;
  
    // Set the Interrupt Properties for this cpu.
    mpic->callPlatformFunction(mpic_getProvider, false, (void *)&mpicRegEntry, 0, 0, 0);
    interruptControllerName = IODTInterruptControllerName(mpicRegEntry);
    mpic->callPlatformFunction(mpic_getIPIVector, false, (void *)&physCPU, (void *)&interruptData, 0, 0);
    if ((interruptControllerName == 0) || (interruptData == 0)) return false;
  
    tmpArray = OSArray::withCapacity(1);
    tmpArray->setObject(interruptControllerName);
    cpuNub->setProperty(gIOInterruptControllersKey, tmpArray);
    tmpArray->release();
  
    tmpArray = OSArray::withCapacity(1);
    tmpArray->setObject(interruptData);
    cpuNub->setProperty(gIOInterruptSpecifiersKey, tmpArray);
    tmpArray->release();
  
    setCPUState(kIOCPUStateUninitalized);
  
	// necessary bootCPU initialization is done, so release other CPU drivers to do their thing
	// other drivers need to be unblocked *before* we call processor_start otherwise we deadlock
	if (bootCPU)
		publishResource ("BootCPU", this);
		
    if (physCPU < numCPUs)
    {
        processor_info.cpu_id           = (cpu_id_t)this;
        processor_info.boot_cpu         = bootCPU;
        processor_info.start_paddr      = 0x0100;
        processor_info.l2cr_value       = l2crValue;
        processor_info.supports_nap     = !flushOnLock;
        processor_info.time_base_enable =
        OSMemberFunctionCast(time_base_enable_t, this, &MacRISC2CPU::enableCPUTimeBase);	// [4091924]
    
        // Register this CPU with mach.
        result = ml_processor_register(&processor_info, &machProcessor,	&ipi_handler);
        if (result == KERN_FAILURE) return false;
    
        processor_start(machProcessor);
    }

    // Before to go to sleep we wish to disable the napping mode so that the PMU
    // will not shutdown the system while going to sleep:
    service = waitForService(serviceMatching("IOPMrootDomain"));
    pmRootDomain = OSDynamicCast(IOPMrootDomain, service);
    if (pmRootDomain != 0)
    {
        kprintf("Register MacRISC2CPU %ld to acknowledge power changes\n", getCPUNumber());
        pmRootDomain->registerInterestedDriver(this);
        
        // Join the Power Management Tree to receive setAggressiveness calls.
        PMinit();
        provider->joinPMtree(this);
    }

    // Finds PMU and UniN so in quiesce we can put the machine to sleep.
    // I can not put these calls there because quiesce runs in interrupt
    // context and waitForService may block.
    pmu = waitForService(serviceMatching("ApplePMU"));
	uniN = waitForService(serviceMatching("AppleUniN"));
    if ((pmu == 0) || (uniN == 0)) return false;
	

    if (macRISC2PE->hasPMon) {
            // Find the platform monitor, if present
            service = waitForService(resourceMatching("IOPlatformMonitor"));
            ioPMon = OSDynamicCast (IOPlatformMonitor, service->getProperty("IOPlatformMonitor"));
            if (!ioPMon) 
                    return false;
            
            ioPMonDict = OSDictionary::withCapacity(2);
            if (!ioPMonDict) {
                    ioPMon = NULL;
            } else {
                    ioPMonDict->setObject (kIOPMonTypeKey, OSSymbol::withCString (kIOPMonTypeCPUCon));
                    ioPMonDict->setObject (kIOPMonCPUIDKey, OSNumber::withNumber ((long long)getCPUNumber(), 32));

                    if (messageClient (kIOPMonMessageRegister, ioPMon, (void *)ioPMonDict) != kIOReturnSuccess) {
                            // IOPMon doesn't need to know about us, so don't bother with it
                            IOLog ("MacRISC2CPU::start - failed to register cpu with IOPlatformMonitor\n");
                            ioPMonDict->release();
                            ioPMon = NULL;
                    }
            }
    }

    if (macRISC2PE->hasPPlugin) {
		IOService		*ioPPlugin;
		OSDictionary	*ioPPluginDict;
		
		// Find the platform plugin, if present
		service = waitForService(resourceMatching("IOPlatformPlugin"));
		ioPPlugin = OSDynamicCast (IOService, service->getProperty("IOPlatformPlugin"));
		if (!ioPPlugin) 
			return false;
		
		ioPPluginDict = OSDictionary::withCapacity(2);
		if (ioPPluginDict) {
			ioPPluginDict->setObject ("cpu-id", OSNumber::withNumber ((long long)getCPUNumber(), 32));

			// Register with the plugin - same API as for platform monitor
			if (messageClient (kIOPMonMessageRegister, ioPPlugin, (void *)ioPPluginDict) != kIOReturnSuccess) {
				// ioPPlugin doesn't need to know about us, so don't bother with it
				IOLog ("MacRISC2CPU::start - failed to register cpu with IOPlatformPlugin\n");
			}
			ioPPluginDict->release();	// Not needed any more
		}
    }

#if enableUserClientInterface    
//   
// UserClient stuff...
//  
    fWorkLoop = getWorkLoop();
    if(!fWorkLoop)
    {
            IOLog("MacRISC2CPU::start ERROR: failed to find a fWorkLoop\n");
    }
    if(!initTimers()) 
    {
            IOLog("MacRISC2CPU::start ERROR: failed to init the timers\n");
    }
    
#endif

    registerService();
  
    return true;
}
bool GeforceSensors::start(IOService * provider)
{
	DebugLog("Starting...");
	
	if (!super::start(provider)) 
    return false;
  
  if (!(fakeSMC = waitForService(serviceMatching(kFakeSMCDeviceService)))) {
		WarningLog("Can't locate fake SMC device, kext will not load");
		return false;
	}  
  
  struct nouveau_device *device = &card;
  
  //Find card number
  card.card_index = getVacantGPUIndex();
  
  if (card.card_index < 0) {
    nv_error(device, "failed to obtain vacant GPU index\n");
    return false;
  }
  
  // map device memory
//  device->pcidev = (IOPCIDevice*)provider;
  if (device->pcidev) {
    
    device->pcidev->setMemoryEnable(true);
    
    if ((device->mmio = device->pcidev->mapDeviceMemoryWithIndex(0))) {
      nv_debug(device, "memory mapped successfully\n");
    }
    else {
      nv_error(device, "failed to map memory\n");
      return false;
    }
  }
  else {
    nv_error(device, "failed to assign PCI device\n");
    return false;
  }
  
  // identify chipset
  if (!nouveau_identify(device))
    return false;
  
  // shadow and parse bios
  
  //try to load bios from registry first from "vbios" property created by Chameleon boolloader
  if (OSData *vbios = OSDynamicCast(OSData, provider->getProperty("vbios"))) {
    device->bios.size = vbios->getLength();
    device->bios.data = (u8*)IOMalloc(card.bios.size);
    memcpy(device->bios.data, vbios->getBytesNoCopy(), device->bios.size);
  }
  
  if (!device->bios.data || !device->bios.size || nouveau_bios_score(device, true) < 1)
    if (!nouveau_bios_shadow(device)) {
      if (device->bios.data && device->bios.size) {
        IOFree(card.bios.data, card.bios.size);
        device->bios.data = NULL;
        device->bios.size = 0;
      }
      
      nv_error(device, "unable to shadow VBIOS\n");
      
      return false;
    }
  
  nouveau_vbios_init(device);
  nouveau_bios_parse(device);
  
  // initialize funcs and variables
  if (!nouveau_init(device)) {
    nv_error(device, "unable to initialize monitoring driver\n");
    return false;
  }
  
  nv_info(device, "chipset: %s (NV%02X) bios: %02x.%02x.%02x.%02x\n", device->cname, (unsigned int)device->chipset, device->bios.version.major, device->bios.version.chip, device->bios.version.minor, device->bios.version.micro);
  
  if (device->card_type < NV_C0) {
    // init i2c structures
    nouveau_i2c_create(device);
    
    // setup nouveau i2c sensors
    nouveau_i2c_probe(device);
  }
  
  // Register sensors
  char key[5];
  
  if (card.core_temp_get || card.board_temp_get) {
    nv_debug(device, "registering i2c temperature sensors...\n");
    
    if (card.core_temp_get && card.board_temp_get) {
      snprintf(key, 5, KEY_FORMAT_GPU_DIODE_TEMPERATURE, card.card_index);
      this->addSensor(key, TYPE_SP78, 2, 0);
      
      snprintf(key, 5, KEY_FORMAT_GPU_HEATSINK_TEMPERATURE, card.card_index);
      addSensor(key, TYPE_SP78, 2, 0);
    }
    else if (card.core_temp_get) {
      snprintf(key, 5, KEY_FORMAT_GPU_PROXIMITY_TEMPERATURE, card.card_index);
      addSensor(key, TYPE_SP78, 2, 0);
    }
    else if (card.board_temp_get) {
      snprintf(key, 5, KEY_FORMAT_GPU_PROXIMITY_TEMPERATURE, card.card_index);
      addSensor(key, TYPE_SP78, 2, 0);
    }
  }
  else if (card.temp_get)
  {
    nv_debug(device, "registering temperature sensors...\n");
    
    snprintf(key, 5, KEY_FORMAT_GPU_PROXIMITY_TEMPERATURE, card.card_index);
    addSensor(key, TYPE_SP78, 2, 0);
  }
  
  if (card.clocks_get) {
    nv_debug(device, "registering clocks sensors...\n");
    
    if (card.clocks_get(&card, nouveau_clock_core) > 0) {
      snprintf(key, 5, KEY_FAKESMC_FORMAT_GPU_FREQUENCY, card.card_index);
      addSensor(key, TYPE_UI32, TYPE_UI32_SIZE, nouveau_clock_core);
    }
    
    if (card.clocks_get(&card, nouveau_clock_shader) > 0) {
      snprintf(key, 5, KEY_FAKESMC_FORMAT_GPU_SHADER_FREQUENCY, card.card_index);
      addSensor(key, TYPE_UI32, TYPE_UI32_SIZE, nouveau_clock_shader);
    }
    
    if (card.clocks_get(&card, nouveau_clock_rop) > 0) {
      snprintf(key, 5, KEY_FAKESMC_FORMAT_GPU_ROP_FREQUENCY, card.card_index);
      addSensor(key, TYPE_UI32, TYPE_UI32_SIZE, nouveau_clock_rop);
    }
    
    if (card.clocks_get(&card, nouveau_clock_memory) > 0) {
      snprintf(key, 5, KEY_FAKESMC_FORMAT_GPU_MEMORY_FREQUENCY, card.card_index);
      addSensor(key, TYPE_UI32, TYPE_UI32_SIZE, nouveau_clock_memory);
    }
  }
  
  if (card.fan_pwm_get || card.fan_rpm_get) {
    nv_debug(device, "registering PWM sensors...\n");
    
    if (card.fan_rpm_get && card.fan_rpm_get(device) > 0) {
      char title[6];
      snprintf (title, 6, "GPU %X", card.card_index + 1);
      
      UInt8 fanIndex = 0;
      
      if (addTachometer( fanIndex)) {
        if (card.fan_pwm_get && card.fan_pwm_get(device) > 0) {
          snprintf(key, 5, KEY_FAKESMC_FORMAT_GPUPWM, fanIndex);
          addSensor(key, TYPE_UI8, TYPE_UI8_SIZE, 0);
        }
      }
    }
  }
  
  if (card.voltage_get && card.voltage.supported) {
    nv_debug(device, "registering voltage sensors...\n");
    snprintf(key, 5, KEY_FORMAT_GPU_VOLTAGE, card.card_index);
    addSensor(key, TYPE_FP2E, TYPE_FPXX_SIZE, 0);
  }
  
  nv_info(device, "started\n");
  
  return true;
}
Esempio n. 15
0
bool AppleMediaBay::start(IOService *provider)
{
    OSData      *compatibleEntry;

    // If the super class failed there is little point in 
    // going on:
    if (!super::start(provider))
        return false;
    
    // Find out the controller for the mediabay:
    mbControllerType = kMBControllerUndefined;
        
    compatibleEntry  = OSDynamicCast( OSData, provider->getProperty( "compatible" ) );
    if ( compatibleEntry == 0 ) {
#ifdef APPLEMB_VERBOSE
        IOLog("No compatible entry found.\n");
#endif //APPLEMB_VERBOSE
        return false;
    }

    if ( compatibleEntry->isEqualTo( "keylargo-media-bay", sizeof("keylargo-media-bay")-1 ) == true ) {
#ifdef APPLEMB_VERBOSE
        IOLog("Found KeyLargo compatible property.\n");
#endif // APPLEMB_VERBOSE

        mbControllerType = kMBControllerKeyLargo;
 
        myMacIO = waitForService(serviceMatching("KeyLargo"));
    }

    if ( compatibleEntry->isEqualTo( "heathrow-media-bay", sizeof("heathrow-media-bay")-1 ) == true )  {
#ifdef APPLEMB_VERBOSE
         IOLog("Found Heathrow compatible property.\n");
#endif // APPLEMB_VERBOSE

        mbControllerType = kMBControllerHeathrow;
        
        // now the parent could be either Hetrow or Gatwick
        // so jump back looking for my MacIO:
        myMacIO = OSDynamicCast(AppleMacIO, provider->getProvider());
    }

    if ( compatibleEntry->isEqualTo( "ohare-media-bay", sizeof("ohare-media-bay")-1 ) == true ) {
#ifdef APPLEMB_VERBOSE
         IOLog("Found OHare compatible property.\n");
#endif // APPLEMB_VERBOSE

        mbControllerType = kMBControllerOHare;
        myMacIO = waitForService(serviceMatching("OHare"));
    }
    
    if( (configAddrMap = provider->mapDeviceMemoryWithIndex( 0 )))
    {
        configAddr = (volatile UInt32 *) configAddrMap->getVirtualAddress();

#ifdef APPLEMB_VERBOSE
         IOLog("configAddr = 0x%08lx.\n",(unsigned int)configAddr);
#endif // APPLEMB_VERBOSE
    }
    else {
#ifdef APPLEMB_VERBOSE
        IOLog("configAddrMap failed.\n");
#endif // APPLEMB_VERBOSE
        return false;
    }

    if (myMacIO == NULL) {
#ifdef APPLEMB_VERBOSE
        IOLog("myMacIO == NULL.\n");
#endif // APPLEMB_VERBOSE
        return false;
    }

    workloop = IOWorkLoop::workLoop();      // make the workloop
    if(!workloop) {
#ifdef APPLEMB_VERBOSE
        IOLog("Error creating workloop.\n");
#endif // APPLEMB_VERBOSE
        return false;
    }
    
    intSource = IOInterruptEventSource::interruptEventSource
                (this, (IOInterruptEventAction) &handleInterrupt,
                 provider);

    if ((intSource == NULL) || (workloop->addEventSource(intSource) != kIOReturnSuccess)) {
#ifdef APPLEMB_VERBOSE
        IOLog("Problem adding interrupt event source...\n");
#endif // APPLEMB_VERBOSE

        return false;
    }
    else
        workloop->enableAllInterrupts();

    // Creates the command gate for the events that need to be in the queue
    commandGate = IOCommandGate::commandGate(this, commandGateCaller);

    // and adds it to the workloop:
    if ((commandGate == NULL) || 
        (workloop->addEventSource(commandGate) != kIOReturnSuccess))
    {
#ifdef VERBOSE_LOGS_ON_PMU_INT
        IOLog("Can not add a new IOCommandGate\n");
#endif // VERBOSE_LOGS_ON_PMU_INT
        return false;
    }

    // by default we start without client:
    ioClient = NULL;
    
    // The symbol to change power to the media bay:
    powerMediaBay = OSSymbol::withCString("powerMediaBay");

    // Remember with wich device we are starting:
    mbCurrentDevice = readMBID();

    // Starts the power managment. NOTE: to assure the correct behavior
    // of the driver initForPM should be called AFTER mbCurrentDevice is
    // set to its initial value.
    if (!initForPM(provider)) {
#ifdef APPLEMB_VERBOSE
        IOLog("Error joining the power managment tree.\n");
#endif // APPLEMB_VERBOSE
        return false;
    }
    
    // calls registerService so that the ata nubs can find this driver
    // and register with it:
    registerService();
    
    return true;
}
Esempio n. 16
0
bool AppleGPIO::start(IOService *provider)
{
	bool					doSleepWake;
	UInt32					i, flags, intCapable;
	IOPlatformFunction		*func;
	const OSSymbol			*functionSymbol = OSSymbol::withCString("InstantiatePlatformFunctions");
	IOReturn				retval;
	IOService				*parentDev;
	OSData					*data;

	if (!super::start(provider)) return(false);
	
	// set my id
	data = OSDynamicCast(OSData, provider->getProperty("reg"));
	if (!data) return(false);
	
	fGPIOID = *(UInt32 *)data->getBytesNoCopy();
	
	// find the gpio parent
	parentDev = OSDynamicCast(IOService, provider->getParentEntry(gIODTPlane));
	if (!parentDev) return(false);

	fParent = OSDynamicCast(IOService, parentDev->getChildEntry(gIOServicePlane));
	if (!fParent) return(false);

	// Create the interrupt register/enable symbols
	fSymIntRegister 	= OSSymbol::withCString(kIOPFInterruptRegister);
	fSymIntUnRegister 	= OSSymbol::withCString(kIOPFInterruptUnRegister);
	fSymIntEnable 		= OSSymbol::withCString(kIOPFInterruptEnable);
	fSymIntDisable		= OSSymbol::withCString(kIOPFInterruptDisable);

	// Allocate our constant callPlatformFunction symbols so we can be called at interrupt time.

	fSymGPIOParentWriteGPIO = OSSymbol::withCString(kSymGPIOParentWriteGPIO);
	fSymGPIOParentReadGPIO = OSSymbol::withCString(kSymGPIOParentReadGPIO);

	// Scan for platform-do-xxx functions
	fPlatformFuncArray = NULL;

	DLOG("AppleGPIO::start(%s@%lx) - calling InstantiatePlatformFunctions\n",
			provider->getName(), fGPIOID);

	retval = provider->getPlatform()->callPlatformFunction(functionSymbol, false,
			(void *)provider, (void *)&fPlatformFuncArray, (void *)0, (void *)0);

	DLOG("AppleGPIO::start(%s@%lx) - InstantiatePlatformFunctions returned %ld, pfArray %sNULL\n",
			provider->getName(), fGPIOID, retval, fPlatformFuncArray ? "NOT " : "");

	if (retval == kIOReturnSuccess && (fPlatformFuncArray != NULL))
	{
		// Find out if the GPIO parent supports interrupt events
		if (fParent->callPlatformFunction(kSymGPIOParentIntCapable, false, &intCapable, 0, 0, 0)
				!= kIOReturnSuccess)
		{
			intCapable = 0;
		}

		DLOG("AppleGPIO::start(%s@%lx) - iterating platformFunc array, count = %ld\n",
			provider->getName(), fGPIOID, fPlatformFuncArray->getCount());

		doSleepWake = false;

		UInt32 count = fPlatformFuncArray->getCount();
		for (i = 0; i < count; i++)
		{
			if (func = OSDynamicCast(IOPlatformFunction, fPlatformFuncArray->getObject(i)))
			{
				flags = func->getCommandFlags();

				DLOG ("AppleGPIO::start(%s@%lx) - functionCheck - got function, flags 0x%lx, pHandle 0x%lx\n", 
					provider->getName(), fGPIOID, flags, func->getCommandPHandle());

				// If this function is flagged to be performed at initialization, do it
				if (flags & kIOPFFlagOnInit)
				{
					performFunction(func, (void *)1, (void *)0, (void *)0, (void *)0);
				}

				if ((flags & kIOPFFlagOnDemand) || ((flags & kIOPFFlagIntGen) && intCapable))
				{
					// Set the flag to indicate whether any of the platform functions are using
					// interrupts -- this is used to allocate some locks that are needed for this
					// functionality
					if ((flags & kIOPFFlagIntGen) && (fIntGen == false))
					{
						fIntGen = true;

						// Allocate event-related state variable locks
						fClientsLock = IOSimpleLockAlloc();
						fAmRegisteredLock = IOLockAlloc();
						fAmEnabledLock = IOSimpleLockAlloc();
					}
					
					// This is a bit of overkill.  Strictly speaking the lock needs to protect
					// individual platformFunc array entries so that only one thread is executing
					// that function at a time.  The way we're using it here is only one of *any*
					// of the platform functions can be executing at a time.
					if (!fPFLock) fPFLock = IOLockAlloc();	// Use for both On-Demand and IntGen functions

					// On-Demand and IntGen functions need to have a resource published
					func->publishPlatformFunction(this);
				}

				// If we need to do anything at sleep/wake time, we'll need to set this
				// flag so we know to register for notifications
				if (flags & (kIOPFFlagOnSleep | kIOPFFlagOnWake))
					doSleepWake = true;
			}
			else
			{
				// This function won't be used -- generate a warning
				IOLog("AppleGPIO::start(%s@%lx) - functionCheck - not an IOPlatformFunction object\n",
						getProvider()->getName(), fGPIOID);
			}
		}

		// Register sleep and wake notifications
		if (doSleepWake)
		{
			mach_timespec_t	waitTimeout;

			waitTimeout.tv_sec = 30;
			waitTimeout.tv_nsec = 0;

			pmRootDomain = OSDynamicCast(IOPMrootDomain,
					waitForService(serviceMatching("IOPMrootDomain"), &waitTimeout));

			if (pmRootDomain != 0)
			{
				DLOG("AppleGPIO::start to acknowledge power changes\n");
				pmRootDomain->registerInterestedDriver(this);
			}
			else
			{
				IOLog("AppleGPIO failed to register PM interest!");
			}
		}
	}


#ifdef OLD_STYLE_COMPAT
	/*
	 * Legacy Support
	 *
	 * In the initial implementation, extra strings were published for event registration
	 * and deregistration as well as enable/disable functions.  In the IOPlatformFunction
	 * implementation, the client access these functions by calling the platform-xxx function
	 * and passing one of four OSSymbol objects (see fSymIntRegister, fSymIntUnRegister,
	 * fSymIntEnable, fSymIntDisable).  For now, we need to continue to support the old
	 * implementation.  The following code will generate and publish resources for these
	 * functions.
	 */

	if (fIntGen)
	{
		const OSSymbol 	*functionSym, *aKey;
		char			funcNameWithPrefix[160];
		const char		*funcName;

		UInt32 count = fPlatformFuncArray->getCount();
		for (i = 0; i < count; i++)
		{
			// Only publish strings for on-demand and int-gen functions
			if ((func = OSDynamicCast(IOPlatformFunction, fPlatformFuncArray->getObject(i))) != NULL &&
				(func->getCommandFlags() & (kIOPFFlagOnDemand | kIOPFFlagIntGen)) != NULL)
			{
				functionSym = func->getPlatformFunctionName();
				if (!functionSym)
					continue;
				else
					funcName = functionSym->getCStringNoCopy() + strlen(kFunctionRequiredPrefix);
			
				// register string list
				strncpy(funcNameWithPrefix, kFunctionRegisterPrefix, strlen (kFunctionRegisterPrefix)+1);
				strncat(funcNameWithPrefix, funcName, sizeof (funcNameWithPrefix) - strlen (funcNameWithPrefix) - 1);
				funcNameWithPrefix[sizeof (funcNameWithPrefix) - 1] = '\0';

				if ((aKey = OSSymbol::withCString(funcNameWithPrefix)) == 0)
					continue;

				ADD_OBJ_TO_SET(aKey, fRegisterStrings);

				// unregister string list
				strncpy(funcNameWithPrefix, kFunctionUnregisterPrefix, strlen (kFunctionUnregisterPrefix)+1);
				strncat(funcNameWithPrefix, funcName, sizeof (funcNameWithPrefix) - strlen (funcNameWithPrefix) - 1);
				funcNameWithPrefix[sizeof (funcNameWithPrefix) - 1] = '\0';
				
				if ((aKey = OSSymbol::withCString(funcNameWithPrefix)) == 0)
					continue;
				
				ADD_OBJ_TO_SET(aKey, fUnregisterStrings);

				// register string list
				strncpy(funcNameWithPrefix, kFunctionEvtEnablePrefix, strlen (kFunctionEvtEnablePrefix)+1);
				strncat(funcNameWithPrefix, funcName, sizeof (funcNameWithPrefix) - strlen (funcNameWithPrefix) - 1);
				funcNameWithPrefix[sizeof (funcNameWithPrefix) - 1] = '\0';

				if ((aKey = OSSymbol::withCString(funcNameWithPrefix)) == 0)
					continue;

				ADD_OBJ_TO_SET(aKey, fEnableStrings);

				// register string list
				strncpy(funcNameWithPrefix, kFunctionEvtDisablePrefix, strlen (kFunctionEvtDisablePrefix)+1);
				strncat(funcNameWithPrefix, funcName, sizeof (funcNameWithPrefix) - strlen (funcNameWithPrefix) - 1);
				funcNameWithPrefix[sizeof (funcNameWithPrefix) - 1] = '\0';

				if ((aKey = OSSymbol::withCString(funcNameWithPrefix)) == 0)
					continue;

				ADD_OBJ_TO_SET(aKey, fDisableStrings);
			}
		}

		publishStrings(fRegisterStrings);
		publishStrings(fUnregisterStrings);
		publishStrings(fEnableStrings);
		publishStrings(fDisableStrings);
	}

#endif

	if (fPlatformFuncArray && fPlatformFuncArray->getCount() > 0)
	{
		registerService();
		return(true);
	}
	else
	{
		// No reason for me to be here
		return(false);
	}
}