X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/d7e50217d7adf6e52786a38bcaa4cd698cb9a79e..c0fea4742e91338fffdcf79f86a7c1d5e2b97eb1:/iokit/Kernel/IORegistryEntry.cpp?ds=sidebyside diff --git a/iokit/Kernel/IORegistryEntry.cpp b/iokit/Kernel/IORegistryEntry.cpp index f95427287..4be7e3aa5 100644 --- a/iokit/Kernel/IORegistryEntry.cpp +++ b/iokit/Kernel/IORegistryEntry.cpp @@ -3,22 +3,19 @@ * * @APPLE_LICENSE_HEADER_START@ * - * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * The contents of this file constitute Original Code as defined in and + * are subject to the Apple Public Source License Version 1.1 (the + * "License"). You may not use this file except in compliance with the + * License. Please obtain a copy of the License at + * http://www.apple.com/publicsource and read it before using this file. * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * This Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. * * @APPLE_LICENSE_HEADER_END@ */ @@ -47,6 +44,12 @@ OSDefineMetaClassAndStructors(IORegistryEntry, OSObject) /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +#define kIORegPlaneParentSuffix "ParentLinks" +#define kIORegPlaneChildSuffix "ChildLinks" +#define kIORegPlaneNameSuffix "Name" +#define kIORegPlaneLocationSuffix "Location" +#define kIORegPlaneParentSuffixLen (sizeof(kIORegPlaneParentSuffix) - 1) + static IORegistryEntry * gRegistryRoot; static OSDictionary * gIORegistryPlanes; @@ -84,9 +87,9 @@ OSDefineMetaClassAndStructors(IORegistryPlane, OSObject) static IORecursiveLock * gPropertiesLock; static SInt32 gIORegistryGenerationCount; -#define UNLOCK s_lock_done( &gIORegistryLock ) -#define RLOCK s_lock_read( &gIORegistryLock ) -#define WLOCK s_lock_write( &gIORegistryLock ); \ +#define UNLOCK lck_rw_done( &gIORegistryLock ) +#define RLOCK lck_rw_lock_shared( &gIORegistryLock ) +#define WLOCK lck_rw_lock_exclusive( &gIORegistryLock ); \ gIORegistryGenerationCount++ // make atomic @@ -105,173 +108,11 @@ static SInt32 gIORegistryGenerationCount; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -struct s_lock_t { - decl_simple_lock_data(,interlock) /* "hardware" interlock field */ - volatile unsigned int - read_count:16, /* No. of accepted readers */ - want_upgrade:1, /* Read-to-write upgrade waiting */ - want_write:1, /* Writer is waiting, or - locked for write */ - waiting:1, /* Someone is sleeping on lock */ - can_sleep:1; /* Can attempts to lock go to sleep? */ -}; - -static struct s_lock_t gIORegistryLock; - -/* Time we loop without holding the interlock. - * The former is for when we cannot sleep, the latter - * for when our thread can go to sleep (loop less) - * we shouldn't retake the interlock at all frequently - * if we cannot go to sleep, since it interferes with - * any other processors. In particular, 100 is too small - * a number for powerpc MP systems because of cache - * coherency issues and differing lock fetch times between - * the processors - */ -static unsigned int lock_wait_time[2] = { (unsigned int)-1, 100 } ; - -static void -s_lock_init( - s_lock_t *l, - boolean_t can_sleep) -{ - (void) memset((void *) l, 0, sizeof(s_lock_t)); - - simple_lock_init(&l->interlock, 0); - l->want_write = FALSE; - l->want_upgrade = FALSE; - l->read_count = 0; - l->can_sleep = can_sleep; -} - -static void -s_lock_write( - register s_lock_t * l) -{ - register int i; - - simple_lock(&l->interlock); - - /* - * Try to acquire the want_write bit. - */ - while (l->want_write) { - - i = lock_wait_time[l->can_sleep ? 1 : 0]; - if (i != 0) { - simple_unlock(&l->interlock); - while (--i != 0 && l->want_write) - continue; - simple_lock(&l->interlock); - } - - if (l->can_sleep && l->want_write) { - l->waiting = TRUE; - thread_sleep_simple_lock((event_t) l, - simple_lock_addr(l->interlock), - THREAD_UNINT); - /* interlock relocked */ - } - } - l->want_write = TRUE; - - /* Wait for readers (and upgrades) to finish */ - - while ((l->read_count != 0) || l->want_upgrade) { +lck_rw_t gIORegistryLock; +lck_grp_t *gIORegistryLockGrp; +lck_grp_attr_t *gIORegistryLockGrpAttr; +lck_attr_t *gIORegistryLockAttr; - i = lock_wait_time[l->can_sleep ? 1 : 0]; - if (i != 0) { - simple_unlock(&l->interlock); - while (--i != 0 && (l->read_count != 0 || - l->want_upgrade)) - continue; - simple_lock(&l->interlock); - } - - 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), - THREAD_UNINT); - /* interlock relocked */ - } - } - - simple_unlock(&l->interlock); -} - -static void -s_lock_done( - register s_lock_t * l) -{ - boolean_t do_wakeup = FALSE; - - simple_lock(&l->interlock); - - if (l->read_count != 0) { - l->read_count -= 1; - } - else { - if (l->want_upgrade) { - l->want_upgrade = FALSE; - } - else { - l->want_write = FALSE; - } - } - - /* - * There is no reason to wakeup a waiting thread - * if the read-count is non-zero. Consider: - * we must be dropping a read lock - * threads are waiting only if one wants a write lock - * if there are still readers, they can't proceed - */ - if (l->waiting && (l->read_count == 0)) { - l->waiting = FALSE; - do_wakeup = TRUE; - } - - simple_unlock(&l->interlock); - - if (do_wakeup) - thread_wakeup((event_t) l); -} - -static void -s_lock_read( - register s_lock_t * l) -{ - register int i; - - simple_lock(&l->interlock); - - while ( l->want_upgrade || ((0 == l->read_count) && l->want_write )) { - - i = lock_wait_time[l->can_sleep ? 1 : 0]; - - if (i != 0) { - simple_unlock(&l->interlock); - while (--i != 0 && - (l->want_upgrade || ((0 == l->read_count) && l->want_write ))) - continue; - simple_lock(&l->interlock); - } - - if (l->can_sleep && - (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), - THREAD_UNINT); - /* interlock relocked */ - } - } - - l->read_count += 1; - simple_unlock(&l->interlock); - -} /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ @@ -281,7 +122,15 @@ IORegistryEntry * IORegistryEntry::initialize( void ) if( !gRegistryRoot) { - s_lock_init( &gIORegistryLock, true ); + + gIORegistryLockGrpAttr = lck_grp_attr_alloc_init(); + //lck_grp_attr_setstat(gIORegistryLockGrpAttr); + gIORegistryLockGrp = lck_grp_alloc_init("IORegistryLock", gIORegistryLockGrpAttr); + gIORegistryLockAttr = lck_attr_alloc_init(); + lck_attr_rw_shared_priority(gIORegistryLockAttr); + //lck_attr_setdebug(gIORegistryLockAttr); + lck_rw_init( &gIORegistryLock, gIORegistryLockGrp, gIORegistryLockAttr); + gRegistryRoot = new IORegistryEntry; gPropertiesLock = IORecursiveLockAlloc(); gIORegistryPlanes = OSDictionary::withCapacity( 1 ); @@ -330,16 +179,16 @@ const IORegistryPlane * IORegistryEntry::makePlane( const char * name ) nameKey = OSSymbol::withCString( key); - strcpy( end, "ParentLinks" ); + strcpy( end, kIORegPlaneParentSuffix ); parentKey = OSSymbol::withCString( key); - strcpy( end, "ChildLinks" ); + strcpy( end, kIORegPlaneChildSuffix ); childKey = OSSymbol::withCString( key); - strcpy( end, "Name" ); + strcpy( end, kIORegPlaneNameSuffix ); pathNameKey = OSSymbol::withCString( key); - strcpy( end, "Location" ); + strcpy( end, kIORegPlaneLocationSuffix ); pathLocationKey = OSSymbol::withCString( key); plane = new IORegistryPlane; @@ -396,7 +245,7 @@ bool IORegistryPlane::serialize(OSSerialize *s) const enum { kIORegCapacityIncrement = 4 }; -bool IORegistryEntry::init( OSDictionary * dict = 0 ) +bool IORegistryEntry::init( OSDictionary * dict ) { OSString * prop; @@ -523,19 +372,6 @@ void IORegistryEntry::setPropertyTable( OSDictionary * dict ) /* Wrappers to synchronize property table */ -#define wrap1(func, type, constant) \ -OSObject * \ -IORegistryEntry::func ## Property( type * aKey) constant \ -{ \ - OSObject * obj; \ - \ - PLOCK; \ - obj = getPropertyTable()->func ## Object( aKey ); \ - PUNLOCK; \ - \ - return( obj ); \ -} - #define wrap2(type, constant) \ OSObject * \ IORegistryEntry::copyProperty( type * aKey) constant \ @@ -551,15 +387,6 @@ IORegistryEntry::copyProperty( type * aKey) constant \ return( obj ); \ } -#define wrap3(func,type,constant) \ -void \ -IORegistryEntry::func ## Property( type * aKey) constant \ -{ \ - PLOCK; \ - getPropertyTable()->func ## Object( aKey ); \ - PUNLOCK; \ -} - #define wrap4(type,constant) \ OSObject * \ IORegistryEntry::getProperty( type * aKey, \ @@ -610,14 +437,14 @@ IORegistryEntry::copyProperty( type * aKey, \ bool IORegistryEntry::serializeProperties( OSSerialize * s ) const { - bool ok; - // setProperty( getRetainCount(), 32, "__retain" ); PLOCK; - ok = getPropertyTable()->serialize( s ); + OSCollection *snapshotProperties = getPropertyTable()->copyCollection(); PUNLOCK; + bool ok = snapshotProperties->serialize( s ); + snapshotProperties->release(); return( ok ); } @@ -638,18 +465,10 @@ IOReturn IORegistryEntry::setProperties( OSObject * properties ) return( kIOReturnUnsupported ); } -wrap1(get, const OSSymbol, const) // getProperty() definition -wrap1(get, const OSString, const) // getProperty() definition -wrap1(get, const char, const) // getProperty() definition - wrap2(const OSSymbol, const) // copyProperty() definition wrap2(const OSString, const) // copyProperty() definition wrap2(const char, const) // copyProperty() definition -wrap3(remove, const OSSymbol,) // removeProperty() definition -wrap3(remove, const OSString,) // removeProperty() definition -wrap3(remove, const char,) // removeProperty() definition - wrap4(const OSSymbol, const) // getProperty() w/plane definition wrap4(const OSString, const) // getProperty() w/plane definition wrap4(const char, const) // getProperty() w/plane definition @@ -659,36 +478,115 @@ wrap5(const OSString, const) // copyProperty() w/plane definition wrap5(const char, const) // copyProperty() w/plane definition +OSObject * +IORegistryEntry::getProperty( const OSSymbol * aKey) const +{ + OSObject * obj; + + PLOCK; + obj = getPropertyTable()->getObject( aKey ); + PUNLOCK; + + return( obj ); +} + +void +IORegistryEntry::removeProperty( const OSSymbol * aKey) +{ + PLOCK; + getPropertyTable()->removeObject( aKey ); + PUNLOCK; +} + bool IORegistryEntry::setProperty( const OSSymbol * aKey, OSObject * anObject) { bool ret = false; + + // If we are inserting a collection class and the current entry + // is attached into the registry (inPlane()) then mark the collection + // as immutable. + OSCollection *coll = OSDynamicCast(OSCollection, anObject); + bool makeImmutable = (coll && inPlane()); + PLOCK; + if( makeImmutable ) + coll->setOptions( OSCollection::kMASK, OSCollection::kImmutable ); + ret = getPropertyTable()->setObject( aKey, anObject ); PUNLOCK; return ret; } -bool -IORegistryEntry::setProperty( const OSString * aKey, OSObject * anObject) +IOReturn IORegistryEntry:: +runPropertyAction(Action inAction, OSObject *target, + void *arg0, void *arg1, void *arg2, void *arg3) { - bool ret = false; + IOReturn res; + + // closeGate is recursive so don't worry if we already hold the lock. PLOCK; - ret = getPropertyTable()->setObject( aKey, anObject ); + res = (*inAction)(target, arg0, arg1, arg2, arg3); PUNLOCK; + return res; +} + +OSObject * +IORegistryEntry::getProperty( const OSString * aKey) const +{ + const OSSymbol * tmpKey = OSSymbol::withString( aKey ); + OSObject * obj = getProperty( tmpKey ); + + tmpKey->release(); + return( obj ); +} + +OSObject * +IORegistryEntry::getProperty( const char * aKey) const +{ + const OSSymbol * tmpKey = OSSymbol::withCString( aKey ); + OSObject * obj = getProperty( tmpKey ); + + tmpKey->release(); + return( obj ); +} + + +void +IORegistryEntry::removeProperty( const OSString * aKey) +{ + const OSSymbol * tmpKey = OSSymbol::withString( aKey ); + removeProperty( tmpKey ); + tmpKey->release(); +} + +void +IORegistryEntry::removeProperty( const char * aKey) +{ + const OSSymbol * tmpKey = OSSymbol::withCString( aKey ); + removeProperty( tmpKey ); + tmpKey->release(); +} + +bool +IORegistryEntry::setProperty( const OSString * aKey, OSObject * anObject) +{ + const OSSymbol * tmpKey = OSSymbol::withString( aKey ); + bool ret = setProperty( tmpKey, anObject ); + + tmpKey->release(); return ret; } bool IORegistryEntry::setProperty( const char * aKey, OSObject * anObject) { - bool ret = false; - PLOCK; - ret = getPropertyTable()->setObject( aKey, anObject ); - PUNLOCK; - + const OSSymbol * tmpKey = OSSymbol::withCString( aKey ); + bool ret = setProperty( tmpKey, anObject ); + + tmpKey->release(); return ret; } @@ -699,9 +597,10 @@ IORegistryEntry::setProperty(const char * aKey, const char * aString) OSSymbol * aSymbol = (OSSymbol *) OSSymbol::withCString( aString ); if( aSymbol) { - PLOCK; - ret = getPropertyTable()->setObject( aKey, aSymbol ); - PUNLOCK; + const OSSymbol * tmpKey = OSSymbol::withCString( aKey ); + ret = setProperty( tmpKey, aSymbol ); + + tmpKey->release(); aSymbol->release(); } return( ret ); @@ -714,9 +613,10 @@ IORegistryEntry::setProperty(const char * aKey, bool aBoolean) OSBoolean * aBooleanObj = OSBoolean::withBoolean( aBoolean ); if( aBooleanObj) { - PLOCK; - ret = getPropertyTable()->setObject( aKey, aBooleanObj ); - PUNLOCK; + const OSSymbol * tmpKey = OSSymbol::withCString( aKey ); + ret = setProperty( tmpKey, aBooleanObj ); + + tmpKey->release(); aBooleanObj->release(); } return( ret ); @@ -731,9 +631,10 @@ IORegistryEntry::setProperty( const char * aKey, OSNumber * anOffset = OSNumber::withNumber( aValue, aNumberOfBits ); if( anOffset) { - PLOCK; - ret = getPropertyTable()->setObject( aKey, anOffset ); - PUNLOCK; + const OSSymbol * tmpKey = OSSymbol::withCString( aKey ); + ret = setProperty( tmpKey, anOffset ); + + tmpKey->release(); anOffset->release(); } return( ret ); @@ -748,9 +649,10 @@ IORegistryEntry::setProperty( const char * aKey, OSData * data = OSData::withBytes( bytes, length ); if( data) { - PLOCK; - ret = getPropertyTable()->setObject( aKey, data ); - PUNLOCK; + const OSSymbol * tmpKey = OSSymbol::withCString( aKey ); + ret = setProperty( tmpKey, data ); + + tmpKey->release(); data->release(); } return( ret ); @@ -760,7 +662,7 @@ IORegistryEntry::setProperty( const char * aKey, /* Name, location, paths */ -const char * IORegistryEntry::getName( const IORegistryPlane * plane = 0 ) const +const char * IORegistryEntry::getName( const IORegistryPlane * plane ) const { OSSymbol * sym = 0; @@ -778,7 +680,7 @@ const char * IORegistryEntry::getName( const IORegistryPlane * plane = 0 ) const } const OSSymbol * IORegistryEntry::copyName( - const IORegistryPlane * plane = 0 ) const + const IORegistryPlane * plane ) const { OSSymbol * sym = 0; @@ -798,7 +700,7 @@ const OSSymbol * IORegistryEntry::copyName( } const OSSymbol * IORegistryEntry::copyLocation( - const IORegistryPlane * plane = 0 ) const + const IORegistryPlane * plane ) const { OSSymbol * sym = 0; @@ -814,7 +716,7 @@ const OSSymbol * IORegistryEntry::copyLocation( return( sym ); } -const char * IORegistryEntry::getLocation( const IORegistryPlane * plane = 0 ) const +const char * IORegistryEntry::getLocation( const IORegistryPlane * plane ) const { const OSSymbol * sym = copyLocation( plane ); const char * result = 0; @@ -828,7 +730,7 @@ const char * IORegistryEntry::getLocation( const IORegistryPlane * plane = 0 ) c } void IORegistryEntry::setName( const OSSymbol * name, - const IORegistryPlane * plane = 0 ) + const IORegistryPlane * plane ) { const OSSymbol * key; @@ -845,7 +747,7 @@ void IORegistryEntry::setName( const OSSymbol * name, } void IORegistryEntry::setName( const char * name, - const IORegistryPlane * plane = 0 ) + const IORegistryPlane * plane ) { OSSymbol * sym = (OSSymbol *)OSSymbol::withCString( name ); if ( sym ) { @@ -855,7 +757,7 @@ void IORegistryEntry::setName( const char * name, } void IORegistryEntry::setLocation( const OSSymbol * location, - const IORegistryPlane * plane = 0 ) + const IORegistryPlane * plane ) { const OSSymbol * key; @@ -872,7 +774,7 @@ void IORegistryEntry::setLocation( const OSSymbol * location, } void IORegistryEntry::setLocation( const char * location, - const IORegistryPlane * plane = 0 ) + const IORegistryPlane * plane ) { OSSymbol * sym = (OSSymbol *)OSSymbol::withCString( location ); if ( sym ) { @@ -882,7 +784,7 @@ void IORegistryEntry::setLocation( const char * location, } bool -IORegistryEntry::compareName( OSString * name, OSString ** matched = 0 ) const +IORegistryEntry::compareName( OSString * name, OSString ** matched ) const { const OSSymbol * sym = copyName(); bool isEqual; @@ -901,7 +803,7 @@ IORegistryEntry::compareName( OSString * name, OSString ** matched = 0 ) const } bool -IORegistryEntry::compareNames( OSObject * names, OSString ** matched = 0 ) const +IORegistryEntry::compareNames( OSObject * names, OSString ** matched ) const { OSString * string; OSCollection * collection; @@ -1068,39 +970,38 @@ const char * IORegistryEntry::matchPathLocation( const char * cmp, const char * str; const char * result = 0; u_quad_t num1, num2; - char c1, c2; + char lastPathChar, lastLocationChar; str = getLocation( plane ); if( str) { - c2 = str[0]; + lastPathChar = cmp[0]; + lastLocationChar = str[0]; do { - num1 = strtouq( cmp, (char **) &cmp, 16 ); - if( c2) { + if( lastPathChar) { + num1 = strtouq( cmp, (char **) &cmp, 16 ); + lastPathChar = *cmp++; + } else + num1 = 0; + + if( lastLocationChar) { num2 = strtouq( str, (char **) &str, 16 ); - c2 = str[0]; + lastLocationChar = *str++; } else num2 = 0; if( num1 != num2) break; - c1 = *cmp++; - - if( (c2 == ':') && (c2 == c1)) { - str++; - continue; - } - - if( ',' != c1) { + if (!lastPathChar && !lastLocationChar) { result = cmp - 1; break; } - if( c2) { - if( c2 != ',') - break; - str++; - } + if( (',' != lastPathChar) && (':' != lastPathChar)) + lastPathChar = 0; + + if (lastPathChar && lastLocationChar && (lastPathChar != lastLocationChar)) + break; } while( true); } @@ -1156,7 +1057,7 @@ IORegistryEntry * IORegistryEntry::getChildFromComponent( const char ** opath, } const OSSymbol * IORegistryEntry::hasAlias( const IORegistryPlane * plane, - char * opath = 0, int * length = 0 ) const + char * opath, int * length ) const { IORegistryEntry * entry; IORegistryEntry * entry2; @@ -1238,10 +1139,10 @@ const char * IORegistryEntry::dealiasPath( IORegistryEntry * IORegistryEntry::fromPath( const char * path, - const IORegistryPlane * plane = 0, - char * opath = 0, - int * length = 0, - IORegistryEntry * fromEntry = 0 ) + const IORegistryPlane * plane, + char * opath, + int * length, + IORegistryEntry * fromEntry ) { IORegistryEntry * where = 0; IORegistryEntry * aliasEntry = 0; @@ -1334,9 +1235,9 @@ IORegistryEntry * IORegistryEntry::fromPath( IORegistryEntry * IORegistryEntry::childFromPath( const char * path, - const IORegistryPlane * plane = 0, - char * opath = 0, - int * len = 0 ) + const IORegistryPlane * plane, + char * opath, + int * len ) { return( IORegistryEntry::fromPath( path, plane, opath, len, this )); } @@ -1350,7 +1251,7 @@ IORegistryEntry * IORegistryEntry::childFromPath( inline bool IORegistryEntry::arrayMember( OSArray * set, const IORegistryEntry * member, - unsigned int * index = 0 ) const + unsigned int * index ) const { int i; OSObject * probeObject; @@ -1381,7 +1282,7 @@ bool IORegistryEntry::makeLink( IORegistryEntry * to, } else { - links = OSArray::withObjects( & (const OSObject *) to, 1, 1 ); + links = OSArray::withObjects( (const OSObject **) &to, 1, 1 ); result = (links != 0); if( result) { result = registryTable()->setObject( plane->keys[ relation ], @@ -1587,7 +1488,7 @@ void IORegistryEntry::applyToParents( IORegistryEntryApplierFunction applier, bool IORegistryEntry::isChild( IORegistryEntry * child, const IORegistryPlane * plane, - bool onlyChild = false ) const + bool onlyChild ) const { OSArray * links; bool ret = false; @@ -1608,7 +1509,7 @@ bool IORegistryEntry::isChild( IORegistryEntry * child, bool IORegistryEntry::isParent( IORegistryEntry * parent, const IORegistryPlane * plane, - bool onlyParent = false ) const + bool onlyParent ) const { OSArray * links; @@ -1634,7 +1535,34 @@ bool IORegistryEntry::inPlane( const IORegistryPlane * plane ) const RLOCK; - ret = (0 != getParentSetReference( plane )); + if( plane) + ret = (0 != getParentSetReference( plane )); + else { + + // Check to see if this is in any plane. If it is in a plane + // then the registryTable will contain a key with the ParentLinks + // suffix. When we iterate over the keys looking for that suffix + ret = false; + + OSCollectionIterator *iter = + OSCollectionIterator::withCollection( registryTable()); + if( iter) { + const OSSymbol *key; + + while( (key = (OSSymbol *) iter->getNextObject()) ) { + const char *keysuffix; + + // Get a pointer to this keys suffix + keysuffix = key->getCStringNoCopy() + + key->getLength() - kIORegPlaneParentSuffixLen; + if( !strcmp(keysuffix, kIORegPlaneParentSuffix) ) { + ret = true; + break; + } + } + iter->release(); + } + } UNLOCK; @@ -1660,10 +1588,33 @@ bool IORegistryEntry::attachToParent( IORegistryEntry * parent, else needParent = true; -// ret &= parent->makeLink( this, kChildSetIndex, plane ); - UNLOCK; + PLOCK; + + // Mark any collections in the property list as immutable + OSDictionary *ptable = getPropertyTable(); + OSCollectionIterator *iter = + OSCollectionIterator::withCollection( ptable ); + if( iter) { + const OSSymbol *key; + + while( (key = (OSSymbol *) iter->getNextObject( ))) { + // Is object for key a collection? + OSCollection *coll = + OSDynamicCast( OSCollection, ptable->getObject( key )); + + if( coll) { + // Yup so mark it as immutable + coll->setOptions( OSCollection::kMASK, + OSCollection::kImmutable ); + } + } + iter->release(); + } + + PUNLOCK; + if( needParent) ret &= parent->attachToChild( this, plane ); @@ -1839,7 +1790,7 @@ enum { kIORegistryIteratorInvalidFlag = 0x80000000 }; IORegistryIterator * IORegistryIterator::iterateOver( IORegistryEntry * root, const IORegistryPlane * plane, - IOOptionBits options = 0 ) + IOOptionBits options ) { IORegistryIterator * create; @@ -1869,7 +1820,7 @@ IORegistryIterator::iterateOver( IORegistryEntry * root, IORegistryIterator * IORegistryIterator::iterateOver( const IORegistryPlane * plane, - IOOptionBits options = 0 ) + IOOptionBits options ) { return( iterateOver( gRegistryRoot, plane, options )); } @@ -2051,8 +2002,8 @@ OSMetaClassDefineReservedUsed(IORegistryEntry, 1); OSMetaClassDefineReservedUsed(IORegistryEntry, 2); OSMetaClassDefineReservedUsed(IORegistryEntry, 3); OSMetaClassDefineReservedUsed(IORegistryEntry, 4); +OSMetaClassDefineReservedUsed(IORegistryEntry, 5); -OSMetaClassDefineReservedUnused(IORegistryEntry, 5); OSMetaClassDefineReservedUnused(IORegistryEntry, 6); OSMetaClassDefineReservedUnused(IORegistryEntry, 7); OSMetaClassDefineReservedUnused(IORegistryEntry, 8);