Annotation of driverkit/libDriver/ppc/IODeviceTreeBus.m, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
        !             7:  * Reserved.  This file contains Original Code and/or Modifications of
        !             8:  * Original Code as defined in and that are subject to the Apple Public
        !             9:  * Source License Version 1.1 (the "License").  You may not use this file
        !            10:  * except in compliance with the License.  Please obtain a copy of the
        !            11:  * License at http://www.apple.com/publicsource and read it before using
        !            12:  * this file.
        !            13:  * 
        !            14:  * The Original Code and all software distributed under the License are
        !            15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
        !            19:  * License for the specific language governing rights and limitations
        !            20:  * under the License.
        !            21:  * 
        !            22:  * @APPLE_LICENSE_HEADER_END@
        !            23:  */
        !            24: /*
        !            25:  * Copyright (c) 1997 Apple Computer, Inc.
        !            26:  *
        !            27:  *
        !            28:  * HISTORY
        !            29:  *
        !            30:  * Simon Douglas  22 Oct 97
        !            31:  * - first checked in. Some stuff from ExpMgr in MacOS.
        !            32:  */
        !            33: 
        !            34: 
        !            35: #import <mach/mach_types.h>
        !            36: #import <machdep/ppc/DeviceTree.h>
        !            37: 
        !            38: #import <driverkit/KernDeviceDescription.h>
        !            39: #import <driverkit/ppc/PPCKernBus.h>
        !            40: 
        !            41: #import <driverkit/ppc/IOPPCDeviceDescription.h>
        !            42: #import <driverkit/ppc/IOPPCDeviceDescriptionPriv.h>
        !            43: #import <driverkit/IODeviceDescriptionPrivate.h>
        !            44: #import <driverkit/ppc/directDevice.h>
        !            45: #import <string.h>
        !            46: 
        !            47: #import <driverkit/ppc/IODeviceTreeBus.h>
        !            48: 
        !            49: /* DK calls this for PExpert to change DT entries */
        !            50: extern int PEEditDTEntry( DTEntry dtEntry, char * nodeName, int index,
        !            51:                     char ** propName , void ** propData, int * propSize);
        !            52: 
        !            53: static const char * device_type = "device_type";
        !            54: 
        !            55: @implementation IODeviceTreeBus
        !            56: 
        !            57: static IOPropertyTable *
        !            58: MakeReferenceTable( DTEntry dtEntry )
        !            59: {
        !            60:     IOReturn           err;
        !            61:     IOPropertyTable *  propTable;
        !            62:     DTPropertyIterator dtIter;
        !            63:     void *             prop;
        !            64:     int                        propSize;
        !            65:     char *             name;
        !            66:     char *             nodeName = NULL;
        !            67:     int                        index;
        !            68: 
        !            69:     propTable = [[IOPropertyTable alloc] init];
        !            70:     err = DTCreatePropertyIterator( dtEntry, &dtIter);
        !            71: 
        !            72:     if( err == kSuccess) {
        !            73:        while( kSuccess == DTIterateProperties( dtIter, &name)) {
        !            74:            err = DTGetProperty( dtEntry, name, &prop, &propSize );
        !            75:            if( err != kSuccess)
        !            76:                continue;
        !            77: 
        !            78:            if( 0 == strcmp( name, "name"))
        !            79:                nodeName = (char *) prop;
        !            80: 
        !            81:            err = [propTable createProperty:name flags:kReferenceProperty value:prop length:propSize];
        !            82:        }
        !            83:        DTDisposePropertyIterator( dtIter);
        !            84:     }
        !            85: 
        !            86:     index = 0;
        !            87:     do {
        !            88:         err = PEEditDTEntry( dtEntry, nodeName, index++, &name, &prop, &propSize);
        !            89:        if( err)
        !            90:            continue;
        !            91: 
        !            92:         [propTable deleteProperty:name];
        !            93:        if( prop)
        !            94:             err = [propTable createProperty:name flags:kReferenceProperty value:prop length:propSize];
        !            95: 
        !            96:     } while( err == noErr);
        !            97: 
        !            98:     return( propTable);
        !            99: }
        !           100: 
        !           101: 
        !           102: + (BOOL)probe:deviceDescription
        !           103: {
        !           104:     id inst;
        !           105: 
        !           106:     // Create an instance and initialize some basic instance variables.
        !           107:     inst = [[self alloc] initFromDeviceDescription:deviceDescription];
        !           108:     if (inst == nil)
        !           109:         return NO;
        !           110: 
        !           111:     [inst setDeviceKind:"Bus"];
        !           112: 
        !           113:     [inst registerDevice];
        !           114: 
        !           115:     [inst probeBus];
        !           116: 
        !           117:     return( YES);
        !           118: }
        !           119: 
        !           120: - initFromDeviceDescription:(IOTreeDevice *)deviceDescription
        !           121: {
        !           122:     void *             prop;
        !           123:     UInt32             propSize;
        !           124:     IOReturn           err;
        !           125:     char               nameBuf[ 64 ];
        !           126: 
        !           127:     if ([super initFromDeviceDescription:deviceDescription] == nil)
        !           128:        return [super free];
        !           129: 
        !           130:     myDevice = deviceDescription;
        !           131:     myParent = [deviceDescription parent];
        !           132:     propTable = [deviceDescription propertyTable];
        !           133:     myEntry = [deviceDescription getRef];
        !           134: 
        !           135:     [self setUnit:0];
        !           136:     [myDevice getDevicePath:nameBuf maxLength:sizeof( nameBuf) useAlias:NO];
        !           137:     [self setName:nameBuf];
        !           138: 
        !           139:     prop = &childSizeCells;
        !           140:     propSize = 4;
        !           141:     err = [propTable getProperty:"#size-cells" flags:0
        !           142:                 value:(void **) &prop length:&propSize];
        !           143:     if( err || (propSize < sizeof(int)))
        !           144:        childSizeCells = 1;
        !           145: 
        !           146:     prop = &childAddrCells;
        !           147:     propSize = 4;
        !           148:     err = [propTable getProperty:"#address-cells" flags:0
        !           149:                 value:(void **) &prop length:&propSize];
        !           150:     if( err || (propSize < sizeof(int)))
        !           151:        childAddrCells = 2;
        !           152: 
        !           153:     myAddrCells = [deviceDescription addressCells];
        !           154:     mySizeCells = [deviceDescription sizeCells];
        !           155: 
        !           156:     return( self);
        !           157: }
        !           158: 
        !           159: 
        !           160: - probeBus
        !           161: {
        !           162:     IOReturn           err;
        !           163:     IOPropertyTable   *        table;
        !           164:     DTEntryIterator    iter;
        !           165:     DTEntry            child;
        !           166:     void *             prop;
        !           167:     UInt32                     propSize;
        !           168:     id                 dev;
        !           169: 
        !           170:     DTCreateEntryIterator( (DTEntry) myEntry, &iter );
        !           171: 
        !           172:     while( kSuccess == DTIterateEntries( iter, &child) ) {
        !           173: 
        !           174:        table = MakeReferenceTable( child);
        !           175: 
        !           176:         // Look for existence of a debug property to skip
        !           177:         if( [table getProperty:"AAPL,ignore" flags:kReferenceProperty
        !           178:                 value:&prop length:&propSize])
        !           179:             dev = [self createDevice:table ref:(id)child];
        !           180:        else
        !           181:            dev = nil;
        !           182: 
        !           183:        if( nil == dev)
        !           184:            [table free];
        !           185: 
        !           186:     }
        !           187:     DTDisposeEntryIterator( iter);
        !           188: 
        !           189:     return( self);
        !           190: }
        !           191: 
        !           192: 
        !           193: - createDevice:(IOPropertyTable *)newTable ref:ref
        !           194: {
        !           195:     id         newDev;
        !           196: 
        !           197:     newDev = [[IOTreeDevice alloc] initAt:newTable parent:self ref:ref];
        !           198: 
        !           199:     return( [newDev publish] );
        !           200: }
        !           201: 
        !           202: static BOOL CompareName( const char * keys, const char * nameList, IOPropertyTable * table)
        !           203: {
        !           204:     BOOL               matched;
        !           205:     UInt32             keyLen, nameLen;
        !           206:     const char *       nextKey;
        !           207:     const char *       names;
        !           208:     const char *       nextName;
        !           209:     BOOL               wild;
        !           210: 
        !           211:     do {
        !           212:        // for each key
        !           213: 
        !           214:        nextKey = strchr( keys, ' ');
        !           215:        if( nextKey)
        !           216:            keyLen = nextKey - keys;
        !           217:        else
        !           218:            keyLen = strlen( keys);
        !           219:        wild = (keys[ keyLen - 1 ] == '*');
        !           220: 
        !           221:        names = nameList;
        !           222:        do {
        !           223:            // for each name
        !           224: 
        !           225:            nextName = strchr( names, ' ');
        !           226:            if( nextName)
        !           227:                nameLen = nextName - names;
        !           228:            else
        !           229:                nameLen = strlen( names);
        !           230: 
        !           231:            if( wild)
        !           232:                matched = (0 == strncmp( keys, names, keyLen - 1 ));
        !           233:            else
        !           234:                matched =  ((nameLen == keyLen) 
        !           235:                        && (0 == strncmp( keys, names, keyLen )));
        !           236: 
        !           237:            if( matched)
        !           238:                [table createProperty:"AAPL,matched-on" flags:0
        !           239:                    value:names length:nameLen];
        !           240: 
        !           241:            names = nextName + 1;
        !           242: 
        !           243:        } while( nextName && (NO == matched));
        !           244: 
        !           245:        keys = nextKey + 1;
        !           246: 
        !           247:     } while( nextKey && (NO == matched));
        !           248: 
        !           249:     return( matched);
        !           250: }
        !           251: 
        !           252: - (BOOL) match:(IOTreeDevice *)device key:(const char *)keys location:(const char *)location
        !           253: {
        !           254:     UInt32             propSize, i;
        !           255:     IOPropertyTable  *  table;
        !           256:     const char *       nodeName;
        !           257:     char       *       compat;
        !           258:     char       *       tail;
        !           259:     const char *       devType;
        !           260:     const char *       model;
        !           261:     BOOL               matched;
        !           262: 
        !           263:     table = [device propertyTable];
        !           264: 
        !           265:     if( 0 == strcmp( keys, "device-tree")) {
        !           266: 
        !           267:        // match ourselves to anything looking like a bus
        !           268:        return(
        !           269:             (noErr == [table getProperty:"ranges" flags:kReferenceProperty
        !           270:                value:NULL length:&propSize])   );
        !           271:     }
        !           272: 
        !           273:     nodeName = [device nodeName];
        !           274: 
        !           275:     if( [table getProperty:device_type flags:kReferenceProperty
        !           276:            value:(void **)&devType length:&propSize])
        !           277:        devType = NULL;
        !           278: 
        !           279:     if( [table getProperty:"model" flags:kReferenceProperty
        !           280:            value:(void **)&model length:&propSize])
        !           281:        model = NULL;
        !           282: 
        !           283:     if( [table getProperty:"compatible" flags:kReferenceProperty
        !           284:            value:(void **)&compat length:&propSize])
        !           285:        compat = NULL;
        !           286:     else {
        !           287:        // convert separators from null to blanks. Blech.
        !           288:        compat = (char *)IOMalloc( propSize);
        !           289:        [table getProperty:"compatible" flags:0
        !           290:            value:(void **)&compat length:&propSize];
        !           291:        for( i = 0; i < propSize - 1; i++)
        !           292:            if( compat[ i ] == 0)
        !           293:                compat[ i ] = ' ';
        !           294:     }
        !           295: 
        !           296:     // Is this enough ordering?
        !           297:     matched =  (model && CompareName( keys, model, table))
        !           298:            || (compat && CompareName( keys, compat, table))
        !           299:            || (nodeName && CompareName( keys, nodeName, table))
        !           300:            || (devType && CompareName( keys, devType, table));
        !           301: 
        !           302:     if( compat)
        !           303:        IOFree( compat, propSize);
        !           304: 
        !           305:     if( matched && location)
        !           306:        matched = ((tail = [device matchDevicePath:location]) && (tail[0] == 0));
        !           307: 
        !           308:     return( matched );
        !           309: }
        !           310: 
        !           311: + probeTree
        !           312: {
        !           313:     IOPropertyTable *   table;
        !           314:     id                 root;
        !           315:     DTEntry            rootEntry;
        !           316: 
        !           317:     DTLookupEntry( (DTEntry) 0, "/", &rootEntry );
        !           318:     table = MakeReferenceTable( rootEntry);
        !           319: 
        !           320:     root = [[IORootDevice alloc] initAt:table ref:(id)rootEntry];
        !           321:     if( nil == root)
        !           322:         return( [table free]);
        !           323:     else
        !           324:         return( [root publish]);
        !           325: }
        !           326: 
        !           327: void DeviceTreeProbe( void )
        !           328: {
        !           329:     [IODeviceTreeBus probeTree];
        !           330: }
        !           331: 
        !           332: // Cells in child nodes
        !           333: - (ItemCount) sizeCells
        !           334: {
        !           335:     return( childSizeCells );
        !           336: }
        !           337: - (ItemCount) addressCells
        !           338: {
        !           339:     return( childAddrCells );
        !           340: }
        !           341: 
        !           342: // Given an addr-len cell from our child, find it in our ranges property, then
        !           343: // recurse to our parent to resolve the base of the range for us.
        !           344: 
        !           345: // Range[]: child-addr  our-addr  child-len
        !           346: // #cells:    child       ours     child
        !           347: 
        !           348: - (IOReturn) resolveAddressCell:(UInt32 *)cell physicalAddress:(PhysicalAddress *)phys
        !           349: {
        !           350:     IOReturn   err;
        !           351:     UInt32  *  nextRange;
        !           352:     UInt32  *  endRanges;
        !           353:     UInt32     start, rangeStart;
        !           354:     UInt32     rangeAddr[ 5 ];
        !           355:     UInt32     childCells;
        !           356:     UInt32     propSize;
        !           357:     UInt32     result;
        !           358: 
        !           359:     childCells = childAddrCells + childSizeCells;
        !           360: 
        !           361:     err = [propTable getProperty:"ranges" flags:kReferenceProperty
        !           362:                 value:(void **) &nextRange length:&propSize];
        !           363: 
        !           364:     if( err) {
        !           365:         // 1-1 map at root
        !           366:         *phys = (PhysicalAddress) cell[ childAddrCells - 1 ];
        !           367:         return( noErr);
        !           368:     }
        !           369: 
        !           370:     if( propSize == 0)
        !           371:         return( [myDevice resolveAddressCell:cell
        !           372:                 physicalAddress:(PhysicalAddress *)phys] );
        !           373: 
        !           374:     if( propSize < (sizeof(int) * (childCells + myAddrCells)) )
        !           375:         return( IO_R_NO_MEMORY);
        !           376: 
        !           377:     err = IO_R_NO_MEMORY;
        !           378:     endRanges = nextRange + (propSize / sizeof(int));
        !           379: 
        !           380:     for(    ;
        !           381:            nextRange < endRanges;
        !           382:            nextRange += (childCells + myAddrCells)) {
        !           383: 
        !           384:        // how is the address compare really supposed to be done?
        !           385:        if( childAddrCells > 1) {
        !           386:            UInt32 space1, space2;
        !           387:            // treat 64-bit memory spaces as 32-bit
        !           388:            space1 = (nextRange[ 0 ] >> 24) & 0x03;
        !           389:            space2 = (cell[ 0 ] >> 24) & 0x03;
        !           390:            if( space1 == 3)
        !           391:                space1 = 2;
        !           392:            if( space2 == 3)
        !           393:                space2 = 2;
        !           394:            if( space1 != space2)
        !           395:                continue;
        !           396:        }
        !           397: 
        !           398:        rangeStart      = nextRange[ childAddrCells - 1 ];
        !           399:        start           = cell[ childAddrCells - 1 ];
        !           400: 
        !           401:        if( (rangeStart <= start)
        !           402:        &&  ( (start + cell[ childCells - 1 ]) 
        !           403:                <= (rangeStart + nextRange[ childCells + myAddrCells - 1 ]) )) {
        !           404: 
        !           405:            // Get the physical start of the range from our parent
        !           406:            bcopy( nextRange + childAddrCells, rangeAddr, 4 * myAddrCells );
        !           407:            bzero( rangeAddr + myAddrCells, 4 * mySizeCells );
        !           408:            err = [myDevice resolveAddressCell:rangeAddr
        !           409:                    physicalAddress:(PhysicalAddress *)&result];
        !           410:            if( err)
        !           411:                continue;
        !           412:            *phys = (PhysicalAddress) (result + start - rangeStart);
        !           413:            break;
        !           414:        }
        !           415:     }
        !           416:     return( err);
        !           417: }
        !           418: 
        !           419: // Find interrupt addressing info
        !           420: 
        !           421: - (IOReturn) interruptSpecCells:(UInt32)handle count:(UInt32 *)count
        !           422: {
        !           423:     IOReturn   err;
        !           424:     UInt32     cells;
        !           425:     UInt32 *   prop;
        !           426:     UInt32     propSize;
        !           427: 
        !           428:     err = [propTable getProperty:"AAPL,phandle"
        !           429:                           flags:kReferenceProperty
        !           430:                           value:(void **)&prop length:&propSize];
        !           431:     if( err)
        !           432:        return( err);
        !           433: 
        !           434:     if( handle && (handle != *prop)) {
        !           435:        // This is a hack - a non-DT-parent interrupt parent
        !           436:        // is assumed the root controller.
        !           437:        *count = 1;
        !           438:        return( noErr );
        !           439:     }
        !           440: 
        !           441:     err = [propTable getProperty:"#interrupt-cells"
        !           442:                           flags:kReferenceProperty
        !           443:                           value:(void **)&prop length:&propSize];
        !           444: 
        !           445:     cells = childAddrCells;
        !           446:     if( err == noErr)
        !           447:        cells += *prop;
        !           448:     *count = cells;
        !           449: 
        !           450:     return( noErr);
        !           451: }
        !           452: 
        !           453: // Map one 'unit interrupt specifier' to platform interrupt
        !           454: 
        !           455: - (IOReturn) mapUnitInterrupt:(UInt32 *)interruptSpec
        !           456:                toInterrupt:(UInt32 **)mapped
        !           457:                parentHandle:(UInt32)handle
        !           458: {
        !           459:     IOReturn   err;
        !           460:     UInt32 *   map;
        !           461:     UInt32 *   mapEnd;
        !           462:     UInt32     propSize;
        !           463:     UInt32 *   mask;
        !           464:     UInt32     myICells, parentICells;
        !           465:     UInt32     iParent;
        !           466:     int                i;
        !           467: 
        !           468:     err = [self interruptSpecCells:handle count:&myICells];
        !           469:     if( err)
        !           470:        return( err);
        !           471: 
        !           472:     if( 1 == myICells) {
        !           473:        *mapped = interruptSpec;
        !           474:        return( noErr);
        !           475:     }
        !           476: 
        !           477:     err = [propTable getProperty:"interrupt-map-mask"
        !           478:                           flags:kReferenceProperty
        !           479:                           value:(void **)&mask length:&propSize];
        !           480:     if( err)
        !           481:        return( err);
        !           482:     if( propSize != (4 * myICells))
        !           483:        return( IO_R_INVALID_ARG);
        !           484: 
        !           485:     err = [propTable getProperty:"interrupt-map"
        !           486:                           flags:kReferenceProperty
        !           487:                           value:(void **)&map length:&propSize];
        !           488:     if( err)
        !           489:        return( err);
        !           490: 
        !           491:     mapEnd = map + (propSize / 4);
        !           492: 
        !           493:     while( map < mapEnd) {
        !           494: 
        !           495:        for( i = 0; i < myICells; i++) {
        !           496:            if( (interruptSpec[ i ] & mask[ i ]) != map[ i ])
        !           497:                break;
        !           498:        }
        !           499: 
        !           500:        iParent = map[ myICells ];
        !           501: 
        !           502:        if( i == myICells) {
        !           503:            // it matched
        !           504:             err = [myParent mapUnitInterrupt:(map + myICells + 1)
        !           505:                             toInterrupt:mapped
        !           506:                             parentHandle:iParent];
        !           507:            break;
        !           508:        }
        !           509: 
        !           510:        // skip this controller's stuff & loop
        !           511:         err = [myParent interruptSpecCells:iParent count:&parentICells];
        !           512:         if( err == noErr)
        !           513:             map += myICells + parentICells + 1;
        !           514:        else
        !           515:            break;
        !           516:     }
        !           517: 
        !           518:     return( err);
        !           519: }
        !           520: 
        !           521: // Create platform interrupts for a child device
        !           522: 
        !           523: - (IOReturn) mapInterrupts:(IOTreeDevice *)device
        !           524:        interrupts:(UInt32 *)interrupts num:(UInt32 *)count
        !           525: {
        !           526:     IOReturn   err;
        !           527:     UInt32 *   prop;
        !           528:     UInt32     propSize;
        !           529:     UInt32     iParent = 0;
        !           530:     UInt32     intSpec[ 5 ];
        !           531:     UInt32     myICells;
        !           532:     UInt32 *   mapped;
        !           533:     int                i, num;
        !           534: 
        !           535:     do {
        !           536:         propSize = *count * 4;
        !           537:         err = [[device propertyTable] getProperty:"interrupts" flags:0
        !           538:                                 value:(void **)&interrupts length:&propSize];
        !           539:         if( err)
        !           540:            continue;
        !           541:         num = propSize / 4;
        !           542:        *count = num;
        !           543: 
        !           544:         err = [[device propertyTable] getProperty:"interrupt-parent"
        !           545:                             flags:kReferenceProperty
        !           546:                             value:(void **)&prop length:&propSize];
        !           547:         if( err == noErr)
        !           548:             iParent = *prop;
        !           549: 
        !           550:         err = [self interruptSpecCells:iParent count:&myICells];
        !           551:         if( err)
        !           552:            continue;
        !           553:         if( 1 == myICells)
        !           554:            continue;
        !           555: 
        !           556:         err = [[device propertyTable] getProperty:"reg"
        !           557:                     flags:kReferenceProperty
        !           558:                    value:(void **)&prop length:&propSize];
        !           559:         if( err)
        !           560:            continue;
        !           561:         bcopy( prop, intSpec, childAddrCells * 4);
        !           562: 
        !           563:        for( i = 0; (err == noErr) && (i < num); i++ ) {
        !           564:            // assuming #interrupt-cell == 1
        !           565:            intSpec[ childAddrCells ] = interrupts[ i ];
        !           566:             err = [self mapUnitInterrupt:intSpec
        !           567:                                 toInterrupt:&mapped
        !           568:                                 parentHandle:iParent];
        !           569:            interrupts[ i ] = *mapped;
        !           570:        }
        !           571: 
        !           572:     } while( NO);
        !           573: 
        !           574:     return( err);
        !           575: }
        !           576: 
        !           577: // Create an AAPL,slot-name property from parent's slot-names
        !           578: 
        !           579: - getSlotName:(IOTreeDevice *) device index:(UInt32)deviceNum
        !           580: {
        !           581:     IOReturn           err;
        !           582:     UInt32     *       prop;
        !           583:     UInt32             propSize;
        !           584:     int                        i;
        !           585:     char *             names;
        !           586:     char *             lastName;
        !           587:     UInt32             mask;
        !           588: 
        !           589:     err = [propTable getProperty:"slot-names"
        !           590:                     flags:kReferenceProperty
        !           591:                     value:(void **) &prop
        !           592:                     length:&propSize];
        !           593: 
        !           594:     if( err == noErr) {
        !           595:         mask = *prop;
        !           596:         names = (char *)(prop + 1);
        !           597:        lastName = names + (propSize - 4);
        !           598: 
        !           599:         for(   i = 0;
        !           600:                (i <= deviceNum) && (names < lastName);
        !           601:                i++ ) {
        !           602: 
        !           603:             if( mask & (1 << i)) {
        !           604:                 if( i == deviceNum) {
        !           605:                     err = [[device propertyTable]
        !           606:                                 createProperty:"AAPL,slot-name" flags:0
        !           607:                                 value:(void *)names
        !           608:                                 length:(1 + strlen( names))];
        !           609:                 } else
        !           610:                    names += 1 + strlen( names);
        !           611:             }
        !           612:         }
        !           613:     }
        !           614: 
        !           615:     return( self);
        !           616: }
        !           617: 
        !           618: 
        !           619: // Set the NVRAM description for the child device, which could be a bridge
        !           620: // as this recurses up the tree.
        !           621: 
        !           622: - makeNVRAMDescriptor:(IOTreeDevice *)device
        !           623:        descriptor:(NVRAMDescriptor *)propHdr
        !           624: {
        !           625:     UInt8      busNum, deviceNum, functionNum;
        !           626: 
        !           627:     [device getLocation:&busNum device:&deviceNum function:&functionNum];
        !           628: 
        !           629:     if( propHdr->format == 0) {
        !           630:        propHdr->format         = 0x1;
        !           631:        propHdr->busNum         = busNum;
        !           632:        propHdr->functionNum    = functionNum;
        !           633:        propHdr->deviceNum      = deviceNum;
        !           634: 
        !           635:     } else if( propHdr->bridgeCount < 6) {
        !           636:        propHdr->bridgeDevices |= (deviceNum << (propHdr->bridgeCount * 5));
        !           637:        propHdr->bridgeCount++;
        !           638:     }
        !           639: 
        !           640:     if( myParent)
        !           641:        return( [myParent makeNVRAMDescriptor:myDevice descriptor:propHdr] );
        !           642: 
        !           643:     return( self);
        !           644: }
        !           645: 
        !           646: - getDevicePath:(IOTreeDevice *)device path:(char *)path maxLength:(int)maxLen
        !           647: {
        !           648:     IOReturn   err = noErr;
        !           649:     int                len;
        !           650:     ByteCount  propSize;
        !           651:     char *     nextComp;
        !           652: 
        !           653:     if( myParent)
        !           654:        if( nil == [myParent getDevicePath:myDevice path:path maxLength:maxLen])
        !           655:             return( nil);
        !           656: 
        !           657:     len = strlen( path);
        !           658:     maxLen--;
        !           659:     nextComp = path + len;
        !           660: 
        !           661:     len++;
        !           662:     if( len < maxLen) {
        !           663:        *(nextComp++) = '/';
        !           664:        len += strlen( [device nodeName]);
        !           665:        if( len < maxLen) {
        !           666:            strcpy( nextComp, [device nodeName] );
        !           667:            nextComp = path + len;
        !           668:            len++;
        !           669:            if( len < maxLen) {
        !           670:                *(nextComp++) = '@';
        !           671:                if( [self getDeviceUnitStr:device name:nextComp maxLength:(maxLen - len)])
        !           672:                    return( self);
        !           673:            }
        !           674:        }
        !           675:     }
        !           676:     // failed
        !           677:     *path = 0;
        !           678:     return( nil);
        !           679: }
        !           680: 
        !           681: - getDeviceUnitStr:(IOTreeDevice *)device name:(char *)name maxLength:(int)len
        !           682: {
        !           683:     IOReturn   err;
        !           684:     UInt32  *  regProp;
        !           685:     ByteCount  propSize;
        !           686:     char       unitStr[ 10 ] = "0";            // lame default for no reg, just like OF
        !           687: 
        !           688:     err = [[device propertyTable] getProperty:"reg" flags:kReferenceProperty
        !           689:                 value:(void **) &regProp length:&propSize];
        !           690:     if( err == noErr)
        !           691:        sprintf( unitStr, "%lx", regProp[ childAddrCells - 1 ]);
        !           692: 
        !           693:     if( strlen( unitStr) < len) {
        !           694:         strcpy( name, unitStr);
        !           695:         return( self);
        !           696:     }
        !           697:     // failed
        !           698:     return( nil);
        !           699: }
        !           700: 
        !           701: - registerLoudly
        !           702: {
        !           703:     return( nil);
        !           704: }
        !           705: 
        !           706: @end
        !           707: 
        !           708: 
        !           709: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.