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

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
        !             7:  * Reserved.  This file contains Original Code and/or Modifications of
        !             8:  * Original Code as defined in and that are subject to the Apple Public
        !             9:  * Source License Version 1.1 (the "License").  You may not use this file
        !            10:  * except in compliance with the License.  Please obtain a copy of the
        !            11:  * License at http://www.apple.com/publicsource and read it before using
        !            12:  * this file.
        !            13:  * 
        !            14:  * The Original Code and all software distributed under the License are
        !            15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
        !            19:  * License for the specific language governing rights and limitations
        !            20:  * under the License.
        !            21:  * 
        !            22:  * @APPLE_LICENSE_HEADER_END@
        !            23:  */
        !            24: /*
        !            25:  * Copyright (c) 1997 Apple Computer, Inc.
        !            26:  *
        !            27:  *
        !            28:  * HISTORY
        !            29:  *
        !            30:  * Simon Douglas  22 Oct 97
        !            31:  * - first checked in.
        !            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.