X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/39236c6e673c41db228275375ab7fdb0f837b292..d9a64523371fa019c4575bb400cbbc3a50ac9903:/iokit/Kernel/IODeviceTreeSupport.cpp?ds=sidebyside diff --git a/iokit/Kernel/IODeviceTreeSupport.cpp b/iokit/Kernel/IODeviceTreeSupport.cpp index 5d6188086..1a3b426d8 100644 --- a/iokit/Kernel/IODeviceTreeSupport.cpp +++ b/iokit/Kernel/IODeviceTreeSupport.cpp @@ -37,6 +37,12 @@ #include +#if __arm64__ +typedef UInt64 dtptr_t; +#else +typedef UInt32 dtptr_t; +#endif + #include extern "C" { @@ -53,14 +59,16 @@ int IODTGetDefault(const char *key, void *infoAddr, unsigned int infoSize ); const IORegistryPlane * gIODTPlane; -static OSArray * gIODTPHandles; -static OSArray * gIODTPHandleMap; +static OSArray * gIODTPHandles; +static OSArray * gIODTPHandleMap; +static OSData * gIODTResolvers; const OSSymbol * gIODTNameKey; const OSSymbol * gIODTUnitKey; const OSSymbol * gIODTCompatibleKey; const OSSymbol * gIODTTypeKey; const OSSymbol * gIODTModelKey; +const OSSymbol * gIODTTargetTypeKey; const OSSymbol * gIODTSizeCellKey; const OSSymbol * gIODTAddressCellKey; @@ -77,6 +85,8 @@ const OSSymbol * gIODTNWInterruptMappingKey; OSDictionary * gIODTSharedInterrupts; +static IOLock * gIODTResolversLock; + static IORegistryEntry * MakeReferenceTable( DTEntry dtEntry, bool copy ); static void AddPHandle( IORegistryEntry * regEntry ); static void FreePhysicalMemory( vm_offset_t * range ); @@ -88,7 +98,7 @@ IODeviceTreeAlloc( void * dtTop ) IORegistryEntry * parent; IORegistryEntry * child; IORegistryIterator * regIter; - DTEntryIterator iter; + OpaqueDTEntryIterator iter; DTEntry dtChild; DTEntry mapEntry; OSArray * stack; @@ -106,6 +116,7 @@ IODeviceTreeAlloc( void * dtTop ) gIODTCompatibleKey = OSSymbol::withCStringNoCopy( "compatible" ); gIODTTypeKey = OSSymbol::withCStringNoCopy( "device_type" ); gIODTModelKey = OSSymbol::withCStringNoCopy( "model" ); + gIODTTargetTypeKey = OSSymbol::withCStringNoCopy( "target-type" ); gIODTSizeCellKey = OSSymbol::withCStringNoCopy( "#size-cells" ); gIODTAddressCellKey = OSSymbol::withCStringNoCopy( "#address-cells" ); gIODTRangeKey = OSSymbol::withCStringNoCopy( "ranges" ); @@ -131,6 +142,9 @@ IODeviceTreeAlloc( void * dtTop ) gIODTPHandles = OSArray::withCapacity( 1 ); gIODTPHandleMap = OSArray::withCapacity( 1 ); + gIODTResolvers = OSData::withCapacity(16); + + gIODTResolversLock = IOLockAlloc(); gIODTInterruptCellKey = OSSymbol::withCStringNoCopy("#interrupt-cells"); @@ -138,7 +152,7 @@ IODeviceTreeAlloc( void * dtTop ) assert( gIODTDefaultInterruptController && gIODTNWInterruptMappingKey && gIODTAAPLInterruptsKey && gIODTPHandleKey && gIODTInterruptParentKey - && gIODTPHandles && gIODTPHandleMap + && gIODTPHandles && gIODTPHandleMap && gIODTResolvers && gIODTResolversLock && gIODTInterruptCellKey ); @@ -150,21 +164,21 @@ IODeviceTreeAlloc( void * dtTop ) parent = MakeReferenceTable( (DTEntry)dtTop, freeDT ); stack = OSArray::withObjects( (const OSObject **) &parent, 1, 10 ); - DTCreateEntryIterator( (DTEntry)dtTop, &iter ); + DTInitEntryIterator( (DTEntry)dtTop, &iter ); do { parent = (IORegistryEntry *)stack->getObject( stack->getCount() - 1); //parent->release(); stack->removeObject( stack->getCount() - 1); - while( kSuccess == DTIterateEntries( iter, &dtChild) ) { + while( kSuccess == DTIterateEntries( &iter, &dtChild) ) { child = MakeReferenceTable( dtChild, freeDT ); child->attachToParent( parent, gIODTPlane); AddPHandle( child ); - if( kSuccess == DTEnterEntry( iter, dtChild)) { + if( kSuccess == DTEnterEntry( &iter, dtChild)) { stack->setObject( parent); parent = child; } @@ -173,10 +187,10 @@ IODeviceTreeAlloc( void * dtTop ) } } while( stack->getCount() - && (kSuccess == DTExitEntry( iter, &dtChild))); + && (kSuccess == DTExitEntry( &iter, &dtChild))); stack->release(); - DTDisposeEntryIterator( iter); + assert(kSuccess != DTExitEntry(&iter, &dtChild)); // parent is now root of the created tree @@ -251,25 +265,31 @@ int IODTGetLoaderInfo( const char *key, void **infoAddr, int *infoSize ) { IORegistryEntry *chosen; OSData *propObj; - unsigned int *propPtr; + dtptr_t *propPtr; unsigned int propSize; + int ret = -1; chosen = IORegistryEntry::fromPath( "/chosen/memory-map", gIODTPlane ); if ( chosen == 0 ) return -1; propObj = OSDynamicCast( OSData, chosen->getProperty(key) ); - if ( propObj == 0 ) return -1; + if ( propObj == 0 ) goto cleanup; propSize = propObj->getLength(); - if ( propSize != (2 * sizeof(UInt32)) ) return -1; + if ( propSize != (2 * sizeof(dtptr_t)) ) goto cleanup; - propPtr = (unsigned int *)propObj->getBytesNoCopy(); - if ( propPtr == 0 ) return -1; + propPtr = (dtptr_t *)propObj->getBytesNoCopy(); + if ( propPtr == 0 ) goto cleanup; *infoAddr = (void *)(uintptr_t) (propPtr[0]); *infoSize = (int) (propPtr[1]); - return 0; + ret = 0; + +cleanup: + chosen->release(); + + return ret; } void IODTFreeLoaderInfo( const char *key, void *infoAddr, int infoSize ) @@ -285,6 +305,7 @@ void IODTFreeLoaderInfo( const char *key, void *infoAddr, int infoSize ) chosen = IORegistryEntry::fromPath( "/chosen/memory-map", gIODTPlane ); if ( chosen != 0 ) { chosen->removeProperty(key); + chosen->release(); } } } @@ -327,12 +348,13 @@ MakeReferenceTable( DTEntry dtEntry, bool copy ) const OSSymbol *nameKey; OSData *data; const OSSymbol *sym; - DTPropertyIterator dtIter; + OpaqueDTPropertyIterator dtIter; void *prop; unsigned int propSize; char *name; char location[ 32 ]; bool noLocation = true; + bool kernelOnly; regEntry = new IOService; @@ -342,11 +364,12 @@ MakeReferenceTable( DTEntry dtEntry, bool copy ) } if( regEntry && - (kSuccess == DTCreatePropertyIterator( dtEntry, &dtIter))) { + (kSuccess == DTInitPropertyIterator( dtEntry, &dtIter))) { + kernelOnly = (kSuccess == DTGetProperty(dtEntry, "kernel-only", &prop, &propSize)); propTable = regEntry->getPropertyTable(); - while( kSuccess == DTIterateProperties( dtIter, &name)) { + while( kSuccess == DTIterateProperties( &dtIter, &name)) { if( kSuccess != DTGetProperty( dtEntry, name, &prop, &propSize )) continue; @@ -360,6 +383,9 @@ MakeReferenceTable( DTEntry dtEntry, bool copy ) } assert( nameKey && data ); + if (kernelOnly) + data->setSerializable(false); + propTable->setObject( nameKey, data); data->release(); nameKey->release(); @@ -388,7 +414,6 @@ MakeReferenceTable( DTEntry dtEntry, bool copy ) regEntry->setLocation( location ); } } - DTDisposePropertyIterator( dtIter); } return( regEntry); @@ -426,14 +451,17 @@ static IORegistryEntry * FindPHandle( UInt32 phandle ) static bool GetUInt32( IORegistryEntry * regEntry, const OSSymbol * name, UInt32 * value ) { - OSData *data; + OSObject * obj; + OSData * data; + bool result; - if( (data = OSDynamicCast( OSData, regEntry->getProperty( name ))) - && (4 == data->getLength())) { - *value = *((UInt32 *) data->getBytesNoCopy()); - return( true ); - } else - return( false ); + if (!(obj = regEntry->copyProperty(name))) return (false); + + result = ((data = OSDynamicCast(OSData, obj)) && (sizeof(UInt32) == data->getLength())); + if (result) *value = *((UInt32 *) data->getBytesNoCopy()); + + obj->release(); + return(result); } static IORegistryEntry * IODTFindInterruptParent( IORegistryEntry * regEntry, IOItemCount index ) @@ -767,23 +795,24 @@ bool IODTMapInterrupts( IORegistryEntry * regEntry ) /* */ -static const char * +static bool CompareKey( OSString * key, - const IORegistryEntry * table, const OSSymbol * propName ) + const IORegistryEntry * table, const OSSymbol * propName, + OSString ** matchingName ) { OSObject *prop; OSData *data; OSString *string; const char *ckey; UInt32 keyLen; + UInt32 nlen; const char *names; const char *lastName; bool wild; bool matched; const char *result = 0; - if( 0 == (prop = table->getProperty( propName ))) - return( 0 ); + if( 0 == (prop = table->copyProperty( propName ))) return( 0 ); if( (data = OSDynamicCast( OSData, prop ))) { names = (const char *) data->getBytesNoCopy(); @@ -791,47 +820,48 @@ CompareKey( OSString * key, } else if( (string = OSDynamicCast( OSString, prop ))) { names = string->getCStringNoCopy(); lastName = names + string->getLength() + 1; - } else - return( 0 ); + } else names = 0; - ckey = key->getCStringNoCopy(); - keyLen = key->getLength(); - wild = ('*' == key->getChar( keyLen - 1 )); + if (names) { + ckey = key->getCStringNoCopy(); + keyLen = key->getLength(); + wild = ('*' == key->getChar( keyLen - 1 )); - do { - // for each name in the property - if( wild) - matched = (0 == strncmp( ckey, names, keyLen - 1 )); - else - matched = (keyLen == strlen( names )) - && (0 == strncmp( ckey, names, keyLen )); + do { + // for each name in the property + nlen = strnlen(names, lastName - names); + if( wild) + matched = ((nlen >= (keyLen - 1)) && (0 == strncmp(ckey, names, keyLen - 1))); + else + matched = (keyLen == nlen) && (0 == strncmp(ckey, names, keyLen)); + + if( matched) + result = names; - if( matched) - result = names; + names = names + nlen + 1; - names = names + strlen( names) + 1; + } while( (names < lastName) && (false == matched)); + } + + if (result && matchingName) *matchingName = OSString::withCString( result ); - } while( (names < lastName) && (false == matched)); + if (prop) prop->release(); - return( result); + return (result != 0); } bool IODTCompareNubName( const IORegistryEntry * regEntry, OSString * name, OSString ** matchingName ) { - const char *result; - bool matched; + bool matched; - matched = (0 != (result = CompareKey( name, regEntry, gIODTNameKey))) - || (0 != (result = CompareKey( name, regEntry, gIODTCompatibleKey))) - || (0 != (result = CompareKey( name, regEntry, gIODTTypeKey))) - || (0 != (result = CompareKey( name, regEntry, gIODTModelKey))); + matched = CompareKey( name, regEntry, gIODTNameKey, matchingName) + || CompareKey( name, regEntry, gIODTCompatibleKey, matchingName) + || CompareKey( name, regEntry, gIODTTypeKey, matchingName) + || CompareKey( name, regEntry, gIODTModelKey, matchingName); - if( result && matchingName) - *matchingName = OSString::withCString( result ); - - return( result != 0 ); + return (matched); } bool IODTMatchNubWithKeys( IORegistryEntry * regEntry, @@ -897,7 +927,7 @@ OSCollectionIterator * IODTFindMatchingEntries( IORegistryEntry * from, } cIter = OSCollectionIterator::withCollection( result); - result->release(); + if (result) result->release(); return( cIter); } @@ -905,29 +935,57 @@ OSCollectionIterator * IODTFindMatchingEntries( IORegistryEntry * from, struct IODTPersistent { IODTCompareAddressCellFunc compareFunc; - IODTNVLocationFunc locationFunc; }; void IODTSetResolving( IORegistryEntry * regEntry, IODTCompareAddressCellFunc compareFunc, - IODTNVLocationFunc locationFunc ) + IODTNVLocationFunc locationFunc __unused ) { - IODTPersistent persist; - OSData *prop; - - persist.compareFunc = compareFunc; - persist.locationFunc = locationFunc; - prop = OSData::withBytes( &persist, sizeof(persist)); - if( !prop) - return; - - prop->setSerializable(false); - regEntry->setProperty( gIODTPersistKey, prop); - prop->release(); + IODTPersistent persist; + IODTPersistent * entry; + OSNumber * num; + unsigned int index, count; + + IOLockLock(gIODTResolversLock); + + count = (gIODTResolvers->getLength() / sizeof(IODTPersistent)); + entry = (typeof(entry)) gIODTResolvers->getBytesNoCopy(); + for (index = 0; index < count; index++) + { + if (compareFunc == entry->compareFunc) break; + entry++; + } + if (index == count) + { + persist.compareFunc = compareFunc; + if (!gIODTResolvers->appendBytes(&persist, sizeof(IODTPersistent))) panic("IODTSetResolving"); + } + + IOLockUnlock(gIODTResolversLock); + + num = OSNumber::withNumber(index, 32); + regEntry->setProperty(gIODTPersistKey, num); + OSSafeReleaseNULL(num); + return; } -#if defined(__arm__) || defined(__i386__) || defined(__x86_64__) +#if defined(__arm64__) +static SInt64 DefaultCompare( UInt32 cellCount, UInt32 left[], UInt32 right[] ) +{ + SInt64 diff = 0; + + if (cellCount == 2) { + diff = IOPhysical32(left[1], left[0]) - IOPhysical32(right[1], right[0]); + } else if (cellCount == 1) { + diff = ( left[0] - right[0] ); + } else { + panic("DefaultCompare only knows how to handle 1 or 2 cells."); + } + + return diff; +} +#elif defined(__arm__) || defined(__i386__) || defined(__x86_64__) static SInt32 DefaultCompare( UInt32 cellCount, UInt32 left[], UInt32 right[] ) { cellCount--; @@ -944,11 +1002,19 @@ static void AddLengthToCells( UInt32 numCells, UInt32 *cells, UInt64 offset) cells[0] += (UInt32)offset; } else { +#if defined(__arm64__) || defined(__arm__) + UInt64 sum = cells[numCells - 2] + offset; + cells[numCells - 2] = (UInt32)sum; + if (sum > UINT32_MAX) { + cells[numCells - 1] += (UInt32)(sum >> 32); + } +#else UInt64 sum = cells[numCells - 1] + offset; cells[numCells - 1] = (UInt32)sum; if (sum > UINT32_MAX) { cells[numCells - 2] += (UInt32)(sum >> 32); } +#endif } } @@ -957,7 +1023,11 @@ static IOPhysicalAddress CellsValue( UInt32 numCells, UInt32 *cells) if (numCells == 1) { return IOPhysical32( 0, cells[0] ); } else { +#if defined(__arm64__) || defined(arm) + return IOPhysical32( cells[numCells - 1], cells[numCells - 2] ); +#else return IOPhysical32( cells[numCells - 2], cells[numCells - 1] ); +#endif } } @@ -977,12 +1047,15 @@ void IODTGetCellCounts( IORegistryEntry * regEntry, // Range[]: child-addr our-addr child-len // #cells: child ours child -bool IODTResolveAddressCell( IORegistryEntry * regEntry, +bool IODTResolveAddressCell( IORegistryEntry * startEntry, UInt32 cellsIn[], IOPhysicalAddress * phys, IOPhysicalLength * lenOut ) { - IORegistryEntry *parent; - OSData *prop; + IORegistryEntry * parent; + IORegistryEntry * regEntry; + OSData * prop; + OSNumber * num; + unsigned int index, count; // cells in addresses at regEntry UInt32 sizeCells, addressCells; // cells in addresses below regEntry @@ -1002,6 +1075,7 @@ bool IODTResolveAddressCell( IORegistryEntry * regEntry, IODTPersistent *persist; IODTCompareAddressCellFunc compare; + regEntry = startEntry; IODTGetCellCounts( regEntry, &childSizeCells, &childAddressCells ); childCells = childAddressCells + childSizeCells; @@ -1018,10 +1092,11 @@ bool IODTResolveAddressCell( IORegistryEntry * regEntry, /* end of the road */ *phys = CellsValue( childAddressCells, cell ); *phys += offset; + if (regEntry != startEntry) regEntry->release(); break; } - parent = regEntry->getParentEntry( gIODTPlane ); + parent = regEntry->copyParentEntry( gIODTPlane ); IODTGetCellCounts( parent, &sizeCells, &addressCells ); if( (propLen = prop->getLength())) { @@ -1030,13 +1105,25 @@ bool IODTResolveAddressCell( IORegistryEntry * regEntry, range = startRange; endRanges = range + (propLen / sizeof(UInt32)); - prop = (OSData *) regEntry->getProperty( gIODTPersistKey ); - if( prop) { - persist = (IODTPersistent *) prop->getBytesNoCopy(); - compare = persist->compareFunc; - } else if (addressCells == childAddressCells) { + compare = NULL; + num = OSDynamicCast(OSNumber, regEntry->getProperty(gIODTPersistKey)); + if (num) + { + IOLockLock(gIODTResolversLock); + index = num->unsigned32BitValue(); + count = gIODTResolvers->getLength() / sizeof(IODTPersistent); + if (index < count) + { + persist = ((IODTPersistent *) gIODTResolvers->getBytesNoCopy()) + index; + compare = persist->compareFunc; + } + IOLockUnlock(gIODTResolversLock); + } + + if (!compare && (addressCells == childAddressCells)) { compare = DefaultCompare; - } else { + } + if (!compare) { panic("There is no mixed comparison function yet..."); } @@ -1104,6 +1191,7 @@ bool IODTResolveAddressCell( IORegistryEntry * regEntry, } /* else zero length range => pass thru to parent */ + if (regEntry != startEntry) regEntry->release(); regEntry = parent; childSizeCells = sizeCells; childAddressCells = addressCells; @@ -1129,107 +1217,45 @@ OSArray * IODTResolveAddressing( IORegistryEntry * regEntry, OSArray *array; IODeviceMemory *range; - parentEntry = regEntry->getParentEntry( gIODTPlane ); - addressProperty = (OSData *) regEntry->getProperty( addressPropertyName ); - if( (0 == addressProperty) || (0 == parentEntry)) - return( 0); - - IODTGetCellCounts( parentEntry, &sizeCells, &addressCells ); - if( 0 == sizeCells) - return( 0); - - cells = sizeCells + addressCells; - reg = (UInt32 *) addressProperty->getBytesNoCopy(); - num = addressProperty->getLength() / (4 * cells); - - array = OSArray::withCapacity( 1 ); - if( 0 == array) - return( 0); - - for( i = 0; i < num; i++) { - if( IODTResolveAddressCell( parentEntry, reg, &phys, &len )) { - range = 0; - if( parent) - range = IODeviceMemory::withSubRange( parent, - phys - parent->getPhysicalSegment(0, 0, kIOMemoryMapperNone), len ); - if( 0 == range) - range = IODeviceMemory::withRange( phys, len ); - if( range) - array->setObject( range ); + array = 0; + do + { + parentEntry = regEntry->copyParentEntry( gIODTPlane ); + addressProperty = (OSData *) regEntry->getProperty( addressPropertyName ); + if( (0 == addressProperty) || (0 == parentEntry)) break; + + IODTGetCellCounts( parentEntry, &sizeCells, &addressCells ); + if( 0 == sizeCells) break; + + cells = sizeCells + addressCells; + reg = (UInt32 *) addressProperty->getBytesNoCopy(); + num = addressProperty->getLength() / (4 * cells); + + array = OSArray::withCapacity( 1 ); + if( 0 == array) break; + + for( i = 0; i < num; i++) { + if( IODTResolveAddressCell( parentEntry, reg, &phys, &len )) { + range = 0; + if( parent) + range = IODeviceMemory::withSubRange( parent, + phys - parent->getPhysicalSegment(0, 0, kIOMemoryMapperNone), len ); + if( 0 == range) + range = IODeviceMemory::withRange( phys, len ); + if( range) + array->setObject( range ); + } + reg += cells; } - reg += cells; - } - regEntry->setProperty( gIODeviceMemoryKey, array); - array->release(); /* ??? */ - - return( array); -} - -static void IODTGetNVLocation( - IORegistryEntry * parent, - IORegistryEntry * regEntry, - UInt8 * busNum, UInt8 * deviceNum, UInt8 * functionNum ) -{ - - OSData *prop; - IODTPersistent *persist; - UInt32 *cell; - - prop = (OSData *) parent->getProperty( gIODTPersistKey ); - if( prop) { - persist = (IODTPersistent *) prop->getBytesNoCopy(); - (*persist->locationFunc)( regEntry, busNum, deviceNum, functionNum ); - } else { - prop = (OSData *) regEntry->getProperty( "reg" ); - *functionNum = 0; - if( prop) { - cell = (UInt32 *) prop->getBytesNoCopy(); - *busNum = 3; - *deviceNum = 0x1f & (cell[ 0 ] >> 24); - } else { - *busNum = 0; - *deviceNum = 0; - } + regEntry->setProperty( gIODeviceMemoryKey, array); + array->release(); /* ??? */ } - return; -} - -/* - * Try to make the same messed up descriptor as Mac OS - */ + while (false); -IOReturn IODTMakeNVDescriptor( IORegistryEntry * regEntry, - IONVRAMDescriptor * hdr ) -{ - IORegistryEntry *parent; - UInt32 level; - UInt32 bridgeDevices; - UInt8 busNum; - UInt8 deviceNum; - UInt8 functionNum; - - hdr->format = 1; - hdr->marker = 0; - - for(level = 0, bridgeDevices = 0; - (parent = regEntry->getParentEntry( gIODTPlane )) && (level < 7); level++ ) { - - IODTGetNVLocation( parent, regEntry, - &busNum, &deviceNum, &functionNum ); - if( level) - bridgeDevices |= ((deviceNum & 0x1f) << ((level - 1) * 5)); - else { - hdr->busNum = busNum; - hdr->deviceNum = deviceNum; - hdr->functionNum = functionNum; - } - regEntry = parent; - } - hdr->bridgeCount = level - 2; - hdr->bridgeDevices = bridgeDevices; + OSSafeReleaseNULL(parentEntry); - return( kIOReturnSuccess ); + return (array); } OSData * IODTFindSlotName( IORegistryEntry * regEntry, UInt32 deviceNumber ) @@ -1239,44 +1265,49 @@ OSData * IODTFindSlotName( IORegistryEntry * regEntry, UInt32 deviceNumber ) OSData *ret = 0; UInt32 *bits; UInt32 i; + size_t nlen; char *names; char *lastName; UInt32 mask; data = (OSData *) regEntry->getProperty("AAPL,slot-name"); - if( data) - return( data); - parent = regEntry->getParentEntry( gIODTPlane ); - if( !parent) - return( 0 ); - data = OSDynamicCast( OSData, parent->getProperty("slot-names")); - if( !data) - return( 0 ); - if( data->getLength() <= 4) - return( 0 ); - - bits = (UInt32 *) data->getBytesNoCopy(); - mask = *bits; - if( (0 == (mask & (1 << deviceNumber)))) - return( 0 ); - - names = (char *)(bits + 1); - lastName = names + (data->getLength() - 4); - - for( i = 0; (i <= deviceNumber) && (names < lastName); i++ ) { - - if( mask & (1 << i)) { - if( i == deviceNumber) { - data = OSData::withBytesNoCopy( names, 1 + strlen( names)); - if( data) { - regEntry->setProperty("AAPL,slot-name", data); - ret = data; - data->release(); - } - } else - names += 1 + strlen( names); + if (data) return (data); + + do + { + parent = regEntry->copyParentEntry( gIODTPlane ); + if (!parent) break; + + data = OSDynamicCast( OSData, parent->getProperty("slot-names")); + if (!data) break; + if (data->getLength() <= 4) break; + + bits = (UInt32 *) data->getBytesNoCopy(); + mask = *bits; + if ((0 == (mask & (1 << deviceNumber)))) break; + + names = (char *)(bits + 1); + lastName = names + (data->getLength() - 4); + + for( i = 0; (i <= deviceNumber) && (names < lastName); i++ ) { + + if( mask & (1 << i)) { + nlen = 1 + strnlen(names, lastName - names); + if( i == deviceNumber) { + data = OSData::withBytesNoCopy(names, nlen); + if( data) { + regEntry->setProperty("AAPL,slot-name", data); + ret = data; + data->release(); + } + } else + names += nlen; + } } } + while (false); + + OSSafeReleaseNULL(parent); return( ret ); }