/*
* Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
*
- * @APPLE_LICENSE_HEADER_START@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
- * The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
- * "License"). You may not use this file except in compliance with the
- * License. Please obtain a copy of the License at
- * http://www.apple.com/publicsource and read it before using this file.
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
*
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
*
- * @APPLE_LICENSE_HEADER_END@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
*/
/*
* Copyright (c) 1998 Apple Computer, Inc. All rights reserved.
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+#define kIORegPlaneParentSuffix "ParentLinks"
+#define kIORegPlaneChildSuffix "ChildLinks"
+#define kIORegPlaneNameSuffix "Name"
+#define kIORegPlaneLocationSuffix "Location"
+#define kIORegPlaneParentSuffixLen (sizeof(kIORegPlaneParentSuffix) - 1)
+
static IORegistryEntry * gRegistryRoot;
static OSDictionary * gIORegistryPlanes;
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
struct s_lock_t {
- decl_simple_lock_data(,interlock) /* "hardware" interlock field */
+ lck_spin_t interlock; /* "hardware" interlock field */
volatile unsigned int
read_count:16, /* No. of accepted readers */
want_upgrade:1, /* Read-to-write upgrade waiting */
{
(void) memset((void *) l, 0, sizeof(s_lock_t));
- simple_lock_init(&l->interlock, 0);
+ lck_spin_init(&l->interlock, IOLockGroup, LCK_ATTR_NULL);
l->want_write = FALSE;
l->want_upgrade = FALSE;
l->read_count = 0;
{
register int i;
- simple_lock(&l->interlock);
+ lck_spin_lock(&l->interlock);
/*
* Try to acquire the want_write bit.
i = lock_wait_time[l->can_sleep ? 1 : 0];
if (i != 0) {
- simple_unlock(&l->interlock);
+ lck_spin_unlock(&l->interlock);
while (--i != 0 && l->want_write)
continue;
- simple_lock(&l->interlock);
+ lck_spin_lock(&l->interlock);
}
if (l->can_sleep && l->want_write) {
l->waiting = TRUE;
- thread_sleep_simple_lock((event_t) l,
- simple_lock_addr(l->interlock),
- THREAD_UNINT);
+ lck_spin_sleep( &l->interlock, LCK_SLEEP_DEFAULT,
+ (event_t) l, THREAD_UNINT);
/* interlock relocked */
}
}
i = lock_wait_time[l->can_sleep ? 1 : 0];
if (i != 0) {
- simple_unlock(&l->interlock);
+ lck_spin_unlock(&l->interlock);
while (--i != 0 && (l->read_count != 0 ||
l->want_upgrade))
continue;
- simple_lock(&l->interlock);
+ lck_spin_lock(&l->interlock);
}
if (l->can_sleep && (l->read_count != 0 || l->want_upgrade)) {
l->waiting = TRUE;
- thread_sleep_simple_lock((event_t) l,
- simple_lock_addr(l->interlock),
- THREAD_UNINT);
+ lck_spin_sleep( &l->interlock, LCK_SLEEP_DEFAULT,
+ (event_t) l, THREAD_UNINT);
/* interlock relocked */
}
}
- simple_unlock(&l->interlock);
+ lck_spin_unlock(&l->interlock);
}
static void
{
boolean_t do_wakeup = FALSE;
- simple_lock(&l->interlock);
+ lck_spin_lock(&l->interlock);
if (l->read_count != 0) {
l->read_count -= 1;
do_wakeup = TRUE;
}
- simple_unlock(&l->interlock);
+ lck_spin_unlock(&l->interlock);
if (do_wakeup)
thread_wakeup((event_t) l);
{
register int i;
- simple_lock(&l->interlock);
+ lck_spin_lock(&l->interlock);
while ( l->want_upgrade || ((0 == l->read_count) && l->want_write )) {
i = lock_wait_time[l->can_sleep ? 1 : 0];
if (i != 0) {
- simple_unlock(&l->interlock);
+ lck_spin_unlock(&l->interlock);
while (--i != 0 &&
(l->want_upgrade || ((0 == l->read_count) && l->want_write )))
continue;
- simple_lock(&l->interlock);
+ lck_spin_lock(&l->interlock);
}
if (l->can_sleep &&
(l->want_upgrade || ((0 == l->read_count) && l->want_write ))) {
l->waiting = TRUE;
- thread_sleep_simple_lock((event_t) l,
- simple_lock_addr(l->interlock),
- THREAD_UNINT);
+ lck_spin_sleep( &l->interlock, LCK_SLEEP_DEFAULT,
+ (event_t) l, THREAD_UNINT);
/* interlock relocked */
}
}
l->read_count += 1;
- simple_unlock(&l->interlock);
+ lck_spin_unlock(&l->interlock);
}
nameKey = OSSymbol::withCString( key);
- strcpy( end, "ParentLinks" );
+ strcpy( end, kIORegPlaneParentSuffix );
parentKey = OSSymbol::withCString( key);
- strcpy( end, "ChildLinks" );
+ strcpy( end, kIORegPlaneChildSuffix );
childKey = OSSymbol::withCString( key);
- strcpy( end, "Name" );
+ strcpy( end, kIORegPlaneNameSuffix );
pathNameKey = OSSymbol::withCString( key);
- strcpy( end, "Location" );
+ strcpy( end, kIORegPlaneLocationSuffix );
pathLocationKey = OSSymbol::withCString( key);
plane = new IORegistryPlane;
bool IORegistryEntry::serializeProperties( OSSerialize * s ) const
{
- bool ok;
-
// setProperty( getRetainCount(), 32, "__retain" );
PLOCK;
- ok = getPropertyTable()->serialize( s );
+ OSCollection *snapshotProperties = getPropertyTable()->copyCollection();
PUNLOCK;
+ bool ok = snapshotProperties->serialize( s );
+ snapshotProperties->release();
return( ok );
}
return( obj );
}
+void
+IORegistryEntry::removeProperty( const OSSymbol * aKey)
+{
+ PLOCK;
+ getPropertyTable()->removeObject( aKey );
+ PUNLOCK;
+}
+
+bool
+IORegistryEntry::setProperty( const OSSymbol * aKey, OSObject * anObject)
+{
+ bool ret = false;
+
+ // If we are inserting a collection class and the current entry
+ // is attached into the registry (inPlane()) then mark the collection
+ // as immutable.
+ OSCollection *coll = OSDynamicCast(OSCollection, anObject);
+ bool makeImmutable = (coll && inPlane());
+
+ PLOCK;
+ if( makeImmutable )
+ coll->setOptions( OSCollection::kMASK, OSCollection::kImmutable );
+
+ ret = getPropertyTable()->setObject( aKey, anObject );
+ PUNLOCK;
+
+ return ret;
+}
+
+IOReturn IORegistryEntry::
+runPropertyAction(Action inAction, OSObject *target,
+ void *arg0, void *arg1, void *arg2, void *arg3)
+{
+ IOReturn res;
+
+ // closeGate is recursive so don't worry if we already hold the lock.
+ PLOCK;
+ res = (*inAction)(target, arg0, arg1, arg2, arg3);
+ PUNLOCK;
+
+ return res;
+}
+
OSObject *
IORegistryEntry::getProperty( const OSString * aKey) const
{
return( obj );
}
-void
-IORegistryEntry::removeProperty( const OSSymbol * aKey)
-{
- PLOCK;
- getPropertyTable()->removeObject( aKey );
- PUNLOCK;
-}
void
IORegistryEntry::removeProperty( const OSString * aKey)
tmpKey->release();
}
-bool
-IORegistryEntry::setProperty( const OSSymbol * aKey, OSObject * anObject)
-{
- bool ret = false;
- PLOCK;
- ret = getPropertyTable()->setObject( aKey, anObject );
- PUNLOCK;
-
- return ret;
-}
-
bool
IORegistryEntry::setProperty( const OSString * aKey, OSObject * anObject)
{
RLOCK;
- ret = (0 != getParentSetReference( plane ));
+ if( plane)
+ ret = (0 != getParentSetReference( plane ));
+ else {
+
+ // Check to see if this is in any plane. If it is in a plane
+ // then the registryTable will contain a key with the ParentLinks
+ // suffix. When we iterate over the keys looking for that suffix
+ ret = false;
+
+ OSCollectionIterator *iter =
+ OSCollectionIterator::withCollection( registryTable());
+ if( iter) {
+ const OSSymbol *key;
+
+ while( (key = (OSSymbol *) iter->getNextObject()) ) {
+ const char *keysuffix;
+
+ // Get a pointer to this keys suffix
+ keysuffix = key->getCStringNoCopy()
+ + key->getLength() - kIORegPlaneParentSuffixLen;
+ if( !strcmp(keysuffix, kIORegPlaneParentSuffix) ) {
+ ret = true;
+ break;
+ }
+ }
+ iter->release();
+ }
+ }
UNLOCK;
else
needParent = true;
-// ret &= parent->makeLink( this, kChildSetIndex, plane );
-
UNLOCK;
+ PLOCK;
+
+ // Mark any collections in the property list as immutable
+ OSDictionary *ptable = getPropertyTable();
+ OSCollectionIterator *iter =
+ OSCollectionIterator::withCollection( ptable );
+ if( iter) {
+ const OSSymbol *key;
+
+ while( (key = (OSSymbol *) iter->getNextObject( ))) {
+ // Is object for key a collection?
+ OSCollection *coll =
+ OSDynamicCast( OSCollection, ptable->getObject( key ));
+
+ if( coll) {
+ // Yup so mark it as immutable
+ coll->setOptions( OSCollection::kMASK,
+ OSCollection::kImmutable );
+ }
+ }
+ iter->release();
+ }
+
+ PUNLOCK;
+
if( needParent)
ret &= parent->attachToChild( this, plane );
OSMetaClassDefineReservedUsed(IORegistryEntry, 2);
OSMetaClassDefineReservedUsed(IORegistryEntry, 3);
OSMetaClassDefineReservedUsed(IORegistryEntry, 4);
+OSMetaClassDefineReservedUsed(IORegistryEntry, 5);
-OSMetaClassDefineReservedUnused(IORegistryEntry, 5);
OSMetaClassDefineReservedUnused(IORegistryEntry, 6);
OSMetaClassDefineReservedUnused(IORegistryEntry, 7);
OSMetaClassDefineReservedUnused(IORegistryEntry, 8);