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>
36 #include <stdatomic.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
{
62 IORecursiveLock
* fLock
;
63 uint64_t fRegistryEntryID
;
64 SInt32 fRegistryEntryGenerationCount
;
65 OSObject
**_Atomic fIndexedProperties
;
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
{
91 friend class IORegistryEntry
;
93 OSDeclareAbstractStructors(IORegistryPlane
)
95 const OSSymbol
* nameKey
;
96 const OSSymbol
* keys
[kNumSetIndex
];
97 const OSSymbol
* pathNameKey
;
98 const OSSymbol
* pathLocationKey
;
102 virtual bool serialize(OSSerialize
*s
) const APPLE_KEXT_OVERRIDE
;
105 OSDefineMetaClassAndStructors(IORegistryPlane
, OSObject
)
108 static IORecursiveLock
* gPropertiesLock
;
109 static SInt32 gIORegistryGenerationCount
;
111 #define UNLOCK lck_rw_done( &gIORegistryLock )
112 #define RLOCK lck_rw_lock_shared( &gIORegistryLock )
113 #define WLOCK lck_rw_lock_exclusive( &gIORegistryLock ); \
114 gIORegistryGenerationCount++
117 #define PUNLOCK IORecursiveLockUnlock( reserved->fLock )
118 #define PLOCK IORecursiveLockLock( reserved->fLock )
120 #define IOREGSPLITTABLES
122 #ifdef IOREGSPLITTABLES
123 #define registryTable() fRegistryTable
125 #define registryTable() fPropertyTable
130 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
132 lck_rw_t gIORegistryLock
;
133 lck_grp_t
*gIORegistryLockGrp
;
134 lck_grp_attr_t
*gIORegistryLockGrpAttr
;
135 lck_attr_t
*gIORegistryLockAttr
;
138 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
141 IORegistryEntry::initialize( void )
145 if (!gRegistryRoot
) {
146 gIORegistryLockGrpAttr
= lck_grp_attr_alloc_init();
147 gIORegistryLockGrp
= lck_grp_alloc_init("IORegistryLock", gIORegistryLockGrpAttr
);
148 gIORegistryLockAttr
= lck_attr_alloc_init();
149 lck_attr_rw_shared_priority(gIORegistryLockAttr
);
150 lck_rw_init( &gIORegistryLock
, gIORegistryLockGrp
, gIORegistryLockAttr
);
152 gRegistryRoot
= new IORegistryEntry
;
153 gPropertiesLock
= IORecursiveLockAlloc();
154 gIORegistryPlanes
= OSDictionary::withCapacity( 1 );
156 assert( gRegistryRoot
&& gPropertiesLock
157 && gIORegistryPlanes
);
158 ok
= gRegistryRoot
->init();
161 gRegistryRoot
->reserved
->fRegistryEntryID
= ++gIORegistryLastID
;
164 gIONameKey
= OSSymbol::withCStringNoCopy( "IOName" );
165 gIOLocationKey
= OSSymbol::withCStringNoCopy( "IOLocation" );
166 gIORegistryEntryIDKey
= OSSymbol::withCStringNoCopy( kIORegistryEntryIDKey
);
167 gIORegistryEntryPropertyKeysKey
= OSSymbol::withCStringNoCopy( kIORegistryEntryPropertyKeysKey
);
169 assert( ok
&& gIONameKey
&& gIOLocationKey
);
171 gRegistryRoot
->setName( "Root" );
172 gRegistryRoot
->setProperty( kIORegistryPlanesKey
, gIORegistryPlanes
);
175 return gRegistryRoot
;
179 IORegistryEntry::getRegistryRoot( void )
181 return gRegistryRoot
;
185 IORegistryEntry::getGenerationCount( void )
187 return gIORegistryGenerationCount
;
191 IORegistryEntry::getRegistryEntryGenerationCount(void) const
193 return reserved
->fRegistryEntryGenerationCount
;
196 const IORegistryPlane
*
197 IORegistryEntry::makePlane( const char * name
)
199 IORegistryPlane
* plane
;
200 const OSSymbol
* nameKey
;
201 const OSSymbol
* parentKey
;
202 const OSSymbol
* childKey
;
203 const OSSymbol
* pathNameKey
;
204 const OSSymbol
* pathLocationKey
;
205 char key
[kIOMaxPlaneName
+ 16];
208 strlcpy( key
, name
, kIOMaxPlaneName
+ 1 );
209 end
= key
+ strlen( key
);
211 nameKey
= OSSymbol::withCString( key
);
213 strlcpy( end
, kIORegPlaneParentSuffix
, kIORegPlaneParentSuffixLen
+ 1 );
214 parentKey
= OSSymbol::withCString( key
);
216 strlcpy( end
, kIORegPlaneChildSuffix
, kIORegPlaneChildSuffixLen
+ 1 );
217 childKey
= OSSymbol::withCString( key
);
219 strlcpy( end
, kIORegPlaneNameSuffix
, kIORegPlaneNameSuffixLen
+ 1 );
220 pathNameKey
= OSSymbol::withCString( key
);
222 strlcpy( end
, kIORegPlaneLocationSuffix
, kIORegPlaneLocationSuffixLen
+ 1 );
223 pathLocationKey
= OSSymbol::withCString( key
);
225 plane
= new IORegistryPlane
;
227 if (plane
&& plane
->init()
228 && nameKey
&& parentKey
&& childKey
229 && 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
);
243 if (pathLocationKey
) {
244 pathLocationKey
->release();
247 pathNameKey
->release();
250 parentKey
->release();
264 const IORegistryPlane
*
265 IORegistryEntry::getPlane( const char * name
)
267 const IORegistryPlane
* plane
;
270 plane
= (const IORegistryPlane
*) gIORegistryPlanes
->getObject( name
);
277 IORegistryPlane::serialize(OSSerialize
*s
) const
279 return nameKey
->serialize(s
);
282 enum { kIORegCapacityIncrement
= 4 };
285 IORegistryEntry::init( OSDictionary
* dict
)
289 if (!super::init()) {
294 reserved
= IONew(ExpansionData
, 1);
298 bzero(reserved
, sizeof(ExpansionData
));
299 reserved
->fLock
= IORecursiveLockAlloc();
300 if (!reserved
->fLock
) {
305 if (OSCollection::kImmutable
& dict
->setOptions(0, 0)) {
306 dict
= (OSDictionary
*) dict
->copyCollection();
313 if (fPropertyTable
) {
314 fPropertyTable
->release();
316 fPropertyTable
= dict
;
317 } else if (!fPropertyTable
) {
318 fPropertyTable
= OSDictionary::withCapacity( kIORegCapacityIncrement
);
319 if (fPropertyTable
) {
320 fPropertyTable
->setCapacityIncrement( kIORegCapacityIncrement
);
324 if (!fPropertyTable
) {
328 #ifdef IOREGSPLITTABLES
329 if (!fRegistryTable
) {
330 fRegistryTable
= OSDictionary::withCapacity( kIORegCapacityIncrement
);
331 if (fRegistryTable
) {
332 fRegistryTable
->setCapacityIncrement( kIORegCapacityIncrement
);
336 if ((prop
= OSDynamicCast( OSString
, getProperty( gIONameKey
)))) {
337 OSSymbol
* sym
= (OSSymbol
*)OSSymbol::withString( prop
);
338 // ok for OSSymbol too
343 #endif /* IOREGSPLITTABLES */
349 IORegistryEntry::init( IORegistryEntry
* old
,
350 const IORegistryPlane
* plane
)
353 IORegistryEntry
* next
;
356 if (!super::init()) {
361 reserved
= IONew(ExpansionData
, 1);
365 bzero(reserved
, sizeof(ExpansionData
));
366 reserved
->fLock
= IORecursiveLockAlloc();
367 if (!reserved
->fLock
) {
374 reserved
->fRegistryEntryID
= old
->reserved
->fRegistryEntryID
;
376 fPropertyTable
= old
->dictionaryWithProperties();
377 #ifdef IOREGSPLITTABLES
378 fRegistryTable
= old
->fRegistryTable
;
379 old
->fRegistryTable
= (OSDictionary
*) fRegistryTable
->copyCollection();
380 #endif /* IOREGSPLITTABLES */
382 old
->registryTable()->removeObject( plane
->keys
[kParentSetIndex
] );
383 old
->registryTable()->removeObject( plane
->keys
[kChildSetIndex
] );
385 all
= getParentSetReference( plane
);
388 (next
= (IORegistryEntry
*) all
->getObject(index
));
390 next
->makeLink( this, kChildSetIndex
, plane
);
391 next
->breakLink( old
, kChildSetIndex
, plane
);
395 all
= getChildSetReference( plane
);
398 (next
= (IORegistryEntry
*) all
->getObject(index
));
400 next
->makeLink( this, kParentSetIndex
, plane
);
401 next
->breakLink( old
, kParentSetIndex
, plane
);
411 IORegistryEntry::free( void )
414 if (registryTable() && gIOServicePlane
) {
415 if (getParentSetReference( gIOServicePlane
)
416 || getChildSetReference( gIOServicePlane
)) {
417 panic("%s: attached at free()", getName());
422 if (getPropertyTable()) {
423 getPropertyTable()->release();
426 #ifdef IOREGSPLITTABLES
427 if (registryTable()) {
428 registryTable()->release();
430 #endif /* IOREGSPLITTABLES */
433 if (reserved
->fIndexedProperties
) {
434 for (int idx
= 0; idx
< kIORegistryEntryIndexedPropertyCount
; idx
++) {
435 if (reserved
->fIndexedProperties
[idx
]) {
436 reserved
->fIndexedProperties
[idx
]->release();
439 IODelete(reserved
->fIndexedProperties
, OSObject
*, kIORegistryEntryIndexedPropertyCount
);
441 if (reserved
->fLock
) {
442 IORecursiveLockFree(reserved
->fLock
);
444 IODelete(reserved
, ExpansionData
, 1);
451 IORegistryEntry::setPropertyTable( OSDictionary
* dict
)
456 if (fPropertyTable
) {
457 fPropertyTable
->release();
460 fPropertyTable
= dict
;
463 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
465 /* Wrappers to synchronize property table */
467 #define wrap2(type, constant) \
469 IORegistryEntry::copyProperty( type * aKey) constant \
474 obj = getProperty( aKey ); \
482 #define wrap4(type, constant) \
484 IORegistryEntry::getProperty( type * aKey, \
485 const IORegistryPlane * plane, \
486 IOOptionBits options ) constant \
488 OSObject * obj = getProperty( aKey ); \
490 if ( (0 == obj) && plane && (options & kIORegistryIterateRecursively) ) { \
491 IORegistryEntry * entry = (IORegistryEntry *) this; \
492 IORegistryIterator * iter; \
493 iter = IORegistryIterator::iterateOver( entry, plane, options ); \
496 while ( (0 == obj) && (entry = iter->getNextObject()) ) { \
497 obj = entry->getProperty( aKey ); \
506 #define wrap5(type, constant) \
508 IORegistryEntry::copyProperty( type * aKey, \
509 const IORegistryPlane * plane, \
510 IOOptionBits options ) constant \
512 OSObject * obj = copyProperty( aKey ); \
514 if ( (0 == obj) && plane && (options & kIORegistryIterateRecursively) ) { \
515 IORegistryEntry * entry = (IORegistryEntry *) this; \
516 IORegistryIterator * iter; \
517 iter = IORegistryIterator::iterateOver( entry, plane, options ); \
520 while ( (0 == obj) && (entry = iter->getNextObject()) ) { \
521 obj = entry->copyProperty( aKey ); \
531 IORegistryEntry::serializeProperties( OSSerialize
* s
) const
533 // setProperty( getRetainCount(), 32, "__retain" );
536 OSCollection
*snapshotProperties
= getPropertyTable()->copyCollection();
539 if (!snapshotProperties
) {
543 bool ok
= snapshotProperties
->serialize( s
);
544 snapshotProperties
->release();
549 IORegistryEntry::copyPropertyKeys(void) const
552 OSArray
* keys
= getPropertyTable()->copyKeys();
559 IORegistryEntry::dictionaryWithProperties( void ) const
564 dict
= OSDictionary::withDictionary( getPropertyTable(),
565 getPropertyTable()->getCapacity());
572 IORegistryEntry::setProperties( OSObject
* properties
)
574 return kIOReturnUnsupported
;
577 wrap2(const OSSymbol
, const) // copyProperty() definition
578 wrap2(const OSString
, const) // copyProperty() definition
579 wrap2(const char, const) // copyProperty() definition
581 wrap4(const OSSymbol
, const) // getProperty() w/plane definition
582 wrap4(const OSString
, const) // getProperty() w/plane definition
583 wrap4(const char, const) // getProperty() w/plane definition
585 wrap5(const OSSymbol
, const) // copyProperty() w/plane definition
586 wrap5(const OSString
, const) // copyProperty() w/plane definition
587 wrap5(const char, const) // copyProperty() w/plane definition
591 IORegistryEntry::getProperty( const OSSymbol
* aKey
) const
596 obj
= getPropertyTable()->getObject( aKey
);
603 IORegistryEntry::removeProperty( const OSSymbol
* aKey
)
606 getPropertyTable()->removeObject( aKey
);
610 #if KASLR_IOREG_DEBUG
612 bool ScanForAddrInObject(OSObject
* theObject
,
618 IORegistryEntry::setProperty( const OSSymbol
* aKey
, OSObject
* anObject
)
622 // If we are inserting a collection class and the current entry
623 // is attached into the registry (inPlane()) then mark the collection
625 OSCollection
*coll
= OSDynamicCast(OSCollection
, anObject
);
626 bool makeImmutable
= (coll
&& inPlane());
630 coll
->setOptions( OSCollection::kMASK
, OSCollection::kImmutable
);
633 ret
= getPropertyTable()->setObject( aKey
, anObject
);
636 #if KASLR_IOREG_DEBUG
637 if (anObject
&& strcmp(kIOKitDiagnosticsKey
, aKey
->getCStringNoCopy()) != 0) {
638 if (ScanForAddrInObject(anObject
, 0)) {
639 IOLog("%s: IORegistryEntry name %s with key \"%s\" \n",
642 aKey
->getCStringNoCopy());
652 runPropertyAction(Action inAction
, OSObject
*target
,
653 void *arg0
, void *arg1
, void *arg2
, void *arg3
)
657 // closeGate is recursive so don't worry if we already hold the lock.
659 res
= (*inAction
)(target
, arg0
, arg1
, arg2
, arg3
);
666 IORegistryEntry::getProperty( const OSString
* aKey
) const
668 const OSSymbol
* tmpKey
= OSSymbol::withString( aKey
);
669 OSObject
* obj
= getProperty( tmpKey
);
676 IORegistryEntry::getProperty( const char * aKey
) const
678 const OSSymbol
* tmpKey
= OSSymbol::withCString( aKey
);
679 OSObject
* obj
= getProperty( tmpKey
);
687 IORegistryEntry::removeProperty( const OSString
* aKey
)
689 const OSSymbol
* tmpKey
= OSSymbol::withString( aKey
);
690 removeProperty( tmpKey
);
695 IORegistryEntry::removeProperty( const char * aKey
)
697 const OSSymbol
* tmpKey
= OSSymbol::withCString( aKey
);
698 removeProperty( tmpKey
);
703 IORegistryEntry::setProperty( const OSString
* aKey
, OSObject
* anObject
)
705 const OSSymbol
* tmpKey
= OSSymbol::withString( aKey
);
706 bool ret
= setProperty( tmpKey
, anObject
);
713 IORegistryEntry::setProperty( const char * aKey
, OSObject
* anObject
)
715 const OSSymbol
* tmpKey
= OSSymbol::withCString( aKey
);
716 bool ret
= setProperty( tmpKey
, anObject
);
723 IORegistryEntry::setProperty(const char * aKey
, const char * aString
)
726 OSSymbol
* aSymbol
= (OSSymbol
*) OSSymbol::withCString( aString
);
729 const OSSymbol
* tmpKey
= OSSymbol::withCString( aKey
);
730 ret
= setProperty( tmpKey
, aSymbol
);
739 IORegistryEntry::setProperty(const char * aKey
, bool aBoolean
)
742 OSBoolean
* aBooleanObj
= OSBoolean::withBoolean( aBoolean
);
745 const OSSymbol
* tmpKey
= OSSymbol::withCString( aKey
);
746 ret
= setProperty( tmpKey
, aBooleanObj
);
749 aBooleanObj
->release();
755 IORegistryEntry::setProperty( const char * aKey
,
756 unsigned long long aValue
,
757 unsigned int aNumberOfBits
)
760 OSNumber
* anOffset
= OSNumber::withNumber( aValue
, aNumberOfBits
);
763 const OSSymbol
* tmpKey
= OSSymbol::withCString( aKey
);
764 ret
= setProperty( tmpKey
, anOffset
);
773 IORegistryEntry::setProperty( const char * aKey
,
778 OSData
* data
= OSData::withBytes( bytes
, length
);
781 const OSSymbol
* tmpKey
= OSSymbol::withCString( aKey
);
782 ret
= setProperty( tmpKey
, data
);
790 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
793 IORegistryEntry::setIndexedProperty(uint32_t index
, OSObject
* anObject
)
798 if (index
>= kIORegistryEntryIndexedPropertyCount
) {
802 array
= atomic_load_explicit(&reserved
->fIndexedProperties
, memory_order_acquire
);
804 array
= IONew(OSObject
*, kIORegistryEntryIndexedPropertyCount
);
808 bzero(array
, kIORegistryEntryIndexedPropertyCount
* sizeof(array
[0]));
809 if (!OSCompareAndSwapPtr(NULL
, array
, &reserved
->fIndexedProperties
)) {
810 IODelete(array
, OSObject
*, kIORegistryEntryIndexedPropertyCount
);
813 if (!reserved
->fIndexedProperties
) {
817 prior
= reserved
->fIndexedProperties
[index
];
821 reserved
->fIndexedProperties
[index
] = anObject
;
827 IORegistryEntry::getIndexedProperty(uint32_t index
) const
829 if (index
>= kIORegistryEntryIndexedPropertyCount
) {
832 if (!reserved
->fIndexedProperties
) {
836 return reserved
->fIndexedProperties
[index
];
839 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
841 /* Name, location, paths */
844 IORegistryEntry::getName( const IORegistryPlane
* plane
) const
850 sym
= (OSSymbol
*) registryTable()->getObject( plane
->pathNameKey
);
853 sym
= (OSSymbol
*) registryTable()->getObject( gIONameKey
);
858 return sym
->getCStringNoCopy();
860 return (getMetaClass())->getClassName();
865 IORegistryEntry::copyName(
866 const IORegistryPlane
* plane
) const
872 sym
= (OSSymbol
*) registryTable()->getObject( plane
->pathNameKey
);
875 sym
= (OSSymbol
*) registryTable()->getObject( gIONameKey
);
885 return OSSymbol::withCString((getMetaClass())->getClassName());
890 IORegistryEntry::copyLocation(
891 const IORegistryPlane
* plane
) const
897 sym
= (OSSymbol
*) registryTable()->getObject( plane
->pathLocationKey
);
900 sym
= (OSSymbol
*) registryTable()->getObject( gIOLocationKey
);
911 IORegistryEntry::getLocation( const IORegistryPlane
* plane
) const
913 const OSSymbol
* sym
= copyLocation( plane
);
914 const char * result
= 0;
917 result
= sym
->getCStringNoCopy();
925 IORegistryEntry::setName( const OSSymbol
* name
,
926 const IORegistryPlane
* plane
)
928 const OSSymbol
* key
;
932 key
= plane
->pathNameKey
;
937 if (gIOKitTrace
&& reserved
&& reserved
->fRegistryEntryID
) {
939 uint64_t __unused regID
= getRegistryEntryID();
940 kernel_debug_string(IODBG_IOREGISTRY(IOREGISTRYENTRY_NAME_STRING
), &str_id
, name
->getCStringNoCopy());
941 KERNEL_DEBUG_CONSTANT(IODBG_IOREGISTRY(IOREGISTRYENTRY_NAME
),
943 (uintptr_t) (regID
>> 32),
945 (uintptr_t) (str_id
>> 32),
950 registryTable()->setObject( key
, (OSObject
*) name
);
956 IORegistryEntry::setName( const char * name
,
957 const IORegistryPlane
* plane
)
959 OSSymbol
* sym
= (OSSymbol
*)OSSymbol::withCString( name
);
961 setName( sym
, plane
);
967 IORegistryEntry::setLocation( const OSSymbol
* location
,
968 const IORegistryPlane
* plane
)
970 const OSSymbol
* key
;
974 key
= plane
->pathLocationKey
;
976 key
= gIOLocationKey
;
980 registryTable()->setObject( key
, (OSObject
*) location
);
986 IORegistryEntry::setLocation( const char * location
,
987 const IORegistryPlane
* plane
)
989 OSSymbol
* sym
= (OSSymbol
*)OSSymbol::withCString( location
);
991 setLocation( sym
, plane
);
997 IORegistryEntry::compareName( OSString
* name
, OSString
** matched
) const
999 const OSSymbol
* sym
= copyName();
1002 isEqual
= (sym
&& sym
->isEqualTo(name
));
1004 if (isEqual
&& matched
) {
1017 IORegistryEntry::compareNames( OSObject
* names
, OSString
** matched
) const
1020 OSCollection
* collection
;
1021 OSIterator
* iter
= 0;
1022 bool result
= false;
1024 if ((collection
= OSDynamicCast( OSCollection
, names
))) {
1025 iter
= OSCollectionIterator::withCollection( collection
);
1028 string
= OSDynamicCast( OSString
, names
);
1033 result
= compareName( string
, matched
);
1035 } while ((false == result
)
1036 && iter
&& (string
= OSDynamicCast( OSString
, iter
->getNextObject())));
1047 IORegistryEntry::getPath( char * path
, int * length
,
1048 const IORegistryPlane
* plane
) const
1051 IORegistryEntry
* root
;
1052 const IORegistryEntry
* entry
;
1053 const IORegistryEntry
* parent
;
1054 const OSSymbol
* alias
;
1056 int len
, maxLength
, compLen
, aliasLen
;
1060 if (!path
|| !length
|| !plane
) {
1065 maxLength
= *length
- 2;
1068 len
= plane
->nameKey
->getLength();
1069 if (len
>= maxLength
) {
1072 strlcpy( nextComp
, plane
->nameKey
->getCStringNoCopy(), len
+ 1);
1073 nextComp
[len
++] = ':';
1076 if ((alias
= hasAlias( plane
))) {
1077 aliasLen
= alias
->getLength();
1079 ok
= (maxLength
> len
);
1082 strlcpy( nextComp
, alias
->getCStringNoCopy(), aliasLen
+ 1);
1087 stack
= OSArray::withCapacity( getDepth( plane
));
1094 parent
= entry
= this;
1095 root
= gRegistryRoot
->getChildEntry( plane
);
1096 while (parent
&& (parent
!= root
)) {
1099 parent
= entry
->getParentEntry( plane
);
1100 stack
->setObject((OSObject
*) entry
);
1105 index
= stack
->getCount();
1111 while (ok
&& ((--index
) >= 0)) {
1112 entry
= (IORegistryEntry
*) stack
->getObject((unsigned int) index
);
1115 if ((alias
= entry
->hasAlias( plane
))) {
1116 len
= plane
->nameKey
->getLength() + 1;
1117 nextComp
= path
+ len
;
1119 compLen
= alias
->getLength();
1120 ok
= (maxLength
> (len
+ compLen
));
1122 strlcpy( nextComp
, alias
->getCStringNoCopy(), compLen
+ 1);
1125 compLen
= maxLength
- len
;
1126 ok
= entry
->getPathComponent( nextComp
+ 1, &compLen
, plane
);
1128 if (ok
&& compLen
) {
1136 nextComp
+= compLen
;
1149 IORegistryEntry::getPathComponent( char * path
, int * length
,
1150 const IORegistryPlane
* plane
) const
1152 int len
, locLen
, maxLength
;
1153 const char * compName
;
1157 maxLength
= *length
;
1159 compName
= getName( plane
);
1160 len
= strlen( compName
);
1161 if ((loc
= getLocation( plane
))) {
1162 locLen
= 1 + strlen( loc
);
1167 ok
= ((len
+ locLen
+ 1) < maxLength
);
1169 strlcpy( path
, compName
, len
+ 1 );
1174 strlcpy( path
, loc
, locLen
);
1183 IORegistryEntry::matchPathLocation( const char * cmp
,
1184 const IORegistryPlane
* plane
)
1187 const char * result
= 0;
1188 u_quad_t num1
, num2
;
1189 char lastPathChar
, lastLocationChar
;
1191 str
= getLocation( plane
);
1193 lastPathChar
= cmp
[0];
1194 lastLocationChar
= str
[0];
1197 num1
= strtouq( cmp
, (char **) &cmp
, 16 );
1198 lastPathChar
= *cmp
++;
1203 if (lastLocationChar
) {
1204 num2
= strtouq( str
, (char **) &str
, 16 );
1205 lastLocationChar
= *str
++;
1214 if (!lastPathChar
&& !lastLocationChar
) {
1219 if ((',' != lastPathChar
) && (':' != lastPathChar
)) {
1223 if (lastPathChar
&& lastLocationChar
&& (lastPathChar
!= lastLocationChar
)) {
1233 IORegistryEntry::getChildFromComponent( const char ** opath
,
1234 const IORegistryPlane
* plane
)
1236 IORegistryEntry
* entry
= 0;
1240 const char * cmp
= 0;
1245 set
= getChildSetReference( plane
);
1250 (entry
= (IORegistryEntry
*) set
->getObject(index
));
1255 str
= entry
->getName( plane
);
1256 len
= strlen( str
);
1257 if (strncmp( str
, cmp
, len
)) {
1263 if ((c
== 0) || (c
== '/') || (c
== ':')) {
1271 if ((cmp
= entry
->matchPathLocation( cmp
, plane
))) {
1284 IORegistryEntry::hasAlias( const IORegistryPlane
* plane
,
1285 char * opath
, int * length
) const
1287 IORegistryEntry
* entry
;
1288 IORegistryEntry
* entry2
;
1289 const OSSymbol
* key
;
1290 const OSSymbol
* bestKey
= 0;
1293 const char * path
= "/aliases";
1295 entry
= IORegistryEntry::fromPath( path
, plane
);
1298 if ((iter
= OSCollectionIterator::withCollection(
1299 entry
->getPropertyTable()))) {
1300 while ((key
= (OSSymbol
*) iter
->getNextObject())) {
1301 data
= (OSData
*) entry
->getProperty( key
);
1302 path
= (const char *) data
->getBytesNoCopy();
1303 if ((entry2
= IORegistryEntry::fromPath( path
, plane
,
1305 if (this == entry2
) {
1307 || (bestKey
->getLength() > key
->getLength())) {
1308 // pick the smallest alias
1324 IORegistryEntry::dealiasPath(
1325 const char ** opath
,
1326 const IORegistryPlane
* plane
)
1328 IORegistryEntry
* entry
;
1330 const char * path
= *opath
;
1331 const char * rpath
= 0;
1334 char temp
[kIOMaxPlaneName
+ 1];
1336 if (path
[0] == '/') {
1342 while ((c
= *end
++) && (c
!= '/') && (c
!= ':')) {
1345 if ((end
- path
) < kIOMaxPlaneName
) {
1346 strlcpy( temp
, path
, end
- path
+ 1 );
1349 entry
= IORegistryEntry::fromPath( "/aliases", plane
);
1351 data
= (OSData
*) entry
->getProperty( temp
);
1353 rpath
= (const char *) data
->getBytesNoCopy();
1367 IORegistryEntry::fromPath(
1369 const IORegistryPlane
* plane
,
1372 IORegistryEntry
* fromEntry
)
1374 IORegistryEntry
* where
= 0;
1375 IORegistryEntry
* aliasEntry
= 0;
1376 IORegistryEntry
* next
;
1382 char temp
[kIOMaxPlaneName
+ 1];
1390 end
= strchr( path
, ':' );
1391 if (end
&& ((end
- path
) < kIOMaxPlaneName
)) {
1392 strlcpy( temp
, path
, end
- path
+ 1 );
1393 plane
= getPlane( temp
);
1403 if ((alias
= dealiasPath( &end
, plane
))) {
1407 aliasEntry
= IORegistryEntry::fromPath( alias
, plane
,
1408 opath
, &len
, fromEntry
);
1421 if ((0 == fromEntry
) && (*path
++ == '/')) {
1422 fromEntry
= gRegistryRoot
->getChildEntry( plane
);
1431 if (c
&& (c
!= ':')) { // check valid terminator
1437 next
= where
->getChildFromComponent( &path
, plane
);
1444 // check residual path
1445 if (where
!= fromEntry
) {
1449 if (opath
&& length
) {
1450 // copy out residual path
1451 len2
= strlen( path
);
1452 if ((len
+ len2
) < *length
) {
1453 strlcpy( opath
+ len
, path
, len2
+ 1 );
1455 *length
= (len
+ len2
);
1456 } else if (path
[0]) {
1457 // no residual path => must be no tail for success
1466 aliasEntry
->release();
1475 IORegistryEntry::childFromPath(
1477 const IORegistryPlane
* plane
,
1481 return IORegistryEntry::fromPath( path
, plane
, opath
, len
, this );
1484 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1486 #define IOLinkIterator OSCollectionIterator
1489 #define super OSObject
1492 IORegistryEntry::arrayMember( OSArray
* set
,
1493 const IORegistryEntry
* member
,
1494 unsigned int * index
) const
1497 OSObject
* probeObject
;
1499 for (i
= 0; (probeObject
= set
->getObject(i
)); i
++) {
1500 if (probeObject
== (OSObject
*) member
) {
1511 IORegistryEntry::makeLink( IORegistryEntry
* to
,
1512 unsigned int relation
,
1513 const IORegistryPlane
* plane
) const
1516 bool result
= false;
1518 if ((links
= (OSArray
*)
1519 registryTable()->getObject( plane
->keys
[relation
] ))) {
1520 result
= arrayMember( links
, to
);
1522 result
= links
->setObject( to
);
1525 links
= OSArray::withObjects((const OSObject
**) &to
, 1, 1 );
1526 result
= (links
!= 0);
1528 result
= registryTable()->setObject( plane
->keys
[relation
],
1533 reserved
->fRegistryEntryGenerationCount
++;
1539 IORegistryEntry::breakLink( IORegistryEntry
* to
,
1540 unsigned int relation
,
1541 const IORegistryPlane
* plane
) const
1546 if ((links
= (OSArray
*)
1547 registryTable()->getObject( plane
->keys
[relation
]))) {
1548 if (arrayMember( links
, to
, &index
)) {
1549 links
->removeObject( index
);
1550 if (0 == links
->getCount()) {
1551 registryTable()->removeObject( plane
->keys
[relation
]);
1555 reserved
->fRegistryEntryGenerationCount
++;
1560 IORegistryEntry::getParentSetReference(
1561 const IORegistryPlane
* plane
) const
1564 return (OSArray
*) registryTable()->getObject(
1565 plane
->keys
[kParentSetIndex
]);
1572 IORegistryEntry::getParentIterator(
1573 const IORegistryPlane
* plane
) const
1583 links
= getParentSetReference( plane
);
1585 links
= OSArray::withCapacity( 1 );
1587 links
= OSArray::withArray( links
, links
->getCount());
1591 iter
= IOLinkIterator::withCollection( links
);
1601 IORegistryEntry::copyParentEntry( const IORegistryPlane
* plane
) const
1603 IORegistryEntry
* entry
= 0;
1608 if ((links
= getParentSetReference( plane
))) {
1609 entry
= (IORegistryEntry
*) links
->getObject( 0 );
1619 IORegistryEntry::getParentEntry( const IORegistryPlane
* plane
) const
1621 IORegistryEntry
* entry
;
1623 entry
= copyParentEntry( plane
);
1632 IORegistryEntry::getChildSetReference( const IORegistryPlane
* plane
) const
1635 return (OSArray
*) registryTable()->getObject(
1636 plane
->keys
[kChildSetIndex
]);
1643 IORegistryEntry::getChildIterator( const IORegistryPlane
* plane
) const
1653 links
= getChildSetReference( plane
);
1655 links
= OSArray::withCapacity( 1 );
1657 links
= OSArray::withArray( links
, links
->getCount());
1661 iter
= IOLinkIterator::withCollection( links
);
1671 IORegistryEntry::getChildCount( const IORegistryPlane
* plane
) const
1677 links
= getChildSetReference( plane
);
1679 count
= links
->getCount();
1687 IORegistryEntry::copyChildEntry(
1688 const IORegistryPlane
* plane
) const
1690 IORegistryEntry
* entry
= 0;
1695 if ((links
= getChildSetReference( plane
))) {
1696 entry
= (IORegistryEntry
*) links
->getObject( 0 );
1706 IORegistryEntry::getChildEntry(
1707 const IORegistryPlane
* plane
) const
1709 IORegistryEntry
* entry
;
1711 entry
= copyChildEntry( plane
);
1720 IORegistryEntry::applyToChildren( IORegistryEntryApplierFunction applier
,
1722 const IORegistryPlane
* plane
) const
1726 IORegistryEntry
* next
;
1733 array
= OSArray::withArray( getChildSetReference( plane
));
1737 (next
= (IORegistryEntry
*) array
->getObject( index
));
1739 (*applier
)(next
, context
);
1746 IORegistryEntry::applyToParents( IORegistryEntryApplierFunction applier
,
1748 const IORegistryPlane
* plane
) const
1752 IORegistryEntry
* next
;
1759 array
= OSArray::withArray( getParentSetReference( plane
));
1763 (next
= (IORegistryEntry
*) array
->getObject( index
));
1765 (*applier
)(next
, context
);
1772 IORegistryEntry::isChild( IORegistryEntry
* child
,
1773 const IORegistryPlane
* plane
,
1774 bool onlyChild
) const
1781 if ((links
= getChildSetReference( plane
))) {
1782 if ((!onlyChild
) || (1 == links
->getCount())) {
1783 ret
= arrayMember( links
, child
);
1786 if (ret
&& (links
= child
->getParentSetReference( plane
))) {
1787 ret
= arrayMember( links
, this );
1796 IORegistryEntry::isParent( IORegistryEntry
* parent
,
1797 const IORegistryPlane
* plane
,
1798 bool onlyParent
) const
1805 if ((links
= getParentSetReference( plane
))) {
1806 if ((!onlyParent
) || (1 == links
->getCount())) {
1807 ret
= arrayMember( links
, parent
);
1810 if (ret
&& (links
= parent
->getChildSetReference( plane
))) {
1811 ret
= arrayMember( links
, this );
1820 IORegistryEntry::inPlane( const IORegistryPlane
* plane
) const
1827 ret
= (0 != getParentSetReference( plane
));
1829 // Check to see if this is in any plane. If it is in a plane
1830 // then the registryTable will contain a key with the ParentLinks
1831 // suffix. When we iterate over the keys looking for that suffix
1834 OSCollectionIterator
*iter
=
1835 OSCollectionIterator::withCollection( registryTable());
1837 const OSSymbol
*key
;
1839 while ((key
= (OSSymbol
*) iter
->getNextObject())) {
1842 // Get a pointer to this keys suffix
1843 keysuffix
= key
->getLength();
1844 if (keysuffix
<= kIORegPlaneParentSuffixLen
) {
1847 keysuffix
-= kIORegPlaneParentSuffixLen
;
1848 if (!strncmp(key
->getCStringNoCopy() + keysuffix
,
1849 kIORegPlaneParentSuffix
,
1850 kIORegPlaneParentSuffixLen
+ 1)) {
1865 IORegistryEntry::attachToParent( IORegistryEntry
* parent
,
1866 const IORegistryPlane
* plane
)
1871 bool traceName
= false;
1873 if (this == parent
) {
1879 if (!reserved
->fRegistryEntryID
) {
1880 reserved
->fRegistryEntryID
= ++gIORegistryLastID
;
1881 traceName
= (0 != gIOKitTrace
);
1884 ret
= makeLink( parent
, kParentSetIndex
, plane
);
1886 if ((links
= parent
->getChildSetReference( plane
))) {
1887 needParent
= (false == arrayMember( links
, this ));
1895 uint64_t str_id
= 0;
1896 uint64_t __unused regID
= getRegistryEntryID();
1897 kernel_debug_string(IODBG_IOREGISTRY(IOREGISTRYENTRY_NAME_STRING
), &str_id
, getName());
1898 KERNEL_DEBUG_CONSTANT(IODBG_IOREGISTRY(IOREGISTRYENTRY_NAME
),
1900 (uintptr_t) (regID
>> 32),
1902 (uintptr_t) (str_id
>> 32),
1908 // Mark any collections in the property list as immutable
1909 OSDictionary
*ptable
= getPropertyTable();
1910 OSCollectionIterator
*iter
=
1911 OSCollectionIterator::withCollection( ptable
);
1913 const OSSymbol
*key
;
1915 while ((key
= (OSSymbol
*) iter
->getNextObject())) {
1916 // Is object for key a collection?
1917 OSCollection
*coll
=
1918 OSDynamicCast( OSCollection
, ptable
->getObject( key
));
1921 // Yup so mark it as immutable
1922 coll
->setOptions( OSCollection::kMASK
,
1923 OSCollection::kImmutable
);
1932 ret
&= parent
->attachToChild( this, plane
);
1939 IORegistryEntry::getRegistryEntryID( void )
1942 return reserved
->fRegistryEntryID
;
1949 IORegistryEntry::attachToChild( IORegistryEntry
* child
,
1950 const IORegistryPlane
* plane
)
1956 if (this == child
) {
1962 ret
= makeLink( child
, kChildSetIndex
, plane
);
1964 if ((links
= child
->getParentSetReference( plane
))) {
1965 needChild
= (false == arrayMember( links
, this ));
1973 ret
&= child
->attachToParent( this, plane
);
1980 IORegistryEntry::detachFromParent( IORegistryEntry
* parent
,
1981 const IORegistryPlane
* plane
)
1990 breakLink( parent
, kParentSetIndex
, plane
);
1992 if ((links
= parent
->getChildSetReference( plane
))) {
1993 needParent
= arrayMember( links
, this );
1998 // parent->breakLink( this, kChildSetIndex, plane );
2003 parent
->detachFromChild( this, plane
);
2010 IORegistryEntry::detachFromChild( IORegistryEntry
* child
,
2011 const IORegistryPlane
* plane
)
2020 breakLink( child
, kChildSetIndex
, plane
);
2022 if ((links
= child
->getParentSetReference( plane
))) {
2023 needChild
= arrayMember( links
, this );
2031 child
->detachFromParent( this, plane
);
2038 IORegistryEntry::detachAbove( const IORegistryPlane
* plane
)
2040 IORegistryEntry
* parent
;
2043 while ((parent
= copyParentEntry( plane
))) {
2044 detachFromParent( parent
, plane
);
2051 IORegistryEntry::detachAll( const IORegistryPlane
* plane
)
2054 IORegistryEntry
* next
;
2055 IORegistryIterator
* regIter
;
2057 regIter
= IORegistryIterator::iterateOver( this, plane
, true );
2061 all
= regIter
->iterateAll();
2064 detachAbove( plane
);
2066 while ((next
= (IORegistryEntry
*) all
->getLastObject())) {
2068 all
->removeObject(next
);
2070 next
->detachAbove( plane
);
2078 IORegistryEntry::getDepth( const IORegistryPlane
* plane
) const
2080 unsigned int depth
= 1;
2082 unsigned int oneDepth
, maxParentDepth
, count
;
2083 IORegistryEntry
* one
;
2084 const IORegistryEntry
* next
;
2090 while ((parents
= next
->getParentSetReference( plane
))) {
2091 count
= parents
->getCount();
2097 next
= (IORegistryEntry
*) parents
->getObject( 0 );
2102 (one
= (IORegistryEntry
*) parents
->getObject( index
));
2104 oneDepth
= one
->getDepth( plane
);
2105 if (oneDepth
> maxParentDepth
) {
2106 maxParentDepth
= oneDepth
;
2109 depth
+= maxParentDepth
;
2119 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2122 #define super OSIterator
2124 OSDefineMetaClassAndStructors(IORegistryIterator
, OSIterator
)
2126 enum { kIORegistryIteratorInvalidFlag
= 0x80000000 };
2128 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2130 IORegistryIterator
*
2131 IORegistryIterator::iterateOver( IORegistryEntry
* root
,
2132 const IORegistryPlane
* plane
,
2133 IOOptionBits options
)
2135 IORegistryIterator
* create
;
2144 create
= new IORegistryIterator
;
2146 if (create
->init()) {
2148 create
->root
= root
;
2149 create
->where
= &create
->start
;
2150 create
->start
.current
= root
;
2151 create
->plane
= plane
;
2152 create
->options
= options
& ~kIORegistryIteratorInvalidFlag
;
2161 IORegistryIterator
*
2162 IORegistryIterator::iterateOver( const IORegistryPlane
* plane
,
2163 IOOptionBits options
)
2165 return iterateOver( gRegistryRoot
, plane
, options
);
2169 IORegistryIterator::isValid( void )
2178 ok
= (0 == (kIORegistryIteratorInvalidFlag
& options
));
2180 while (ok
&& next
) {
2182 ok
= where
->iter
->isValid();
2192 IORegistryIterator::enterEntry( const IORegistryPlane
* enterPlane
)
2197 where
= (IORegCursor
*) IOMalloc( sizeof(IORegCursor
));
2203 where
->current
= prev
->current
;
2209 IORegistryIterator::enterEntry( void )
2211 enterEntry( plane
);
2215 IORegistryIterator::exitEntry( void )
2220 where
->iter
->release();
2222 if (where
->current
) {// && (where != &start))
2223 where
->current
->release();
2227 if (where
!= &start
) {
2230 IOFree( gone
, sizeof(IORegCursor
));
2238 IORegistryIterator::reset( void )
2240 while (exitEntry()) {
2248 where
->current
= root
;
2249 options
&= ~kIORegistryIteratorInvalidFlag
;
2253 IORegistryIterator::free( void )
2266 IORegistryIterator::getNextObjectFlat( void )
2268 IORegistryEntry
* next
= 0;
2269 OSArray
* links
= 0;
2273 if ((0 == where
->iter
)) {
2274 // just entered - create new iter
2277 && (links
= ((options
& kIORegistryIterateParents
) ?
2278 where
->current
->getParentSetReference( plane
) :
2279 where
->current
->getChildSetReference( plane
)))) {
2280 where
->iter
= OSCollectionIterator::withCollection( links
);
2283 // next sibling - release current
2284 if (where
->current
) {
2285 where
->current
->release();
2289 next
= (IORegistryEntry
*) where
->iter
->getNextObject();
2293 } else if (!where
->iter
->isValid()) {
2294 options
|= kIORegistryIteratorInvalidFlag
;
2298 where
->current
= next
;
2306 IORegistryIterator::getNextObjectRecursive( void )
2308 IORegistryEntry
* next
;
2311 next
= getNextObjectFlat();
2312 } while ((0 == next
) && exitEntry());
2316 done
= OSOrderedSet::withCapacity( 10 );
2318 if (done
->setObject((OSObject
*) next
)) {
2319 // done set didn't contain this one, so recurse
2327 IORegistryIterator::getNextObject( void )
2329 if (options
& kIORegistryIterateRecursively
) {
2330 return getNextObjectRecursive();
2332 return getNextObjectFlat();
2337 IORegistryIterator::getCurrentEntry( void )
2340 return where
->current
;
2347 IORegistryIterator::iterateAll( void )
2350 while (getNextObjectRecursive()) {
2359 OSMetaClassDefineReservedUnused(IORegistryEntry
, 0);
2360 OSMetaClassDefineReservedUnused(IORegistryEntry
, 1);
2361 OSMetaClassDefineReservedUnused(IORegistryEntry
, 2);
2362 OSMetaClassDefineReservedUnused(IORegistryEntry
, 3);
2363 OSMetaClassDefineReservedUnused(IORegistryEntry
, 4);
2364 OSMetaClassDefineReservedUnused(IORegistryEntry
, 5);
2366 OSMetaClassDefineReservedUsed(IORegistryEntry
, 0);
2367 OSMetaClassDefineReservedUsed(IORegistryEntry
, 1);
2368 OSMetaClassDefineReservedUsed(IORegistryEntry
, 2);
2369 OSMetaClassDefineReservedUsed(IORegistryEntry
, 3);
2370 OSMetaClassDefineReservedUsed(IORegistryEntry
, 4);
2371 OSMetaClassDefineReservedUsed(IORegistryEntry
, 5);
2373 OSMetaClassDefineReservedUnused(IORegistryEntry
, 6);
2374 OSMetaClassDefineReservedUnused(IORegistryEntry
, 7);
2375 OSMetaClassDefineReservedUnused(IORegistryEntry
, 8);
2376 OSMetaClassDefineReservedUnused(IORegistryEntry
, 9);
2377 OSMetaClassDefineReservedUnused(IORegistryEntry
, 10);
2378 OSMetaClassDefineReservedUnused(IORegistryEntry
, 11);
2379 OSMetaClassDefineReservedUnused(IORegistryEntry
, 12);
2380 OSMetaClassDefineReservedUnused(IORegistryEntry
, 13);
2381 OSMetaClassDefineReservedUnused(IORegistryEntry
, 14);
2382 OSMetaClassDefineReservedUnused(IORegistryEntry
, 15);
2383 OSMetaClassDefineReservedUnused(IORegistryEntry
, 16);
2384 OSMetaClassDefineReservedUnused(IORegistryEntry
, 17);
2385 OSMetaClassDefineReservedUnused(IORegistryEntry
, 18);
2386 OSMetaClassDefineReservedUnused(IORegistryEntry
, 19);
2387 OSMetaClassDefineReservedUnused(IORegistryEntry
, 20);
2388 OSMetaClassDefineReservedUnused(IORegistryEntry
, 21);
2389 OSMetaClassDefineReservedUnused(IORegistryEntry
, 22);
2390 OSMetaClassDefineReservedUnused(IORegistryEntry
, 23);
2391 OSMetaClassDefineReservedUnused(IORegistryEntry
, 24);
2392 OSMetaClassDefineReservedUnused(IORegistryEntry
, 25);
2393 OSMetaClassDefineReservedUnused(IORegistryEntry
, 26);
2394 OSMetaClassDefineReservedUnused(IORegistryEntry
, 27);
2395 OSMetaClassDefineReservedUnused(IORegistryEntry
, 28);
2396 OSMetaClassDefineReservedUnused(IORegistryEntry
, 29);
2397 OSMetaClassDefineReservedUnused(IORegistryEntry
, 30);
2398 OSMetaClassDefineReservedUnused(IORegistryEntry
, 31);
2400 /* inline function implementation */
2402 IORegistryEntry::getPropertyTable( void ) const
2404 return fPropertyTable
;