X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/1c79356b52d46aa6b508fb032f5ae709b1f2897b..9bccf70c0258c7cac2dcb80011b2a964d884c552:/iokit/Kernel/IORegistryEntry.cpp diff --git a/iokit/Kernel/IORegistryEntry.cpp b/iokit/Kernel/IORegistryEntry.cpp index bb72bda03..5d1e530f1 100644 --- a/iokit/Kernel/IORegistryEntry.cpp +++ b/iokit/Kernel/IORegistryEntry.cpp @@ -61,7 +61,7 @@ enum { class IORegistryPlane : public OSObject { - friend IORegistryEntry; + friend class IORegistryEntry; OSDeclareAbstractStructors(IORegistryPlane) @@ -98,6 +98,8 @@ static SInt32 gIORegistryGenerationCount; #define registryTable() fPropertyTable #endif +#define DEBUG_FREE 1 + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ struct s_lock_t { @@ -163,8 +165,9 @@ s_lock_write( if (l->can_sleep && l->want_write) { l->waiting = TRUE; thread_sleep_simple_lock((event_t) l, - simple_lock_addr(l->interlock), FALSE); - simple_lock(&l->interlock); + simple_lock_addr(l->interlock), + THREAD_UNINT); + /* interlock relocked */ } } l->want_write = TRUE; @@ -185,8 +188,9 @@ s_lock_write( if (l->can_sleep && (l->read_count != 0 || l->want_upgrade)) { l->waiting = TRUE; thread_sleep_simple_lock((event_t) l, - simple_lock_addr(l->interlock), FALSE); - simple_lock(&l->interlock); + simple_lock_addr(l->interlock), + THREAD_UNINT); + /* interlock relocked */ } } @@ -255,8 +259,9 @@ s_lock_read( (l->want_upgrade || ((0 == l->read_count) && l->want_write ))) { l->waiting = TRUE; thread_sleep_simple_lock((event_t) l, - simple_lock_addr(l->interlock), FALSE); - simple_lock(&l->interlock); + simple_lock_addr(l->interlock), + THREAD_UNINT); + /* interlock relocked */ } } @@ -397,9 +402,11 @@ bool IORegistryEntry::init( OSDictionary * dict = 0 ) if( dict) { dict->retain(); + if( fPropertyTable) + fPropertyTable->release(); fPropertyTable = dict; - } else { + } else if( !fPropertyTable) { fPropertyTable = OSDictionary::withCapacity( kIORegCapacityIncrement ); if( fPropertyTable) fPropertyTable->setCapacityIncrement( kIORegCapacityIncrement ); @@ -409,9 +416,11 @@ bool IORegistryEntry::init( OSDictionary * dict = 0 ) return( false); #ifdef IOREGSPLITTABLES - fRegistryTable = OSDictionary::withCapacity( kIORegCapacityIncrement ); - if( fRegistryTable) - fRegistryTable->setCapacityIncrement( kIORegCapacityIncrement ); + if( !fRegistryTable) { + fRegistryTable = OSDictionary::withCapacity( kIORegCapacityIncrement ); + if( fRegistryTable) + fRegistryTable->setCapacityIncrement( kIORegCapacityIncrement ); + } if( (prop = OSDynamicCast( OSString, getProperty( gIONameKey)))) { OSSymbol * sym = (OSSymbol *)OSSymbol::withString( prop); @@ -438,12 +447,15 @@ bool IORegistryEntry::init( IORegistryEntry * old, WLOCK; fPropertyTable = old->getPropertyTable(); - old->fPropertyTable = 0; + fPropertyTable->retain(); #ifdef IOREGSPLITTABLES fRegistryTable = old->fRegistryTable; - old->fRegistryTable = 0; + old->fRegistryTable = OSDictionary::withDictionary( fRegistryTable ); #endif /* IOREGSPLITTABLES */ + old->registryTable()->removeObject( plane->keys[ kParentSetIndex ] ); + old->registryTable()->removeObject( plane->keys[ kChildSetIndex ] ); + all = getParentSetReference( plane ); if( all) for( index = 0; (next = (IORegistryEntry *) all->getObject(index)); @@ -468,28 +480,18 @@ bool IORegistryEntry::init( IORegistryEntry * old, void IORegistryEntry::free( void ) { -#ifdef DEBUG - OSArray * links; - const OSSymbol * key; - const IORegistryPlane * plane; - OSCollectionIterator * iter; - - if( registryTable()) { - iter = OSCollectionIterator::withCollection( gIORegistryPlanes ); - if( iter) { - while( (key = (const OSSymbol *) iter->getNextObject())) { - if( 0 == (plane = (const IORegistryPlane *) - OSDynamicCast( IORegistryPlane, - gIORegistryPlanes->getObject( key )))) - continue; - if( (links = getParentSetReference( plane )) - || (links = getChildSetReference( plane )) ) { - - IOLog("%s: Still attached in %s at free()\n", - getName(), plane->nameKey->getCStringNoCopy()); - } - } - iter->release(); +#if DEBUG_FREE +#define msg ": attached at free()" + char buf[ strlen(msg) + 40 ]; + + if( registryTable() && gIOServicePlane) { + if( getParentSetReference( gIOServicePlane ) + || getChildSetReference( gIOServicePlane )) { + + strncpy( buf, getName(), 32); + buf[32] = 0; + strcat( buf, msg ); + IOPanic( buf ); } } #endif @@ -518,7 +520,7 @@ void IORegistryEntry::setPropertyTable( OSDictionary * dict ) /* Wrappers to synchronize property table */ -#define wrap1(func,type,constant) \ +#define wrap1(func, type, constant) \ OSObject * \ IORegistryEntry::func ## Property( type * aKey) constant \ { \ @@ -531,14 +533,14 @@ IORegistryEntry::func ## Property( type * aKey) constant \ return( obj ); \ } -#define wrap2(type,constant) \ +#define wrap2(type, constant) \ OSObject * \ IORegistryEntry::copyProperty( type * aKey) constant \ { \ OSObject * obj; \ \ PLOCK; \ - obj = getPropertyTable()->getObject( aKey ); \ + obj = getProperty( aKey ); \ if( obj) \ obj->retain(); \ PUNLOCK; \ @@ -563,15 +565,41 @@ IORegistryEntry::getProperty( type * aKey, \ { \ OSObject * obj = getProperty( aKey ); \ \ - if ( (0 == obj) && (options & kIORegistryIterateRecursively) ) { \ + if ( (0 == obj) && plane && (options & kIORegistryIterateRecursively) ) { \ + IORegistryEntry * entry = (IORegistryEntry *) this; \ + IORegistryIterator * iter; \ + iter = IORegistryIterator::iterateOver( entry, plane, options ); \ + \ + if(iter) { \ + while ( (0 == obj) && (entry = iter->getNextObject()) ) { \ + obj = entry->getProperty( aKey ); \ + } \ + iter->release(); \ + } \ + } \ + \ + return( obj ); \ +} + +#define wrap5(type,constant) \ +OSObject * \ +IORegistryEntry::copyProperty( type * aKey, \ + const IORegistryPlane * plane, \ + IOOptionBits options ) constant \ +{ \ + OSObject * obj = copyProperty( aKey ); \ + \ + if ( (0 == obj) && plane && (options & kIORegistryIterateRecursively) ) { \ IORegistryEntry * entry = (IORegistryEntry *) this; \ IORegistryIterator * iter; \ iter = IORegistryIterator::iterateOver( entry, plane, options ); \ \ - while ( (0 == obj) && (entry = iter->getNextObject()) ) { \ - obj = entry->getProperty( aKey ); \ + if(iter) { \ + while ( (0 == obj) && (entry = iter->getNextObject()) ) { \ + obj = entry->copyProperty( aKey ); \ + } \ + iter->release(); \ } \ - iter->release(); \ } \ \ return( obj ); \ @@ -623,6 +651,11 @@ wrap4(const OSSymbol, const) // getProperty() w/plane definition wrap4(const OSString, const) // getProperty() w/plane definition wrap4(const char, const) // getProperty() w/plane definition +wrap5(const OSSymbol, const) // copyProperty() w/plane definition +wrap5(const OSString, const) // copyProperty() w/plane definition +wrap5(const char, const) // copyProperty() w/plane definition + + bool IORegistryEntry::setProperty( const OSSymbol * aKey, OSObject * anObject) { @@ -1031,16 +1064,16 @@ const char * IORegistryEntry::matchPathLocation( const char * cmp, { const char * str; const char * result = 0; - int num1, num2; + u_quad_t num1, num2; char c1, c2; str = getLocation( plane ); if( str) { c2 = str[0]; do { - num1 = strtoul( cmp, (char **) &cmp, 16 ); + num1 = strtouq( cmp, (char **) &cmp, 16 ); if( c2) { - num2 = strtoul( str, (char **) &str, 16 ); + num2 = strtouq( str, (char **) &str, 16 ); c2 = str[0]; } else num2 = 0; @@ -1080,6 +1113,7 @@ IORegistryEntry * IORegistryEntry::getChildFromComponent( const char ** opath, unsigned int index; const char * path; const char * cmp = 0; + char c; size_t len; const char * str; @@ -1100,8 +1134,12 @@ IORegistryEntry * IORegistryEntry::getChildFromComponent( const char ** opath, if( strncmp( str, cmp, len )) continue; cmp += len; - if( *cmp != '@' ) - break; + + c = *cmp; + if( (c == 0) || (c == '/') || (c == ':')) + break; + if( c != '@') + continue; } cmp++; if( (cmp = entry->matchPathLocation( cmp, plane ))) @@ -1203,6 +1241,7 @@ IORegistryEntry * IORegistryEntry::fromPath( IORegistryEntry * fromEntry = 0 ) { IORegistryEntry * where = 0; + IORegistryEntry * aliasEntry = 0; IORegistryEntry * next; const char * alias; const char * end; @@ -1232,8 +1271,9 @@ IORegistryEntry * IORegistryEntry::fromPath( if( (alias = dealiasPath( &end, plane))) { if( length) len = *length; - where = IORegistryEntry::fromPath( alias, plane, + aliasEntry = IORegistryEntry::fromPath( alias, plane, opath, &len, fromEntry ); + where = aliasEntry; if( where) path = end; else @@ -1281,6 +1321,8 @@ IORegistryEntry * IORegistryEntry::fromPath( if( where) where->retain(); + if( aliasEntry) + aliasEntry->release(); UNLOCK; @@ -1402,21 +1444,34 @@ OSIterator * IORegistryEntry::getParentIterator( return( iter ); } -IORegistryEntry * IORegistryEntry::getParentEntry( const IORegistryPlane * plane ) const +IORegistryEntry * IORegistryEntry::copyParentEntry( const IORegistryPlane * plane ) const { IORegistryEntry * entry = 0; OSArray * links; RLOCK; - if( (links = getParentSetReference( plane ))) + if( (links = getParentSetReference( plane ))) { entry = (IORegistryEntry *) links->getObject( 0 ); + entry->retain(); + } UNLOCK; return( entry); } +IORegistryEntry * IORegistryEntry::getParentEntry( const IORegistryPlane * plane ) const +{ + IORegistryEntry * entry; + + entry = copyParentEntry( plane ); + if( entry) + entry->release(); + + return( entry ); +} + OSArray * IORegistryEntry::getChildSetReference( const IORegistryPlane * plane ) const { if( plane) @@ -1451,7 +1506,7 @@ OSIterator * IORegistryEntry::getChildIterator( const IORegistryPlane * plane ) } -IORegistryEntry * IORegistryEntry::getChildEntry( +IORegistryEntry * IORegistryEntry::copyChildEntry( const IORegistryPlane * plane ) const { IORegistryEntry * entry = 0; @@ -1459,14 +1514,28 @@ IORegistryEntry * IORegistryEntry::getChildEntry( RLOCK; - if( (links = getChildSetReference( plane ))) + if( (links = getChildSetReference( plane ))) { entry = (IORegistryEntry *) links->getObject( 0 ); + entry->retain(); + } UNLOCK; return( entry); } +IORegistryEntry * IORegistryEntry::getChildEntry( + const IORegistryPlane * plane ) const +{ + IORegistryEntry * entry; + + entry = copyChildEntry( plane ); + if( entry) + entry->release(); + + return( entry ); +} + void IORegistryEntry::applyToChildren( IORegistryEntryApplierFunction applier, void * context, const IORegistryPlane * plane ) const @@ -1760,6 +1829,8 @@ unsigned int IORegistryEntry::getDepth( const IORegistryPlane * plane ) const OSDefineMetaClassAndStructors(IORegistryIterator, OSIterator) +enum { kIORegistryIteratorInvalidFlag = 0x80000000 }; + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ IORegistryIterator * @@ -1783,7 +1854,7 @@ IORegistryIterator::iterateOver( IORegistryEntry * root, create->where = &create->start; create->start.current = root; create->plane = plane; - create->options = options; + create->options = options & ~kIORegistryIteratorInvalidFlag; } else { create->release(); @@ -1805,10 +1876,12 @@ bool IORegistryIterator::isValid( void ) bool ok; IORegCursor * next; - ok = true; next = where; RLOCK; + + ok = (0 == (kIORegistryIteratorInvalidFlag & options)); + while( ok && next) { if( where->iter) ok = where->iter->isValid(); @@ -1872,6 +1945,7 @@ void IORegistryIterator::reset( void ) } where->current = root; + options &= ~kIORegistryIteratorInvalidFlag; } void IORegistryIterator::free( void ) @@ -1907,11 +1981,15 @@ IORegistryEntry * IORegistryIterator::getNextObjectFlat( void ) if( where->current) where->current->release(); - if( where->iter) + if( where->iter) { + next = (IORegistryEntry *) where->iter->getNextObject(); - if( next) - next->retain(); + if( next) + next->retain(); + else if( !where->iter->isValid()) + options |= kIORegistryIteratorInvalidFlag; + } where->current = next; @@ -1965,11 +2043,12 @@ OSOrderedSet * IORegistryIterator::iterateAll( void ) return( done); } -OSMetaClassDefineReservedUnused(IORegistryEntry, 0); -OSMetaClassDefineReservedUnused(IORegistryEntry, 1); -OSMetaClassDefineReservedUnused(IORegistryEntry, 2); -OSMetaClassDefineReservedUnused(IORegistryEntry, 3); -OSMetaClassDefineReservedUnused(IORegistryEntry, 4); +OSMetaClassDefineReservedUsed(IORegistryEntry, 0); +OSMetaClassDefineReservedUsed(IORegistryEntry, 1); +OSMetaClassDefineReservedUsed(IORegistryEntry, 2); +OSMetaClassDefineReservedUsed(IORegistryEntry, 3); +OSMetaClassDefineReservedUsed(IORegistryEntry, 4); + OSMetaClassDefineReservedUnused(IORegistryEntry, 5); OSMetaClassDefineReservedUnused(IORegistryEntry, 6); OSMetaClassDefineReservedUnused(IORegistryEntry, 7); @@ -1997,3 +2076,7 @@ OSMetaClassDefineReservedUnused(IORegistryEntry, 28); OSMetaClassDefineReservedUnused(IORegistryEntry, 29); OSMetaClassDefineReservedUnused(IORegistryEntry, 30); OSMetaClassDefineReservedUnused(IORegistryEntry, 31); + +/* inline function implementation */ +OSDictionary * IORegistryEntry::getPropertyTable( void ) const +{ return(fPropertyTable); }