|
|
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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.