]> git.saurik.com Git - apple/xnu.git/blobdiff - iokit/Kernel/IORegistryEntry.cpp
xnu-201.19.tar.gz
[apple/xnu.git] / iokit / Kernel / IORegistryEntry.cpp
index bb72bda03651e62e4df6ab86f87a384c9e00cbb6..4040b3cd0d25948d74c4861d75ce1eca0a2fec05 100644 (file)
@@ -98,6 +98,8 @@ static SInt32                 gIORegistryGenerationCount;
 #define registryTable()        fPropertyTable
 #endif
 
+#define DEBUG_FREE     1
+
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
 struct s_lock_t {
@@ -438,12 +440,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 +473,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
@@ -563,15 +558,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 ); \
         \
-        while ( (0 == obj) && (entry = iter->getNextObject()) ) { \
-            obj = entry->getProperty( aKey ); \
+        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 ); \
+        \
+        if(iter) { \
+            while ( (0 == obj) && (entry = iter->getNextObject()) ) { \
+                obj = entry->copyProperty( aKey ); \
+            } \
+            iter->release(); \
         } \
-        iter->release(); \
     } \
     \
     return( obj ); \
@@ -623,6 +644,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 +1057,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 +1106,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 +1127,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 )))
@@ -1402,21 +1433,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 +1495,7 @@ OSIterator * IORegistryEntry::getChildIterator( const IORegistryPlane * plane )
 }
 
 
-IORegistryEntry * IORegistryEntry::getChildEntry(
+IORegistryEntry * IORegistryEntry::copyChildEntry(
                                const IORegistryPlane * plane ) const
 {
     IORegistryEntry *  entry = 0;
@@ -1459,14 +1503,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 +1818,8 @@ unsigned int IORegistryEntry::getDepth( const IORegistryPlane * plane ) const
 
 OSDefineMetaClassAndStructors(IORegistryIterator, OSIterator)
 
+enum { kIORegistryIteratorInvalidFlag = 0x80000000 };
+
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
 IORegistryIterator *
@@ -1783,7 +1843,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 +1865,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 +1934,7 @@ void IORegistryIterator::reset( void )
     }
 
     where->current = root;
+    options &= ~kIORegistryIteratorInvalidFlag;
 }
 
 void IORegistryIterator::free( void )
@@ -1907,11 +1970,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 +2032,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);