void IOGUIDPartitionScheme::stop(IOService * provider)
{
    //
    // Clean up after the media objects we published before terminating.
    //

    IOMedia *    partition;
    OSIterator * partitionIterator;

    // State our assumptions.

    assert(_partitions);

    // Detach the media objects we previously attached to the device tree.

    partitionIterator = OSCollectionIterator::withCollection(_partitions);

    if ( partitionIterator )
    {
        while ( (partition = (IOMedia *) partitionIterator->getNextObject()) )
        {
            detachMediaObjectFromDeviceTree(partition);
        }

        partitionIterator->release();
    }

    super::stop(provider);
}
示例#2
0
IOReturn AppleLM8x::publishChildren(IOService *nub)
{
	OSIterator			*childIterator = NULL;
	IORegistryEntry		*childEntry = NULL;
    IOService			*childNub = NULL;
    IOReturn 			status;

	childIterator = nub->getChildIterator(gIODTPlane);
	if( childIterator != NULL )
	{
		// Iterate through children and create nubs
		while ( ( childEntry = (IORegistryEntry *)( childIterator->getNextObject() ) ) != NULL )
		{
			// Build Table
			status = buildEntryTable(childEntry);
			LUNtableElement++;
			
			// Publish child as IOService
			childNub = OSDynamicCast(IOService, OSMetaClass::allocClassWithName("IOService"));
		
			childNub->init(childEntry, gIODTPlane);
			childNub->attach(this);
			childNub->registerService();
			
//			DLOG("AppleLM8x::publishChildren(0x%x) published child %s\n", kLM8xAddr<<1, childEntry->getName());
		}
	
		childIterator->release();
	}

	return kIOReturnSuccess;
}
示例#3
0
IOReturn
IOI2CLM6x::createChildNubs	(
								IOService*			nub
							)
{
	OSIterator*							childIterator;
	IORegistryEntry*					childEntry;
	IOService*							childNub;

	require( ( childIterator = nub->getChildIterator( gIODTPlane ) ) != NULL, IOI2CLM6x_createChildNubs_getChildIteratorNull );

	while ( ( childEntry = ( IORegistryEntry * ) childIterator->getNextObject() ) != NULL )
	{
		childNub = OSDynamicCast( IOService, OSMetaClass::allocClassWithName( "IOService" ) );

		if ( childNub )
		{
			childNub->init( childEntry, gIODTPlane );
			childNub->attach( this );
			childNub->registerService();
		}
	}

IOI2CLM6x_createChildNubs_getChildIteratorNull:
	return( kIOReturnSuccess );
}
IOACPIPlatformDevice * ACPIBacklightPanel::getChildWithBacklightMethods(IOACPIPlatformDevice * GPUdevice)
{
    DbgLog("%s::%s()\n", this->getName(),__FUNCTION__);
    
	OSIterator * 		iter = NULL;
	OSObject *		entry;
    
	iter =  GPUdevice->getChildIterator(gIOACPIPlane);
	if (iter)
	{
		while ( true )
		{			
			entry = iter->getNextObject();
			if (NULL == entry)
				break;
			
			if (entry->metaCast("IOACPIPlatformDevice"))
			{
				IOACPIPlatformDevice * device = (IOACPIPlatformDevice *) entry;
				
				if (hasBacklightMethods(device))
				{
					IOLog("ACPIBacklight: Found Backlight Device: %s\n", device->getName());
					return device;
				}
			}
			else {
				DbgLog("%s: getChildWithBacklightMethods() Cast Error\n", this->getName());
			}
		} //end while
		iter->release();
		DbgLog("%s: getChildWithBacklightMethods() iterator end\n", this->getName());
	}
	return NULL;
}
IOService * ACPIBacklightPanel::getBatteryDevice()
{
	DbgLog("%s::%s()\n", this->getName(),__FUNCTION__);
    
    OSDictionary * matching = IOService::serviceMatching("IOPMPowerSource");
	OSIterator *   iter = NULL;
	IOService * bat = NULL;
	
	if (matching)
	{
		DbgLog("%s: getBatteryDevice() serviceMatching OK\n", this->getName());
		iter = IOService::getMatchingServices(matching);
		matching->release();
	}
	
	if (iter)
	{
		DbgLog("%s: getBatteryDevice() iter OK\n", this->getName());
		
		bat = OSDynamicCast(IOService, iter->getNextObject());
		if (bat)
		{
			DbgLog("%s: getBatteryDevice() bat is of class %s\n", this->getName(), bat->getMetaClass()->getClassName());	
		}
		
		iter->release();
	}
	
	return bat;
}
void IOPMPagingPlexus::processChildren ( void )
{
    OSIterator *	childIterator;
    IOPowerConnection *	nextChildNub;
    IORegistryEntry *	nextChild;
    IOService *		child;
    unsigned int	i;
    
    childIterator = getChildIterator(gIOPowerPlane);

    if ( childIterator ) {
        while ( (nextChild = (IORegistryEntry *)(childIterator->getNextObject())) ) {
            if ( (nextChildNub = OSDynamicCast(IOPowerConnection,nextChild)) ) {
                child = (IOService *)nextChild->getChildEntry(gIOPowerPlane);
                if ( child->pm_vars->theControllingDriver ) {
                    for ( i = 1; i < child->pm_vars->theNumberOfPowerStates; i++ ) {
                        child->pm_vars->thePowerStates[i].inputPowerRequirement |= IOPMPagingAvailable;
                    }
                }
                if ( child->pm_vars->myCurrentState ) {
                    nextChildNub->setDesiredDomainState(kIOPlexusPowerStateCount-1);
                }
            }
        }
        childIterator->release();
    }
}
示例#7
0
kern_return_t pmem_iokit_enumerate_pci(pmem_pci_callback_t callback,
                                       void *ctx) {
    kern_return_t error = KERN_FAILURE;
    OSObject *obj = nullptr;
    OSDictionary *search = nullptr;
    OSIterator *iter = nullptr;
    IOPCIDevice *dev = nullptr;
    IODeviceMemory *mem = nullptr;
    IOItemCount mem_count = 0;
    int cmp;

    search = IOService::serviceMatching("IOPCIDevice");
    iter = IOService::getMatchingServices(search);
    if (!iter) {
        pmem_error("Couldn't find any PCI devices.");
        goto bail;
    }

    while ((obj = iter->getNextObject())) {
        cmp = strncmp("IOPCIDevice",
                      obj->getMetaClass()->getClassName(),
                      strlen("IOPCIDevice"));
        if (cmp != 0) {
            // I haven't seen the above return anything other than
            // PCI devices, but Apple's documentation is sparse (which
            // is a nice word for what it is) and doesn't actually
            // say anything about what's guaranteed to be returned.
            // I'd just as well rather not chance it.
            pmem_warn("Expected IOPCIDevice but got %s - skipping.",
                      obj->getMetaClass()->getClassName());
            continue;
        }
        dev = (IOPCIDevice *)obj;
        mem_count = dev->getDeviceMemoryCount();
        pmem_debug("Found PCI device %s", dev->getName());

        for (unsigned idx = 0; idx < mem_count; ++idx) {
            pmem_debug("Memory segment %d found.", idx);
            mem = dev->getDeviceMemoryWithIndex(idx);
            pmem_signal_t signal = callback(dev, mem, idx, ctx);
            if (signal == pmem_Stop) {
                error = KERN_FAILURE;
                goto bail;
            }
        }
    }

    error = KERN_SUCCESS;

bail:
    if (iter) {
        iter->release();
    }

    if (search) {
        search->release();
    }

    return error;
}
示例#8
0
IOReturn IOI2CMaxim1631::publishChildren(IOService *nub)
{
    OSIterator			*childIterator = NULL;
    IORegistryEntry		*childEntry = NULL;
    IOService			*childNub = NULL;

	childIterator = nub->getChildIterator(gIODTPlane);
	if( childIterator != NULL )
	{
		// Iterate through children and create nubs
		while ( ( childEntry = (IORegistryEntry *)( childIterator->getNextObject() ) ) != NULL )
		{
			// Publish child as IOService
			childNub = OSDynamicCast(IOService, OSMetaClass::allocClassWithName("IOService"));
		
			childNub->init(childEntry, gIODTPlane);
			childNub->attach(this);
			childNub->registerService();
                           			
			DLOG("IOI2CMaxim1631::publishChildren(0x%x) published child %s\n", getI2CAddress(), childEntry->getName());
		}
	
		childIterator->release();
	}

	return kIOReturnSuccess;
}
示例#9
0
IOReturn IOI2CDriveBayGPIO::publishChildren(IOService *provider)
{
    IOReturn 			status = kIOReturnSuccess;
	OSIterator			*iter;
	IORegistryEntry		*next;
    IOService			*nub;

	if (iter = provider->getChildIterator(gIODTPlane))
	{
		// Iterate through children and create nubs
		while (next = (IORegistryEntry *)(iter->getNextObject()))
		{
			nub = OSDynamicCast(IOService, OSMetaClass::allocClassWithName("IOI2CService"));
			if (nub)
			{
				nub->init(next, gIODTPlane);
				nub->attach(this);
				nub->registerService();
			
//				DLOG("IOI2CDriveBayGPIO@%lx::publishChildren published child %s\n", getI2CAddress(), next->getName());
			}
		}

		iter->release();
	}

	return status;
}
示例#10
0
void MacRISC2CPU::haltCPU(void)
{
	OSIterator 		*childIterator;
	IORegistryEntry *childEntry, *childDriver;
	IOPCIBridge		*pciDriver;
	OSData			*deviceTypeString;
	UInt32			i;

  
    setCPUState(kIOCPUStateStopped);
  
    if (bootCPU)
    {
		// Some systems require special handling of Ultra-ATA at sleep.
		// Call UniN to prepare for that, if necessary
		uniN->callPlatformFunction ("setupUATAforSleep", false, (void *)0, (void *)0, (void *)0, (void *)0);

		// Notify our pci children to save their state
		if (!topLevelPCIBridgeCount) {
			// First build list of top level bridges - only need to do once as these don't change
			if ((childIterator = macRISC2PE->getChildIterator (gIOServicePlane)) != NULL) {
				while ((childEntry = (IORegistryEntry *)(childIterator->getNextObject ())) != NULL) {
					deviceTypeString = OSDynamicCast( OSData, childEntry->getProperty( "device_type" ));
					if (deviceTypeString) {
						if (!strcmp((const char *)deviceTypeString->getBytesNoCopy(), "pci")) {
							childDriver = childEntry->copyChildEntry(gIOServicePlane);
							if (childDriver) {
								pciDriver = OSDynamicCast( IOPCIBridge, childDriver );
								if (pciDriver)
									if (topLevelPCIBridgeCount < kMaxPCIBridges)
										// Remember this driver
										topLevelPCIBridges[topLevelPCIBridgeCount++] = pciDriver;
									else
										kprintf ("MacRISC2CPU::haltCPU - warning, more than %d PCI bridges - cannot save/restore them all\n", kMaxPCIBridges);
								childDriver->release();
							}
						}
					}
				}
				childIterator->release();
			}
		}
		for (i = 0; i < topLevelPCIBridgeCount; i++)
			if (pciDriver = topLevelPCIBridges[i]) {
				// Got the driver - send the message
				pciDriver->setDevicePowerState (NULL, 2);
			}
    }

   kprintf("MacRISC2CPU::haltCPU %ld Here!\n", getCPUNumber());

   processor_exit(machProcessor);
}
bool AutoThrottler::setup(OSObject* owner) {
	if (setupDone) return true;
	
	workLoop = IOWorkLoop::workLoop();
	if (workLoop == 0) return false;
	
	perfTimer = IOTimerEventSource::timerEventSource(owner, (IOTimerEventSource::Action) &perfTimerWrapper);
	if (perfTimer == 0) return false;
	
	/* from Superhai (modified by mercurysquad) */
	cpu_count = 0; OSDictionary* service;
	mach_timespec_t serviceTimeout = { 60, 0 }; // in seconds
	totalTimerEvents = 0;
	
	IOService* firstCPU = IOService::waitForService(IOService::serviceMatching("IOCPU"), &serviceTimeout);

	if (!firstCPU) {
		warn("IOKit CPUs not found. Auto-throttle may not work.\n");
		return false;
	} else {
		// we got first cpu, so the others should also be available by now. get them
		service = IOService::serviceMatching("IOCPU");
	}
	
	OSIterator* iterator = IOService::getMatchingServices(service);
	
	if (!iterator) {
		warn("IOKit CPU iterator couldn't be created. Auto-throttle may not work.\n");
		return false;
	}

	IOCPU * cpu;
	while ((cpu = OSDynamicCast(IOCPU, iterator->getNextObject())))
	{
		/*dbg("Got I/O Kit CPU %d (%u) named %s", cpu_count, (unsigned int)(cpu->getCPUNumber(), cpu->getCPUName()->getCStringNoCopy());
    */
		mach_cpu[cpu_count] = cpu->getMachProcessor();
		if (cpu_count++ > max_cpus) break;
	}
	selfHost = host_priv_self();
	if (workLoop->addEventSource(perfTimer) != kIOReturnSuccess) return false;
	currentPState = NumberOfPStates - 1;
	perfTimer->setTimeoutMS(throttleQuantum * (1 + currentPState));
	clock_get_uptime(&lastTime);
	if (!targetCPULoad) targetCPULoad = defaultTargetLoad; // % x10
	sysctl_register_oid(&sysctl__kern_cputhrottle_targetload);
	sysctl_register_oid(&sysctl__kern_cputhrottle_auto);
	setupDone = true;
	return true;
}
示例#12
0
int num_kids(IOService *provider)
{
	int total = 1;
	//total++;
	OSIterator *kids;
	const char* poo = provider->getName();
	IOLog("name: %s \n", poo);
	if (kids = provider->getChildIterator(gIOServicePlane)) {
		IOService *nextkid;
		while (nextkid = (IOService*)kids->getNextObject()) {
			total += num_kids(nextkid);
		}
		kids->release();
	}
	return total;
}
示例#13
0
static IOReturn _terminateDrivers(OSDictionary * matching)
{
    OSDictionary         * dict;
    OSIterator           * iter;
    IOService            * service;
    IOReturn               ret;

    if ( !matching )
        return kIOReturnBadArgument;

    ret = kIOReturnSuccess;
    dict = 0;
    iter = IORegistryIterator::iterateOver(gIOServicePlane,
                                           kIORegistryIterateRecursively);
    if ( !iter )
        return kIOReturnNoMemory;

    UniqueProperties( matching );

    // terminate instances.
    do {
        iter->reset();
        while( (service = (IOService *)iter->getNextObject()) ) {
            dict = service->getPropertyTable();
            if ( !dict )
                continue;

            /* Terminate only for personalities that match the matching dictionary.
             * This comparison must be done with only the keys in the
             * "matching" dict to enable general matching.
             */
            if ( !dict->isEqualTo(matching, matching) )
                continue;

            if ( !service->terminate(kIOServiceRequired|kIOServiceSynchronous) ) {
                ret = kIOReturnUnsupported;
                break;
            }
        }
    } while( !service && !iter->isValid());
    iter->release();

    return ret;
}
bool AppleACPIBatteryDevice::isStartUp()
{
    OSDictionary * matching = IOService::serviceMatching("AppleBacklightDisplay");
	OSIterator *   iter = NULL;
	IOService * service = NULL;
	
	if (matching)
	{
		iter = IOService::getMatchingServices(matching);
		matching->release();
	}
	
	if (iter)
	{
		service = OSDynamicCast(IOService, iter->getNextObject());
		iter->release();
	}
	return (service != NULL);
}
IOReturn IOPMPagingPlexus::setAggressiveness ( unsigned long type, unsigned long )
{
    OSDictionary *	dict;
    OSIterator *	iter;
    OSObject *		next;
    IOService *		candidate = 0;
    IOService *		pagingProvider;

    if( type != kPMMinutesToSleep)
        return IOPMNoErr;
    
    IOLockLock(ourLock);
    if ( systemBooting ) {
        systemBooting = false;
        IOLockUnlock(ourLock);
        dict = IOBSDNameMatching(rootdevice);
        if ( dict ) {
            iter = getMatchingServices(dict);
            if ( iter ) {
                while ( (next = iter->getNextObject()) ) {
                    if ( (candidate = OSDynamicCast(IOService,next)) ) {
                        break;
                    }
                }
                iter->release();
            }
        }
        if ( candidate ) {
            pagingProvider = findProvider(candidate);
            if ( pagingProvider ) {
                processSiblings(pagingProvider);
                pagingProvider->addPowerChild(this);
                getPMRootDomain()->removePowerChild(((IOPowerConnection *)getParentEntry(gIOPowerPlane)));
                processChildren();
            }
        }
    }
    else {
        IOLockUnlock(ourLock);
    }
    return IOPMNoErr;
}
示例#16
0
static IOService * getBatteryDevice()
{
    OSDictionary * matching = IOService::serviceMatching("IOPMPowerSource");
	OSIterator *   iter = NULL;
	IOService * bat = NULL;
	
	if (matching)
	{
		iter = IOService::getMatchingServices(matching);
		matching->release();
	}
	
	if (iter)
	{
		bat = OSDynamicCast(IOService, iter->getNextObject());
		iter->release();
	}
	
	return bat;
}
void IODTPlatformExpert::processTopLevel( IORegistryEntry * root )
{
    OSIterator * 	kids;
    IORegistryEntry *	next;
    IORegistryEntry *	cpus;
    IORegistryEntry *	options;

    // infanticide
    kids = IODTFindMatchingEntries( root, 0, deleteList() );
    if( kids) {
	while( (next = (IORegistryEntry *)kids->getNextObject())) {
	    next->detachAll( gIODTPlane);
	}
	kids->release();
    }

    // Publish an IODTNVRAM class on /options.
    options = root->childFromPath("options", gIODTPlane);
    if (options) {
      dtNVRAM = new IODTNVRAM;
      if (dtNVRAM) {
        if (!dtNVRAM->init(options, gIODTPlane)) {
	  dtNVRAM->release();
	  dtNVRAM = 0;
        } else {
	  dtNVRAM->attach(this);
	  dtNVRAM->registerService();
	}
      }
    }

    // Publish the cpus.
    cpus = root->childFromPath( "cpus", gIODTPlane);
    if ( cpus)
      createNubs( this, IODTFindMatchingEntries( cpus, kIODTExclusive, 0));

    // publish top level, minus excludeList
    createNubs( this, IODTFindMatchingEntries( root, kIODTExclusive, excludeList()));
}
示例#18
0
IORegistryEntry * AppleIntelPIIXATARoot::getDTChannelEntry( int channelID )
{
    IORegistryEntry * entry = 0;
    const char *      location;

    OSIterator * iter = _provider->getChildIterator( gIODTPlane );
    if (iter == 0) return 0;

    while (( entry = (IORegistryEntry *) iter->getNextObject() ))
    {
        location = entry->getLocation();
        if ( location && strtol(location, 0, 10) == channelID )
        {
            entry->retain();
            break;
        }
    }

    iter->release();
    
    return entry;  // retain held on the entry
}
示例#19
0
static IOService *
IOCopyMediaForDev(dev_t device)
{
    OSDictionary * matching;
    OSNumber *     num;
    OSIterator *   iter;
    IOService *    result = 0;

    matching = IOService::serviceMatching("IOMedia");
    if (!matching)
        return (0);
    do
    {
        num = OSNumber::withNumber(major(device), 32);
        if (!num)
            break;
        matching->setObject(kIOBSDMajorKey, num);
        num->release();
        num = OSNumber::withNumber(minor(device), 32);
        if (!num)
            break;
        matching->setObject(kIOBSDMinorKey, num);
        num->release();
        if (!num)
            break;
        iter = IOService::getMatchingServices(matching);
        if (iter)
        {
            result = (IOService *) iter->getNextObject();
            result->retain();
            iter->release();
        }
    }
    while (false);
    matching->release();

    return (result);
}
bool IOGUIDPartitionScheme::start(IOService * provider)
{
    //
    // Publish the new media objects which represent our partitions.
    //

    IOMedia *    partition;
    OSIterator * partitionIterator;

    // State our assumptions.

    assert(_partitions);

    // Ask our superclass' opinion.

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

    // Attach and register the new media objects representing our partitions.

    partitionIterator = OSCollectionIterator::withCollection(_partitions);
    if ( partitionIterator == 0 )  return false;

    while ( (partition = (IOMedia *) partitionIterator->getNextObject()) )
    {
        if ( partition->attach(this) )
        {
            attachMediaObjectToDeviceTree(partition);

            partition->registerService();
        }
    }

    partitionIterator->release();

    return true;
}
void IOPMPagingPlexus::processSiblings ( IOService * aNode )
{
    OSIterator *	parentIterator;
    IORegistryEntry *	nextNub;
    IORegistryEntry *	nextParent;
    OSIterator *	siblingIterator;
    IORegistryEntry *	nextSibling;

    parentIterator = aNode->getParentIterator(gIOPowerPlane);		// iterate parents of this node

    if ( parentIterator ) {
        while ( true ) {
            if ( ! (nextNub = (IORegistryEntry *)(parentIterator->getNextObject())) ) {
                parentIterator->release();
                break;
            }
            if ( OSDynamicCast(IOPowerConnection,nextNub) ) {
                nextParent = nextNub->getParentEntry(gIOPowerPlane);
                if ( nextParent == getPMRootDomain() ) {
                    continue;				// plexus already has root's children
                }
                if ( nextParent == this ) {
                    parentIterator->release();
                    removePowerChild((IOPowerConnection *)nextNub);
                    break;
                }
                siblingIterator = nextParent->getChildIterator(gIOPowerPlane);
                                                                                // iterate children of this parent
                if ( siblingIterator ) {
                    while ( (nextSibling = (IORegistryEntry *)(siblingIterator->getNextObject())) ) {
                        if ( OSDynamicCast(IOPowerConnection,nextSibling) ) {
                            nextSibling = nextSibling->getChildEntry(gIOPowerPlane);
                            if ( nextSibling != aNode ) {			// non-ancestor of driver gets
                                addPowerChild((IOService *)nextSibling);	// plexus as parent
                            }
                        }
                    }
                    siblingIterator->release();
                }
                processSiblings((IOService *)nextParent);			// do the same thing to this parent
            }
   	}
    }
}
示例#22
0
int PTnVmon::probe_devices()
{
	IOPCIDevice* PTCard=NULL;
	int i=0;
	UInt16 vendor_id;
	IOLog("PTKawainVi: started\n");
	OSData* idKey;
	OSDictionary * iopci = serviceMatching("IOPCIDevice");
	OSString* str;
#if __LP64__
	mach_vm_address_t addr;
	//mach_vm_size_t size;
#else
	vm_address_t addr;
	//vm_size_t size;
#endif
	nvclock.num_cards=0;
	if (iopci) {
		OSIterator * iterator = getMatchingServices(iopci);
		if (iterator) {
			while (PTCard = OSDynamicCast(IOPCIDevice, iterator->getNextObject())) {
				vendor_id=0;
				str=OSDynamicCast(OSString, PTCard->getProperty("IOName"));
				idKey=OSDynamicCast(OSData, PTCard->getProperty("vendor-id"));
				if (idKey)
					vendor_id=*(UInt32*)idKey->getBytesNoCopy();
				if ((str->isEqualTo("display"))&&(vendor_id==0x10de)){
					PTCard->setMemoryEnable(true);
					nvio = PTCard->mapDeviceMemoryWithIndex(0);		
					addr = (vm_address_t)nvio->getVirtualAddress();
					idKey=OSDynamicCast(OSData, PTCard->getProperty("device-id"));
					if (idKey)
						nvclock.card[i].device_id=*(UInt32*)idKey->getBytesNoCopy();
					IOLog("Vendor ID: %x, Device ID: %x\n", vendor_id, nvclock.card[i].device_id);
					nvclock.card[i].arch = get_gpu_arch(nvclock.card[i].device_id);
					IOLog("Architecture: %x\n", nvclock.card[i].arch);
					nvclock.card[i].number = i;
					nvclock.card[i].card_name = (char*)get_card_name(nvclock.card[i].device_id, &nvclock.card[i].gpu);
					IOLog("%s\n", nvclock.card[i].card_name);
					nvclock.card[i].state = 0;
					
					nvclock.card[i].reg_address = addr;
					map_mem_card( &nvclock.card[i], addr );
					
					
					
					
					i++;
					
				}
			}
		}
	}
	
	nvclock.num_cards = i;
	
	if (!i) {
		IOLog("PTKawainVi: No nVidia graphics adapters found\n");
	}	
	
	return nvclock.num_cards;
}
IOCDMedia *
GetCDMediaObjectFromName ( const char * ioBSDNamePtr )
{
	
	OSIterator *		iteratorPtr			= NULL;
	IORegistryEntry *	registryEntryPtr	= NULL;
	IOCDMedia *			objectPtr			= NULL;
	OSDictionary *		matchingDictPtr		= NULL;
	
	DebugLog ( ( "GetCDMediaObjectFromName: Entering...\n" ) );
	
	DebugAssert ( ( ioBSDNamePtr != NULL ) );
	
	DebugLog ( ( "GetCDMediaObjectFromName: On enter ioBSDNamePtr = %s.\n", ioBSDNamePtr ) );
	
	// Check to see if we need to strip off any leading stuff
	if ( !strncmp ( ioBSDNamePtr, "/dev/r", 6 ) )
	{

		// Strip off the /dev/r from /dev/rdiskX
		ioBSDNamePtr = &ioBSDNamePtr[6];	

	}

	else if ( !strncmp ( ioBSDNamePtr, "/dev/", 5 ) )
	{

		// Strip off the /dev/ from /dev/diskX
		ioBSDNamePtr = &ioBSDNamePtr[5];	

	}
	
	if ( strncmp ( ioBSDNamePtr, "disk", 4 ) )
	{
		
		// Not in correct format, return NULL
		DebugLog ( ( "GetCDMediaObjectFromName: not in correct format, ioBSDNamePtr = %s.\n", ioBSDNamePtr ) );
		
		return NULL;
		
	}
	
	DebugLog ( ( "GetCDMediaObjectFromName: ioBSDNamePtr = %s.\n", ioBSDNamePtr ) );
	
	// Get a dictionary which describes the bsd device
	matchingDictPtr = IOBSDNameMatching ( ioBSDNamePtr );
	
	// Get an iterator of registry entries
	iteratorPtr = IOService::getMatchingServices ( matchingDictPtr );
	if ( iteratorPtr == NULL )
	{
		
		DebugLog ( ( "GetCDMediaObjectFromName: iteratorPtr is NULL.\n" ) );
		return NULL;
		
	}
	
	// Release the dictionary
	matchingDictPtr->release ( );
			
	DebugLog ( ( "Acquired refcount on iterator and media.\n" ) );
	
	// Get the object out of the iterator (NB: we're guaranteed only one object in the iterator
	// because there is a 1:1 correspondence between BSD Names for devices and IOKit objects
	registryEntryPtr = ( IORegistryEntry * ) iteratorPtr->getNextObject ( );
	if ( registryEntryPtr == NULL )
	{
		
		DebugLog ( ( "GetCDMediaObjectFromName: registryEntryPtr is NULL.\n" ) );
		return NULL;
		
	}
	
	// Cast it to the correct type
	objectPtr = OSDynamicCast ( IOCDMedia, registryEntryPtr );
	if ( objectPtr == NULL )
	{
		
		// Cast failed...spew an error
		DebugLog ( ( "GetCDMediaObjectFromName: objectPtr is NULL, Dynamic Cast failed.\n" ) );
		
	}
	
	DebugLog ( ( "GetCDMediaObjectFromName: exiting...\n" ) );
	
	// Bump the refcount on the CDMedia so that when we release the iterator
	// we still have a refcount on it.
	if ( objectPtr != NULL )
	{
		
		objectPtr->retain ( );
		
	}
	
	// Release the iterator
	iteratorPtr->release ( );	
	
	return ( objectPtr );
	
}
示例#24
0
文件: ODINX.cpp 项目: winsock/ODINX
// We are the best match, setup driver
bool ODINXHostDevice::start(IOService *provider) {
    LOG(V_DEBUG, "ODINXHostDevice::start called");

    this->usbDevice = OSDynamicCast(IOUSBHostDevice, provider);
    if (!this->usbDevice) {
        
        LOG(V_ERROR, "Provider is not an IOUSBHostDevice, this is impossible!");
        // Tell the kernel to try the next highest score driver
        return false;
    }
    
    const StandardUSB::ConfigurationDescriptor *activeConfiguration = nullptr;
    IOReturn returnCode = NULL;
    
    if (!this->usbDevice->isOpen()) {
        returnCode = this->usbDevice->open(this);
        if (returnCode != kIOReturnSuccess && returnCode != kIOReturnExclusiveAccess) {
            /*
             * Only error if return code is neither kIOReturnSuccess or kIOReturnExclusiveAccess.
             * If we got kIOReturnExclusiveAccess that means we do (not?) have exclusivity and that open has already been called.
             */
            LOG(V_ERROR, "Error opening the USB device! Code: %04X", returnCode);
            return false;
        }
        LOG(V_DEBUG, "Device is not open and we failed to open it!");
    }
    
    // DEBUG
    {
        LOG(V_NOTE, "      Manufacturer: \"%s\"\n", ODINXHostDevice::stringDescriptorToCString(this->usbDevice->getStringDescriptor(this->usbDevice->getDeviceDescriptor()->iManufacturer)));
        LOG(V_NOTE, "           Product: \"%s\"\n", ODINXHostDevice::stringDescriptorToCString(this->usbDevice->getStringDescriptor(this->usbDevice->getDeviceDescriptor()->iProduct)));
        LOG(V_NOTE, "         Serial No: \"%s\"\n", ODINXHostDevice::stringDescriptorToCString(this->usbDevice->getStringDescriptor(this->usbDevice->getDeviceDescriptor()->iSerialNumber)));
        
        LOG(V_NOTE, "            length: %d\n", this->usbDevice->getDeviceDescriptor()->bLength);
        LOG(V_NOTE, "      device class: %d\n", this->usbDevice->getDeviceDescriptor()->bDeviceClass);
        LOG(V_NOTE, "               S/N: %d\n", this->usbDevice->getDeviceDescriptor()->iSerialNumber);
        LOG(V_NOTE, "           VID:PID: %04X:%04X\n", this->usbDevice->getDeviceDescriptor()->idVendor, this->usbDevice->getDeviceDescriptor()->idProduct);
        LOG(V_NOTE, "         bcdDevice: %04X\n", this->usbDevice->getDeviceDescriptor()->bcdDevice);
        LOG(V_NOTE, "   iMan:iProd:iSer: %d:%d:%d\n", this->usbDevice->getDeviceDescriptor()->iManufacturer, this->usbDevice->getDeviceDescriptor()->iProduct, this->usbDevice->getDeviceDescriptor()->iSerialNumber);
        LOG(V_NOTE, "          nb confs: %d\n", this->usbDevice->getDeviceDescriptor()->bNumConfigurations);
    }
    
    if (this->usbDevice->getDeviceDescriptor()->bNumConfigurations > 0 && returnCode != kIOReturnExclusiveAccess) {
        for (int configIndex = 0; configIndex < this->usbDevice->getDeviceDescriptor()->bNumConfigurations; configIndex++) {
            // Set the configuration active, the second param disables IOKit from automaticly trying to find drivers for the new interfaces since we do it ourselves.
            activeConfiguration = this->usbDevice->getConfigurationDescriptor(configIndex);
            returnCode = this->usbDevice->setConfiguration(activeConfiguration->bConfigurationValue, false);
            if (returnCode != kIOReturnSuccess) {
                LOG(V_ERROR, "Error setting the device to the configuration at index zero!");
            }
            
            // Find the interfaces
            OSIterator *deviceInterfaceIterator = this->usbDevice->getChildIterator(gIOServicePlane);
            if (!deviceInterfaceIterator) {
                LOG(V_ERROR, "USB Device has no interfaces?!?!");
                return false;
            }
            
            OSObject *entry = nullptr;
            
            while ((entry = deviceInterfaceIterator->getNextObject()) != nullptr) {
                IOUSBHostInterface *usbInterface = OSDynamicCast(IOUSBHostInterface, entry);
                if (!usbInterface) {
                    LOG(V_DEBUG, "Object in interface iterator that isn't a IOUSBHostInterface!");
                    continue;
                }
                
                uint8_t interfaceClass = usbInterface->getInterfaceDescriptor()->bInterfaceClass;
                if (interfaceClass != USB_INTERFACE_CLASS_CDC_DATA) {
                    LOG(V_DEBUG, "Interface isn't of the CDC Data class. Interface class: 0x%02X!", interfaceClass);
                    continue;
                }

                {
                    LOG(V_NOTE, "config[%d].interface[%d]: num endpoints = %d", configIndex, usbInterface->getInterfaceDescriptor()->bInterfaceNumber, usbInterface->getInterfaceDescriptor()->bNumEndpoints);
                    LOG(V_NOTE, "   Class.SubClass.Protocol: %02X.%02X.%02X", usbInterface->getInterfaceDescriptor()->bInterfaceClass, usbInterface->getInterfaceDescriptor()->bInterfaceSubClass, usbInterface->getInterfaceDescriptor()->bInterfaceProtocol);
                }
                
                const StandardUSB::EndpointDescriptor *endpoint = nullptr;
                while ((endpoint = StandardUSB::getNextEndpointDescriptor(activeConfiguration, usbInterface->getInterfaceDescriptor(), endpoint)) != nullptr) {
                    {
                        LOG(V_NOTE, "       endpoint address: %02X\n", endpoint->bEndpointAddress);
                        LOG(V_NOTE, "           max packet size: %04X\n", endpoint->wMaxPacketSize);
                        LOG(V_NOTE, "          polling interval: %02X\n", endpoint->bInterval);
                    }
                    
                    if (!inPipe || !outPipe) {
                        if (StandardUSB::getEndpointDirection(endpoint)) {
                            if (inPipe) {
                                OSSafeReleaseNULL(inPipe);
                            }
                            this->inPipe = usbInterface->copyPipe(endpoint->bEndpointAddress);
                            LOG(V_DEBUG, "Found an input endpoint: 0x%02X!", endpoint->bEndpointAddress);
                        } else {
                            if (outPipe) {
                                OSSafeReleaseNULL(outPipe);
                            }
                            this->outPipe = usbInterface->copyPipe(endpoint->bEndpointAddress);
                            LOG(V_DEBUG, "Found an output endpoint: 0x%02X!", endpoint->bEndpointAddress);
                        }
                    }
                }
            }
            OSSafeReleaseNULL(deviceInterfaceIterator);
        }
        
        if (!inPipe || !outPipe) {
            LOG(V_ERROR, "Error opening I/O pipes!");
            OSSafeReleaseNULL(inPipe);
            OSSafeReleaseNULL(outPipe);
            return false;
        }
    } else if (returnCode != kIOReturnExclusiveAccess) {
        LOG(V_ERROR, "The USB device somehow has no valid configurations?!?!");
        return false;
    }
    
    // Retain the device
    usbDevice->retain();
    
    // Kick off input
    inPipe->io(inbuf.mdp, PAGE_SIZE, &inbuf.comp);
    this->handshake();
    
    LOG(V_NOTE, "ODIN Mode device successfully started!");
    return true;
}
示例#25
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;
}
OSSet * IOPartitionScheme::juxtaposeMediaObjects(OSSet * partitionsOld,
                                                 OSSet * partitionsNew)
{
    //
    // Updates a set of existing partitions, represented by partitionsOld,
    // with possible updates from a rescan of the disk, represented by
    // partitionsNew.  It returns a new set of partitions with the results,
    // removing partitions from partitionsOld where applicable, adding
    // partitions from partitionsNew where applicable, and folding in property
    // changes to partitions from partitionsNew into partitionsOld where
    // applicable.
    //

    OSIterator *   iterator    = 0;
    OSIterator *   iterator1   = 0;
    OSIterator *   iterator2   = 0;
    OSSymbol *     key;
    OSSet *        keys        = 0;
    IOMedia *      partition;
    IOMedia *      partition1;
    IOMedia *      partition2;
    OSSet *        partitions  = 0;
    OSOrderedSet * partitions1 = 0;
    OSOrderedSet * partitions2 = 0;
    UInt32         partitionID = 0;
    OSDictionary * properties;

    // Allocate a set to hold the set of media objects representing partitions.

    partitions = OSSet::withCapacity( partitionsNew->getCapacity( ) );
    if ( partitions == 0 ) goto juxtaposeErr;

    // Prepare the reference set of partitions.

    partitions1 = OSOrderedSet::withCapacity( partitionsOld->getCapacity( ), partitionComparison, 0 );
    if ( partitions1 == 0 ) goto juxtaposeErr;

    iterator1 = OSCollectionIterator::withCollection( partitionsOld );
    if ( iterator1 == 0 ) goto juxtaposeErr;

    while ( ( partition1 = ( IOMedia * ) iterator1->getNextObject( ) ) )
    {
        partitionID = max( partitionID, strtoul( partition1->getLocation( ), NULL, 10 ) );

        partitions1->setObject( partition1 );
    }

    iterator1->release( );
    iterator1 = 0;

    // Prepare the comparison set of partitions.

    partitions2 = OSOrderedSet::withCapacity( partitionsNew->getCapacity( ), partitionComparison, 0 );
    if ( partitions2 == 0 ) goto juxtaposeErr;

    iterator2 = OSCollectionIterator::withCollection( partitionsNew );
    if ( iterator2 == 0 ) goto juxtaposeErr;

    while ( ( partition2 = ( IOMedia * ) iterator2->getNextObject( ) ) )
    {
        partitionID = max( partitionID, strtoul( partition2->getLocation( ), NULL, 10 ) );

        partitions2->setObject( partition2 );
    }

    iterator2->release( );
    iterator2 = 0;

    // Juxtapose the partitions.

    iterator1 = OSCollectionIterator::withCollection( partitions1 );
    if ( iterator1 == 0 ) goto juxtaposeErr;

    iterator2 = OSCollectionIterator::withCollection( partitions2 );
    if ( iterator2 == 0 ) goto juxtaposeErr;

    partition1 = ( IOMedia * ) iterator1->getNextObject( );
    partition2 = ( IOMedia * ) iterator2->getNextObject( );

    while ( partition1 || partition2 )
    {
        UInt64 base1;
        UInt64 base2;

        base1 = partition1 ? partition1->getBase( ) : UINT64_MAX;
        base2 = partition2 ? partition2->getBase( ) : UINT64_MAX;

#if TARGET_OS_EMBEDDED
        if ( partition1 && partition2 )
        {
            OSString * uuid1;
            OSString * uuid2;

            uuid1 = OSDynamicCast( OSString, partition1->getProperty( kIOMediaUUIDKey ) );
            uuid2 = OSDynamicCast( OSString, partition2->getProperty( kIOMediaUUIDKey ) );

            if ( uuid1 || uuid2 )
            {
                if ( uuid1 == 0 )
                {
                   base1 = UINT64_MAX;
                }
                else if ( uuid2 == 0 )
                {
                   base2 = UINT64_MAX;
                }
                else
                {
                    int compare;

                    compare = strcmp( uuid1->getCStringNoCopy( ), uuid2->getCStringNoCopy( ) );

                    if ( compare > 0 )
                    {
                        base1 = UINT64_MAX;
                    }
                    else if ( compare < 0 )
                    {
                        base2 = UINT64_MAX;
                    }
                    else
                    {
                        base1 = base2;
                    }
                }
            }
        }
#endif /* TARGET_OS_EMBEDDED */

        if ( base1 > base2 )
        {
            // A partition was added.

            partition2->setProperty( kIOMediaLiveKey, true );

            iterator = OSCollectionIterator::withCollection( partitions1 );
            if ( iterator == 0 ) goto juxtaposeErr;

            while ( ( partition = ( IOMedia * ) iterator->getNextObject( ) ) )
            {
                if ( strcmp( partition->getLocation( ), partition2->getLocation( ) ) == 0 )
                {
                    // Set a location value for this partition.

                    char location[ 12 ];

                    partitionID++;

                    snprintf( location, sizeof( location ), "%d", ( int ) partitionID );

                    partition2->setLocation( location );

                    partition2->setProperty( kIOMediaLiveKey, false );

                    break;
                }
            }

            iterator->release( );
            iterator = 0;

            if ( partition2->attach( this ) )
            {
                attachMediaObjectToDeviceTree( partition2 );

                partition2->registerService( kIOServiceAsynchronous );
            }

            partitions->setObject( partition2 );

            partition2 = ( IOMedia * ) iterator2->getNextObject( );
        }
        else if ( base1 < base2 )
        {
            // A partition was removed.

            partition1->setProperty( kIOMediaLiveKey, false );

            if ( handleIsOpen( partition1 ) == false )
            {
                partition1->terminate( kIOServiceSynchronous );

                detachMediaObjectFromDeviceTree( partition1 );
            }
            else
            {
                partition1->removeProperty( kIOMediaPartitionIDKey );

                partitions->setObject( partition1 );
            }

            partition1 = ( IOMedia * ) iterator1->getNextObject( );
        }
        else
        {
            // A partition was matched.

            bool edit;
            bool move;

            edit = false;
            move = false;

            keys = OSSet::withCapacity( 1 );
            if ( keys == 0 ) goto juxtaposeErr;

            properties = partition2->getPropertyTable( );

            // Determine which properties were updated.

            if ( partition1->getBase( )               != partition2->getBase( )               ||
                 partition1->getSize( )               != partition2->getSize( )               ||
                 partition1->getPreferredBlockSize( ) != partition2->getPreferredBlockSize( ) ||
                 partition1->getAttributes( )         != partition2->getAttributes( )         ||
                 partition1->isWhole( )               != partition2->isWhole( )               ||
                 partition1->isWritable( )            != partition2->isWritable( )            ||
                 strcmp( partition1->getContentHint( ), partition2->getContentHint( ) )       )
            {
                edit = true;
            }

            if ( strcmp( partition1->getName( ),     partition2->getName( )     ) ||
                 strcmp( partition1->getLocation( ), partition2->getLocation( ) ) )
            {
                move = true;
            }

            iterator = OSCollectionIterator::withCollection( properties );
            if ( iterator == 0 ) goto juxtaposeErr;

            while ( ( key = ( OSSymbol * ) iterator->getNextObject( ) ) )
            {
                OSObject * value1;
                OSObject * value2;

                if ( key->isEqualTo( kIOMediaContentHintKey        ) ||
                     key->isEqualTo( kIOMediaEjectableKey          ) ||
                     key->isEqualTo( kIOMediaPreferredBlockSizeKey ) ||
                     key->isEqualTo( kIOMediaRemovableKey          ) ||
                     key->isEqualTo( kIOMediaSizeKey               ) ||
                     key->isEqualTo( kIOMediaWholeKey              ) ||
                     key->isEqualTo( kIOMediaWritableKey           ) )
                {
                    continue;
                }

                if ( key->isEqualTo( kIOMediaContentKey ) ||
                     key->isEqualTo( kIOMediaLeafKey    ) ||
                     key->isEqualTo( kIOMediaLiveKey    ) ||
                     key->isEqualTo( kIOMediaOpenKey    ) )
                {
                    continue;
                }

                value1 = partition1->getProperty( key );
                value2 = partition2->getProperty( key );

                if ( value1 == 0 || value1->isEqualTo( value2 ) == false )
                {
                    keys->setObject( key );
                }
            }

            iterator->release( );
            iterator = 0;

            // A partition was updated.

            partition1->setProperty( kIOMediaLiveKey, ( move == false ) );

            if ( edit )
            {
                partition1->init( partition2->getBase( ),
                                  partition2->getSize( ),
                                  partition2->getPreferredBlockSize( ),
                                  partition2->getAttributes( ),
                                  partition2->isWhole( ),
                                  partition2->isWritable( ),
                                  partition2->getContentHint( ) );
            }

            if ( keys->getCount( ) )
            {
                iterator = OSCollectionIterator::withCollection( keys );
                if ( iterator == 0 ) goto juxtaposeErr;

                while ( ( key = ( OSSymbol * ) iterator->getNextObject( ) ) )
                {
                    partition1->setProperty( key, partition2->getProperty( key ) );
                }

                iterator->release( );
                iterator = 0;
            }

            if ( edit || keys->getCount( ) )
            {
                partition1->messageClients( kIOMessageServicePropertyChange );

                partition1->registerService( kIOServiceAsynchronous );
            }

            keys->release( );
            keys = 0;

            partitions->setObject( partition1 );

            partition1 = ( IOMedia * ) iterator1->getNextObject( );
            partition2 = ( IOMedia * ) iterator2->getNextObject( );
        }
    }

    // Release our resources.

    iterator1->release( );
    iterator2->release( );
    partitions1->release( );
    partitions2->release( );

    return partitions;

juxtaposeErr:

    // Release our resources.

    if ( iterator    ) iterator->release( );
    if ( iterator1   ) iterator1->release( );
    if ( iterator2   ) iterator2->release( );
    if ( keys        ) keys->release( );
    if ( partitions  ) partitions->release( );
    if ( partitions1 ) partitions1->release( );
    if ( partitions2 ) partitions2->release( );

    return 0;
}
示例#27
0
bool ACPIMonitor::start(IOService * provider)
{
    if (!super::start(provider))
        return false;

    acpiDevice = (IOACPIPlatformDevice *)provider;

    char key[5];

    //Here is Fan in ACPI
    OSArray* fanNames = OSDynamicCast(OSArray, getProperty("FanNames"));

    for (int i=0; i<10; i++)
    {
        snprintf(key, 5, "FAN%X", i);

        if (kIOReturnSuccess == acpiDevice->validateObject(key)) {
            OSString* name = NULL;

            if (fanNames )
                name = OSDynamicCast(OSString, fanNames->getObject(i));

            if (!addTachometer(key, name ? name->getCStringNoCopy() : 0))
                WarningLog("Can't add tachometer sensor, key %s", key);
        }
        else {
            snprintf(key, 5, "FTN%X", i);
            if (kIOReturnSuccess == acpiDevice->validateObject(key)) {
                OSString* name = NULL;

                if (fanNames )
                    name = OSDynamicCast(OSString, fanNames->getObject(i));

                if (!addTachometer(key, name ? name->getCStringNoCopy() : 0))
                    WarningLog("Can't add tachometer sensor, key %s", key);
            }
            else
                break;
        }
    }

    //Next step - temperature keys
    if (kIOReturnSuccess == acpiDevice->validateObject("TCPU"))
        addSensor("TCPU", KEY_CPU_HEATSINK_TEMPERATURE, TYPE_SP78, 2);

    if (kIOReturnSuccess == acpiDevice->validateObject("TSYS"))
        addSensor("TSYS", KEY_NORTHBRIDGE_TEMPERATURE, TYPE_SP78, 2);

    if (kIOReturnSuccess == acpiDevice->validateObject("TDIM"))
        addSensor("TDIM", KEY_DIMM_TEMPERATURE, TYPE_SP78, 2);

    if (kIOReturnSuccess == acpiDevice->validateObject("TAMB"))
        addSensor("TAMB", KEY_AMBIENT_TEMPERATURE, TYPE_SP78, 2);

    if (kIOReturnSuccess == acpiDevice->validateObject("TCPP"))
        addSensor("TCPP", KEY_CPU_PROXIMITY_TEMPERATURE, TYPE_SP78, 2);
    // We should add also GPU reading stuff for those who has no supported plug in but have the value on EC registers



    //Voltage
    if (kIOReturnSuccess == acpiDevice->validateObject("VCPU"))
        addSensor("VSN0", KEY_CPU_VOLTAGE, TYPE_FP2E, 2);

    if (kIOReturnSuccess == acpiDevice->validateObject("VMEM"))
        addSensor("VSN0", KEY_MEMORY_VOLTAGE, TYPE_FP2E, 2);

    if (kIOReturnSuccess == acpiDevice->validateObject("VSN1"))
        addSensor("VSN1", "Vp0C", TYPE_FP2E, 2);

    if (kIOReturnSuccess == acpiDevice->validateObject("VSN2"))
        addSensor("VSN2", "Vp1C", TYPE_FP2E, 2);

    if (kIOReturnSuccess == acpiDevice->validateObject("VSN3"))
        addSensor("VSN3", "Vp2C", TYPE_FP2E, 2);

    //Amperage
    if (kIOReturnSuccess == acpiDevice->validateObject("ISN0"))
        addSensor("ISN0", "ICAC", TYPE_UI16, 2);

    if (kIOReturnSuccess == acpiDevice->validateObject("ISN1"))
        addSensor("ISN1", "Ip0C", TYPE_UI16, 2);

    if (kIOReturnSuccess == acpiDevice->validateObject("ISN2"))
        addSensor("ISN2", "Ip1C", TYPE_UI16, 2);

    if (kIOReturnSuccess == acpiDevice->validateObject("ISN3"))
        addSensor("ISN3", "Ip2C", TYPE_UI16, 2);

    //Power
    if (kIOReturnSuccess == acpiDevice->validateObject("PSN0"))
        addSensor("PSN0", "PC0C", TYPE_UI16, 2);

    if (kIOReturnSuccess == acpiDevice->validateObject("PSN1"))
        addSensor("PSN1", "PC1C", TYPE_UI16, 2);

    // AC Power/Battery
    if (kIOReturnSuccess == acpiDevice->validateObject("ACDC")) // Power Source Read AC/Battery
    {
        addSensor("ACDC", "ACEN", TYPE_UI8, 1);
        addSensor("ACDC", "ACFP", TYPE_FLAG, 1);
        addSensor("ACDC", "ACIN", TYPE_FLAG, 1);
    }
    // TODO real SMC returns ACID only when AC is plugged, if not is zeroed, so hardcoding it in plist is not OK IMHO
    // Same goes for ACIC, but no idea how we can get the AC current value..

    // Here if ACDC returns 0 we need to set the on battery BATP flag

    // Battery stuff, need to implement rest of the keys once i figure those
    if (kIOReturnSuccess == acpiDevice->validateObject("BAK0")) // Battery 0 Current
        addSensor("BAK0", "B0AC", TYPE_SI16, 2);

    if (kIOReturnSuccess == acpiDevice->validateObject("BAK1")) // Battery 0 Voltage
        addSensor("BAK1", "B0AV", TYPE_UI16, 2);

    //Keys from info.plist
    OSString *tmpString = 0;
    OSData   *tmpObj = 0;

//	UInt32 tmpUI32;
//	char tmpCString[7];
    char acpiName[5];
    char aKey[5];

    OSIterator *iter = 0;
    const OSSymbol *dictKey = 0;
    OSDictionary *keysToAdd = 0;

    keysToAdd = OSDynamicCast(OSDictionary, getProperty("keysToAdd"));
    if (keysToAdd) {
        iter = OSCollectionIterator::withCollection(keysToAdd);
        if (iter) {
            while ((dictKey = (const OSSymbol *)iter->getNextObject())) {
                tmpObj = 0;
                snprintf(acpiName, 5, "%s", dictKey->getCStringNoCopy());
                //WarningLog(" Found key %s", acpiName);
                tmpString = OSDynamicCast(OSString, keysToAdd->getObject(dictKey));
                if (tmpString) {
                    snprintf(aKey, 5, "%s", tmpString->getCStringNoCopy());
                    InfoLog("Custom name=%s key=%s", acpiName, aKey);
                    if (kIOReturnSuccess == acpiDevice->validateObject(acpiName)) {
                        if (aKey[0] == 'F') {
                            if (!addTachometer(aKey, acpiName))
                                WarningLog("Can't add tachometer sensor, key %s", aKey);

                        } else {
                            addSensor(acpiName, aKey, TYPE_UI16, 2);
                        }
                    }
                }
                else {
                    WarningLog(" no value for key %s", acpiName);
                }

            }

            iter->release();
        } else {
            WarningLog(" can't interate keysToAdd");
        }

    } else {
        WarningLog(" keysToAdd not found");
    }

    registerService(0);

    return true;
}
示例#28
0
void FileNVRAM::copyEntryProperties(const char* prefix, IORegistryEntry* entry)
{
	IORegistryEntry* child;
	OSDictionary* properties;
	OSCollectionIterator *iter;

	if (entry)
	{
		// Parse all IORegistery Children
		OSIterator * iterator = entry->getChildIterator(gIODTPlane);

		if (iterator)
		{
			while((child = OSDynamicCast(IORegistryEntry, iterator->getNextObject())) != NULL)
			{
				const char* name = child->getName();

				if (prefix)
				{
					size_t size = strlen(prefix) + sizeof(NVRAM_SEPERATOR) + strlen(name);
					char* newPrefix = (char*)IOMalloc(size);

					snprintf(newPrefix, size, "%s%s%s", prefix, NVRAM_SEPERATOR, name);
					copyEntryProperties(newPrefix, child);

					IOFree(newPrefix, size);
				}
				else
				{
					copyEntryProperties(name, child);
				}
			}

			iterator->release();
		}

		// Parse entry properties and add them to our self
		properties = entry->dictionaryWithProperties();

		bool                 result = true;
		OSObject             *object;
		const OSSymbol       *key;

		iter = OSCollectionIterator::withCollection(properties);

		if (iter == 0)
		{
			return;
		}
	
		while (result)
		{

			key = OSDynamicCast(OSSymbol, iter->getNextObject());

			if (key == 0)
			{
				break;
			}
			
			if (key->isEqualTo("name"))
			{
				continue; // Special property in IORegistery, ignore
			}
			
			object = properties->getObject(key);

			if (object == 0)
			{
				continue;
			}
			
			if (prefix)
			{
				size_t size = strlen(prefix) + sizeof(NVRAM_SEPERATOR) + strlen(key->getCStringNoCopy());
				char* newKey = (char*)IOMalloc(size);

				snprintf(newKey, size, "%s%s%s", prefix, NVRAM_SEPERATOR, key->getCStringNoCopy());

				setProperty(OSSymbol::withCString(newKey), object);

				IOFree(newKey, size);
			}
			else
			{
				setProperty(key, object);
			}
		}

		iter->release();
	}
}