|
|
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.