Exemple #1
0
/* static */
void
OSMetaClass::printInstanceCounts()
{
    OSCollectionIterator * classes;
    OSSymbol             * className;
    OSMetaClass          * meta;

    IOLockLock(sAllClassesLock);
    classes = OSCollectionIterator::withCollection(sAllClassesDict);
    assert(classes);

    while( (className = (OSSymbol *)classes->getNextObject())) {
        meta = (OSMetaClass *)sAllClassesDict->getObject(className);
        assert(meta);

        printf("%24s count: %03d x 0x%03x = 0x%06x\n",
            className->getCStringNoCopy(),
            meta->getInstanceCount(),
            meta->getClassSize(),
            meta->getInstanceCount() * meta->getClassSize() );
    }
    printf("\n");
    classes->release();
    IOLockUnlock(sAllClassesLock);
    return;
}
Exemple #2
0
void
IOCatalogue::ping(thread_call_param_t arg, thread_call_param_t)
{
    IOCatalogue 	 * self = (IOCatalogue *) arg;
    OSOrderedSet         * set;
    OSDictionary         * table;
    int	                   newLimit;

    set = OSOrderedSet::withCapacity( 1 );

    IOLockLock( &self->lock );

    for( newLimit = 0; newLimit < kDriversPerIter; newLimit++) {
        table = (OSDictionary *) self->array->getObject(
                    hackLimit + newLimit );
        if( table) {
            set->setLastObject( table );

            OSSymbol * sym = (OSSymbol *) table->getObject(gIOClassKey);
            kprintf("enabling %s\n", sym->getCStringNoCopy());

        } else {
            newLimit--;
            break;
        }
    }

    IOService::catalogNewDrivers( set );

    hackLimit += newLimit;
    self->generation++;

    IOLockUnlock( &self->lock );

    if( kDriversPerIter == newLimit) {
        AbsoluteTime deadline;
        clock_interval_to_deadline(500, kMillisecondScale);
        thread_call_func_delayed(ping, this, deadline);
    }
}
Exemple #3
0
OSObject *
OSUnserializeBinary(const char *buffer, size_t bufferSize, OSString **errorString)
{
	OSObject ** objsArray;
	uint32_t    objsCapacity;
	enum      { objsCapacityMax = 16*1024*1024 };
	uint32_t    objsIdx;

	OSObject ** stackArray;
	uint32_t    stackCapacity;
	enum      { stackCapacityMax = 64 };
	uint32_t    stackIdx;

    OSObject     * result;
    OSObject     * parent;
    OSDictionary * dict;
    OSArray      * array;
    OSSet        * set;
    OSDictionary * newDict;
    OSArray      * newArray;
    OSSet        * newSet;
    OSObject     * o;
    OSSymbol     * sym;
    OSString     * str;

    size_t           bufferPos;
    const uint32_t * next;
    uint32_t         key, len, wordLen;
    bool             end, newCollect, isRef;
    unsigned long long value;
    bool ok;

	if (errorString) *errorString = 0;
	if (bufferSize < sizeof(kOSSerializeBinarySignature)) return (NULL);
	if (0 != strcmp(kOSSerializeBinarySignature, buffer)) return (NULL);
	if (3 & ((uintptr_t) buffer)) return (NULL);
	bufferPos = sizeof(kOSSerializeBinarySignature);
	next = (typeof(next)) (((uintptr_t) buffer) + bufferPos);

	DEBG("---------OSUnserializeBinary(%p)\n", buffer);

	objsArray = stackArray    = NULL;
	objsIdx   = objsCapacity  = 0;
	stackIdx  = stackCapacity = 0;

    result   = 0;
    parent   = 0;
	dict     = 0;
	array    = 0;
	set      = 0;
	sym      = 0;

	ok = true;
	while (ok)
	{
		bufferPos += sizeof(*next);
		if (!(ok = (bufferPos <= bufferSize))) break;
		key = *next++;

        len = (key & kOSSerializeDataMask);
        wordLen = (len + 3) >> 2;
		end = (0 != (kOSSerializeEndCollecton & key));
        DEBG("key 0x%08x: 0x%04x, %d\n", key, len, end);

        newCollect = isRef = false;
		o = 0; newDict = 0; newArray = 0; newSet = 0;
		
		switch (kOSSerializeTypeMask & key)
		{
		    case kOSSerializeDictionary:
				o = newDict = OSDictionary::withCapacity(len);
				newCollect = (len != 0);
		        break;
		    case kOSSerializeArray:
				o = newArray = OSArray::withCapacity(len);
				newCollect = (len != 0);
		        break;
		    case kOSSerializeSet:
				o = newSet = OSSet::withCapacity(len);
				newCollect = (len != 0);
		        break;

		    case kOSSerializeObject:
				if (len >= objsIdx) break;
				o = objsArray[len];
				isRef = true;
				break;

		    case kOSSerializeNumber:
				bufferPos += sizeof(long long);
				if (bufferPos > bufferSize) break;
		        if ((len != 32) && (len != 64) && (len != 16) && (len != 8)) break;
		    	value = next[1];
		    	value <<= 32;
		    	value |= next[0];
		    	o = OSNumber::withNumber(value, len);
		    	next += 2;
		        break;

		    case kOSSerializeSymbol:
				bufferPos += (wordLen * sizeof(uint32_t));
				if (bufferPos > bufferSize)           break;
				if (len < 2)                          break;
				if (0 != ((const char *)next)[len-1]) break;
		        o = (OSObject *) OSSymbol::withCString((const char *) next);
		        next += wordLen;
		        break;

		    case kOSSerializeString:
				bufferPos += (wordLen * sizeof(uint32_t));
				if (bufferPos > bufferSize) break;
		        o = OSString::withStringOfLength((const char *) next, len);
		        next += wordLen;
		        break;

    	    case kOSSerializeData:
				bufferPos += (wordLen * sizeof(uint32_t));
				if (bufferPos > bufferSize) break;
		        o = OSData::withBytes(next, len);
		        next += wordLen;
		        break;

    	    case kOSSerializeBoolean:
				o = (len ? kOSBooleanTrue : kOSBooleanFalse);
		        break;

		    default:
		        break;
		}

		if (!(ok = (o != 0))) break;

		if (!isRef)
		{
			setAtIndex(objs, objsIdx, o);
			if (!ok)
			{
			    o->release();
                break;
            }
			objsIdx++;
		}

		if (dict)
		{
			if (!sym) sym = (OSSymbol *) o;
			else
			{
                str = sym;
				sym = OSDynamicCast(OSSymbol, sym);
				if (!sym && (str = OSDynamicCast(OSString, str)))
				{
				    sym = const_cast<OSSymbol *>(OSSymbol::withString(str));
                    ok = (sym != 0);
                    if (!ok) break;
				}
				DEBG("%s = %s\n", sym->getCStringNoCopy(), o->getMetaClass()->getClassName());
				if (o != dict) ok = dict->setObject(sym, o);
                if (sym && (sym != str)) sym->release();
				sym = 0;
			}
		}
		else if (array)  ok = array->setObject(o);
		else if (set)    ok = set->setObject(o);
		else if (result) ok = false;
		else
		{
		    assert(!parent);
		    result = o;
		}

		if (!ok) break;

        if (end) parent = 0;
		if (newCollect)
		{
            stackIdx++;
            setAtIndex(stack, stackIdx, parent);
            if (!ok) break;
			DEBG("++stack[%d] %p\n", stackIdx, parent);
			parent = o;
			dict   = newDict;
			array  = newArray;
			set    = newSet;
			end    = false;
		}

		if (end)
		{
            while (stackIdx)
            {
                parent = stackArray[stackIdx];
                DEBG("--stack[%d] %p\n", stackIdx, parent);
                stackIdx--;
                if (parent) break;
            }
            if (!parent) break;
			set   = 0;
			dict  = 0; 
			array = 0;
			if (!(dict = OSDynamicCast(OSDictionary, parent)))
			{
				if (!(array = OSDynamicCast(OSArray, parent))) ok = (0 != (set = OSDynamicCast(OSSet, parent)));
			}
		}
	}
	DEBG("ret %p\n", result);

	if (!ok) result = 0;

	if (objsCapacity)
	{
        for (len = (result != 0); len < objsIdx; len++) objsArray[len]->release();
	    kfree(objsArray,  objsCapacity  * sizeof(*objsArray));
    }
	if (stackCapacity) kfree(stackArray, stackCapacity * sizeof(*stackArray));

	return (result);
}
Exemple #4
0
bool OSSerialize::binarySerialize(const OSMetaClassBase *o)
{
    OSDictionary * dict;
    OSArray      * array;
    OSSet        * set;
    OSNumber     * num;
    OSSymbol     * sym;
    OSString     * str;
    OSData       * ldata;
    OSBoolean    * boo;

	unsigned int  tagIdx;
    uint32_t   i, key;
    size_t     len;
    bool       ok;

	tagIdx = tags->getNextIndexOfObject(o, 0);
	// does it exist?
	if (-1U != tagIdx)
	{
		key = (kOSSerializeObject | tagIdx);
		if (endCollection)
		{
			 endCollection = false;
			 key |= kOSSerializeEndCollecton;
		}
		ok = addBinary(&key, sizeof(key));
		return (ok);
	}

	if ((dict = OSDynamicCast(OSDictionary, o)))
	{
		key = (kOSSerializeDictionary | dict->count);
		ok = addBinaryObject(o, key, NULL, 0);
		for (i = 0; ok && (i < dict->count);)
		{
			const OSSymbol        * dictKey;
			const OSMetaClassBase * dictValue;
			const OSMetaClassBase * nvalue = 0;

			dictKey = dict->dictionary[i].key;
			dictValue = dict->dictionary[i].value;
			i++;
			if (editor)
			{
				dictValue = nvalue = (*editor)(editRef, this, dict, dictKey, dictValue);
				if (!dictValue) dictValue = dict;
			}
			ok = binarySerialize(dictKey);
			if (!ok) break;
			endCollection = (i == dict->count);
			ok = binarySerialize(dictValue);
			if (!ok) ok = dictValue->serialize(this);
			if (nvalue) nvalue->release();
//			if (!ok) ok = binarySerialize(kOSBooleanFalse);
		}			
	}
	else if ((array = OSDynamicCast(OSArray, o)))
	{
		key = (kOSSerializeArray | array->count);
		ok = addBinaryObject(o, key, NULL, 0);
		for (i = 0; ok && (i < array->count);)
		{
			i++;
			endCollection = (i == array->count);
			ok = binarySerialize(array->array[i-1]);
			if (!ok) ok = array->array[i-1]->serialize(this);
//			if (!ok) ok = binarySerialize(kOSBooleanFalse);
		}			
	}
	else if ((set = OSDynamicCast(OSSet, o)))
	{
		key = (kOSSerializeSet | set->members->count);
		ok = addBinaryObject(o, key, NULL, 0);
		for (i = 0; ok && (i < set->members->count);)
		{
			i++;
			endCollection = (i == set->members->count);
			ok = binarySerialize(set->members->array[i-1]);
			if (!ok) ok = set->members->array[i-1]->serialize(this);
//			if (!ok) ok = binarySerialize(kOSBooleanFalse);
		}			
	}
	else if ((num = OSDynamicCast(OSNumber, o)))
	{
		key = (kOSSerializeNumber | num->size);
		ok = addBinaryObject(o, key, &num->value, sizeof(num->value));
	}
	else if ((boo = OSDynamicCast(OSBoolean, o)))
	{
		key = (kOSSerializeBoolean | (kOSBooleanTrue == boo));
		ok = addBinaryObject(o, key, NULL, 0);
	}
	else if ((sym = OSDynamicCast(OSSymbol, o)))
	{
		len = (sym->getLength() + 1);
		key = (kOSSerializeSymbol | len);
		ok = addBinaryObject(o, key, sym->getCStringNoCopy(), len);
	}
	else if ((str = OSDynamicCast(OSString, o)))
	{
		len = (str->getLength() + 0);
		key = (kOSSerializeString | len);
		ok = addBinaryObject(o, key, str->getCStringNoCopy(), len);
	}
	else if ((ldata = OSDynamicCast(OSData, o)))
	{
		len = ldata->getLength();
		if (ldata->reserved && ldata->reserved->disableSerialization) len = 0;
		key = (kOSSerializeData | len);
		ok = addBinaryObject(o, key, ldata->getBytesNoCopy(), len);
	}
	else return (false);

    return (ok);
}
//================================================================================================
//
//  MergeDictionaryIntoDictionary( parentSourceDictionary, parentTargetDictionary)
//
//  This routine will merge the contents of parentSourceDictionary into the parentTargetDictionary, recursively.
//  Note that we are only modifying copies of the parentTargetDictionary, so we don't expect anybody
//  else to be accessing them at the same time.
//
//================================================================================================
//
bool
IOUSBUserClientInit::MergeDictionaryIntoDictionary(OSDictionary * parentSourceDictionary,  OSDictionary * parentTargetDictionary)
{
    OSCollectionIterator*	srcIterator = NULL;
    OSSymbol*			keyObject = NULL ;
    OSObject*			targetObject = NULL ;
    bool			result = false;

    USBLog(6,"+%s[%p]::MergeDictionaryIntoDictionary(%p => %p)", getName(), this, parentSourceDictionary, parentTargetDictionary);

    if (!parentSourceDictionary || !parentTargetDictionary)
        return false ;

    // Get our source dictionary
    //
    srcIterator = OSCollectionIterator::withCollection(parentSourceDictionary) ;

    while (NULL != (keyObject = OSDynamicCast(OSSymbol, srcIterator->getNextObject())))
    {
        const char *	str;
        OSDictionary *	childSourceDictionary = NULL;
        OSDictionary *	childTargetDictionary = NULL;
        OSObject *	childTargetObject = NULL;

        // Get the symbol name for debugging
        //
        str = keyObject->getCStringNoCopy();
        USBLog(6,"%s[%p]::MergeDictionaryIntoDictionary  merging \"%s\"", getName(), this, str);

        // Check to see if our destination already has the same entry.
        //
        childTargetObject = parentTargetDictionary->getObject(keyObject);
        if ( childTargetObject )
        {
            childTargetDictionary = OSDynamicCast(OSDictionary, childTargetObject);
            if ( childTargetDictionary )
			{
                USBLog(6,"%s[%p]::MergeDictionaryIntoDictionary  target object %s is a dictionary (%p)", getName(), this, str, childTargetDictionary);
			}
        }

        // See if our source entry is also a dictionary
        //
        childSourceDictionary = OSDynamicCast(OSDictionary, parentSourceDictionary->getObject(keyObject));
        if ( childSourceDictionary )
        {
            USBLog(6,"%s[%p]::MergeDictionaryIntoDictionary  source dictionary had %s as a dictionary (%p)", getName(), this, str, childSourceDictionary);
        }

        if ( childTargetDictionary && childSourceDictionary)
        {
            // Our destination dictionary already has the entry for this same object AND our
            // source is also a dcitionary, so we need to recursively add it.
            //
            USBLog(6,"%s[%p]::MergeDictionaryIntoDictionary  recursing(%p,%p)", getName(), this, childSourceDictionary, childTargetDictionary);
            result = MergeDictionaryIntoDictionary(childSourceDictionary, childTargetDictionary) ;
            if ( !result )
            {
                USBLog(6,"%s[%p]::MergeDictionaryIntoDictionary  recursing (%p,%p) failed", getName(), this, childSourceDictionary, childTargetDictionary);
                break;
            }
        }
        else
        {
            // We have a property that we need to merge into our parent dictionary.
            //
            USBLog(6,"%s[%p]::MergeDictionaryIntoDictionary  setting object %s into dictionary %p", getName(), this, str, parentTargetDictionary);
            result = parentTargetDictionary->setObject(keyObject, parentSourceDictionary->getObject(keyObject)) ;
            if ( !result )
            {
                USBLog(6,"%s[%p]::MergeDictionaryIntoDictionary  setObject %s, returned false", getName(), this, str);
                break;
            }
        }

    }

    srcIterator->release();

    USBLog(6,"-%s[%p]::MergeDictionaryIntoDictionary(%p=>(%p)  result %d", getName(), this, parentSourceDictionary, parentTargetDictionary, result);
    return result;
}
Exemple #6
0
void FileNVRAM::doSync(void)
{
	LOG(NOTICE, "doSync() called\n");

	/* if (!mFilePath)
	{
		return;
	} */

	if (!mSafeToSync)
	{
		return;
	}
	
	LOG(NOTICE, "doSync() running\n");

	//create the output Dictionary
	OSDictionary * outputDict = OSDictionary::withCapacity(1);

	//going to have to spin over ourselves..
	OSDictionary * inputDict = dictionaryWithProperties();
	OSCollectionIterator *iter = OSCollectionIterator::withCollection(inputDict);

	if (iter == 0)
	{
		LOG(ERROR, "FAILURE!. No iterator on input dictionary (myself)\n");
		return;
	}

	OSSymbol * key = NULL;
	OSObject * value = NULL;

	while ((key = OSDynamicCast(OSSymbol,iter->getNextObject())))
	{
		//just get the value now anyway
		value = inputDict->getObject(key);

		//if the key conmektains :, look to see if it's in the map already, cause we'll add a child pair to it
		//otherwise we just slam the key/val pair in

		const char * keyChar = key->getCStringNoCopy();
		const char * guidValueStr = NULL;

		if (( guidValueStr = strstr(keyChar , NVRAM_SEPERATOR)) != NULL)
		{
			//we have a GUID child to deal with
			//now substring out the GUID cause thats going to be a DICT itself on the new outputDict
			//guidValueStr points to the :
			size_t guidCutOff = guidValueStr - keyChar;

			//allocate buffer
			//we ar ereally accounting for + sizeof('\0')
			//thats always 1. so 1.
			char guidStr[guidCutOff+1];
			strlcpy(guidStr, keyChar, guidCutOff+1);

			//in theory we have a guid and a value
			//LOG("sync() -> Located GUIDStr as %s\n",guidStr);

			//check for ?OSDictionary? from the dictionary
			OSDictionary * guidDict = OSDynamicCast(OSDictionary, outputDict->getObject(guidStr));

			if (!guidDict)
			{
				guidDict = OSDictionary::withCapacity(1);
				outputDict->setObject(guidStr,guidDict);
			}

			//now we have a dict for the guid no matter what (mapping GUID | DICT)
			guidDict->setObject(OSString::withCString(guidValueStr+strlen(NVRAM_SEPERATOR)), value);
		}
		else
		{
			//we are boring.
			outputDict->setObject(key,value);
		}
	}//end while

	//serialize and write this out
	OSSerialize *s = OSSerialize::withCapacity(10000);
	s->addString(NVRAM_FILE_HEADER);
	outputDict->serialize(s);
	s->addString(NVRAM_FILE_FOOTER);

	int error = write_buffer(s->text(), mCtx);

	if (error)
	{
		LOG(ERROR, "Unable to write to %s, errno %d\n", mFilePath->getCStringNoCopy(), error);
	}

	//now free the dictionaries && iter
	iter->release();
	outputDict->release();
	s->release();

}
Exemple #7
0
bool
ZFSDatasetProxy::start(IOService *provider)
{
	OSObject *property = NULL, *size = NULL;
	OSString *nameString = NULL;
	OSNumber *sizeNum = NULL;
	OSDictionary *deviceDict = NULL, *protocolDict = NULL;
	const OSSymbol *virtualSymbol = NULL, *internalSymbol = NULL;
	const char *cstr = NULL;
	char *pstring = NULL;
	int plen = 0;
	bool started = false;

	size = copyProperty(kZFSPoolSizeKey, gIOServicePlane,
	    (kIORegistryIterateRecursively|kIORegistryIterateParents));
	property = copyProperty(kZFSPoolNameKey, gIOServicePlane,
	    (kIORegistryIterateRecursively|kIORegistryIterateParents));

	if (!size || !property) {
		dprintf("couldn't get pool name or size");
		goto error;
	}

	nameString = OSDynamicCast(OSString, property);
	if (!nameString) {
		dprintf("missing pool name");
		goto error;
	}
#if 0
	/* Try hard to get the name string */
	do {
		nameString = OSDynamicCast(OSString, property);

		if (nameString) nameString->retain();

		if (!nameString) {
			OSSymbol *nameSymbol;
		       	nameSymbol = OSDynamicCast(OSSymbol, property);
			if (!nameSymbol) {
				dprintf("couldn't get name");
				goto error;
			}
			nameString = OSString::withCString(
			    nameSymbol->getCStringNoCopy());
		}
	} while (0);
#endif

	sizeNum = OSDynamicCast(OSNumber, size);
	if (!sizeNum) {
		dprintf("invalid size");
		goto error;
	}
	_pool_bcount = sizeNum->unsigned64BitValue() / DEV_BSIZE;
	sizeNum = 0;
	size->release();
	size = 0;

	cstr = nameString->getCStringNoCopy();
	if (!cstr || (plen = strlen(cstr) + 1) == 1) {
		goto error;
	}
	pstring = (char *)IOMalloc(plen);
	if (!pstring) {
		goto error;
	}
	snprintf(pstring, plen, "%s", cstr);
	productString = pstring;
	pstring = 0;

	if (IOBlockStorageDevice::start(provider) == false) {
		dprintf("BlockStorageDevice start failed");
		goto error;
	}
	started = true;

	deviceDict = OSDynamicCast(OSDictionary,
	    getProperty(kIOPropertyDeviceCharacteristicsKey));
	if (deviceDict) {
		/* Clone a new dictionary */
		deviceDict = OSDictionary::withDictionary(deviceDict);
		if (!deviceDict) {
			dprintf("dict clone failed");
			goto error;
		}
	}

	if (!deviceDict) {
		dprintf("creating new device dict");
		deviceDict = OSDictionary::withCapacity(1);
	}

	if (!deviceDict) {
		dprintf("missing device dict");
		goto error;
	}

	deviceDict->setObject(kIOPropertyProductNameKey, nameString);
	OSSafeReleaseNULL(nameString);

	if (setProperty(kIOPropertyDeviceCharacteristicsKey,
	    deviceDict) == false) {
		dprintf("device dict setProperty failed");
		goto error;
	}
	OSSafeReleaseNULL(deviceDict);

	protocolDict = OSDynamicCast(OSDictionary,
	    getProperty(kIOPropertyProtocolCharacteristicsKey));
	if (protocolDict) {
		/* Clone a new dictionary */
		protocolDict = OSDictionary::withDictionary(protocolDict);
		if (!protocolDict) {
			dprintf("dict clone failed");
			goto error;
		}
	}

	if (!protocolDict) {
		dprintf("creating new protocol dict");
		protocolDict = OSDictionary::withCapacity(1);
	}

	if (!protocolDict) {
		dprintf("missing protocol dict");
		goto error;
	}

	virtualSymbol = OSSymbol::withCString(
	    kIOPropertyPhysicalInterconnectTypeVirtual);
	internalSymbol = OSSymbol::withCString(
	    kIOPropertyInternalKey);
	if (!virtualSymbol || !internalSymbol) {
		dprintf("symbol alloc failed");
		goto error;
	}

	protocolDict->setObject(kIOPropertyPhysicalInterconnectTypeKey,
	    virtualSymbol);
	protocolDict->setObject(kIOPropertyPhysicalInterconnectLocationKey,
	    internalSymbol);

	OSSafeReleaseNULL(virtualSymbol);
	OSSafeReleaseNULL(internalSymbol);

	if (setProperty(kIOPropertyProtocolCharacteristicsKey,
	    protocolDict) == false) {
		dprintf("protocol dict setProperty failed");
		goto error;
	}
	OSSafeReleaseNULL(protocolDict);
	registerService(kIOServiceAsynchronous);

	return (true);

error:
	OSSafeReleaseNULL(size);
	OSSafeReleaseNULL(property);
	OSSafeReleaseNULL(deviceDict);
	OSSafeReleaseNULL(protocolDict);
	OSSafeReleaseNULL(nameString);
	OSSafeReleaseNULL(virtualSymbol);
	OSSafeReleaseNULL(internalSymbol);
	if (pstring) IOFree(pstring, plen);
	if (started) IOBlockStorageDevice::stop(provider);
	return (false);
}
static void _OSMetaClassConsiderUnloads(thread_call_param_t p0,
                                        thread_call_param_t p1)
{
    OSSet *kmodClasses;
    OSSymbol *kmodName;
    OSCollectionIterator *kmods;
    OSCollectionIterator *classes;
    OSMetaClass *checkClass;
    kmod_info_t *ki = 0;
    kern_return_t ret;
    bool didUnload;

    mutex_lock(loadLock);

    do {

	kmods = OSCollectionIterator::withCollection(sKModClassesDict);
	if (!kmods)
	    break;

        didUnload = false;
        while ( (kmodName = (OSSymbol *) kmods->getNextObject()) ) {

            if (ki) {
                kfree((vm_offset_t) ki, sizeof(kmod_info_t));
                ki = 0;
            }

            ki = kmod_lookupbyname_locked((char *)kmodName->getCStringNoCopy());
            if (!ki)
                continue;

            if (ki->reference_count) {
                 continue;
            }

            kmodClasses = OSDynamicCast(OSSet,
                                sKModClassesDict->getObject(kmodName));
            classes = OSCollectionIterator::withCollection(kmodClasses);
            if (!classes)
                continue;
    
            while ((checkClass = (OSMetaClass *) classes->getNextObject())
              && (0 == checkClass->getInstanceCount()))
                {}
            classes->release();

            if (0 == checkClass) {
                OSRuntimeUnloadCPP(ki, 0);	// call destructors
                ret = kmod_destroy(host_priv_self(), ki->id);
                didUnload = true;
            }

        }

        kmods->release();

    } while (didUnload);

    mutex_unlock(loadLock);

    kmod_unload_cache();
}
Exemple #9
0
IOReturn AppleGPIO::callPlatformFunction(const OSSymbol *functionName,
                                         bool waitForFunction,
                                         void *param1, void *param2,
                                         void *param3, void *param4 )
{
	DLOG("AppleGPIO::callPlatformFunction %s %s %08lx %08lx %08lx %08lx\n",
			functionName->getCStringNoCopy(), waitForFunction ? "TRUE" : "FALSE",
			(UInt32)param1, (UInt32)param2, (UInt32)param3, (UInt32)param4);

	if (fPlatformFuncArray)
	{
		UInt32 i;
		IOPlatformFunction *pfFunc;
		
		UInt32 count = fPlatformFuncArray->getCount();
		for (i = 0; i < count; i++)
		{
			if (pfFunc = OSDynamicCast(IOPlatformFunction, fPlatformFuncArray->getObject(i)))
			{
				DLOG ("AppleGPIO::callPlatformFunction '%s' - got platformFunction object\n",
						functionName->getCStringNoCopy());

				// If param4 is an OSSymbol reference, check for interrupt event registration
				// or enable/disable symbols
				if (pfFunc->platformFunctionMatch(functionName, kIOPFFlagIntGen, NULL))
				{
					OSSymbol *subFunctionSym;
					
					DLOG ("AppleGPIO::callPlatformFunction '%s' - got platformFunction interrupt match\n",
							functionName->getCStringNoCopy());

					if (param4 && (subFunctionSym = OSDynamicCast(OSSymbol, (const OSMetaClassBase *)param4)))
					{
						DLOG ("AppleGPIO::callPlatformFunction '%s', subFunction '%s'\n",
								functionName->getCStringNoCopy(), subFunctionSym->getCStringNoCopy());

						if (subFunctionSym == fSymIntRegister)
							return (registerClient(param1, param2, param3) ? kIOReturnSuccess : kIOReturnBadArgument);
						if (subFunctionSym == fSymIntUnRegister)
							return (unregisterClient(param1, param2, param3) ? kIOReturnSuccess : kIOReturnBadArgument);
						if (subFunctionSym == fSymIntEnable)
							return (enableClient(param1, param2, param3) ? kIOReturnSuccess : kIOReturnBadArgument);
						if (subFunctionSym == fSymIntDisable)
							return (disableClient(param1, param2, param3) ? kIOReturnSuccess : kIOReturnBadArgument);
						return kIOReturnBadArgument;			// Unknown function
					}
					else
					{
						DLOG ("AppleGPIO::callPlatformFunction '%s', param4 not a OSSymbol\n",
								functionName->getCStringNoCopy());
					}
				}

				// Check for on-demand case
				if (pfFunc->platformFunctionMatch (functionName, kIOPFFlagOnDemand, NULL))
				{
					DLOG ("AppleGPIO::callPlatformFunction '%s', calling demand function\n",
							functionName->getCStringNoCopy());

					return (performFunction (pfFunc, param1, param2, param3, param4) ? kIOReturnSuccess : kIOReturnBadArgument);
				}

				DLOG ("AppleGPIO::callPlatformFunction '%s' - got no match\n", functionName->getCStringNoCopy());
			}
		}

#ifdef OLD_STYLE_COMPAT

		// Need to catch old-style register-, unregister-, enable-, disable- commands

		DLOG ("AppleGPIO::callPlatformFunction '%s' - handling old style\n", functionName->getCStringNoCopy());

		// Is it an interrupt notification registration request?
		if (fRegisterStrings &&
		    fRegisterStrings->containsObject(functionName))
		{
			return (registerClient(param1, param2, param3) ? kIOReturnSuccess : kIOReturnBadArgument);
		}
		// unregister?
		else if (fUnregisterStrings && 
		         fUnregisterStrings->containsObject(functionName))
		{
			return (unregisterClient(param1, param2, param3) ? kIOReturnSuccess : kIOReturnBadArgument);
		}
		else if (fEnableStrings &&
		         fEnableStrings->containsObject(functionName))
		{
			return (enableClient(param1, param2, param3) ? kIOReturnSuccess : kIOReturnBadArgument);
		}
		else if (fDisableStrings &&
		         fDisableStrings->containsObject(functionName))
		{
			return (disableClient(param1, param2, param3) ? kIOReturnSuccess : kIOReturnBadArgument);
		}

#endif

	}

	DLOG("AppleGPIO::callPlatformFunction unrecognized function\n");

	return super::callPlatformFunction(functionName, waitForFunction, param1, param2,
			param3, param4);

}