Annotation of driverkit/libDriver/ppc/IOTreeDevice.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.
                     32:  */
                     33: 
                     34: 
                     35: #import <mach/mach_types.h>
                     36: #import <machdep/ppc/DeviceTree.h>
                     37: #import <machdep/ppc/powermac.h>
                     38: 
                     39: #import <driverkit/KernDeviceDescription.h>
                     40: #import <driverkit/ppc/PPCKernBus.h>
                     41: 
                     42: #import <driverkit/ppc/IOPPCDeviceDescription.h>
                     43: #import <driverkit/ppc/IOPPCDeviceDescriptionPriv.h>
                     44: #import <driverkit/IODeviceDescriptionPrivate.h>
                     45: #import <driverkit/ppc/directDevice.h>
                     46: 
                     47: #import <driverkit/ppc/IODeviceTreeBus.h>
                     48: 
                     49: // platform expert
                     50: extern vm_offset_t
                     51: PEResidentAddress( vm_offset_t address, vm_size_t length );
                     52: 
                     53: 
                     54: #define INFO   if(0)   kprintf
                     55: 
                     56: 
                     57: struct tree_private {
                     58:     IOTreeDevice       *       listNext;
                     59:     id                         parent;
                     60:     id                         ref;
                     61:     IOPropertyTable   *                propTable;
                     62:     char                       nodeName[ 40 ];
                     63:     BOOL                       matched;
                     64:     BOOL                       denyNVRAM;
                     65:     UInt32                             numMaps;
                     66:     UInt32                     addressCells;
                     67:     UInt32                     sizeCells;
                     68:     IOApertureInfo                     maps[8];         // FIXME
                     69:     char                       nvramPropName[ 5 ];
                     70: };
                     71: 
                     72: @implementation IOTreeDevice
                     73: 
                     74: 
                     75: - initAt:(IOPropertyTable *)_propTable parent:_parent ref:_ref
                     76: {
                     77:     struct tree_private        *private;
                     78:     IOReturn           err;
                     79:     char           *   prop;
                     80:     ByteCount          propSize;
                     81: 
                     82:     [super _initWithDelegate:nil];
                     83: 
                     84:     _tree_private = (void *)IOMalloc(sizeof (struct tree_private));
                     85:     bzero(_tree_private, sizeof (struct tree_private));
                     86:     private = _tree_private;
                     87: 
                     88:     private->parent = _parent;
                     89:     private->ref = _ref;
                     90:     private->propTable = _propTable;
                     91: 
                     92:     propSize = 40;
                     93:     prop = private->nodeName;
                     94:     err = [_propTable getProperty:"name" flags:0
                     95:                value:(void **) &prop length:&propSize];
                     96:     private->nodeName[ propSize ] = 0;
                     97: 
                     98:     INFO("---- Adding device %s\n", private->nodeName );
                     99: 
                    100:     if( _parent) {
                    101:         private->addressCells = [_parent addressCells];
                    102:         private->sizeCells = [_parent sizeCells];
                    103:     } else     // must be device-tree root
                    104:         private->addressCells = private->sizeCells = 1;
                    105: 
                    106:     return( self);
                    107: }
                    108: 
                    109: - (IOReturn) resolveAddressing
                    110: {
                    111:     struct tree_private        *private = _tree_private;
                    112:     IOReturn           err;
                    113:     UInt32     *       cells;
                    114:     ByteCount          propSize;
                    115: 
                    116:     err = [private->propTable getProperty:"reg" flags:kReferenceProperty
                    117:                 value:(void **) &cells length:&propSize];
                    118: 
                    119:     if( err == noErr) {
                    120: 
                    121:        err = [self findMemoryApertures:cells
                    122:            num:(propSize / (4 * (private->addressCells + private->sizeCells)))];
                    123:     } else
                    124:        err = noErr;
                    125: 
                    126:     return( err);
                    127: }
                    128: 
                    129: 
                    130: - (IOReturn) findMemoryApertures:(UInt32 *)cells num:(UInt32)numCells
                    131: {
                    132:     struct tree_private        *private = _tree_private;
                    133:     IOReturn           err;
                    134:     UInt32             num;
                    135:     IOApertureInfo  *  map;
                    136:     IORange        *   ranges = NULL;
                    137:     IOLogicalAddress * aaplAddress = NULL;
                    138:     UInt32             myCells;
                    139: 
                    140:     do {
                    141:         ranges = (IORange *) IOMalloc( numCells * sizeof( IORange));
                    142:        if( ranges == NULL)
                    143:            continue;
                    144:         aaplAddress = (IOLogicalAddress *) IOMalloc( numCells * sizeof( IOLogicalAddress));
                    145:         if( aaplAddress == NULL)
                    146:             continue;
                    147: 
                    148:         myCells = private->addressCells + private->sizeCells;
                    149:         map = private->maps;
                    150:         private->numMaps = 0;
                    151:        num = numCells;
                    152: 
                    153:         while( num--) {
                    154: 
                    155:             err = [private->parent resolveAddressCell:cells
                    156:                     physicalAddress:(PhysicalAddress) &map->physical];
                    157: 
                    158:             // resolvePhysicalAddresses should return only memory mapped apertures
                    159:             if( err == noErr) {
                    160: 
                    161:                 map->length    = cells[ myCells - 1 ];
                    162: #if 0
                    163:                 map->length    = 0xfffff000 & (0xfff + map->length);
                    164: #endif
                    165:                 map->logical   = (IOLogicalAddress)
                    166:                     PEResidentAddress( map->physical, map->length);
                    167:                 map->cacheMode         = 0;
                    168:                 map->usage     = 0;
                    169: 
                    170:                 ranges[ private->numMaps ].start = map->physical;
                    171:                 ranges[ private->numMaps ].size = map->length;
                    172: 
                    173:                 INFO("Physical = %08x, %08x\n", map->physical, map->length );
                    174: 
                    175:                 aaplAddress[ private->numMaps++ ] = map->logical;
                    176:                 map++;
                    177:             }
                    178: 
                    179:             cells += myCells;
                    180:         }
                    181: 
                    182:         [private->propTable createProperty:"AAPL,dk_Share "MEM_MAPS_KEY flags:0
                    183:                 value:"Y" length:1];
                    184:         [private->propTable createProperty:"AAPL,address" flags:0
                    185:                 value:aaplAddress length:(private->numMaps * sizeof( IOLogicalAddress))];
                    186: 
                    187:         err = [self setMemoryRangeList:ranges num:private->numMaps];
                    188:         if( err)
                    189:             IOLog("%s: couldn't get physical range.\n", [self nodeName]);
                    190: 
                    191:     } while( false);
                    192: 
                    193:     if( ranges)
                    194:         IOFree( ranges, numCells * sizeof( IORange));
                    195:     if( aaplAddress)
                    196:         IOFree( aaplAddress, numCells * sizeof( IOLogicalAddress));
                    197: 
                    198:     return( err);
                    199: }
                    200: 
                    201: 
                    202: - (IOReturn) resolveAddressCell:(UInt32 *)cell physicalAddress:(PhysicalAddress *)phys
                    203: {
                    204:     struct tree_private        *private = _tree_private;
                    205: 
                    206:     // root has no regs or ranges so shouldn't get here
                    207:     return( [private->parent resolveAddressCell:cell physicalAddress:phys] );
                    208: }
                    209: 
                    210: - (IOReturn) resolveInterrupts
                    211: {
                    212:     struct tree_private        *private = _tree_private;
                    213:     id                 propTable;
                    214:     IOReturn           err;
                    215:     UInt32             propSize;
                    216:     void       *       prop;
                    217:     UInt32             i;
                    218:     UInt32             intBuf[ 16 ];
                    219: 
                    220:     propTable = private->propTable;
                    221: 
                    222:     prop = intBuf;
                    223:     propSize = sizeof( intBuf);
                    224:     err = [propTable getProperty:"AAPL,interrupts" flags:0
                    225:                 value:&prop length:&propSize];
                    226: 
                    227:     if (err == noErr)
                    228:        propSize = propSize / 4;
                    229: 
                    230:     else {
                    231:        // Try NewWorld mapping
                    232:        // NB: IsYosemite == IsNewWorld
                    233:         if ([self parent] && (IsYosemite())) {
                    234:            propSize = 16;
                    235:            err = [[self parent] mapInterrupts:self
                    236:                        interrupts:intBuf num:&propSize];
                    237:             if( err == noErr) {
                    238:                // only necessary for ATY66
                    239:                 [propTable createProperty:"AAPL,interrupts" flags:0
                    240:                             value:intBuf length:(propSize * 4)];
                    241:            }
                    242:        }
                    243:     } 
                    244: 
                    245:     if( err == noErr) {
                    246: 
                    247:        for( i = 0; i < propSize; i++ ) {
                    248:            INFO("{%x", intBuf[ i ]);
                    249:            intBuf[ i ] ^= 0x18;                // !!remove : byte reverse bit number
                    250:            INFO(" = %x}\n", intBuf[ i ]);
                    251:        }
                    252: 
                    253:        err = [self setInterruptList:(unsigned int *)intBuf num:propSize];
                    254:         if( err)
                    255:            IOLog("%s: couldn't get interrupts.\n", [self nodeName]);
                    256:     }
                    257: 
                    258:     return( err);
                    259: }
                    260: 
                    261: - getResources
                    262: {
                    263:     struct tree_private        *private = _tree_private;
                    264:     IOReturn           err;
                    265:     UInt8              nvramProp[ 8 ];
                    266:     ByteCount          propSize;
                    267: 
                    268:     [self resolveInterrupts];
                    269:     [self resolveAddressing];
                    270: 
                    271:     // read the nvram property into the table
                    272: 
                    273:     err = [self readNVRAMProperty:private->nvramPropName value:(void *)nvramProp length:&propSize];
                    274:     if( err == noErr)
                    275:         err = [private->propTable createProperty:private->nvramPropName flags:0
                    276:                        value:nvramProp length:propSize ];
                    277:     return( self);
                    278: }
                    279: 
                    280: - (IOReturn) getApertures:(IOApertureInfo *)info items:(UInt32 *)items
                    281: {
                    282:     struct tree_private        *private = _tree_private;
                    283:     UInt32     count = *items;
                    284: 
                    285:     *items = private->numMaps;
                    286:     if( info) {
                    287:         if( count > private->numMaps)
                    288:             count = private->numMaps;
                    289:         bcopy( private->maps, info, count * sizeof( IOApertureInfo));
                    290:     }
                    291:     return( noErr);
                    292: }
                    293: 
                    294: // This is used to generate the NVRAM node description.
                    295: // It will make "PCI" IDs for non-PCI devices, using the Expansion Mgr method.
                    296: 
                    297: - getLocation:(UInt8 *)bus device:(UInt8 *)device function:(UInt8 *)function
                    298: {
                    299:     struct tree_private        *private = _tree_private;
                    300:     UInt32             regHi;
                    301:     IOReturn           err;
                    302:     UInt32     *       cells;
                    303:     ByteCount          propSize;
                    304: 
                    305:     err = [private->propTable getProperty:"reg" flags:kReferenceProperty
                    306:                 value:(void **) &cells length:&propSize];
                    307: 
                    308:     if( err) {
                    309:        *bus            = 0;
                    310:        *function       = 0;
                    311:        *device         = 0;
                    312:        return( nil);
                    313:     }
                    314: 
                    315:     regHi = *cells;
                    316:     if( (regHi & 0xf0000000) != 0xf0000000) {
                    317:        // ExpMgr considers this a PCI device!
                    318:        // Wacky, but works out well for gc's children.
                    319:        *bus            = 0x03 & (regHi >> 16);
                    320:        *function       = 0x07 & (regHi >> 8);
                    321:        *device         = 0x1f & (regHi >> 11);
                    322: 
                    323:     } else {
                    324:        *bus            = 3;
                    325:        *function       = 0;
                    326:        *device         = 0x1f & (regHi >> 24);
                    327:     }
                    328:     return( self);
                    329: }
                    330: 
                    331: - getRef
                    332: {
                    333:     struct tree_private        *private = _tree_private;
                    334: 
                    335:     return( private->ref);
                    336: }
                    337: 
                    338: - setDelegate:delegate
                    339: {
                    340:     id         ret;
                    341: 
                    342:     ret = [super _initWithDelegate:delegate];
                    343: 
                    344:     if( ret && delegate) {
                    345:        [self getResources];
                    346: //     [[delegate bus] allocateResourcesForDeviceDescription:delegate];
                    347:     }
                    348:     return( ret);
                    349: }
                    350: 
                    351: - (IOConfigTable *) configTable
                    352: {
                    353:     struct tree_private        *  private = _tree_private;
                    354: 
                    355:     return( (IOConfigTable *) private->propTable);
                    356: }
                    357: 
                    358: - propertyTable
                    359: {
                    360:     struct tree_private        *private = _tree_private;
                    361: 
                    362:     return( private->propTable);
                    363: }
                    364: 
                    365: - parent
                    366: {
                    367:     struct tree_private        *private = _tree_private;
                    368: 
                    369:     return( private->parent);
                    370: }
                    371: 
                    372: - (char *)nodeName
                    373: {
                    374:     struct tree_private        *private = _tree_private;
                    375: 
                    376:     return( private->nodeName);
                    377: }
                    378: 
                    379: - (ItemCount) addressCells
                    380: {
                    381:     struct tree_private        *private = _tree_private;
                    382: 
                    383:     return( private->addressCells);
                    384: }
                    385: 
                    386: - (ItemCount) sizeCells
                    387: {
                    388:     struct tree_private        *private = _tree_private;
                    389: 
                    390:     return( private->sizeCells);
                    391: }
                    392: 
                    393: 
                    394: - (BOOL) match:(const char *)key location:(const char *)location
                    395: {
                    396:     struct tree_private        *private = _tree_private;
                    397: 
                    398:     return( [private->parent match:self key:key location:location]);
                    399: }
                    400: 
                    401: - taken:(BOOL)taken
                    402: {
                    403:     struct tree_private        *private = _tree_private;
                    404: 
                    405:     private->matched = taken;
                    406:     return( self);
                    407: }
                    408: 
                    409: static IOTreeDevice *   firstDevice;
                    410: static IOTreeDevice *   lastDevice;
                    411: 
                    412: - publish
                    413: {
                    414:     struct tree_private        *private;
                    415: 
                    416:     if( firstDevice == nil)
                    417:        firstDevice = self;
                    418:     if( lastDevice) {
                    419:        private = lastDevice->_tree_private;
                    420:         private->listNext = self;
                    421:     }
                    422:     lastDevice = self;
                    423:     PublishDevice( self);
                    424:     return( self);
                    425: }
                    426: 
                    427: + findMatchingDevice:(const char *)key location:(const char *)location
                    428: {
                    429:     IOTreeDevice       *       list = firstDevice;
                    430:     struct tree_private        *       private;
                    431: 
                    432:     while( list) {
                    433:        private = list->_tree_private;
                    434: 
                    435:        if( (NO == private->matched) && ([list match:key location:location]) )
                    436:            return( list);
                    437:        list = private->listNext;
                    438:     }
                    439:     return( nil);
                    440: }
                    441: 
                    442: + findForIndex:(UInt32 )index
                    443: {
                    444:     IOTreeDevice       *       list = firstDevice;
                    445:     struct tree_private        *       private;
                    446: 
                    447:     while( list && (index--)) {
                    448:        private = list->_tree_private;
                    449:        list = private->listNext;
                    450:     }
                    451:     return( list);
                    452: }
                    453: 
                    454: 
                    455: ////////
                    456: //////// NVRAM device property access.
                    457: ////////
                    458: 
                    459: // move these to platform expert:
                    460: // Can't be used anymore...
                    461: #if 0
                    462: enum {
                    463:     kXPRAMNVPartition          = 0x1300,
                    464:     kNameRegistryNVPartition   = 0x1400,
                    465:     kOpenFirmwareNVPartition   = 0x1800,
                    466: };
                    467: #endif
                    468: extern IOReturn ReadNVRAM( unsigned int offset, unsigned int length, unsigned char * buffer );
                    469: extern IOReturn WriteNVRAM( unsigned int offset, unsigned int length, unsigned char * buffer );
                    470: ////
                    471: 
                    472: 
                    473: #define READINC( size,dest )   ReadNVRAM( nvpc, size, (unsigned char *) dest); \
                    474:                                nvpc += size;
                    475: 
                    476: #define MIN(a,b) ((a > b) ? b : a)
                    477: 
                    478: 
                    479: static UInt16
                    480: SearchNVRAMProperty( NVRAMDescriptor * propHdr, UInt16 * theEnd )
                    481: {
                    482: UInt16         nvpc, nvEnd;
                    483: NVRAMDescriptor        nvDescrip;
                    484: 
                    485:     nvpc = NVRAM_NameRegistry_Offset;
                    486:     READINC( sizeof( short), &nvEnd );
                    487: 
                    488:     if( (nvEnd < NVRAM_NameRegistry_Offset) || (nvEnd >= (NVRAM_NameRegistry_Offset + 0x400)))
                    489:        nvEnd = NVRAM_NameRegistry_Offset + 2;
                    490:     *theEnd = nvEnd;
                    491: 
                    492:     while( (nvpc + sizeof( NVRAMProperty)) <= nvEnd ) {
                    493: 
                    494:        READINC( sizeof( NVRAMDescriptor), &nvDescrip )
                    495:        if( 0 == bcmp( &nvDescrip, propHdr, sizeof( NVRAMDescriptor)))
                    496:            return( nvpc );
                    497:        else
                    498:            nvpc += (sizeof( NVRAMProperty) - sizeof( NVRAMDescriptor));
                    499:     }
                    500: 
                    501:     return( 0);
                    502: }
                    503: 
                    504: - (IOReturn) readNVRAMProperty:(char *)name value:(void *)buffer length:(ByteCount *)length
                    505: {
                    506:     IOReturn           err = nrNotFoundErr;
                    507:     UInt16             nvpc, nvEnd;
                    508:     unsigned char      nameLen, dataLen;
                    509:     NVRAMDescriptor    propHdr;
                    510: 
                    511:     bzero( &propHdr, sizeof( NVRAMDescriptor));
                    512:     [[self parent] makeNVRAMDescriptor:self descriptor:&propHdr];
                    513: 
                    514: #if 0
                    515:     kprintf("makeNVRAMDescriptor:bridgeCount %x, busNum %x, bridgeDevices %x, functionNum %x, deviceNum %x\n", 
                    516:        propHdr.bridgeCount, propHdr.busNum, propHdr.bridgeDevices, propHdr.functionNum, propHdr.deviceNum );
                    517: #endif
                    518: 
                    519:     nvpc = SearchNVRAMProperty( &propHdr, &nvEnd);
                    520: 
                    521:     if( nvpc) {
                    522:        READINC( sizeof( UInt8), &nameLen )
                    523:        nameLen = MIN( nameLen, 4);
                    524:        ReadNVRAM( nvpc, nameLen, (unsigned char *) name);
                    525:        name[ nameLen ] = 0;
                    526:        nvpc += kMaxNVNameLen;
                    527:        READINC( sizeof( UInt8), &dataLen )
                    528:        dataLen = MIN( dataLen, 8);
                    529:        *length = dataLen;
                    530:        ReadNVRAM( nvpc, dataLen, (unsigned char *) buffer);
                    531:        err = noErr;
                    532:     }
                    533:     return( err);
                    534: }
                    535: 
                    536: - (IOReturn) writeNVRAMProperty:(const char *)name value:(void *)value length:(ByteCount)length
                    537: {
                    538:     IOReturn           err = noErr;
                    539:     UInt16             nvpc, nvEnd;
                    540:     UInt8              nameLen;
                    541:     NVRAMProperty      nvram;
                    542: 
                    543:     nameLen = strlen( name);
                    544:     if( (nameLen > kMaxNVNameLen) || (length > kMaxNVDataLen))
                    545:        return( nrOverrunErr);
                    546: 
                    547:     nvram.nameLen = nameLen;
                    548:     bcopy( name, nvram.name, nameLen);
                    549:     nvram.dataLen = length;
                    550:     bcopy( value, nvram.data, length);
                    551: 
                    552:     bzero( &nvram.header, sizeof( NVRAMDescriptor));
                    553:     [[self parent] makeNVRAMDescriptor:self descriptor:&nvram.header];
                    554:     nvpc = SearchNVRAMProperty( &nvram.header, &nvEnd);
                    555: 
                    556:     if( nvpc == 0) {
                    557: 
                    558:        // Not found - append it.
                    559:        nvpc = nvEnd;
                    560:        nvEnd += sizeof( NVRAMProperty);
                    561:        if( nvEnd > (NVRAM_NameRegistry_Offset + 0x400))
                    562:            err = nrNotEnoughMemoryErr;
                    563:        else {
                    564:            WriteNVRAM( nvpc, sizeof( NVRAMProperty), (UInt8 *) &nvram );
                    565:            WriteNVRAM( NVRAM_NameRegistry_Offset, 2, (UInt8 *) &nvEnd );
                    566:        }
                    567: 
                    568:     } else {
                    569: 
                    570:        // Overwrite the current one. They're all maximum length.
                    571:        WriteNVRAM( nvpc, sizeof( NVRAMProperty) - sizeof( NVRAMDescriptor), (UInt8 *) &nvram.nameLen );
                    572:     }
                    573: 
                    574: #if 0
                    575:     {
                    576:        int i;
                    577:        ReadNVRAM( NVRAM_NameRegistry_Offset, 0x50, buffer);
                    578:        for( i=0; i<0x50; i++) {
                    579:            kprintf(" 0x%02x,", buffer[i]);
                    580:            if( (i%16) == 15) kprintf("\n");
                    581:        }
                    582:     }
                    583: #endif
                    584: 
                    585:     return( err);
                    586: }
                    587: 
                    588: // The following are property table based for NDRV support
                    589: 
                    590: - (IOReturn) setNVRAMProperty:(const char *)propertyName
                    591: {
                    592:     struct tree_private        *private = _tree_private;
                    593:     IOReturn           err;
                    594:     void *             value;
                    595:     ByteCount          propSize;
                    596: 
                    597:     err = [[self propertyTable] getProperty:propertyName flags:kReferenceProperty
                    598:                 value:&value length:&propSize];
                    599:     if( err)
                    600:         return( err);
                    601: 
                    602:     if( private->denyNVRAM)
                    603:         return( noErr);
                    604: 
                    605:     err = [self writeNVRAMProperty:propertyName value:value length:propSize];
                    606:     if( err)
                    607:         return( err);
                    608: 
                    609:     strcpy( private->nvramPropName, propertyName);             // already checked length
                    610:     return( noErr);
                    611: }
                    612: 
                    613: - (BOOL) isNVRAMProperty:(const char *)propertyName
                    614: {
                    615:     struct tree_private        *private = _tree_private;
                    616: 
                    617:     return( 0 == strcmp( propertyName, private->nvramPropName));
                    618: }
                    619: 
                    620: - denyNVRAM:(BOOL)flag
                    621: {
                    622:     struct tree_private        *private = _tree_private;
                    623: 
                    624:     private->denyNVRAM = flag;
                    625:     return( self);
                    626: }
                    627: 
                    628: /* ---------------------------------------------------------- */
                    629: 
                    630: const char * MatchPaths( const char * matchPath, const char * fullPath)
                    631: {
                    632:     const char *       ourPath;
                    633:     char               c1, c2;
                    634: 
                    635:     ourPath = fullPath;
                    636:     do {
                    637:         c2 = *ourPath++;
                    638:         if( c2 == 0)
                    639:             return( matchPath);                // return tail of match path
                    640:         if( (c2 >= 'A') && (c2 <= 'Z'))
                    641:             c2 += 'a' - 'A';
                    642: 
                    643:         c1 = *matchPath++;
                    644:         if( (c1 >= 'A') && (c1 <= 'Z'))
                    645:             c1 += 'a' - 'A';
                    646: 
                    647:         if( c1 != c2) {
                    648:             // our path always has unit numbers, match may not
                    649:             if( c2 == '@') {
                    650:                 while( (c2 = *ourPath++)
                    651:                     && (c2 != '/') )   {}
                    652:                 ourPath--;
                    653:                 matchPath--;
                    654: 
                    655:             // our path always has device names, match may not
                    656:             } else if( c1 == '@') {
                    657:                     while( (c2 = *ourPath++)
                    658:                         && (c2 != '@') )       {}
                    659: 
                    660:             } else
                    661:                 break;
                    662:        }
                    663:     } while( YES );
                    664: 
                    665:     return( NULL);                     // no match
                    666: }
                    667: 
                    668: // Remove aliases from the head of the path
                    669: // returns difference in length
                    670: 
                    671: int
                    672: IODealiasPath( char * outputPath, const char * inputPath)
                    673: {
                    674:     IOReturn           err;
                    675:     DTEntry            dtEntry;
                    676:     DTPropertyIterator dtIter;
                    677:     int                        nameSize, aliasSize;
                    678:     char       *       name;
                    679:     char               c;
                    680:     int                        diff = 0;
                    681: 
                    682:     outputPath[ 0 ] = 0;
                    683: 
                    684:     if( (inputPath[ 0 ] != '/')
                    685:     && (kSuccess == DTLookupEntry(0, "/aliases", &dtEntry) )) {
                    686: 
                    687:         err = DTCreatePropertyIterator( dtEntry, &dtIter);
                    688:         if( err == kSuccess) {
                    689:             while( kSuccess == DTIterateProperties( dtIter, &name)) {
                    690: 
                    691:                 nameSize = strlen( name);
                    692:                 c = inputPath[ nameSize ];
                    693:                 if( c && (c != '/') && (c != ':') && (c != '@') && (c != ','))
                    694:                     continue;
                    695: 
                    696:                 if( 0 == strncmp( inputPath, name, nameSize)) {
                    697:                     if( kSuccess != DTGetProperty( dtEntry, name, (void **) &name, &aliasSize ))
                    698:                         continue;
                    699:                     aliasSize--;                               // ditch the zero in property
                    700:                     strncpy( outputPath, name, aliasSize);
                    701:                     strcpy( outputPath + aliasSize, inputPath + nameSize);
                    702:                    diff = nameSize - aliasSize;
                    703:                     break;
                    704:                 }
                    705:             }
                    706:             DTDisposePropertyIterator( dtIter);
                    707:         }
                    708:     }
                    709:     if( outputPath[ 0 ] == 0)
                    710:         strcpy( outputPath, inputPath);
                    711: 
                    712:     return( diff);
                    713: }
                    714: 
                    715: 
                    716: // Necessary for bogus G3 requirement for ide alias
                    717: // Only does complete matches,
                    718: // eg. /bandit@f2000000/ATY,mach64@e will NOT become pci1/ATY,mach64@e
                    719: 
                    720: void
                    721: IOAliasPath( char * fullPath)
                    722: {
                    723:     IOReturn           err;
                    724:     DTEntry            dtEntry;
                    725:     DTPropertyIterator dtIter;
                    726:     int                        aliasSize;
                    727:     char       *       name;
                    728:     char       *       alias;
                    729:     const char *       tail;
                    730: 
                    731:     if( (fullPath[ 0 ] == '/')
                    732:     &&  (kSuccess == DTLookupEntry(0, "/aliases", &dtEntry) )) {
                    733: 
                    734:         err = DTCreatePropertyIterator( dtEntry, &dtIter);
                    735:         if( err == kSuccess) {
                    736:             while( kSuccess == DTIterateProperties( dtIter, &name)) {
                    737: 
                    738:                 if( kSuccess != DTGetProperty( dtEntry, name, (void **) &alias, &aliasSize ))
                    739:                     continue;
                    740:                aliasSize--;
                    741:                if( aliasSize <= strlen( name))         // no replace if no gain
                    742:                    continue;
                    743: 
                    744:                if( NULL == (tail = MatchPaths( alias, fullPath)))
                    745:                    continue;
                    746:                if( *tail)                              // exact matches only
                    747:                    continue;
                    748: 
                    749:                strcpy( fullPath, name);
                    750:                break;
                    751:             }
                    752:             DTDisposePropertyIterator( dtIter);
                    753:         }
                    754:     }
                    755: }
                    756: 
                    757: - getDevicePath:(char *)path maxLength:(int)maxLen useAlias:(BOOL)doAlias
                    758: {
                    759:     id         ok;
                    760: 
                    761:     *path = '\0';
                    762: 
                    763:     if( [self parent]) {
                    764:        ok = [[self parent] getDevicePath:self path:path maxLength:maxLen];
                    765: 
                    766:     } else if( maxLen > 1) {
                    767:        strcpy( path, "/");
                    768:         ok = self;
                    769:     } else
                    770:        ok = nil;
                    771: 
                    772:     if( ok && doAlias)
                    773:        IOAliasPath( path);
                    774: 
                    775:     return( ok);
                    776: }
                    777: 
                    778: /*
                    779:  * Returns the tail of the matchPath parameter if the head matches the
                    780:  * device's path, else returns nil. matchPath can contain aliases.
                    781:  */
                    782: 
                    783: - (char *) matchDevicePath:(char *)matchPath
                    784: {
                    785:     char *     pathBuf;
                    786:     char *     expandBuf;
                    787:     char *     tail = NULL;
                    788:     int                diff;
                    789:     enum {     kPathSize = 256 };
                    790: 
                    791:     pathBuf = (char *) IOMalloc( kPathSize * 2);
                    792:     if( !pathBuf)
                    793:        return( NULL);
                    794:     expandBuf = pathBuf + kPathSize;
                    795: 
                    796:     diff = IODealiasPath( expandBuf, matchPath);
                    797: 
                    798:     if( [self getDevicePath:pathBuf maxLength:kPathSize useAlias:NO]) {
                    799: 
                    800:         tail = MatchPaths( expandBuf, pathBuf);
                    801:         if( tail) {
                    802:             diff += tail - expandBuf;
                    803:             if( diff > 0)
                    804:                 tail = matchPath + diff;
                    805:             else
                    806:                 tail = NULL;
                    807:         }
                    808:     }
                    809: 
                    810:     IOFree( pathBuf, kPathSize * 2);
                    811:     return( tail);
                    812: }
                    813: 
                    814: /*
                    815:  */
                    816: 
                    817: - lookUpProperty:(const char *)propertyName
                    818:        value:(unsigned char *)value
                    819:        length:(unsigned int *)length
                    820:        selector:(SEL)selector
                    821:        isString:(BOOL)isString
                    822: {
                    823:     struct tree_private        *private = _tree_private;
                    824:     id                 rtn, prtn = nil;
                    825:     unsigned int       tempLength = *length;
                    826: 
                    827:     if( [self parent])
                    828:        prtn = [[[self parent] deviceDescription]
                    829:                     lookUpProperty:propertyName value:value length:&tempLength
                    830:                         selector:selector isString:isString];
                    831: 
                    832:     rtn = [super lookUpProperty:propertyName value:value length:length
                    833:                             selector:selector isString:isString];
                    834:     if( nil == rtn) {
                    835:         if( noErr == [private->propTable getProperty:propertyName flags:0
                    836:                     value:(void **)&value length:(UInt32 *)length])
                    837:             rtn = self;
                    838:        else
                    839:            *length = tempLength;
                    840:     }
                    841: 
                    842:     return( prtn ? prtn : rtn);
                    843: }
                    844: 
                    845: - property_IODeviceType:(char *)classes length:(unsigned int *)maxLen
                    846: {
                    847:     struct tree_private        *private = _tree_private;
                    848:     char *             type;
                    849:     unsigned int       len;
                    850: 
                    851:     [super property_IODeviceType:classes length:maxLen];
                    852:     if( noErr == [private->propTable getProperty:"device_type" flags:kReferenceProperty
                    853:                 value:(void **)&type length:(UInt32 *)&len]) {
                    854:         strcat( classes, " ");
                    855:         strncat( classes, type, len);
                    856:     }
                    857:     return( self);
                    858: }
                    859: 
                    860: - property_IOSlotName:(char *)name length:(unsigned int *)maxLen
                    861: {
                    862:     if( [[self propertyTable] getProperty:"AAPL,slot-name" flags:0
                    863:                 value:(void **)&name length:(UInt32 *)maxLen])
                    864:        return( nil);
                    865: 
                    866:     if( (0 == *maxLen) || (0 == name[0]))
                    867:        return( nil);
                    868: 
                    869:     return( self);
                    870: }
                    871: 
                    872: @end
                    873: 
                    874: @implementation IORootDevice
                    875: 
                    876: - (BOOL) match:(const char *)key location:(const char *)location
                    877: {
                    878:     return( 0 == strcmp( key, [self nodeName] ));
                    879: }
                    880: 
                    881: - initAt:(IOPropertyTable *)_propTable ref:_ref
                    882: {
                    883:     id         rtn;
                    884: 
                    885:     rtn = [super initAt:_propTable parent:nil ref:_ref];
                    886:     return( rtn);
                    887: }
                    888: 
                    889: 
                    890: @end

unix.superglobalmegacorp.com

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