2 * Copyright (c) 1998-2006 Apple Computer, Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 #include <IOKit/IORegistryEntry.h>
30 #include <libkern/c++/OSContainers.h>
31 #include <IOKit/IOService.h>
32 #include <IOKit/IOKitKeys.h>
33 #include <IOKit/IOTimeStamp.h>
35 #include <IOKit/IOLib.h>
37 #include <IOKit/assert.h>
39 #include "IOKitKernelInternal.h"
41 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
43 #define super OSObject
45 OSDefineMetaClassAndStructors(IORegistryEntry
, OSObject
)
47 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
49 #define kIORegPlaneParentSuffix "ParentLinks"
50 #define kIORegPlaneChildSuffix "ChildLinks"
51 #define kIORegPlaneNameSuffix "Name"
52 #define kIORegPlaneLocationSuffix "Location"
54 #define kIORegPlaneParentSuffixLen (sizeof(kIORegPlaneParentSuffix) - 1)
55 #define kIORegPlaneChildSuffixLen (sizeof(kIORegPlaneChildSuffix) - 1)
56 #define kIORegPlaneNameSuffixLen (sizeof(kIORegPlaneNameSuffix) - 1)
57 #define kIORegPlaneLocationSuffixLen (sizeof(kIORegPlaneLocationSuffix) - 1)
59 #define KASLR_IOREG_DEBUG 0
61 struct IORegistryEntry::ExpansionData
63 IORecursiveLock
* fLock
;
64 uint64_t fRegistryEntryID
;
65 SInt32 fRegistryEntryGenerationCount
;
69 static IORegistryEntry
* gRegistryRoot
;
70 static OSDictionary
* gIORegistryPlanes
;
72 const OSSymbol
* gIONameKey
;
73 const OSSymbol
* gIOLocationKey
;
74 const OSSymbol
* gIORegistryEntryIDKey
;
75 const OSSymbol
* gIORegistryEntryPropertyKeysKey
;
86 enum { kIORegistryIDReserved
= (1ULL << 32) + 255 };
88 static uint64_t gIORegistryLastID
= kIORegistryIDReserved
;
90 class IORegistryPlane
: public OSObject
{
92 friend class IORegistryEntry
;
94 OSDeclareAbstractStructors(IORegistryPlane
)
96 const OSSymbol
* nameKey
;
97 const OSSymbol
* keys
[ kNumSetIndex
];
98 const OSSymbol
* pathNameKey
;
99 const OSSymbol
* pathLocationKey
;
103 virtual bool serialize(OSSerialize
*s
) const APPLE_KEXT_OVERRIDE
;
106 OSDefineMetaClassAndStructors(IORegistryPlane
, OSObject
)
109 static IORecursiveLock
* gPropertiesLock
;
110 static SInt32 gIORegistryGenerationCount
;
112 #define UNLOCK lck_rw_done( &gIORegistryLock )
113 #define RLOCK lck_rw_lock_shared( &gIORegistryLock )
114 #define WLOCK lck_rw_lock_exclusive( &gIORegistryLock ); \
115 gIORegistryGenerationCount++
118 #define PUNLOCK IORecursiveLockUnlock( reserved->fLock )
119 #define PLOCK IORecursiveLockLock( reserved->fLock )
121 #define IOREGSPLITTABLES
123 #ifdef IOREGSPLITTABLES
124 #define registryTable() fRegistryTable
126 #define registryTable() fPropertyTable
131 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
133 lck_rw_t gIORegistryLock
;
134 lck_grp_t
*gIORegistryLockGrp
;
135 lck_grp_attr_t
*gIORegistryLockGrpAttr
;
136 lck_attr_t
*gIORegistryLockAttr
;
139 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
141 IORegistryEntry
* IORegistryEntry::initialize( void )
145 if( !gRegistryRoot
) {
148 gIORegistryLockGrpAttr
= lck_grp_attr_alloc_init();
149 //lck_grp_attr_setstat(gIORegistryLockGrpAttr);
150 gIORegistryLockGrp
= lck_grp_alloc_init("IORegistryLock", gIORegistryLockGrpAttr
);
151 gIORegistryLockAttr
= lck_attr_alloc_init();
152 lck_attr_rw_shared_priority(gIORegistryLockAttr
);
153 //lck_attr_setdebug(gIORegistryLockAttr);
154 lck_rw_init( &gIORegistryLock
, gIORegistryLockGrp
, gIORegistryLockAttr
);
156 gRegistryRoot
= new IORegistryEntry
;
157 gPropertiesLock
= IORecursiveLockAlloc();
158 gIORegistryPlanes
= OSDictionary::withCapacity( 1 );
160 assert( gRegistryRoot
&& gPropertiesLock
161 && gIORegistryPlanes
);
162 ok
= gRegistryRoot
->init();
165 gRegistryRoot
->reserved
->fRegistryEntryID
= ++gIORegistryLastID
;
167 gIONameKey
= OSSymbol::withCStringNoCopy( "IOName" );
168 gIOLocationKey
= OSSymbol::withCStringNoCopy( "IOLocation" );
169 gIORegistryEntryIDKey
= OSSymbol::withCStringNoCopy( kIORegistryEntryIDKey
);
170 gIORegistryEntryPropertyKeysKey
= OSSymbol::withCStringNoCopy( kIORegistryEntryPropertyKeysKey
);
172 assert( ok
&& gIONameKey
&& gIOLocationKey
);
174 gRegistryRoot
->setName( "Root" );
175 gRegistryRoot
->setProperty( kIORegistryPlanesKey
, gIORegistryPlanes
);
178 return( gRegistryRoot
);
181 IORegistryEntry
* IORegistryEntry::getRegistryRoot( void )
183 return( gRegistryRoot
);
186 SInt32
IORegistryEntry::getGenerationCount( void )
188 return( gIORegistryGenerationCount
);
191 SInt32
IORegistryEntry::getRegistryEntryGenerationCount(void) const
193 return (reserved
->fRegistryEntryGenerationCount
);
196 const IORegistryPlane
* IORegistryEntry::makePlane( const char * name
)
198 IORegistryPlane
* plane
;
199 const OSSymbol
* nameKey
;
200 const OSSymbol
* parentKey
;
201 const OSSymbol
* childKey
;
202 const OSSymbol
* pathNameKey
;
203 const OSSymbol
* pathLocationKey
;
204 char key
[ kIOMaxPlaneName
+ 16 ];
207 strlcpy( key
, name
, kIOMaxPlaneName
+ 1 );
208 end
= key
+ strlen( key
);
210 nameKey
= OSSymbol::withCString( key
);
212 strlcpy( end
, kIORegPlaneParentSuffix
, kIORegPlaneParentSuffixLen
+ 1 );
213 parentKey
= OSSymbol::withCString( key
);
215 strlcpy( end
, kIORegPlaneChildSuffix
, kIORegPlaneChildSuffixLen
+ 1 );
216 childKey
= OSSymbol::withCString( key
);
218 strlcpy( end
, kIORegPlaneNameSuffix
, kIORegPlaneNameSuffixLen
+ 1 );
219 pathNameKey
= OSSymbol::withCString( key
);
221 strlcpy( end
, kIORegPlaneLocationSuffix
, kIORegPlaneLocationSuffixLen
+ 1 );
222 pathLocationKey
= OSSymbol::withCString( key
);
224 plane
= new IORegistryPlane
;
226 if( plane
&& plane
->init()
227 && nameKey
&& parentKey
&& childKey
228 && pathNameKey
&& pathLocationKey
) {
230 plane
->nameKey
= nameKey
;
231 plane
->keys
[ kParentSetIndex
] = parentKey
;
232 plane
->keys
[ kChildSetIndex
] = childKey
;
233 plane
->pathNameKey
= pathNameKey
;
234 plane
->pathLocationKey
= pathLocationKey
;
237 gIORegistryPlanes
->setObject( nameKey
, plane
);
245 pathLocationKey
->release();
247 pathNameKey
->release();
249 parentKey
->release();
260 const IORegistryPlane
* IORegistryEntry::getPlane( const char * name
)
262 const IORegistryPlane
* plane
;
265 plane
= (const IORegistryPlane
*) gIORegistryPlanes
->getObject( name
);
271 bool IORegistryPlane::serialize(OSSerialize
*s
) const
273 return( nameKey
->serialize(s
) );
276 enum { kIORegCapacityIncrement
= 4 };
278 bool IORegistryEntry::init( OSDictionary
* dict
)
287 reserved
= IONew(ExpansionData
, 1);
290 bzero(reserved
, sizeof(ExpansionData
));
291 reserved
->fLock
= IORecursiveLockAlloc();
292 if (!reserved
->fLock
) return (false);
295 if (OSCollection::kImmutable
& dict
->setOptions(0, 0)) {
296 dict
= (OSDictionary
*) dict
->copyCollection();
302 fPropertyTable
->release();
303 fPropertyTable
= dict
;
305 } else if( !fPropertyTable
) {
306 fPropertyTable
= OSDictionary::withCapacity( kIORegCapacityIncrement
);
308 fPropertyTable
->setCapacityIncrement( kIORegCapacityIncrement
);
314 #ifdef IOREGSPLITTABLES
315 if( !fRegistryTable
) {
316 fRegistryTable
= OSDictionary::withCapacity( kIORegCapacityIncrement
);
318 fRegistryTable
->setCapacityIncrement( kIORegCapacityIncrement
);
321 if( (prop
= OSDynamicCast( OSString
, getProperty( gIONameKey
)))) {
322 OSSymbol
* sym
= (OSSymbol
*)OSSymbol::withString( prop
);
323 // ok for OSSymbol too
328 #endif /* IOREGSPLITTABLES */
333 bool IORegistryEntry::init( IORegistryEntry
* old
,
334 const IORegistryPlane
* plane
)
337 IORegistryEntry
* next
;
345 reserved
= IONew(ExpansionData
, 1);
346 if (!reserved
) return (false);
347 bzero(reserved
, sizeof(ExpansionData
));
348 reserved
->fLock
= IORecursiveLockAlloc();
349 if (!reserved
->fLock
) return (false);
354 reserved
->fRegistryEntryID
= old
->reserved
->fRegistryEntryID
;
356 fPropertyTable
= old
->dictionaryWithProperties();
357 #ifdef IOREGSPLITTABLES
358 fRegistryTable
= old
->fRegistryTable
;
359 old
->fRegistryTable
= (OSDictionary
*) fRegistryTable
->copyCollection();
360 #endif /* IOREGSPLITTABLES */
362 old
->registryTable()->removeObject( plane
->keys
[ kParentSetIndex
] );
363 old
->registryTable()->removeObject( plane
->keys
[ kChildSetIndex
] );
365 all
= getParentSetReference( plane
);
366 if( all
) for( index
= 0;
367 (next
= (IORegistryEntry
*) all
->getObject(index
));
369 next
->makeLink( this, kChildSetIndex
, plane
);
370 next
->breakLink( old
, kChildSetIndex
, plane
);
373 all
= getChildSetReference( plane
);
374 if( all
) for( index
= 0;
375 (next
= (IORegistryEntry
*) all
->getObject(index
));
377 next
->makeLink( this, kParentSetIndex
, plane
);
378 next
->breakLink( old
, kParentSetIndex
, plane
);
386 void IORegistryEntry::free( void )
389 if( registryTable() && gIOServicePlane
) {
390 if( getParentSetReference( gIOServicePlane
)
391 || getChildSetReference( gIOServicePlane
)) {
392 panic("%s: attached at free()", getName());
397 if( getPropertyTable())
398 getPropertyTable()->release();
400 #ifdef IOREGSPLITTABLES
402 registryTable()->release();
403 #endif /* IOREGSPLITTABLES */
407 if (reserved
->fLock
) IORecursiveLockFree(reserved
->fLock
);
408 IODelete(reserved
, ExpansionData
, 1);
414 void IORegistryEntry::setPropertyTable( OSDictionary
* dict
)
419 fPropertyTable
->release();
421 fPropertyTable
= dict
;
424 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
426 /* Wrappers to synchronize property table */
428 #define wrap2(type, constant) \
430 IORegistryEntry::copyProperty( type * aKey) constant \
435 obj = getProperty( aKey ); \
443 #define wrap4(type,constant) \
445 IORegistryEntry::getProperty( type * aKey, \
446 const IORegistryPlane * plane, \
447 IOOptionBits options ) constant \
449 OSObject * obj = getProperty( aKey ); \
451 if ( (0 == obj) && plane && (options & kIORegistryIterateRecursively) ) { \
452 IORegistryEntry * entry = (IORegistryEntry *) this; \
453 IORegistryIterator * iter; \
454 iter = IORegistryIterator::iterateOver( entry, plane, options ); \
457 while ( (0 == obj) && (entry = iter->getNextObject()) ) { \
458 obj = entry->getProperty( aKey ); \
467 #define wrap5(type,constant) \
469 IORegistryEntry::copyProperty( type * aKey, \
470 const IORegistryPlane * plane, \
471 IOOptionBits options ) constant \
473 OSObject * obj = copyProperty( aKey ); \
475 if ( (0 == obj) && plane && (options & kIORegistryIterateRecursively) ) { \
476 IORegistryEntry * entry = (IORegistryEntry *) this; \
477 IORegistryIterator * iter; \
478 iter = IORegistryIterator::iterateOver( entry, plane, options ); \
481 while ( (0 == obj) && (entry = iter->getNextObject()) ) { \
482 obj = entry->copyProperty( aKey ); \
491 bool IORegistryEntry::serializeProperties( OSSerialize
* s
) const
493 // setProperty( getRetainCount(), 32, "__retain" );
496 OSCollection
*snapshotProperties
= getPropertyTable()->copyCollection();
499 if (!snapshotProperties
) return (false);
501 bool ok
= snapshotProperties
->serialize( s
);
502 snapshotProperties
->release();
506 OSArray
* IORegistryEntry::copyPropertyKeys(void) const
509 OSArray
* keys
= getPropertyTable()->copyKeys();
515 OSDictionary
* IORegistryEntry::dictionaryWithProperties( void ) const
520 dict
= OSDictionary::withDictionary( getPropertyTable(),
521 getPropertyTable()->getCapacity() );
527 IOReturn
IORegistryEntry::setProperties( OSObject
* properties
)
529 return( kIOReturnUnsupported
);
532 wrap2(const OSSymbol
, const) // copyProperty() definition
533 wrap2(const OSString
, const) // copyProperty() definition
534 wrap2(const char, const) // copyProperty() definition
536 wrap4(const OSSymbol
, const) // getProperty() w/plane definition
537 wrap4(const OSString
, const) // getProperty() w/plane definition
538 wrap4(const char, const) // getProperty() w/plane definition
540 wrap5(const OSSymbol
, const) // copyProperty() w/plane definition
541 wrap5(const OSString
, const) // copyProperty() w/plane definition
542 wrap5(const char, const) // copyProperty() w/plane definition
546 IORegistryEntry::getProperty( const OSSymbol
* aKey
) const
551 obj
= getPropertyTable()->getObject( aKey
);
558 IORegistryEntry::removeProperty( const OSSymbol
* aKey
)
561 getPropertyTable()->removeObject( aKey
);
565 #if KASLR_IOREG_DEBUG
568 bool ScanForAddrInObject(OSObject
* theObject
,
575 IORegistryEntry::setProperty( const OSSymbol
* aKey
, OSObject
* anObject
)
579 // If we are inserting a collection class and the current entry
580 // is attached into the registry (inPlane()) then mark the collection
582 OSCollection
*coll
= OSDynamicCast(OSCollection
, anObject
);
583 bool makeImmutable
= (coll
&& inPlane());
587 coll
->setOptions( OSCollection::kMASK
, OSCollection::kImmutable
);
589 ret
= getPropertyTable()->setObject( aKey
, anObject
);
592 #if KASLR_IOREG_DEBUG
593 if ( anObject
&& strcmp(kIOKitDiagnosticsKey
, aKey
->getCStringNoCopy()) != 0 ) {
594 if (ScanForAddrInObject(anObject
, 0)) {
595 IOLog("%s: IORegistryEntry name %s with key \"%s\" \n",
598 aKey
->getCStringNoCopy() );
606 IOReturn
IORegistryEntry::
607 runPropertyAction(Action inAction
, OSObject
*target
,
608 void *arg0
, void *arg1
, void *arg2
, void *arg3
)
612 // closeGate is recursive so don't worry if we already hold the lock.
614 res
= (*inAction
)(target
, arg0
, arg1
, arg2
, arg3
);
621 IORegistryEntry::getProperty( const OSString
* aKey
) const
623 const OSSymbol
* tmpKey
= OSSymbol::withString( aKey
);
624 OSObject
* obj
= getProperty( tmpKey
);
631 IORegistryEntry::getProperty( const char * aKey
) const
633 const OSSymbol
* tmpKey
= OSSymbol::withCString( aKey
);
634 OSObject
* obj
= getProperty( tmpKey
);
642 IORegistryEntry::removeProperty( const OSString
* aKey
)
644 const OSSymbol
* tmpKey
= OSSymbol::withString( aKey
);
645 removeProperty( tmpKey
);
650 IORegistryEntry::removeProperty( const char * aKey
)
652 const OSSymbol
* tmpKey
= OSSymbol::withCString( aKey
);
653 removeProperty( tmpKey
);
658 IORegistryEntry::setProperty( const OSString
* aKey
, OSObject
* anObject
)
660 const OSSymbol
* tmpKey
= OSSymbol::withString( aKey
);
661 bool ret
= setProperty( tmpKey
, anObject
);
668 IORegistryEntry::setProperty( const char * aKey
, OSObject
* anObject
)
670 const OSSymbol
* tmpKey
= OSSymbol::withCString( aKey
);
671 bool ret
= setProperty( tmpKey
, anObject
);
678 IORegistryEntry::setProperty(const char * aKey
, const char * aString
)
681 OSSymbol
* aSymbol
= (OSSymbol
*) OSSymbol::withCString( aString
);
684 const OSSymbol
* tmpKey
= OSSymbol::withCString( aKey
);
685 ret
= setProperty( tmpKey
, aSymbol
);
694 IORegistryEntry::setProperty(const char * aKey
, bool aBoolean
)
697 OSBoolean
* aBooleanObj
= OSBoolean::withBoolean( aBoolean
);
700 const OSSymbol
* tmpKey
= OSSymbol::withCString( aKey
);
701 ret
= setProperty( tmpKey
, aBooleanObj
);
704 aBooleanObj
->release();
710 IORegistryEntry::setProperty( const char * aKey
,
711 unsigned long long aValue
,
712 unsigned int aNumberOfBits
)
715 OSNumber
* anOffset
= OSNumber::withNumber( aValue
, aNumberOfBits
);
718 const OSSymbol
* tmpKey
= OSSymbol::withCString( aKey
);
719 ret
= setProperty( tmpKey
, anOffset
);
728 IORegistryEntry::setProperty( const char * aKey
,
733 OSData
* data
= OSData::withBytes( bytes
, length
);
736 const OSSymbol
* tmpKey
= OSSymbol::withCString( aKey
);
737 ret
= setProperty( tmpKey
, data
);
745 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
747 /* Name, location, paths */
749 const char * IORegistryEntry::getName( const IORegistryPlane
* plane
) const
755 sym
= (OSSymbol
*) registryTable()->getObject( plane
->pathNameKey
);
757 sym
= (OSSymbol
*) registryTable()->getObject( gIONameKey
);
761 return( sym
->getCStringNoCopy());
763 return( (getMetaClass())->getClassName());
766 const OSSymbol
* IORegistryEntry::copyName(
767 const IORegistryPlane
* plane
) const
773 sym
= (OSSymbol
*) registryTable()->getObject( plane
->pathNameKey
);
775 sym
= (OSSymbol
*) registryTable()->getObject( gIONameKey
);
783 return( OSSymbol::withCString((getMetaClass())->getClassName()) );
786 const OSSymbol
* IORegistryEntry::copyLocation(
787 const IORegistryPlane
* plane
) const
793 sym
= (OSSymbol
*) registryTable()->getObject( plane
->pathLocationKey
);
795 sym
= (OSSymbol
*) registryTable()->getObject( gIOLocationKey
);
803 const char * IORegistryEntry::getLocation( const IORegistryPlane
* plane
) const
805 const OSSymbol
* sym
= copyLocation( plane
);
806 const char * result
= 0;
809 result
= sym
->getCStringNoCopy();
816 void IORegistryEntry::setName( const OSSymbol
* name
,
817 const IORegistryPlane
* plane
)
819 const OSSymbol
* key
;
823 key
= plane
->pathNameKey
;
827 if (gIOKitTrace
&& reserved
&& reserved
->fRegistryEntryID
)
830 uint64_t __unused regID
= getRegistryEntryID();
831 kernel_debug_string(IODBG_IOREGISTRY(IOREGISTRYENTRY_NAME_STRING
), &str_id
, name
->getCStringNoCopy());
832 KERNEL_DEBUG_CONSTANT(IODBG_IOREGISTRY(IOREGISTRYENTRY_NAME
),
834 (uintptr_t) (regID
>> 32),
836 (uintptr_t) (str_id
>> 32),
841 registryTable()->setObject( key
, (OSObject
*) name
);
846 void IORegistryEntry::setName( const char * name
,
847 const IORegistryPlane
* plane
)
849 OSSymbol
* sym
= (OSSymbol
*)OSSymbol::withCString( name
);
851 setName( sym
, plane
);
856 void IORegistryEntry::setLocation( const OSSymbol
* location
,
857 const IORegistryPlane
* plane
)
859 const OSSymbol
* key
;
863 key
= plane
->pathLocationKey
;
865 key
= gIOLocationKey
;
868 registryTable()->setObject( key
, (OSObject
*) location
);
873 void IORegistryEntry::setLocation( const char * location
,
874 const IORegistryPlane
* plane
)
876 OSSymbol
* sym
= (OSSymbol
*)OSSymbol::withCString( location
);
878 setLocation( sym
, plane
);
884 IORegistryEntry::compareName( OSString
* name
, OSString
** matched
) const
886 const OSSymbol
* sym
= copyName();
889 isEqual
= sym
->isEqualTo( name
);
891 if( isEqual
&& matched
) {
903 IORegistryEntry::compareNames( OSObject
* names
, OSString
** matched
) const
906 OSCollection
* collection
;
907 OSIterator
* iter
= 0;
910 if( (collection
= OSDynamicCast( OSCollection
, names
))) {
911 iter
= OSCollectionIterator::withCollection( collection
);
914 string
= OSDynamicCast( OSString
, names
);
918 result
= compareName( string
, matched
);
920 } while( (false == result
)
921 && iter
&& (string
= OSDynamicCast( OSString
, iter
->getNextObject())));
930 bool IORegistryEntry::getPath( char * path
, int * length
,
931 const IORegistryPlane
* plane
) const
934 IORegistryEntry
* root
;
935 const IORegistryEntry
* entry
;
936 const IORegistryEntry
* parent
;
937 const OSSymbol
* alias
;
939 int len
, maxLength
, compLen
, aliasLen
;
943 if( !path
|| !length
|| !plane
)
947 maxLength
= *length
- 2;
950 len
= plane
->nameKey
->getLength();
951 if( len
>= maxLength
)
953 strlcpy( nextComp
, plane
->nameKey
->getCStringNoCopy(), len
+ 1);
954 nextComp
[ len
++ ] = ':';
957 if( (alias
= hasAlias( plane
))) {
958 aliasLen
= alias
->getLength();
960 ok
= (maxLength
> len
);
963 strlcpy( nextComp
, alias
->getCStringNoCopy(), aliasLen
+ 1);
967 stack
= OSArray::withCapacity( getDepth( plane
));
968 if (!stack
) return( false);
972 parent
= entry
= this;
973 root
= gRegistryRoot
->getChildEntry( plane
);
974 while (parent
&& (parent
!= root
))
978 parent
= entry
->getParentEntry( plane
);
979 stack
->setObject( (OSObject
*) entry
);
985 index
= stack
->getCount();
992 } else while( ok
&& ((--index
) >= 0)) {
994 entry
= (IORegistryEntry
*) stack
->getObject((unsigned int) index
);
997 if( (alias
= entry
->hasAlias( plane
))) {
998 len
= plane
->nameKey
->getLength() + 1;
999 nextComp
= path
+ len
;
1001 compLen
= alias
->getLength();
1002 ok
= (maxLength
> (len
+ compLen
));
1004 strlcpy( nextComp
, alias
->getCStringNoCopy(), compLen
+ 1);
1006 compLen
= maxLength
- len
;
1007 ok
= entry
->getPathComponent( nextComp
+ 1, &compLen
, plane
);
1009 if( ok
&& compLen
) {
1017 nextComp
+= compLen
;
1028 bool IORegistryEntry::getPathComponent( char * path
, int * length
,
1029 const IORegistryPlane
* plane
) const
1031 int len
, locLen
, maxLength
;
1032 const char * compName
;
1036 maxLength
= *length
;
1038 compName
= getName( plane
);
1039 len
= strlen( compName
);
1040 if( (loc
= getLocation( plane
)))
1041 locLen
= 1 + strlen( loc
);
1045 ok
= ((len
+ locLen
+ 1) < maxLength
);
1047 strlcpy( path
, compName
, len
+ 1 );
1052 strlcpy( path
, loc
, locLen
);
1060 const char * IORegistryEntry::matchPathLocation( const char * cmp
,
1061 const IORegistryPlane
* plane
)
1064 const char * result
= 0;
1065 u_quad_t num1
, num2
;
1066 char lastPathChar
, lastLocationChar
;
1068 str
= getLocation( plane
);
1070 lastPathChar
= cmp
[0];
1071 lastLocationChar
= str
[0];
1074 num1
= strtouq( cmp
, (char **) &cmp
, 16 );
1075 lastPathChar
= *cmp
++;
1079 if( lastLocationChar
) {
1080 num2
= strtouq( str
, (char **) &str
, 16 );
1081 lastLocationChar
= *str
++;
1088 if (!lastPathChar
&& !lastLocationChar
) {
1093 if( (',' != lastPathChar
) && (':' != lastPathChar
))
1096 if (lastPathChar
&& lastLocationChar
&& (lastPathChar
!= lastLocationChar
))
1105 IORegistryEntry
* IORegistryEntry::getChildFromComponent( const char ** opath
,
1106 const IORegistryPlane
* plane
)
1108 IORegistryEntry
* entry
= 0;
1112 const char * cmp
= 0;
1117 set
= getChildSetReference( plane
);
1123 (entry
= (IORegistryEntry
*) set
->getObject(index
));
1129 str
= entry
->getName( plane
);
1130 len
= strlen( str
);
1131 if( strncmp( str
, cmp
, len
))
1136 if( (c
== 0) || (c
== '/') || (c
== ':'))
1142 if( (cmp
= entry
->matchPathLocation( cmp
, plane
)))
1152 const OSSymbol
* IORegistryEntry::hasAlias( const IORegistryPlane
* plane
,
1153 char * opath
, int * length
) const
1155 IORegistryEntry
* entry
;
1156 IORegistryEntry
* entry2
;
1157 const OSSymbol
* key
;
1158 const OSSymbol
* bestKey
= 0;
1161 const char * path
= "/aliases";
1163 entry
= IORegistryEntry::fromPath( path
, plane
);
1166 if( (iter
= OSCollectionIterator::withCollection(
1167 entry
->getPropertyTable() ))) {
1169 while( (key
= (OSSymbol
*) iter
->getNextObject())) {
1171 data
= (OSData
*) entry
->getProperty( key
);
1172 path
= (const char *) data
->getBytesNoCopy();
1173 if( (entry2
= IORegistryEntry::fromPath( path
, plane
,
1175 if( this == entry2
) {
1177 || (bestKey
->getLength() > key
->getLength()))
1178 // pick the smallest alias
1192 const char * IORegistryEntry::dealiasPath(
1193 const char ** opath
,
1194 const IORegistryPlane
* plane
)
1196 IORegistryEntry
* entry
;
1198 const char * path
= *opath
;
1199 const char * rpath
= 0;
1202 char temp
[ kIOMaxPlaneName
+ 1 ];
1209 while( (c
= *end
++) && (c
!= '/') && (c
!= ':'))
1212 if( (end
- path
) < kIOMaxPlaneName
) {
1213 strlcpy( temp
, path
, end
- path
+ 1 );
1216 entry
= IORegistryEntry::fromPath( "/aliases", plane
);
1218 data
= (OSData
*) entry
->getProperty( temp
);
1220 rpath
= (const char *) data
->getBytesNoCopy();
1232 IORegistryEntry
* IORegistryEntry::fromPath(
1234 const IORegistryPlane
* plane
,
1237 IORegistryEntry
* fromEntry
)
1239 IORegistryEntry
* where
= 0;
1240 IORegistryEntry
* aliasEntry
= 0;
1241 IORegistryEntry
* next
;
1247 char temp
[ kIOMaxPlaneName
+ 1 ];
1254 end
= strchr( path
, ':' );
1255 if( end
&& ((end
- path
) < kIOMaxPlaneName
)) {
1256 strlcpy( temp
, path
, end
- path
+ 1 );
1257 plane
= getPlane( temp
);
1266 if( (alias
= dealiasPath( &end
, plane
))) {
1269 aliasEntry
= IORegistryEntry::fromPath( alias
, plane
,
1270 opath
, &len
, fromEntry
);
1282 if( (0 == fromEntry
) && (*path
++ == '/'))
1283 fromEntry
= gRegistryRoot
->getChildEntry( plane
);
1290 if( c
&& (c
!= ':')) // check valid terminator
1295 next
= where
->getChildFromComponent( &path
, plane
);
1301 // check residual path
1302 if( where
!= fromEntry
)
1305 if( opath
&& length
) {
1306 // copy out residual path
1307 len2
= strlen( path
);
1308 if( (len
+ len2
) < *length
)
1309 strlcpy( opath
+ len
, path
, len2
+ 1 );
1310 *length
= (len
+ len2
);
1313 // no residual path => must be no tail for success
1320 aliasEntry
->release();
1327 IORegistryEntry
* IORegistryEntry::childFromPath(
1329 const IORegistryPlane
* plane
,
1333 return( IORegistryEntry::fromPath( path
, plane
, opath
, len
, this ));
1336 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1338 #define IOLinkIterator OSCollectionIterator
1341 #define super OSObject
1343 inline bool IORegistryEntry::arrayMember( OSArray
* set
,
1344 const IORegistryEntry
* member
,
1345 unsigned int * index
) const
1348 OSObject
* probeObject
;
1350 for( i
= 0; (probeObject
= set
->getObject(i
)); i
++) {
1351 if (probeObject
== (OSObject
*) member
) {
1360 bool IORegistryEntry::makeLink( IORegistryEntry
* to
,
1361 unsigned int relation
,
1362 const IORegistryPlane
* plane
) const
1365 bool result
= false;
1367 if( (links
= (OSArray
*)
1368 registryTable()->getObject( plane
->keys
[ relation
] ))) {
1370 result
= arrayMember( links
, to
);
1372 result
= links
->setObject( to
);
1376 links
= OSArray::withObjects( (const OSObject
**) &to
, 1, 1 );
1377 result
= (links
!= 0);
1379 result
= registryTable()->setObject( plane
->keys
[ relation
],
1384 reserved
->fRegistryEntryGenerationCount
++;
1389 void IORegistryEntry::breakLink( IORegistryEntry
* to
,
1390 unsigned int relation
,
1391 const IORegistryPlane
* plane
) const
1396 if( (links
= (OSArray
*)
1397 registryTable()->getObject( plane
->keys
[ relation
]))) {
1399 if( arrayMember( links
, to
, &index
)) {
1400 links
->removeObject( index
);
1401 if( 0 == links
->getCount())
1402 registryTable()->removeObject( plane
->keys
[ relation
]);
1405 reserved
->fRegistryEntryGenerationCount
++;
1409 OSArray
* IORegistryEntry::getParentSetReference(
1410 const IORegistryPlane
* plane
) const
1413 return( (OSArray
*) registryTable()->getObject(
1414 plane
->keys
[ kParentSetIndex
]));
1419 OSIterator
* IORegistryEntry::getParentIterator(
1420 const IORegistryPlane
* plane
) const
1429 links
= getParentSetReference( plane
);
1431 links
= OSArray::withCapacity( 1 );
1433 links
= OSArray::withArray( links
, links
->getCount() );
1436 iter
= IOLinkIterator::withCollection( links
);
1444 IORegistryEntry
* IORegistryEntry::copyParentEntry( const IORegistryPlane
* plane
) const
1446 IORegistryEntry
* entry
= 0;
1451 if( (links
= getParentSetReference( plane
))) {
1452 entry
= (IORegistryEntry
*) links
->getObject( 0 );
1461 IORegistryEntry
* IORegistryEntry::getParentEntry( const IORegistryPlane
* plane
) const
1463 IORegistryEntry
* entry
;
1465 entry
= copyParentEntry( plane
);
1472 OSArray
* IORegistryEntry::getChildSetReference( const IORegistryPlane
* plane
) const
1475 return( (OSArray
*) registryTable()->getObject(
1476 plane
->keys
[ kChildSetIndex
]));
1481 OSIterator
* IORegistryEntry::getChildIterator( const IORegistryPlane
* plane
) const
1490 links
= getChildSetReference( plane
);
1492 links
= OSArray::withCapacity( 1 );
1494 links
= OSArray::withArray( links
, links
->getCount() );
1497 iter
= IOLinkIterator::withCollection( links
);
1505 uint32_t IORegistryEntry::getChildCount( const IORegistryPlane
* plane
) const
1511 links
= getChildSetReference( plane
);
1512 if (links
) count
= links
->getCount();
1518 IORegistryEntry
* IORegistryEntry::copyChildEntry(
1519 const IORegistryPlane
* plane
) const
1521 IORegistryEntry
* entry
= 0;
1526 if( (links
= getChildSetReference( plane
))) {
1527 entry
= (IORegistryEntry
*) links
->getObject( 0 );
1536 IORegistryEntry
* IORegistryEntry::getChildEntry(
1537 const IORegistryPlane
* plane
) const
1539 IORegistryEntry
* entry
;
1541 entry
= copyChildEntry( plane
);
1548 void IORegistryEntry::applyToChildren( IORegistryEntryApplierFunction applier
,
1550 const IORegistryPlane
* plane
) const
1554 IORegistryEntry
* next
;
1560 array
= OSArray::withArray( getChildSetReference( plane
));
1564 (next
= (IORegistryEntry
*) array
->getObject( index
));
1566 (*applier
)(next
, context
);
1571 void IORegistryEntry::applyToParents( IORegistryEntryApplierFunction applier
,
1573 const IORegistryPlane
* plane
) const
1577 IORegistryEntry
* next
;
1583 array
= OSArray::withArray( getParentSetReference( plane
));
1587 (next
= (IORegistryEntry
*) array
->getObject( index
));
1589 (*applier
)(next
, context
);
1594 bool IORegistryEntry::isChild( IORegistryEntry
* child
,
1595 const IORegistryPlane
* plane
,
1596 bool onlyChild
) const
1603 if( (links
= getChildSetReference( plane
))) {
1604 if( (!onlyChild
) || (1 == links
->getCount()))
1605 ret
= arrayMember( links
, child
);
1607 if( ret
&& (links
= child
->getParentSetReference( plane
)))
1608 ret
= arrayMember( links
, this );
1615 bool IORegistryEntry::isParent( IORegistryEntry
* parent
,
1616 const IORegistryPlane
* plane
,
1617 bool onlyParent
) const
1625 if( (links
= getParentSetReference( plane
))) {
1626 if( (!onlyParent
) || (1 == links
->getCount()))
1627 ret
= arrayMember( links
, parent
);
1629 if( ret
&& (links
= parent
->getChildSetReference( plane
)))
1630 ret
= arrayMember( links
, this );
1637 bool IORegistryEntry::inPlane( const IORegistryPlane
* plane
) const
1644 ret
= (0 != getParentSetReference( plane
));
1647 // Check to see if this is in any plane. If it is in a plane
1648 // then the registryTable will contain a key with the ParentLinks
1649 // suffix. When we iterate over the keys looking for that suffix
1652 OSCollectionIterator
*iter
=
1653 OSCollectionIterator::withCollection( registryTable());
1655 const OSSymbol
*key
;
1657 while( (key
= (OSSymbol
*) iter
->getNextObject()) ) {
1660 // Get a pointer to this keys suffix
1661 keysuffix
= key
->getLength();
1662 if (keysuffix
<= kIORegPlaneParentSuffixLen
)
1664 keysuffix
-= kIORegPlaneParentSuffixLen
;
1665 if( !strncmp(key
->getCStringNoCopy() + keysuffix
,
1666 kIORegPlaneParentSuffix
,
1667 kIORegPlaneParentSuffixLen
+ 1) ) {
1681 bool IORegistryEntry::attachToParent( IORegistryEntry
* parent
,
1682 const IORegistryPlane
* plane
)
1687 bool traceName
= false;
1694 if (!reserved
->fRegistryEntryID
)
1696 reserved
->fRegistryEntryID
= ++gIORegistryLastID
;
1697 traceName
= (0 != gIOKitTrace
);
1700 ret
= makeLink( parent
, kParentSetIndex
, plane
);
1702 if( (links
= parent
->getChildSetReference( plane
)))
1703 needParent
= (false == arrayMember( links
, this ));
1711 uint64_t str_id
= 0;
1712 uint64_t __unused regID
= getRegistryEntryID();
1713 kernel_debug_string(IODBG_IOREGISTRY(IOREGISTRYENTRY_NAME_STRING
), &str_id
, getName());
1714 KERNEL_DEBUG_CONSTANT(IODBG_IOREGISTRY(IOREGISTRYENTRY_NAME
),
1716 (uintptr_t) (regID
>> 32),
1718 (uintptr_t) (str_id
>> 32),
1724 // Mark any collections in the property list as immutable
1725 OSDictionary
*ptable
= getPropertyTable();
1726 OSCollectionIterator
*iter
=
1727 OSCollectionIterator::withCollection( ptable
);
1729 const OSSymbol
*key
;
1731 while( (key
= (OSSymbol
*) iter
->getNextObject( ))) {
1732 // Is object for key a collection?
1733 OSCollection
*coll
=
1734 OSDynamicCast( OSCollection
, ptable
->getObject( key
));
1737 // Yup so mark it as immutable
1738 coll
->setOptions( OSCollection::kMASK
,
1739 OSCollection::kImmutable
);
1748 ret
&= parent
->attachToChild( this, plane
);
1753 uint64_t IORegistryEntry::getRegistryEntryID( void )
1756 return (reserved
->fRegistryEntryID
);
1761 bool IORegistryEntry::attachToChild( IORegistryEntry
* child
,
1762 const IORegistryPlane
* plane
)
1773 ret
= makeLink( child
, kChildSetIndex
, plane
);
1775 if( (links
= child
->getParentSetReference( plane
)))
1776 needChild
= (false == arrayMember( links
, this ));
1783 ret
&= child
->attachToParent( this, plane
);
1788 void IORegistryEntry::detachFromParent( IORegistryEntry
* parent
,
1789 const IORegistryPlane
* plane
)
1798 breakLink( parent
, kParentSetIndex
, plane
);
1800 if( (links
= parent
->getChildSetReference( plane
)))
1801 needParent
= arrayMember( links
, this );
1805 // parent->breakLink( this, kChildSetIndex, plane );
1810 parent
->detachFromChild( this, plane
);
1815 void IORegistryEntry::detachFromChild( IORegistryEntry
* child
,
1816 const IORegistryPlane
* plane
)
1825 breakLink( child
, kChildSetIndex
, plane
);
1827 if( (links
= child
->getParentSetReference( plane
)))
1828 needChild
= arrayMember( links
, this );
1835 child
->detachFromParent( this, plane
);
1840 void IORegistryEntry::detachAbove( const IORegistryPlane
* plane
)
1842 IORegistryEntry
* parent
;
1845 while( (parent
= copyParentEntry( plane
)))
1847 detachFromParent( parent
, plane
);
1853 void IORegistryEntry::detachAll( const IORegistryPlane
* plane
)
1856 IORegistryEntry
* next
;
1857 IORegistryIterator
* regIter
;
1859 regIter
= IORegistryIterator::iterateOver( this, plane
, true );
1862 all
= regIter
->iterateAll();
1865 detachAbove( plane
);
1867 while( (next
= (IORegistryEntry
*) all
->getLastObject())) {
1870 all
->removeObject(next
);
1872 next
->detachAbove( plane
);
1879 unsigned int IORegistryEntry::getDepth( const IORegistryPlane
* plane
) const
1881 unsigned int depth
= 1;
1883 unsigned int oneDepth
, maxParentDepth
, count
;
1884 IORegistryEntry
* one
;
1885 const IORegistryEntry
* next
;
1891 while( (parents
= next
->getParentSetReference( plane
))) {
1893 count
= parents
->getCount();
1898 next
= (IORegistryEntry
*) parents
->getObject( 0 );
1903 (one
= (IORegistryEntry
*) parents
->getObject( index
));
1905 oneDepth
= one
->getDepth( plane
);
1906 if( oneDepth
> maxParentDepth
)
1907 maxParentDepth
= oneDepth
;
1909 depth
+= maxParentDepth
;
1919 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1922 #define super OSIterator
1924 OSDefineMetaClassAndStructors(IORegistryIterator
, OSIterator
)
1926 enum { kIORegistryIteratorInvalidFlag
= 0x80000000 };
1928 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1930 IORegistryIterator
*
1931 IORegistryIterator::iterateOver( IORegistryEntry
* root
,
1932 const IORegistryPlane
* plane
,
1933 IOOptionBits options
)
1935 IORegistryIterator
* create
;
1942 create
= new IORegistryIterator
;
1944 if( create
->init()) {
1947 create
->root
= root
;
1948 create
->where
= &create
->start
;
1949 create
->start
.current
= root
;
1950 create
->plane
= plane
;
1951 create
->options
= options
& ~kIORegistryIteratorInvalidFlag
;
1961 IORegistryIterator
*
1962 IORegistryIterator::iterateOver( const IORegistryPlane
* plane
,
1963 IOOptionBits options
)
1965 return( iterateOver( gRegistryRoot
, plane
, options
));
1968 bool IORegistryIterator::isValid( void )
1977 ok
= (0 == (kIORegistryIteratorInvalidFlag
& options
));
1979 while( ok
&& next
) {
1981 ok
= where
->iter
->isValid();
1989 void IORegistryIterator::enterEntry( const IORegistryPlane
* enterPlane
)
1994 where
= (IORegCursor
*) IOMalloc( sizeof(IORegCursor
));
2000 where
->current
= prev
->current
;
2005 void IORegistryIterator::enterEntry( void )
2007 enterEntry( plane
);
2010 bool IORegistryIterator::exitEntry( void )
2015 where
->iter
->release();
2017 if( where
->current
)// && (where != &start))
2018 where
->current
->release();
2021 if( where
!= &start
) {
2024 IOFree( gone
, sizeof(IORegCursor
));
2031 void IORegistryIterator::reset( void )
2041 where
->current
= root
;
2042 options
&= ~kIORegistryIteratorInvalidFlag
;
2045 void IORegistryIterator::free( void )
2056 IORegistryEntry
* IORegistryIterator::getNextObjectFlat( void )
2058 IORegistryEntry
* next
= 0;
2059 OSArray
* links
= 0;
2063 if( (0 == where
->iter
)) {
2064 // just entered - create new iter
2067 && (links
= ( (options
& kIORegistryIterateParents
) ?
2068 where
->current
->getParentSetReference( plane
) :
2069 where
->current
->getChildSetReference( plane
) )) )
2071 where
->iter
= OSCollectionIterator::withCollection( links
);
2074 // next sibling - release current
2076 where
->current
->release();
2080 next
= (IORegistryEntry
*) where
->iter
->getNextObject();
2084 else if( !where
->iter
->isValid())
2085 options
|= kIORegistryIteratorInvalidFlag
;
2088 where
->current
= next
;
2095 IORegistryEntry
* IORegistryIterator::getNextObjectRecursive( void )
2097 IORegistryEntry
* next
;
2100 next
= getNextObjectFlat();
2101 while( (0 == next
) && exitEntry());
2105 done
= OSOrderedSet::withCapacity( 10 );
2106 if( done
->setObject((OSObject
*) next
)) {
2107 // done set didn't contain this one, so recurse
2114 IORegistryEntry
* IORegistryIterator::getNextObject( void )
2116 if( options
& kIORegistryIterateRecursively
)
2117 return( getNextObjectRecursive());
2119 return( getNextObjectFlat());
2122 IORegistryEntry
* IORegistryIterator::getCurrentEntry( void )
2125 return( where
->current
);
2130 OSOrderedSet
* IORegistryIterator::iterateAll( void )
2133 while( getNextObjectRecursive())
2141 OSMetaClassDefineReservedUnused(IORegistryEntry
, 0);
2142 OSMetaClassDefineReservedUnused(IORegistryEntry
, 1);
2143 OSMetaClassDefineReservedUnused(IORegistryEntry
, 2);
2144 OSMetaClassDefineReservedUnused(IORegistryEntry
, 3);
2145 OSMetaClassDefineReservedUnused(IORegistryEntry
, 4);
2146 OSMetaClassDefineReservedUnused(IORegistryEntry
, 5);
2148 OSMetaClassDefineReservedUsed(IORegistryEntry
, 0);
2149 OSMetaClassDefineReservedUsed(IORegistryEntry
, 1);
2150 OSMetaClassDefineReservedUsed(IORegistryEntry
, 2);
2151 OSMetaClassDefineReservedUsed(IORegistryEntry
, 3);
2152 OSMetaClassDefineReservedUsed(IORegistryEntry
, 4);
2153 OSMetaClassDefineReservedUsed(IORegistryEntry
, 5);
2155 OSMetaClassDefineReservedUnused(IORegistryEntry
, 6);
2156 OSMetaClassDefineReservedUnused(IORegistryEntry
, 7);
2157 OSMetaClassDefineReservedUnused(IORegistryEntry
, 8);
2158 OSMetaClassDefineReservedUnused(IORegistryEntry
, 9);
2159 OSMetaClassDefineReservedUnused(IORegistryEntry
, 10);
2160 OSMetaClassDefineReservedUnused(IORegistryEntry
, 11);
2161 OSMetaClassDefineReservedUnused(IORegistryEntry
, 12);
2162 OSMetaClassDefineReservedUnused(IORegistryEntry
, 13);
2163 OSMetaClassDefineReservedUnused(IORegistryEntry
, 14);
2164 OSMetaClassDefineReservedUnused(IORegistryEntry
, 15);
2165 OSMetaClassDefineReservedUnused(IORegistryEntry
, 16);
2166 OSMetaClassDefineReservedUnused(IORegistryEntry
, 17);
2167 OSMetaClassDefineReservedUnused(IORegistryEntry
, 18);
2168 OSMetaClassDefineReservedUnused(IORegistryEntry
, 19);
2169 OSMetaClassDefineReservedUnused(IORegistryEntry
, 20);
2170 OSMetaClassDefineReservedUnused(IORegistryEntry
, 21);
2171 OSMetaClassDefineReservedUnused(IORegistryEntry
, 22);
2172 OSMetaClassDefineReservedUnused(IORegistryEntry
, 23);
2173 OSMetaClassDefineReservedUnused(IORegistryEntry
, 24);
2174 OSMetaClassDefineReservedUnused(IORegistryEntry
, 25);
2175 OSMetaClassDefineReservedUnused(IORegistryEntry
, 26);
2176 OSMetaClassDefineReservedUnused(IORegistryEntry
, 27);
2177 OSMetaClassDefineReservedUnused(IORegistryEntry
, 28);
2178 OSMetaClassDefineReservedUnused(IORegistryEntry
, 29);
2179 OSMetaClassDefineReservedUnused(IORegistryEntry
, 30);
2180 OSMetaClassDefineReservedUnused(IORegistryEntry
, 31);
2182 /* inline function implementation */
2183 OSDictionary
* IORegistryEntry::getPropertyTable( void ) const
2184 { return(fPropertyTable
); }