]> git.saurik.com Git - apple/xnu.git/blobdiff - iokit/Kernel/IORegistryEntry.cpp
xnu-3247.1.106.tar.gz
[apple/xnu.git] / iokit / Kernel / IORegistryEntry.cpp
index 78dbf352792d8e1e19032a19bf0c1b2c2e6868ee..1d9cf8f9d6314ca11eff3bd0649da55eb0a563d0 100644 (file)
@@ -1,23 +1,29 @@
 /*
- * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1998-2006 Apple Computer, Inc. All rights reserved.
  *
- * @APPLE_LICENSE_HEADER_START@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
- * 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. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
  * 
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * 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
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License.
+ * 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.
  * 
- * @APPLE_LICENSE_HEADER_END@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
 /*
  * Copyright (c) 1998 Apple Computer, Inc.  All rights reserved. 
@@ -48,13 +54,20 @@ OSDefineMetaClassAndStructors(IORegistryEntry, OSObject)
 #define kIORegPlaneChildSuffix         "ChildLinks"
 #define kIORegPlaneNameSuffix          "Name"
 #define kIORegPlaneLocationSuffix      "Location"
+
 #define kIORegPlaneParentSuffixLen     (sizeof(kIORegPlaneParentSuffix) - 1)
+#define kIORegPlaneChildSuffixLen      (sizeof(kIORegPlaneChildSuffix) - 1)
+#define kIORegPlaneNameSuffixLen       (sizeof(kIORegPlaneNameSuffix) - 1)
+#define kIORegPlaneLocationSuffixLen   (sizeof(kIORegPlaneLocationSuffix) - 1)
+
+#define KASLR_IOREG_DEBUG 0
 
 static IORegistryEntry * gRegistryRoot;
 static OSDictionary *   gIORegistryPlanes;
 
 const OSSymbol *       gIONameKey;
 const OSSymbol *       gIOLocationKey;
+const OSSymbol *       gIORegistryEntryIDKey;
 
 enum {
     kParentSetIndex    = 0,
@@ -65,6 +78,10 @@ enum {
     kIOMaxPlaneName    = 32
 };
 
+enum { kIORegistryIDReserved = (1ULL << 32) + 255 };
+
+static uint64_t gIORegistryLastID = kIORegistryIDReserved;
+
 class IORegistryPlane : public OSObject {
 
     friend class IORegistryEntry;
@@ -78,7 +95,7 @@ class IORegistryPlane : public OSObject {
     int                        reserved[2];
 
 public:
-    virtual bool serialize(OSSerialize *s) const;
+    virtual bool serialize(OSSerialize *s) const APPLE_KEXT_OVERRIDE;
 };
 
 OSDefineMetaClassAndStructors(IORegistryPlane, OSObject)
@@ -87,9 +104,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
 
@@ -108,170 +125,11 @@ static SInt32                    gIORegistryGenerationCount;
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
-struct s_lock_t {
-       lck_spin_t 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));
-
-       lck_spin_init(&l->interlock, IOLockGroup, LCK_ATTR_NULL);
-       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;
+lck_rw_t       gIORegistryLock;
+lck_grp_t       *gIORegistryLockGrp;
+lck_grp_attr_t  *gIORegistryLockGrpAttr;
+lck_attr_t      *gIORegistryLockAttr;
 
-       lck_spin_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) {
-                       lck_spin_unlock(&l->interlock);
-                       while (--i != 0 && l->want_write)
-                               continue;
-                       lck_spin_lock(&l->interlock);
-               }
-
-               if (l->can_sleep && l->want_write) {
-                       l->waiting = TRUE;
-                       lck_spin_sleep( &l->interlock, LCK_SLEEP_DEFAULT,
-                                       (event_t) l, 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) {
-                       lck_spin_unlock(&l->interlock);
-                       while (--i != 0 && (l->read_count != 0 ||
-                                           l->want_upgrade))
-                               continue;
-                       lck_spin_lock(&l->interlock);
-               }
-
-               if (l->can_sleep && (l->read_count != 0 || l->want_upgrade)) {
-                       l->waiting = TRUE;
-                       lck_spin_sleep( &l->interlock, LCK_SLEEP_DEFAULT,
-                                       (event_t) l, THREAD_UNINT);
-                       /* interlock relocked */
-               }
-       }
-
-       lck_spin_unlock(&l->interlock);
-}
-
-static void
-s_lock_done(
-       register s_lock_t       * l)
-{
-       boolean_t         do_wakeup = FALSE;
-
-       lck_spin_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;
-       }
-
-       lck_spin_unlock(&l->interlock);
-
-       if (do_wakeup)
-               thread_wakeup((event_t) l);
-}
-
-static void
-s_lock_read(
-       register s_lock_t       * l)
-{
-       register int        i;
-
-       lck_spin_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) {
-                       lck_spin_unlock(&l->interlock);
-                       while (--i != 0 && 
-                            (l->want_upgrade || ((0 == l->read_count) && l->want_write )))
-                               continue;
-                       lck_spin_lock(&l->interlock);
-               }
-
-               if (l->can_sleep &&
-                    (l->want_upgrade || ((0 == l->read_count) && l->want_write ))) {
-                       l->waiting = TRUE;
-                       lck_spin_sleep( &l->interlock, LCK_SLEEP_DEFAULT,
-                                       (event_t) l, THREAD_UNINT);
-                       /* interlock relocked */
-               }
-       }
-
-       l->read_count += 1;
-       lck_spin_unlock(&l->interlock);
-
-}
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
@@ -281,7 +139,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 );
@@ -290,8 +156,12 @@ IORegistryEntry * IORegistryEntry::initialize( void )
                && gIORegistryPlanes );
         ok = gRegistryRoot->init();
 
+       if (ok)
+           gRegistryRoot->reserved->fRegistryEntryID = ++gIORegistryLastID;
+
        gIONameKey = OSSymbol::withCStringNoCopy( "IOName" );
        gIOLocationKey = OSSymbol::withCStringNoCopy( "IOLocation" );
+       gIORegistryEntryIDKey = OSSymbol::withCStringNoCopy( kIORegistryEntryIDKey );
 
        assert( ok && gIONameKey && gIOLocationKey );
 
@@ -324,22 +194,21 @@ const IORegistryPlane * IORegistryEntry::makePlane( const char * name )
     char               key[ kIOMaxPlaneName + 16 ];
     char *             end;
 
-    strncpy( key, name, kIOMaxPlaneName );
-    key[ kIOMaxPlaneName ] = 0;
-    end = key + strlen( name );
+    strlcpy( key, name, kIOMaxPlaneName + 1 );
+    end = key + strlen( key );
 
     nameKey = OSSymbol::withCString( key);
 
-    strcpy( end, kIORegPlaneParentSuffix );
+    strlcpy( end, kIORegPlaneParentSuffix, kIORegPlaneParentSuffixLen + 1 );
     parentKey = OSSymbol::withCString( key);
 
-    strcpy( end, kIORegPlaneChildSuffix );
+    strlcpy( end, kIORegPlaneChildSuffix, kIORegPlaneChildSuffixLen + 1 );
     childKey = OSSymbol::withCString( key);
 
-    strcpy( end, kIORegPlaneNameSuffix );
+    strlcpy( end, kIORegPlaneNameSuffix, kIORegPlaneNameSuffixLen + 1 );
     pathNameKey = OSSymbol::withCString( key);
 
-    strcpy( end, kIORegPlaneLocationSuffix );
+    strlcpy( end, kIORegPlaneLocationSuffix, kIORegPlaneLocationSuffixLen + 1 );
     pathLocationKey = OSSymbol::withCString( key);
 
     plane = new IORegistryPlane;
@@ -403,8 +272,20 @@ bool IORegistryEntry::init( OSDictionary * dict )
     if( !super::init())
        return( false);
 
+    if (!reserved)
+    {
+       reserved = IONew(ExpansionData, 1);
+       if (!reserved)
+           return (false);
+       bzero(reserved, sizeof(ExpansionData));
+    }
     if( dict) {
-       dict->retain();
+       if (OSCollection::kImmutable & dict->setOptions(0, 0)) {
+           dict = (OSDictionary *) dict->copyCollection();
+           if (!dict)
+               return (false);
+       } else
+           dict->retain();
        if( fPropertyTable)
            fPropertyTable->release();
        fPropertyTable = dict;
@@ -449,11 +330,14 @@ bool IORegistryEntry::init( IORegistryEntry * old,
 
     WLOCK;
 
+    reserved = old->reserved;
+    old->reserved = NULL;
+
     fPropertyTable = old->getPropertyTable();
     fPropertyTable->retain();
 #ifdef IOREGSPLITTABLES
     fRegistryTable = old->fRegistryTable;
-    old->fRegistryTable = OSDictionary::withDictionary( fRegistryTable );
+    old->fRegistryTable = (OSDictionary *) fRegistryTable->copyCollection();
 #endif /* IOREGSPLITTABLES */
 
     old->registryTable()->removeObject( plane->keys[ kParentSetIndex ] );
@@ -482,19 +366,11 @@ bool IORegistryEntry::init( IORegistryEntry * old,
 
 void IORegistryEntry::free( void )
 {
-
 #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 );
+            panic("%s: attached at free()", getName());
         }
     }
 #endif
@@ -507,6 +383,9 @@ void IORegistryEntry::free( void )
         registryTable()->release();
 #endif /* IOREGSPLITTABLES */
 
+    if (reserved)
+       IODelete(reserved, ExpansionData, 1);
+
     super::free();
 }
 
@@ -649,6 +528,15 @@ IORegistryEntry::removeProperty( const OSSymbol * aKey)
     PUNLOCK;
 }
 
+#if KASLR_IOREG_DEBUG
+extern "C" {
+    
+bool ScanForAddrInObject(OSObject * theObject, 
+                         int indent);
+    
+}; /* extern "C" */
+#endif
+
 bool
 IORegistryEntry::setProperty( const OSSymbol * aKey, OSObject * anObject)
 {
@@ -666,7 +554,18 @@ IORegistryEntry::setProperty( const OSSymbol * aKey, OSObject * anObject)
 
     ret = getPropertyTable()->setObject( aKey, anObject );
     PUNLOCK;
-    
+
+#if KASLR_IOREG_DEBUG
+    if ( anObject && strcmp(kIOKitDiagnosticsKey, aKey->getCStringNoCopy()) != 0 ) {
+        if (ScanForAddrInObject(anObject, 0)) {
+            IOLog("%s: IORegistryEntry name %s with key \"%s\" \n",
+                  __FUNCTION__,
+                  getName(0),
+                  aKey->getCStringNoCopy() );        
+        }
+    }
+#endif
+
     return ret;
 }
 
@@ -987,10 +886,10 @@ bool IORegistryEntry::getPath(    char * path, int * length,
     OSArray *          stack;
     IORegistryEntry *  root;
     const IORegistryEntry * entry;
-    IORegistryEntry *  parent;
+    const IORegistryEntry * parent;
     const OSSymbol *   alias;
     int                        index;
-    int                        len, maxLength, compLen;
+    int                        len, maxLength, compLen, aliasLen;
     char *             nextComp;
     bool               ok;
 
@@ -1004,80 +903,76 @@ bool IORegistryEntry::getPath(   char * path, int * length,
     len = plane->nameKey->getLength();
     if( len >= maxLength)
        return( false);
-    strcpy( nextComp, plane->nameKey->getCStringNoCopy());
+    strlcpy( nextComp, plane->nameKey->getCStringNoCopy(), len + 1);
     nextComp[ len++ ] = ':';
     nextComp += len;
 
     if( (alias = hasAlias( plane ))) {
-       len += alias->getLength();
+       aliasLen = alias->getLength();
+       len += aliasLen;
        ok = (maxLength > len);
        *length = len;
        if( ok)
-           strcpy( nextComp, alias->getCStringNoCopy());
+           strlcpy( nextComp, alias->getCStringNoCopy(), aliasLen + 1);
        return( ok );
     }
 
-    entry = this;
-    parent = entry->getParentEntry( plane );
-    if( !parent)
-       // Error if not attached in plane
-       return( false);
-
     stack = OSArray::withCapacity( getDepth( plane ));
-    if( !stack)
-       return( false);
+    if (!stack) return( false);
 
     RLOCK;
 
+    parent = entry = this;
     root = gRegistryRoot->getChildEntry( plane );
-    while( parent && (entry != root)) {
+    while (parent && (parent != root))
+    {
        // stop below root
-       stack->setObject( (OSObject *) entry );
        entry = parent;
        parent = entry->getParentEntry( plane );
+       stack->setObject( (OSObject *) entry );
     }
 
-    index = stack->getCount();
-    ok = true;
-
-    if( 0 == index) {
+    ok = (0 != parent);
+    if (ok)
+    {
+        index = stack->getCount();
+        if( 0 == index) {
 
-        *nextComp++ = '/';
-        *nextComp = 0;
-        len++;
+            *nextComp++ = '/';
+            *nextComp = 0;
+            len++;
 
-    } else while( ok && ((--index) >= 0)) {
+        } else while( ok && ((--index) >= 0)) {
 
-        entry = (IORegistryEntry *) stack->getObject((unsigned int) index );
-        assert( entry );
+            entry = (IORegistryEntry *) stack->getObject((unsigned int) index );
+            assert( entry );
 
-        if( (alias = entry->hasAlias( plane ))) {
-            len = plane->nameKey->getLength() + 1;
-            nextComp = path + len;
+            if( (alias = entry->hasAlias( plane ))) {
+                len = plane->nameKey->getLength() + 1;
+                nextComp = path + len;
 
-            compLen = alias->getLength();
-            ok = (maxLength > len + compLen);
-            if( ok)
-                strcpy( nextComp, alias->getCStringNoCopy());
-        } else {
-            compLen = maxLength - len;
-            ok = entry->getPathComponent( nextComp + 1, &compLen, plane );
+                compLen = alias->getLength();
+                ok = (maxLength > (len + compLen));
+                if( ok)
+                    strlcpy( nextComp, alias->getCStringNoCopy(), compLen + 1);
+            } else {
+                compLen = maxLength - len;
+                ok = entry->getPathComponent( nextComp + 1, &compLen, plane );
 
-            if( ok && compLen) {
-                compLen++;
-                *nextComp = '/';
+                if( ok && compLen) {
+                    compLen++;
+                    *nextComp = '/';
+                }
             }
-        }
 
-        if( ok) {
-            len += compLen;
-            nextComp += compLen;
+            if( ok) {
+                len += compLen;
+                nextComp += compLen;
+            }
         }
+        *length = len;
     }
-    *length = len;
-
     UNLOCK;
-
     stack->release();
 
     return( ok );
@@ -1100,14 +995,14 @@ bool IORegistryEntry::getPathComponent( char * path, int * length,
     else
        locLen = 0;
 
-    ok = ((len + locLen) < maxLength);
+    ok = ((len + locLen + 1) < maxLength);
     if( ok) {
-        strcpy( path, compName );
+        strlcpy( path, compName, len + 1 );
        if( loc) {
             path += len;
             len += locLen;
             *path++ = '@';
-            strcpy( path, loc );
+            strlcpy( path, loc, locLen );
        }
         *length = len;
     }
@@ -1268,8 +1163,7 @@ const char * IORegistryEntry::dealiasPath(
         {}
     end--;
     if( (end - path) < kIOMaxPlaneName) {
-        strncpy( temp, path, end - path );
-        temp[ end - path ] = 0;
+        strlcpy( temp, path, end - path + 1 );
 
         RLOCK;
         entry = IORegistryEntry::fromPath( "/aliases", plane );
@@ -1312,8 +1206,7 @@ IORegistryEntry * IORegistryEntry::fromPath(
        // get plane name
         end = strchr( path, ':' );
        if( end && ((end - path) < kIOMaxPlaneName)) {
-           strncpy( temp, path, end - path );
-           temp[ end - path ] = 0;
+           strlcpy( temp, path, end - path + 1 );
             plane = getPlane( temp );
            path = end + 1;
        }
@@ -1364,10 +1257,10 @@ IORegistryEntry * IORegistryEntry::fromPath(
 
        if( opath && length) {
             // copy out residual path
-           len2 = len + strlen( path );
-           if( len2 < *length)
-                strcpy( opath + len, path );
-           *length = len2;
+           len2 = strlen( path );
+           if( (len + len2) < *length)
+                strlcpy( opath + len, path, len2 + 1 );
+           *length = (len + len2);
 
        } else if( path[0])
            // no residual path => must be no tail for success
@@ -1701,12 +1594,16 @@ bool IORegistryEntry::inPlane( const IORegistryPlane * plane ) const
            const OSSymbol *key;
 
             while( (key = (OSSymbol *) iter->getNextObject()) ) {
-               const char *keysuffix;
+               size_t keysuffix;
 
                // Get a pointer to this keys suffix
-               keysuffix = key->getCStringNoCopy()
-                         + key->getLength() - kIORegPlaneParentSuffixLen;
-               if( !strcmp(keysuffix, kIORegPlaneParentSuffix) ) {
+               keysuffix = key->getLength();
+               if (keysuffix <= kIORegPlaneParentSuffixLen)
+                   continue;
+               keysuffix -= kIORegPlaneParentSuffixLen;
+               if( !strncmp(key->getCStringNoCopy() + keysuffix, 
+                               kIORegPlaneParentSuffix, 
+                               kIORegPlaneParentSuffixLen + 1) ) {
                    ret = true;
                    break;
                }
@@ -1732,6 +1629,9 @@ bool IORegistryEntry::attachToParent( IORegistryEntry * parent,
 
     WLOCK;
 
+    if (!reserved->fRegistryEntryID)
+       reserved->fRegistryEntryID = ++gIORegistryLastID;
+
     ret = makeLink( parent, kParentSetIndex, plane );
 
     if( (links = parent->getChildSetReference( plane )))
@@ -1772,6 +1672,14 @@ bool IORegistryEntry::attachToParent( IORegistryEntry * parent,
     return( ret );
 }
 
+uint64_t IORegistryEntry::getRegistryEntryID( void )
+{
+    if (reserved)
+       return (reserved->fRegistryEntryID);
+    else
+       return (0);
+}
+
 bool IORegistryEntry::attachToChild( IORegistryEntry * child,
                                         const IORegistryPlane * plane )
 {
@@ -1856,8 +1764,11 @@ void IORegistryEntry::detachAbove( const IORegistryPlane * plane )
     IORegistryEntry *  parent;
 
     retain();
-    while( (parent = getParentEntry( plane )))
+    while( (parent = copyParentEntry( plane )))
+    {
        detachFromParent( parent, plane );
+       parent->release();
+    }
     release();
 }
 
@@ -2002,7 +1913,7 @@ void IORegistryIterator::enterEntry( const IORegistryPlane * enterPlane )
     IORegCursor *      prev;
 
     prev = where;
-    where = (IORegCursor *) IOMalloc( sizeof( IORegCursor));
+    where = (IORegCursor *) IOMalloc( sizeof(IORegCursor));
     assert( where);
 
     if( where) {
@@ -2032,7 +1943,7 @@ bool IORegistryIterator::exitEntry( void )
     if( where != &start) {
        gone = where;
         where = gone->next;
-        IOFree( gone, sizeof( IORegCursor));
+        IOFree( gone, sizeof(IORegCursor));
        return( true);
 
     } else
@@ -2148,13 +2059,21 @@ OSOrderedSet * IORegistryIterator::iterateAll( void )
     return( done);
 }
 
+#if __LP64__
+OSMetaClassDefineReservedUnused(IORegistryEntry, 0);
+OSMetaClassDefineReservedUnused(IORegistryEntry, 1);
+OSMetaClassDefineReservedUnused(IORegistryEntry, 2);
+OSMetaClassDefineReservedUnused(IORegistryEntry, 3);
+OSMetaClassDefineReservedUnused(IORegistryEntry, 4);
+OSMetaClassDefineReservedUnused(IORegistryEntry, 5);
+#else
 OSMetaClassDefineReservedUsed(IORegistryEntry, 0);
 OSMetaClassDefineReservedUsed(IORegistryEntry, 1);
 OSMetaClassDefineReservedUsed(IORegistryEntry, 2);
 OSMetaClassDefineReservedUsed(IORegistryEntry, 3);
 OSMetaClassDefineReservedUsed(IORegistryEntry, 4);
 OSMetaClassDefineReservedUsed(IORegistryEntry, 5);
-
+#endif
 OSMetaClassDefineReservedUnused(IORegistryEntry, 6);
 OSMetaClassDefineReservedUnused(IORegistryEntry, 7);
 OSMetaClassDefineReservedUnused(IORegistryEntry, 8);