Annotation of XNU/iokit/Kernel/IOCatalogue.cpp, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             6:  * The contents of this file constitute Original Code as defined in and
        !             7:  * are subject to the Apple Public Source License Version 1.1 (the
        !             8:  * "License").  You may not use this file except in compliance with the
        !             9:  * License.  Please obtain a copy of the License at
        !            10:  * http://www.apple.com/publicsource and read it before using this file.
        !            11:  * 
        !            12:  * This Original Code and all software distributed under the License are
        !            13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
        !            17:  * License for the specific language governing rights and limitations
        !            18:  * under the License.
        !            19:  * 
        !            20:  * @APPLE_LICENSE_HEADER_END@
        !            21:  */
        !            22: /*
        !            23:  * Copyright (c) 1998 Apple Computer, Inc.  All rights reserved. 
        !            24:  *
        !            25:  * HISTORY
        !            26:  *
        !            27:  */
        !            28: 
        !            29: #include <IOKit/IOService.h>
        !            30: #include <libkern/c++/OSContainers.h>
        !            31: #include <IOKit/IOCatalogue.h>
        !            32: #include <libkern/c++/OSUnserialize.h>
        !            33: #include <mach/kmod.h>
        !            34: 
        !            35: #include <IOKit/IOLib.h>
        !            36: 
        !            37: #include <IOKit/assert.h>
        !            38: 
        !            39: 
        !            40: #define super OSObject
        !            41: #define kModuleKey "Module"
        !            42: 
        !            43: OSDefineMetaClassAndStructors(IOCatalogue, OSObject)
        !            44: 
        !            45: #define CATALOGTEST 0
        !            46: 
        !            47: IOCatalogue                   * gIOCatalogue;
        !            48: const OSSymbol                * gIOClassKey;
        !            49: const OSSymbol                * gIOProbeScoreKey;
        !            50: 
        !            51: static void UniqueProperties( OSDictionary * dict )
        !            52: {
        !            53:     OSString             * data;
        !            54: 
        !            55:     data = OSDynamicCast( OSString, dict->getObject( gIOClassKey ));
        !            56:     if( data) {
        !            57:         const OSSymbol *classSymbol = OSSymbol::withString(data);
        !            58: 
        !            59:         dict->setObject( gIOClassKey, (OSSymbol *) classSymbol);
        !            60:         classSymbol->release();
        !            61:     } else
        !            62:         IOLog("Missing or bad \"%s\" key\n",
        !            63:                     gIOClassKey->getCStringNoCopy());
        !            64: 
        !            65:     data = OSDynamicCast( OSString, dict->getObject( gIOMatchCategoryKey ));
        !            66:     if( data) {
        !            67:         const OSSymbol *classSymbol = OSSymbol::withString(data);
        !            68: 
        !            69:         dict->setObject( gIOMatchCategoryKey, (OSSymbol *) classSymbol);
        !            70:         classSymbol->release();
        !            71:     }
        !            72: }
        !            73: 
        !            74: void IOCatalogue::initialize( void )
        !            75: {
        !            76:     OSArray              * array;
        !            77:     OSString             * errorString;
        !            78:     bool                  rc;
        !            79: 
        !            80:     extern const char * gIOKernelConfigTables;
        !            81: 
        !            82:     array = OSDynamicCast(OSArray, OSUnserialize(gIOKernelConfigTables, &errorString));
        !            83:     if (!array && errorString) {
        !            84:        IOLog("KernelConfigTables syntax error: %s\n",
        !            85:                errorString->getCStringNoCopy());
        !            86:        errorString->release();
        !            87:     }
        !            88: 
        !            89:     gIOClassKey = OSSymbol::withCStringNoCopy( kIOClassKey );
        !            90:     gIOProbeScoreKey = OSSymbol::withCStringNoCopy( kIOProbeScoreKey );
        !            91:     assert( array && gIOClassKey && gIOProbeScoreKey);
        !            92: 
        !            93:     gIOCatalogue = new IOCatalogue;
        !            94:     assert(gIOCatalogue);
        !            95:     rc = gIOCatalogue->init(array);
        !            96:     assert(rc);
        !            97:     array->release();
        !            98: }
        !            99: 
        !           100: // Initialize the IOCatalog object.
        !           101: bool IOCatalogue::init(OSArray * initArray)
        !           102: {
        !           103:     IORegistryEntry      * entry;
        !           104:     OSDictionary         * dict;
        !           105:     
        !           106:     if ( !super::init() )
        !           107:         return false;
        !           108: 
        !           109:     generation = 1;
        !           110:     
        !           111:     array = initArray;
        !           112:     array->retain();
        !           113:     kernelTables = OSCollectionIterator::withCollection( array );
        !           114: 
        !           115:     lock = IOLockAlloc();
        !           116: 
        !           117:     kernelTables->reset();
        !           118:     while( (dict = (OSDictionary *) kernelTables->getNextObject())) {
        !           119:         UniqueProperties(dict);
        !           120:     }
        !           121: 
        !           122: #if CATALOGTEST
        !           123:     AbsoluteTime deadline;
        !           124:     clock_interval_to_deadline( 1000, kMillisecondScale );
        !           125:     thread_call_func_delayed( ping, this, deadline );
        !           126: #endif
        !           127: 
        !           128:     entry = IORegistryEntry::getRegistryRoot();
        !           129:     if ( entry )
        !           130:         entry->setProperty(kIOCatalogueKey, this);
        !           131: 
        !           132:     return true;
        !           133: }
        !           134: 
        !           135: // Release all resources used by IOCatalogue and deallocate.
        !           136: // This will probably never be called.
        !           137: void IOCatalogue::free( void )
        !           138: {
        !           139:     if ( array )
        !           140:         array->release();
        !           141: 
        !           142:     if ( kernelTables )
        !           143:         kernelTables->release();
        !           144:     
        !           145:     super::free();
        !           146: }
        !           147: 
        !           148: #if CATALOGTEST
        !           149: 
        !           150: static int hackLimit;
        !           151: 
        !           152: enum { kDriversPerIter = 4 };
        !           153: 
        !           154: void IOCatalogue::ping( thread_call_param_t arg, thread_call_param_t)
        !           155: {
        !           156:     IOCatalogue         * self = (IOCatalogue *) arg;
        !           157:     OSOrderedSet         * set;
        !           158:     OSDictionary         * table;
        !           159:     int                           newLimit;
        !           160: 
        !           161:     set = OSOrderedSet::withCapacity( 1 );
        !           162: 
        !           163:     IOTakeLock( &self->lock );
        !           164: 
        !           165:     for( newLimit = 0; newLimit < kDriversPerIter; newLimit++) {
        !           166:        table = (OSDictionary *) self->array->getObject(
        !           167:                                        hackLimit + newLimit );
        !           168:        if( table) {
        !           169:            set->setLastObject( table );
        !           170: 
        !           171:            OSSymbol * sym = (OSSymbol *) table->getObject( gIOClassKey );
        !           172:            kprintf("enabling %s\n", sym->getCStringNoCopy());
        !           173: 
        !           174:        } else {
        !           175:            newLimit--;
        !           176:            break;
        !           177:        }
        !           178:     }
        !           179: 
        !           180:     IOService::catalogNewDrivers( set );
        !           181: 
        !           182:     hackLimit += newLimit;
        !           183:     self->generation++;
        !           184: 
        !           185:     IOUnlock( &self->lock );
        !           186: 
        !           187:     if( kDriversPerIter == newLimit) {
        !           188:         AbsoluteTime deadline;
        !           189:         clock_interval_to_deadline( 500, kMillisecondScale );
        !           190:         thread_call_func_delayed( ping, this, deadline );
        !           191:     }
        !           192: }
        !           193: #endif
        !           194: 
        !           195: OSOrderedSet * IOCatalogue::findDrivers( IOService * service,
        !           196:                                        SInt32 * generationCount )
        !           197: {
        !           198:     OSDictionary         * nextTable;
        !           199:     OSOrderedSet         * set;
        !           200:     OSString             * imports;
        !           201: 
        !           202:     set = OSOrderedSet::withCapacity( 1, IOServiceOrdering,
        !           203:                                       (void *)gIOProbeScoreKey );
        !           204:     if( !set )
        !           205:        return( 0 );
        !           206: 
        !           207:     IOTakeLock( lock );
        !           208:     kernelTables->reset();
        !           209: 
        !           210: #if CATALOGTEST
        !           211:     int hackIndex = 0;
        !           212: #endif
        !           213:     while( (nextTable = (OSDictionary *) kernelTables->getNextObject())) {
        !           214: #if CATALOGTEST
        !           215:        if( hackIndex++ > hackLimit)
        !           216:            break;
        !           217: #endif
        !           218:         imports = OSDynamicCast( OSString,
        !           219:                        nextTable->getObject( gIOProviderClassKey ));
        !           220:        if( imports && service->metaCast( imports ))
        !           221:             set->setObject( nextTable );
        !           222:     }
        !           223: 
        !           224:     *generationCount = getGenerationCount();
        !           225: 
        !           226:     IOUnlock( lock );
        !           227: 
        !           228:     return( set );
        !           229: }
        !           230: 
        !           231: // Is personality already in the catalog?
        !           232: OSOrderedSet * IOCatalogue::findDrivers( OSDictionary * matching,
        !           233:                                          SInt32 * generationCount)
        !           234: {
        !           235:     OSDictionary         * dict;
        !           236:     OSOrderedSet         * set;
        !           237: 
        !           238:     UniqueProperties(matching);
        !           239: 
        !           240:     set = OSOrderedSet::withCapacity( 1, IOServiceOrdering,
        !           241:                                       (void *)gIOProbeScoreKey );
        !           242: 
        !           243:     IOTakeLock( lock );
        !           244:     kernelTables->reset();
        !           245:     while ( (dict = (OSDictionary *) kernelTables->getNextObject()) ) {
        !           246:         if ( dict->isEqualTo(matching, matching) )
        !           247:             set->setObject(dict);
        !           248:     }
        !           249:     *generationCount = getGenerationCount();
        !           250:     IOUnlock( lock );
        !           251: 
        !           252:     return set;
        !           253: }
        !           254: 
        !           255: // Add a new personality to the set if it has a unique IOResourceMatchKey value.
        !           256: // XXX -- svail: This should be optimized.
        !           257: static void AddNewImports( OSOrderedSet * set, OSDictionary * dict )
        !           258: {
        !           259:     OSCollectionIterator * iter;
        !           260:     OSDictionary         * entry;
        !           261:     OSString             * imports1;
        !           262:     OSString             * imports2;
        !           263:     bool                   foundMatch;
        !           264: 
        !           265:     imports1 = (OSString *)OSDynamicCast(OSString,
        !           266:                                          dict->getObject(gIOProviderClassKey));
        !           267:     if ( !imports1 )
        !           268:         return;
        !           269: 
        !           270:     foundMatch = false;
        !           271:     iter = OSCollectionIterator::withCollection(set);
        !           272:     if ( !iter )
        !           273:         return;
        !           274:     
        !           275:     while ( (entry = (OSDictionary *)iter->getNextObject()) ) {
        !           276:         imports2 = (OSString *)OSDynamicCast(OSString,
        !           277:                                              entry->getObject(gIOProviderClassKey));
        !           278:         if ( !imports2 )
        !           279:             continue;
        !           280: 
        !           281:         if ( imports1->isEqualTo(imports2) ) {
        !           282:             foundMatch = true;
        !           283:             break;
        !           284:         }
        !           285:     }
        !           286:     iter->release();
        !           287: 
        !           288:     if ( !foundMatch )
        !           289:         set->setObject(dict);
        !           290: }
        !           291: 
        !           292: // Add driver config tables to catalog and start matching process.
        !           293: bool IOCatalogue::addDrivers( OSArray * drivers,
        !           294:                               bool doNubMatching = true )
        !           295: {
        !           296:     OSCollectionIterator * iter;
        !           297:     OSDictionary         * dict;
        !           298:     OSOrderedSet         * set;
        !           299:     OSArray              * persons;
        !           300:     bool                   ret;
        !           301: 
        !           302:     ret = true;
        !           303:     persons = OSDynamicCast(OSArray, drivers);
        !           304:     if ( !persons )
        !           305:         return false;
        !           306: 
        !           307:     iter = OSCollectionIterator::withCollection( persons );
        !           308:     if (!iter )
        !           309:         return false;
        !           310:     
        !           311:     set = OSOrderedSet::withCapacity( 10, IOServiceOrdering,
        !           312:                                       (void *)gIOProbeScoreKey );
        !           313:     if ( !set ) {
        !           314:         iter->release();
        !           315:         return false;
        !           316:     }
        !           317: 
        !           318:     IOTakeLock( lock );
        !           319:     while ( (dict = (OSDictionary *) iter->getNextObject()) ) {
        !           320:         UInt count;
        !           321:         
        !           322:         UniqueProperties( dict );
        !           323: 
        !           324:         // Add driver personality to catalogue.
        !           325:         count = array->getCount();
        !           326:         while ( count-- ) {
        !           327:             OSDictionary         * driver;
        !           328: 
        !           329:             // Be sure not to double up on personalities.
        !           330:             driver = (OSDictionary *)array->getObject(count);
        !           331:             if ( dict->isEqualTo(driver, driver) ) {
        !           332:                 array->removeObject(count);
        !           333:                 break;
        !           334:             }
        !           335:         }
        !           336:         
        !           337:         ret = array->setObject( dict );
        !           338:         if ( !ret )
        !           339:             break;
        !           340: 
        !           341:         AddNewImports( set, dict );
        !           342:     }
        !           343:     // Start device matching.
        !           344:     if ( doNubMatching && (set->getCount() > 0) ) {
        !           345:         IOService::catalogNewDrivers( set );
        !           346:         generation++;
        !           347:     }
        !           348:     IOUnlock( lock );
        !           349: 
        !           350:     set->release();
        !           351:     iter->release();
        !           352:     
        !           353:     return ret;
        !           354: }
        !           355: 
        !           356: // Remove drivers from the catalog which match the
        !           357: // properties in the matching dictionary.
        !           358: bool IOCatalogue::removeDrivers( OSDictionary * matching,
        !           359:                                  bool doNubMatching = true)
        !           360: {
        !           361:     OSCollectionIterator * tables;
        !           362:     OSDictionary         * dict;
        !           363:     OSOrderedSet         * set;
        !           364:     OSArray              * arrayCopy;
        !           365: 
        !           366:     if ( !matching )
        !           367:         return false;
        !           368: 
        !           369:     set = OSOrderedSet::withCapacity(10,
        !           370:                                      IOServiceOrdering,
        !           371:                                      (void *)gIOProbeScoreKey);
        !           372:     if ( !set )
        !           373:         return false;
        !           374: 
        !           375:     arrayCopy = OSArray::withCapacity(100);
        !           376:     if ( !arrayCopy )
        !           377:         return false;
        !           378:     
        !           379:     tables = OSCollectionIterator::withCollection(arrayCopy);
        !           380:     arrayCopy->release();
        !           381:     if ( !tables )
        !           382:         return false;
        !           383: 
        !           384:     UniqueProperties( matching );
        !           385: 
        !           386:     IOTakeLock( lock );
        !           387:     kernelTables->reset();
        !           388:     arrayCopy->merge(array);
        !           389:     array->flushCollection();
        !           390:     tables->reset();
        !           391:     while ( (dict = (OSDictionary *)tables->getNextObject()) ) {
        !           392:         if ( dict->isEqualTo(matching, matching) ) {
        !           393:             AddNewImports( set, dict );
        !           394:             continue;
        !           395:         }
        !           396: 
        !           397:         array->setObject(dict);
        !           398:     }
        !           399:     // Start device matching.
        !           400:     if ( doNubMatching && (set->getCount() > 0) ) {
        !           401:         IOService::catalogNewDrivers(set);
        !           402:         generation++;
        !           403:     }
        !           404:     IOUnlock( lock );
        !           405:     
        !           406:     set->release();
        !           407:     tables->release();
        !           408:     
        !           409:     return true;
        !           410: }
        !           411: 
        !           412: // Return the generation count.
        !           413: SInt32 IOCatalogue::getGenerationCount( void ) const
        !           414: {
        !           415:     return( generation );
        !           416: }
        !           417: 
        !           418: bool IOCatalogue::isModuleLoaded( OSString * moduleName ) const
        !           419: {
        !           420:     return isModuleLoaded(moduleName->getCStringNoCopy());
        !           421: }
        !           422: 
        !           423: bool IOCatalogue::isModuleLoaded( const char * moduleName ) const
        !           424: {
        !           425:     kmod_info_t          * k_info;
        !           426: 
        !           427:     if ( !moduleName )
        !           428:         return false;
        !           429: 
        !           430:     // Is the module already loaded?
        !           431:     k_info = kmod_lookupbyname((char *)moduleName);
        !           432:     if ( !k_info ) {
        !           433:         kern_return_t            ret;
        !           434: 
        !           435:         // If the module hasn't been loaded, then load it.
        !           436:         ret = kmod_load_extension((char *)moduleName);
        !           437:         if  ( ret != kIOReturnSuccess ) {
        !           438:             IOLog("IOCatalogue: %s cannot be loaded.\n", moduleName);
        !           439:         }
        !           440: 
        !           441:         return false;
        !           442:     }
        !           443: 
        !           444:     return true;
        !           445: }
        !           446: 
        !           447: // Check to see if module has been loaded already.
        !           448: bool IOCatalogue::isModuleLoaded( OSDictionary * driver ) const
        !           449: {
        !           450:     OSString             * moduleName;
        !           451: 
        !           452:     if ( !driver )
        !           453:         return false;
        !           454:     
        !           455:     // If a personality doesn't have a module key, it is assumed to
        !           456:     // be an "in-kernel" driver.
        !           457:     moduleName = OSDynamicCast(OSString, driver->getObject(kModuleKey));
        !           458:     if ( moduleName )
        !           459:         return isModuleLoaded(moduleName);
        !           460: 
        !           461:     return true;
        !           462: }
        !           463: 
        !           464: // This function is called after a module has been loaded.
        !           465: void IOCatalogue::moduleHasLoaded( OSString * moduleName )
        !           466: {
        !           467:     OSDictionary         * dict;
        !           468: 
        !           469:     dict = OSDictionary::withCapacity(2);
        !           470:     dict->setObject(kModuleKey, moduleName);
        !           471:     startMatching(dict);
        !           472:     dict->release();
        !           473: }
        !           474: 
        !           475: void IOCatalogue::moduleHasLoaded( const char * moduleName )
        !           476: {
        !           477:     OSString             * name;
        !           478: 
        !           479:     name = OSString::withCString(moduleName);
        !           480:     moduleHasLoaded(name);
        !           481:     name->release();
        !           482: }
        !           483: 
        !           484: IOReturn IOCatalogue::unloadModule( OSString * moduleName ) const
        !           485: {
        !           486:     kmod_info_t          * k_info;
        !           487:     kern_return_t          ret;
        !           488:     const char           * name;
        !           489: 
        !           490:     ret = kIOReturnBadArgument;
        !           491:     if ( moduleName ) {
        !           492:         name = moduleName->getCStringNoCopy();
        !           493:         k_info = kmod_lookupbyname((char *)name);
        !           494:         if ( k_info && (k_info->reference_count < 1) ) {
        !           495:             if ( k_info->stop &&
        !           496:                  !((ret = k_info->stop(k_info, 0)) == kIOReturnSuccess) )
        !           497:                 return ret;
        !           498:             
        !           499:            ret = kmod_destroy((host_t) 1, k_info->id);
        !           500:         }
        !           501:     }
        !           502: 
        !           503:     return ret;
        !           504: }
        !           505: 
        !           506: static IOReturn _terminateDrivers( OSArray * array, OSDictionary * matching )
        !           507: {
        !           508:     OSCollectionIterator * tables;
        !           509:     OSCollectionIterator * props;
        !           510:     OSDictionary         * dict;
        !           511:     OSIterator           * iter;
        !           512:     OSArray              * arrayCopy;
        !           513:     IOService            * service;
        !           514:     IOReturn               ret;
        !           515: 
        !           516:     if ( !matching )
        !           517:         return kIOReturnBadArgument;
        !           518: 
        !           519:     ret = kIOReturnSuccess;
        !           520:     dict = 0;
        !           521:     iter = IORegistryIterator::iterateOver(gIOServicePlane,
        !           522:                                 kIORegistryIterateRecursively);
        !           523:     if ( !iter )
        !           524:         return kIOReturnNoMemory;
        !           525: 
        !           526:     UniqueProperties( matching );
        !           527: 
        !           528:     props = OSCollectionIterator::withCollection(matching);
        !           529:     if ( !props ) {
        !           530:         iter->release();
        !           531:         return kIOReturnNoMemory;
        !           532:     }
        !           533: 
        !           534:     // terminate instances.
        !           535:     do {
        !           536:         iter->reset();
        !           537:         while( (service = (IOService *)iter->getNextObject()) ) {
        !           538:             dict = service->getPropertyTable();
        !           539:             if ( !dict )
        !           540:                 continue;
        !           541: 
        !           542:             if ( !dict->isEqualTo(matching, matching) )
        !           543:                  continue;
        !           544: 
        !           545:             if ( !service->terminate(kIOServiceRequired|kIOServiceSynchronous) ) {
        !           546:                 ret = kIOReturnUnsupported;
        !           547:                 break;
        !           548:             }
        !           549:         }
        !           550:     } while( !service && !iter->isValid());
        !           551:     iter->release();
        !           552: 
        !           553:     // remove configs from catalog.
        !           554:     if ( ret != kIOReturnSuccess ) 
        !           555:         return ret;
        !           556: 
        !           557:     arrayCopy = OSArray::withCapacity(100);
        !           558:     if ( !arrayCopy )
        !           559:         return kIOReturnNoMemory;
        !           560: 
        !           561:     tables = OSCollectionIterator::withCollection(arrayCopy);
        !           562:     arrayCopy->release();
        !           563:     if ( !tables )
        !           564:         return kIOReturnNoMemory;
        !           565: 
        !           566:     arrayCopy->merge(array);
        !           567:     array->flushCollection();
        !           568:     tables->reset();
        !           569:     while ( (dict = (OSDictionary *)tables->getNextObject()) ) {
        !           570:         if ( dict->isEqualTo(matching, matching) )
        !           571:             continue;
        !           572: 
        !           573:         array->setObject(dict);
        !           574:     }
        !           575: 
        !           576:     tables->release();
        !           577: 
        !           578:     return ret;
        !           579: }
        !           580: 
        !           581: IOReturn IOCatalogue::terminateDrivers( OSDictionary * matching )
        !           582: {
        !           583:     IOReturn ret;
        !           584: 
        !           585:     ret = kIOReturnSuccess;
        !           586:     IOTakeLock( lock );
        !           587:     ret = _terminateDrivers(array, matching);
        !           588:     kernelTables->reset();
        !           589:     IOUnlock( lock );
        !           590: 
        !           591:     return ret;
        !           592: }
        !           593: 
        !           594: IOReturn IOCatalogue::terminateDriversForModule(
        !           595:                                       OSString * moduleName,
        !           596:                                       bool unload )
        !           597: {
        !           598:     IOReturn ret;
        !           599:     OSDictionary * dict;
        !           600: 
        !           601:     dict = OSDictionary::withCapacity(1);
        !           602:     if ( !dict )
        !           603:         return kIOReturnNoMemory;
        !           604: 
        !           605:     dict->setObject(kModuleKey, moduleName);
        !           606:     
        !           607:     IOTakeLock( lock );
        !           608: 
        !           609:     ret = _terminateDrivers(array, dict);
        !           610:     kernelTables->reset();
        !           611: 
        !           612:     // Unload the module itself.
        !           613:     if ( unload && ret == kIOReturnSuccess ) {
        !           614:         // Do kmod stop first.
        !           615:         ret = unloadModule(moduleName);
        !           616:     }
        !           617: 
        !           618:     IOUnlock( lock );
        !           619: 
        !           620:     dict->release();
        !           621: 
        !           622:     return ret;
        !           623: }
        !           624: 
        !           625: IOReturn IOCatalogue::terminateDriversForModule(
        !           626:                                       const char * moduleName,
        !           627:                                       bool unload )
        !           628: {
        !           629:     OSString * name;
        !           630:     IOReturn ret;
        !           631: 
        !           632:     name = OSString::withCString(moduleName);
        !           633:     if ( !name )
        !           634:         return kIOReturnNoMemory;
        !           635: 
        !           636:     ret = terminateDriversForModule(name, unload);
        !           637:     name->release();
        !           638:     
        !           639:     return ret;
        !           640: }
        !           641: 
        !           642: bool IOCatalogue::startMatching( OSDictionary * matching )
        !           643: {
        !           644:     OSDictionary         * dict;
        !           645:     OSOrderedSet         * set;
        !           646:     
        !           647:     if ( !matching )
        !           648:         return false;
        !           649: 
        !           650:     set = OSOrderedSet::withCapacity(10, IOServiceOrdering,
        !           651:                                      (void *)gIOProbeScoreKey);
        !           652:     if ( !set )
        !           653:         return false;
        !           654: 
        !           655:     IOTakeLock( lock );
        !           656:     kernelTables->reset();
        !           657: 
        !           658:     while ( (dict = (OSDictionary *)kernelTables->getNextObject()) ) {
        !           659:         if ( dict->isEqualTo(matching, matching) )
        !           660:             AddNewImports(set, dict);
        !           661:     }
        !           662:     // Start device matching.
        !           663:     if ( set->getCount() > 0 ) {
        !           664:         IOService::catalogNewDrivers(set);
        !           665:         generation++;
        !           666:     }
        !           667: 
        !           668:     IOUnlock( lock );
        !           669: 
        !           670:     set->release();
        !           671: 
        !           672:     return true;
        !           673: }
        !           674: 
        !           675: void IOCatalogue::reset(void)
        !           676: {
        !           677:     OSArray              * tables;
        !           678:     OSDictionary         * entry;
        !           679:     unsigned int           count;
        !           680: 
        !           681:     IOLog("Resetting IOCatalogue.\n");
        !           682:     
        !           683:     IOTakeLock( lock );
        !           684:     tables = OSArray::withArray(array);
        !           685:     array->flushCollection();
        !           686:     
        !           687:     count = tables->getCount();
        !           688:     while ( count-- ) {
        !           689:         entry = (OSDictionary *)tables->getObject(count);
        !           690:         if ( entry && !entry->getObject(kModuleKey) ) {
        !           691:             array->setObject(entry);
        !           692:         }
        !           693:     }
        !           694:     
        !           695:     kernelTables->reset();
        !           696:     IOUnlock( lock );
        !           697:     
        !           698:     tables->release();
        !           699: }
        !           700: 
        !           701: bool IOCatalogue::serialize(OSSerialize * s) const
        !           702: {
        !           703:     bool                   ret;
        !           704:     
        !           705:     if ( !s )
        !           706:         return false;
        !           707: 
        !           708:     IOTakeLock( lock );
        !           709:     ret = array->serialize(s);
        !           710:     IOUnlock( lock );
        !           711: 
        !           712:     return ret;
        !           713: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.