Annotation of driverkit/libDriver/ppc/IODeviceTreeBus.m, revision 1.1.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.