]> git.saurik.com Git - apple/xnu.git/blobdiff - iokit/Kernel/IORegistryEntry.cpp
xnu-792.10.96.tar.gz
[apple/xnu.git] / iokit / Kernel / IORegistryEntry.cpp
index 5d1e530f1a7cb99e607c3b16a44d1e1d7cfce74a..4be7e3aa5bb823cfbd3329494f6dc0f38fbf7e7a 100644 (file)
@@ -44,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;
 
@@ -81,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
 
@@ -102,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);
+lck_rw_t       gIORegistryLock;
+lck_grp_t       *gIORegistryLockGrp;
+lck_grp_attr_t  *gIORegistryLockGrpAttr;
+lck_attr_t      *gIORegistryLockAttr;
 
-       /*
-        *      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) {
-
-               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);
-
-}
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
@@ -278,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 );
@@ -327,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;
@@ -393,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;
 
@@ -520,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                   \
@@ -548,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, \
@@ -607,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 );
 }
 
@@ -635,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
@@ -656,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;
 }
 
@@ -696,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 );
@@ -711,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 );
@@ -728,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 );
@@ -745,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 );
@@ -757,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;
 
@@ -775,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;
 
@@ -795,7 +700,7 @@ const OSSymbol * IORegistryEntry::copyName(
 }
 
 const OSSymbol * IORegistryEntry::copyLocation(
-                       const IORegistryPlane * plane = 0 ) const
+                       const IORegistryPlane * plane ) const
 {
     OSSymbol *         sym = 0;
 
@@ -811,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;
@@ -825,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;
 
@@ -842,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 ) {
@@ -852,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;
 
@@ -869,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 ) {
@@ -879,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;
@@ -898,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;
@@ -1065,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);
     }
@@ -1153,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;
@@ -1235,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;
@@ -1331,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 ));
 }
@@ -1347,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;
@@ -1378,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 ],
@@ -1584,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;
@@ -1605,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;
@@ -1631,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;
 
@@ -1657,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 );
 
@@ -1836,7 +1790,7 @@ enum { kIORegistryIteratorInvalidFlag = 0x80000000 };
 IORegistryIterator *
 IORegistryIterator::iterateOver( IORegistryEntry * root,
                                  const IORegistryPlane * plane,
-                                 IOOptionBits options = 0 )
+                                 IOOptionBits options )
 {
     IORegistryIterator *       create;
 
@@ -1866,7 +1820,7 @@ IORegistryIterator::iterateOver( IORegistryEntry * root,
 
 IORegistryIterator *
 IORegistryIterator::iterateOver( const IORegistryPlane * plane,
-                                IOOptionBits options = 0 )
+                                IOOptionBits options )
 {
     return( iterateOver( gRegistryRoot, plane, options ));
 }
@@ -2048,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);