Annotation of driverkit/libDriver/ppc/IOTreeDevice.m, revision 1.1.1.2

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: 
1.1.1.2 ! root      488:     if( IsYosemite())
        !           489:        nvEnd += NVRAM_NameRegistry_Offset - 0x100;
        !           490: 
1.1       root      491:     if( (nvEnd < NVRAM_NameRegistry_Offset) || (nvEnd >= (NVRAM_NameRegistry_Offset + 0x400)))
                    492:        nvEnd = NVRAM_NameRegistry_Offset + 2;
                    493:     *theEnd = nvEnd;
                    494: 
                    495:     while( (nvpc + sizeof( NVRAMProperty)) <= nvEnd ) {
                    496: 
                    497:        READINC( sizeof( NVRAMDescriptor), &nvDescrip )
                    498:        if( 0 == bcmp( &nvDescrip, propHdr, sizeof( NVRAMDescriptor)))
                    499:            return( nvpc );
                    500:        else
                    501:            nvpc += (sizeof( NVRAMProperty) - sizeof( NVRAMDescriptor));
                    502:     }
                    503: 
                    504:     return( 0);
                    505: }
                    506: 
                    507: - (IOReturn) readNVRAMProperty:(char *)name value:(void *)buffer length:(ByteCount *)length
                    508: {
                    509:     IOReturn           err = nrNotFoundErr;
                    510:     UInt16             nvpc, nvEnd;
                    511:     unsigned char      nameLen, dataLen;
                    512:     NVRAMDescriptor    propHdr;
                    513: 
                    514:     bzero( &propHdr, sizeof( NVRAMDescriptor));
                    515:     [[self parent] makeNVRAMDescriptor:self descriptor:&propHdr];
                    516: 
                    517: #if 0
                    518:     kprintf("makeNVRAMDescriptor:bridgeCount %x, busNum %x, bridgeDevices %x, functionNum %x, deviceNum %x\n", 
                    519:        propHdr.bridgeCount, propHdr.busNum, propHdr.bridgeDevices, propHdr.functionNum, propHdr.deviceNum );
                    520: #endif
                    521: 
                    522:     nvpc = SearchNVRAMProperty( &propHdr, &nvEnd);
                    523: 
                    524:     if( nvpc) {
                    525:        READINC( sizeof( UInt8), &nameLen )
                    526:        nameLen = MIN( nameLen, 4);
                    527:        ReadNVRAM( nvpc, nameLen, (unsigned char *) name);
                    528:        name[ nameLen ] = 0;
                    529:        nvpc += kMaxNVNameLen;
                    530:        READINC( sizeof( UInt8), &dataLen )
                    531:        dataLen = MIN( dataLen, 8);
                    532:        *length = dataLen;
                    533:        ReadNVRAM( nvpc, dataLen, (unsigned char *) buffer);
                    534:        err = noErr;
                    535:     }
                    536:     return( err);
                    537: }
                    538: 
                    539: - (IOReturn) writeNVRAMProperty:(const char *)name value:(void *)value length:(ByteCount)length
                    540: {
                    541:     IOReturn           err = noErr;
                    542:     UInt16             nvpc, nvEnd;
                    543:     UInt8              nameLen;
                    544:     NVRAMProperty      nvram;
                    545: 
                    546:     nameLen = strlen( name);
                    547:     if( (nameLen > kMaxNVNameLen) || (length > kMaxNVDataLen))
                    548:        return( nrOverrunErr);
                    549: 
                    550:     nvram.nameLen = nameLen;
                    551:     bcopy( name, nvram.name, nameLen);
                    552:     nvram.dataLen = length;
                    553:     bcopy( value, nvram.data, length);
                    554: 
                    555:     bzero( &nvram.header, sizeof( NVRAMDescriptor));
                    556:     [[self parent] makeNVRAMDescriptor:self descriptor:&nvram.header];
                    557:     nvpc = SearchNVRAMProperty( &nvram.header, &nvEnd);
                    558: 
                    559:     if( nvpc == 0) {
                    560: 
                    561:        // Not found - append it.
                    562:        nvpc = nvEnd;
                    563:        nvEnd += sizeof( NVRAMProperty);
                    564:        if( nvEnd > (NVRAM_NameRegistry_Offset + 0x400))
                    565:            err = nrNotEnoughMemoryErr;
                    566:        else {
                    567:            WriteNVRAM( nvpc, sizeof( NVRAMProperty), (UInt8 *) &nvram );
1.1.1.2 ! root      568:             if( IsYosemite())
        !           569:                 nvEnd -= NVRAM_NameRegistry_Offset - 0x100;
1.1       root      570:            WriteNVRAM( NVRAM_NameRegistry_Offset, 2, (UInt8 *) &nvEnd );
                    571:        }
                    572: 
                    573:     } else {
                    574: 
                    575:        // Overwrite the current one. They're all maximum length.
                    576:        WriteNVRAM( nvpc, sizeof( NVRAMProperty) - sizeof( NVRAMDescriptor), (UInt8 *) &nvram.nameLen );
                    577:     }
                    578: 
                    579: #if 0
                    580:     {
                    581:        int i;
                    582:        ReadNVRAM( NVRAM_NameRegistry_Offset, 0x50, buffer);
                    583:        for( i=0; i<0x50; i++) {
                    584:            kprintf(" 0x%02x,", buffer[i]);
                    585:            if( (i%16) == 15) kprintf("\n");
                    586:        }
                    587:     }
                    588: #endif
                    589: 
                    590:     return( err);
                    591: }
                    592: 
                    593: // The following are property table based for NDRV support
                    594: 
                    595: - (IOReturn) setNVRAMProperty:(const char *)propertyName
                    596: {
                    597:     struct tree_private        *private = _tree_private;
                    598:     IOReturn           err;
                    599:     void *             value;
                    600:     ByteCount          propSize;
                    601: 
                    602:     err = [[self propertyTable] getProperty:propertyName flags:kReferenceProperty
                    603:                 value:&value length:&propSize];
                    604:     if( err)
                    605:         return( err);
                    606: 
                    607:     if( private->denyNVRAM)
                    608:         return( noErr);
                    609: 
                    610:     err = [self writeNVRAMProperty:propertyName value:value length:propSize];
                    611:     if( err)
                    612:         return( err);
                    613: 
                    614:     strcpy( private->nvramPropName, propertyName);             // already checked length
                    615:     return( noErr);
                    616: }
                    617: 
                    618: - (BOOL) isNVRAMProperty:(const char *)propertyName
                    619: {
                    620:     struct tree_private        *private = _tree_private;
                    621: 
                    622:     return( 0 == strcmp( propertyName, private->nvramPropName));
                    623: }
                    624: 
                    625: - denyNVRAM:(BOOL)flag
                    626: {
                    627:     struct tree_private        *private = _tree_private;
                    628: 
                    629:     private->denyNVRAM = flag;
                    630:     return( self);
                    631: }
                    632: 
                    633: /* ---------------------------------------------------------- */
                    634: 
                    635: const char * MatchPaths( const char * matchPath, const char * fullPath)
                    636: {
                    637:     const char *       ourPath;
                    638:     char               c1, c2;
                    639: 
                    640:     ourPath = fullPath;
                    641:     do {
                    642:         c2 = *ourPath++;
                    643:         if( c2 == 0)
                    644:             return( matchPath);                // return tail of match path
                    645:         if( (c2 >= 'A') && (c2 <= 'Z'))
                    646:             c2 += 'a' - 'A';
                    647: 
                    648:         c1 = *matchPath++;
                    649:         if( (c1 >= 'A') && (c1 <= 'Z'))
                    650:             c1 += 'a' - 'A';
                    651: 
                    652:         if( c1 != c2) {
                    653:             // our path always has unit numbers, match may not
                    654:             if( c2 == '@') {
                    655:                 while( (c2 = *ourPath++)
                    656:                     && (c2 != '/') )   {}
                    657:                 ourPath--;
                    658:                 matchPath--;
                    659: 
                    660:             // our path always has device names, match may not
                    661:             } else if( c1 == '@') {
                    662:                     while( (c2 = *ourPath++)
                    663:                         && (c2 != '@') )       {}
                    664: 
                    665:             } else
                    666:                 break;
                    667:        }
                    668:     } while( YES );
                    669: 
                    670:     return( NULL);                     // no match
                    671: }
                    672: 
                    673: // Remove aliases from the head of the path
                    674: // returns difference in length
                    675: 
                    676: int
                    677: IODealiasPath( char * outputPath, const char * inputPath)
                    678: {
                    679:     IOReturn           err;
                    680:     DTEntry            dtEntry;
                    681:     DTPropertyIterator dtIter;
                    682:     int                        nameSize, aliasSize;
                    683:     char       *       name;
                    684:     char               c;
                    685:     int                        diff = 0;
                    686: 
                    687:     outputPath[ 0 ] = 0;
                    688: 
                    689:     if( (inputPath[ 0 ] != '/')
                    690:     && (kSuccess == DTLookupEntry(0, "/aliases", &dtEntry) )) {
                    691: 
                    692:         err = DTCreatePropertyIterator( dtEntry, &dtIter);
                    693:         if( err == kSuccess) {
                    694:             while( kSuccess == DTIterateProperties( dtIter, &name)) {
                    695: 
                    696:                 nameSize = strlen( name);
                    697:                 c = inputPath[ nameSize ];
                    698:                 if( c && (c != '/') && (c != ':') && (c != '@') && (c != ','))
                    699:                     continue;
                    700: 
                    701:                 if( 0 == strncmp( inputPath, name, nameSize)) {
                    702:                     if( kSuccess != DTGetProperty( dtEntry, name, (void **) &name, &aliasSize ))
                    703:                         continue;
                    704:                     aliasSize--;                               // ditch the zero in property
                    705:                     strncpy( outputPath, name, aliasSize);
                    706:                     strcpy( outputPath + aliasSize, inputPath + nameSize);
                    707:                    diff = nameSize - aliasSize;
                    708:                     break;
                    709:                 }
                    710:             }
                    711:             DTDisposePropertyIterator( dtIter);
                    712:         }
                    713:     }
                    714:     if( outputPath[ 0 ] == 0)
                    715:         strcpy( outputPath, inputPath);
                    716: 
                    717:     return( diff);
                    718: }
                    719: 
                    720: 
                    721: // Necessary for bogus G3 requirement for ide alias
                    722: // Only does complete matches,
                    723: // eg. /bandit@f2000000/ATY,mach64@e will NOT become pci1/ATY,mach64@e
                    724: 
                    725: void
                    726: IOAliasPath( char * fullPath)
                    727: {
                    728:     IOReturn           err;
                    729:     DTEntry            dtEntry;
                    730:     DTPropertyIterator dtIter;
                    731:     int                        aliasSize;
                    732:     char       *       name;
                    733:     char       *       alias;
                    734:     const char *       tail;
                    735: 
                    736:     if( (fullPath[ 0 ] == '/')
                    737:     &&  (kSuccess == DTLookupEntry(0, "/aliases", &dtEntry) )) {
                    738: 
                    739:         err = DTCreatePropertyIterator( dtEntry, &dtIter);
                    740:         if( err == kSuccess) {
                    741:             while( kSuccess == DTIterateProperties( dtIter, &name)) {
                    742: 
                    743:                 if( kSuccess != DTGetProperty( dtEntry, name, (void **) &alias, &aliasSize ))
                    744:                     continue;
                    745:                aliasSize--;
                    746:                if( aliasSize <= strlen( name))         // no replace if no gain
                    747:                    continue;
                    748: 
                    749:                if( NULL == (tail = MatchPaths( alias, fullPath)))
                    750:                    continue;
                    751:                if( *tail)                              // exact matches only
                    752:                    continue;
                    753: 
                    754:                strcpy( fullPath, name);
                    755:                break;
                    756:             }
                    757:             DTDisposePropertyIterator( dtIter);
                    758:         }
                    759:     }
                    760: }
                    761: 
                    762: - getDevicePath:(char *)path maxLength:(int)maxLen useAlias:(BOOL)doAlias
                    763: {
                    764:     id         ok;
                    765: 
                    766:     *path = '\0';
                    767: 
                    768:     if( [self parent]) {
                    769:        ok = [[self parent] getDevicePath:self path:path maxLength:maxLen];
                    770: 
                    771:     } else if( maxLen > 1) {
                    772:        strcpy( path, "/");
                    773:         ok = self;
                    774:     } else
                    775:        ok = nil;
                    776: 
                    777:     if( ok && doAlias)
                    778:        IOAliasPath( path);
                    779: 
                    780:     return( ok);
                    781: }
                    782: 
                    783: /*
                    784:  * Returns the tail of the matchPath parameter if the head matches the
                    785:  * device's path, else returns nil. matchPath can contain aliases.
                    786:  */
                    787: 
                    788: - (char *) matchDevicePath:(char *)matchPath
                    789: {
                    790:     char *     pathBuf;
                    791:     char *     expandBuf;
                    792:     char *     tail = NULL;
                    793:     int                diff;
                    794:     enum {     kPathSize = 256 };
                    795: 
                    796:     pathBuf = (char *) IOMalloc( kPathSize * 2);
                    797:     if( !pathBuf)
                    798:        return( NULL);
                    799:     expandBuf = pathBuf + kPathSize;
                    800: 
                    801:     diff = IODealiasPath( expandBuf, matchPath);
                    802: 
                    803:     if( [self getDevicePath:pathBuf maxLength:kPathSize useAlias:NO]) {
                    804: 
                    805:         tail = MatchPaths( expandBuf, pathBuf);
                    806:         if( tail) {
                    807:             diff += tail - expandBuf;
                    808:             if( diff > 0)
                    809:                 tail = matchPath + diff;
                    810:             else
                    811:                 tail = NULL;
                    812:         }
                    813:     }
                    814: 
                    815:     IOFree( pathBuf, kPathSize * 2);
                    816:     return( tail);
                    817: }
                    818: 
                    819: /*
                    820:  */
                    821: 
                    822: - lookUpProperty:(const char *)propertyName
                    823:        value:(unsigned char *)value
                    824:        length:(unsigned int *)length
                    825:        selector:(SEL)selector
                    826:        isString:(BOOL)isString
                    827: {
                    828:     struct tree_private        *private = _tree_private;
                    829:     id                 rtn, prtn = nil;
                    830:     unsigned int       tempLength = *length;
                    831: 
                    832:     if( [self parent])
                    833:        prtn = [[[self parent] deviceDescription]
                    834:                     lookUpProperty:propertyName value:value length:&tempLength
                    835:                         selector:selector isString:isString];
                    836: 
                    837:     rtn = [super lookUpProperty:propertyName value:value length:length
                    838:                             selector:selector isString:isString];
                    839:     if( nil == rtn) {
                    840:         if( noErr == [private->propTable getProperty:propertyName flags:0
                    841:                     value:(void **)&value length:(UInt32 *)length])
                    842:             rtn = self;
                    843:        else
                    844:            *length = tempLength;
                    845:     }
                    846: 
                    847:     return( prtn ? prtn : rtn);
                    848: }
                    849: 
                    850: - property_IODeviceType:(char *)classes length:(unsigned int *)maxLen
                    851: {
                    852:     struct tree_private        *private = _tree_private;
                    853:     char *             type;
                    854:     unsigned int       len;
                    855: 
                    856:     [super property_IODeviceType:classes length:maxLen];
                    857:     if( noErr == [private->propTable getProperty:"device_type" flags:kReferenceProperty
                    858:                 value:(void **)&type length:(UInt32 *)&len]) {
                    859:         strcat( classes, " ");
                    860:         strncat( classes, type, len);
                    861:     }
                    862:     return( self);
                    863: }
                    864: 
                    865: - property_IOSlotName:(char *)name length:(unsigned int *)maxLen
                    866: {
                    867:     if( [[self propertyTable] getProperty:"AAPL,slot-name" flags:0
                    868:                 value:(void **)&name length:(UInt32 *)maxLen])
                    869:        return( nil);
                    870: 
                    871:     if( (0 == *maxLen) || (0 == name[0]))
                    872:        return( nil);
                    873: 
                    874:     return( self);
                    875: }
                    876: 
                    877: @end
                    878: 
                    879: @implementation IORootDevice
                    880: 
                    881: - (BOOL) match:(const char *)key location:(const char *)location
                    882: {
                    883:     return( 0 == strcmp( key, [self nodeName] ));
                    884: }
                    885: 
                    886: - initAt:(IOPropertyTable *)_propTable ref:_ref
                    887: {
                    888:     id         rtn;
                    889: 
                    890:     rtn = [super initAt:_propTable parent:nil ref:_ref];
                    891:     return( rtn);
                    892: }
                    893: 
                    894: 
                    895: @end

unix.superglobalmegacorp.com

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