]> git.saurik.com Git - apple/xnu.git/blame - iokit/bsddev/IOKitBSDInit.cpp
xnu-792.6.61.tar.gz
[apple/xnu.git] / iokit / bsddev / IOKitBSDInit.cpp
CommitLineData
1c79356b
A
1/*
2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
37839358
A
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
1c79356b 11 *
37839358
A
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
1c79356b
A
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
37839358
A
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
1c79356b
A
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22#include <IOKit/IOBSD.h>
23#include <IOKit/IOLib.h>
24#include <IOKit/IOService.h>
25#include <IOKit/IODeviceTreeSupport.h>
26#include <IOKit/IOKitKeys.h>
1c79356b
A
27#include <IOKit/IOPlatformExpert.h>
28
1c79356b
A
29extern "C" {
30
31#include <pexpert/pexpert.h>
32#include <kern/clock.h>
33
34// how long to wait for matching root device, secs
35#define ROOTDEVICETIMEOUT 60
36
55e303ae
A
37extern dev_t mdevadd(int devid, ppnum_t base, unsigned int size, int phys);
38extern dev_t mdevlookup(int devid);
1c79356b
A
39
40kern_return_t
41IOKitBSDInit( void )
42{
1c79356b
A
43 IOService::publishResource("IOBSD");
44
45 return( kIOReturnSuccess );
46}
47
48OSDictionary * IOBSDNameMatching( const char * name )
49{
50 OSDictionary * dict;
51 const OSSymbol * str = 0;
52
53 do {
54
55 dict = IOService::serviceMatching( gIOServiceKey );
56 if( !dict)
57 continue;
58 str = OSSymbol::withCString( name );
59 if( !str)
60 continue;
61 dict->setObject( kIOBSDNameKey, (OSObject *) str );
62 str->release();
63
64 return( dict );
65
66 } while( false );
67
68 if( dict)
69 dict->release();
70 if( str)
71 str->release();
72
73 return( 0 );
74}
75
91447636
A
76OSDictionary * IOUUIDMatching( void )
77{
78 return IOService::resourceMatching( "boot-uuid-media" );
79}
80
81
55e303ae 82OSDictionary * IOCDMatching( void )
0b4e3aa0
A
83{
84 OSDictionary * dict;
85 const OSSymbol * str;
55e303ae
A
86
87 dict = IOService::serviceMatching( "IOMedia" );
88 if( dict == 0 ) {
89 IOLog("Unable to find IOMedia\n");
90 return 0;
91 }
92
93 str = OSSymbol::withCString( "CD_ROM_Mode_1" );
94 if( str == 0 ) {
95 dict->release();
96 return 0;
97 }
98
99 dict->setObject( "Content Hint", (OSObject *)str );
100 str->release();
101 return( dict );
0b4e3aa0
A
102}
103
1c79356b
A
104OSDictionary * IONetworkMatching( const char * path,
105 char * buf, int maxLen )
106{
107 OSDictionary * matching = 0;
108 OSDictionary * dict;
109 OSString * str;
110 char * comp;
111 const char * skip;
112 int len;
113
114 do {
115
116 len = strlen( kIODeviceTreePlane ":" );
117 maxLen -= len;
118 if( maxLen < 0)
119 continue;
120
121 strcpy( buf, kIODeviceTreePlane ":" );
122 comp = buf + len;
123
124 // remove parameters following ':' from the path
125 skip = strchr( path, ':');
126 if( !skip)
127 continue;
128
129 len = skip - path;
130 maxLen -= len;
131 if( maxLen < 0)
132 continue;
133 strncpy( comp, path, len );
134 comp[ len ] = 0;
135
136 matching = IOService::serviceMatching( "IONetworkInterface" );
137 if( !matching)
138 continue;
139 dict = IOService::addLocation( matching );
140 if( !dict)
141 continue;
142
143 str = OSString::withCString( buf );
144 if( !str)
145 continue;
146 dict->setObject( kIOPathMatchKey, str );
147 str->release();
148
149 return( matching );
150
151 } while( false );
152
153 if( matching)
154 matching->release();
155
156 return( 0 );
157}
158
159OSDictionary * IONetworkNamePrefixMatching( const char * prefix )
160{
161 OSDictionary * matching;
162 OSDictionary * propDict = 0;
163 const OSSymbol * str = 0;
164
165 do {
166 matching = IOService::serviceMatching( "IONetworkInterface" );
167 if ( matching == 0 )
168 continue;
169
170 propDict = OSDictionary::withCapacity(1);
171 if ( propDict == 0 )
172 continue;
173
174 str = OSSymbol::withCString( prefix );
175 if ( str == 0 )
176 continue;
177
0b4e3aa0 178 propDict->setObject( "IOInterfaceNamePrefix", (OSObject *) str );
1c79356b
A
179 str->release();
180 str = 0;
181
182 if ( matching->setObject( gIOPropertyMatchKey,
183 (OSObject *) propDict ) != true )
184 continue;
185
186 propDict->release();
187 propDict = 0;
188
189 return( matching );
190
191 } while ( false );
192
193 if ( matching ) matching->release();
194 if ( propDict ) propDict->release();
195 if ( str ) str->release();
196
197 return( 0 );
198}
199
0b4e3aa0 200static bool IORegisterNetworkInterface( IOService * netif )
1c79356b 201{
0b4e3aa0
A
202 // A network interface is typically named and registered
203 // with BSD after receiving a request from a user space
204 // "namer". However, for cases when the system needs to
205 // root from the network, this registration task must be
206 // done inside the kernel and completed before the root
207 // device is handed to BSD.
208
209 IOService * stack;
210 OSNumber * zero = 0;
211 OSString * path = 0;
212 OSDictionary * dict = 0;
213 char * pathBuf = 0;
214 int len;
215 enum { kMaxPathLen = 512 };
1c79356b 216
0b4e3aa0
A
217 do {
218 stack = IOService::waitForService(
219 IOService::serviceMatching("IONetworkStack") );
220 if ( stack == 0 ) break;
1c79356b 221
0b4e3aa0
A
222 dict = OSDictionary::withCapacity(3);
223 if ( dict == 0 ) break;
1c79356b 224
0b4e3aa0
A
225 zero = OSNumber::withNumber((UInt64) 0, 32);
226 if ( zero == 0 ) break;
1c79356b 227
0b4e3aa0
A
228 pathBuf = (char *) IOMalloc( kMaxPathLen );
229 if ( pathBuf == 0 ) break;
230
231 len = kMaxPathLen;
232 if ( netif->getPath( pathBuf, &len, gIOServicePlane )
233 == false ) break;
234
235 path = OSString::withCStringNoCopy( pathBuf );
236 if ( path == 0 ) break;
237
238 dict->setObject( "IOInterfaceUnit", zero );
239 dict->setObject( kIOPathMatchKey, path );
240
241 stack->setProperties( dict );
242 }
243 while ( false );
244
245 if ( zero ) zero->release();
246 if ( path ) path->release();
247 if ( dict ) dict->release();
248 if ( pathBuf ) IOFree(pathBuf, kMaxPathLen);
249
250 return ( netif->getProperty( kIOBSDNameKey ) != 0 );
1c79356b
A
251}
252
253OSDictionary * IODiskMatching( const char * path, char * buf, int maxLen )
254{
255 const char * look;
256 const char * alias;
257 char * comp;
258 long unit = -1;
259 long partition = -1;
55e303ae 260 long lun = -1;
1c79356b
A
261 char c;
262
263 // scan the tail of the path for "@unit:partition"
264 do {
265 // Have to get the full path to the controller - an alias may
266 // tell us next to nothing, like "hd:8"
267 alias = IORegistryEntry::dealiasPath( &path, gIODTPlane );
55e303ae 268
1c79356b
A
269 look = path + strlen( path);
270 c = ':';
271 while( look != path) {
272 if( *(--look) == c) {
273 if( c == ':') {
274 partition = strtol( look + 1, 0, 0 );
275 c = '@';
276 } else if( c == '@') {
91447636
A
277 unit = strtol( look + 1, &comp, 16 );
278
279 if( *comp == ',') {
280 lun = strtol( comp + 1, 0, 16 );
55e303ae
A
281 }
282
1c79356b
A
283 c = '/';
284 } else if( c == '/') {
285 c = 0;
286 break;
287 }
288 }
289
290 if( alias && (look == path)) {
291 path = alias;
292 look = path + strlen( path);
293 alias = 0;
294 }
295 }
296 if( c || unit == -1 || partition == -1)
297 continue;
55e303ae 298
1c79356b
A
299 maxLen -= strlen( "{" kIOPathMatchKey "='" kIODeviceTreePlane ":" );
300 maxLen -= ( alias ? strlen( alias ) : 0 ) + (look - path);
55e303ae 301 maxLen -= strlen( "/@hhhhhhhh,hhhhhhhh:dddddddddd';}" );
1c79356b
A
302
303 if( maxLen > 0) {
304 sprintf( buf, "{" kIOPathMatchKey "='" kIODeviceTreePlane ":" );
305 comp = buf + strlen( buf );
55e303ae 306
1c79356b
A
307 if( alias) {
308 strcpy( comp, alias );
309 comp += strlen( alias );
310 }
55e303ae 311
1c79356b
A
312 if ( (look - path)) {
313 strncpy( comp, path, look - path);
314 comp += look - path;
315 }
55e303ae
A
316
317 if ( lun != -1 )
318 {
319 sprintf ( comp, "/@%lx,%lx:%ld';}", unit, lun, partition );
320 }
321 else
322 {
323 sprintf( comp, "/@%lx:%ld';}", unit, partition );
324 }
1c79356b
A
325 } else
326 continue;
55e303ae 327
1c79356b
A
328 return( OSDynamicCast(OSDictionary, OSUnserialize( buf, 0 )) );
329
330 } while( false );
331
332 return( 0 );
333}
334
335OSDictionary * IOOFPathMatching( const char * path, char * buf, int maxLen )
336{
91447636
A
337 OSDictionary * matching;
338 OSString * str;
339 char * comp;
340 int len;
341
1c79356b
A
342 /* need to look up path, get device type,
343 call matching help based on device type */
344
91447636
A
345 matching = IODiskMatching( path, buf, maxLen );
346 if( matching)
347 return( matching );
348
349 do {
350
351 len = strlen( kIODeviceTreePlane ":" );
352 maxLen -= len;
353 if( maxLen < 0)
354 continue;
355
356 strcpy( buf, kIODeviceTreePlane ":" );
357 comp = buf + len;
358
359 len = strlen( path );
360 maxLen -= len;
361 if( maxLen < 0)
362 continue;
363 strncpy( comp, path, len );
364 comp[ len ] = 0;
365
366 matching = OSDictionary::withCapacity( 1 );
367 if( !matching)
368 continue;
369
370 str = OSString::withCString( buf );
371 if( !str)
372 continue;
373 matching->setObject( kIOPathMatchKey, str );
374 str->release();
375
376 return( matching );
377
378 } while( false );
1c79356b 379
91447636
A
380 if( matching)
381 matching->release();
382
383 return( 0 );
1c79356b
A
384}
385
55e303ae
A
386IOService * IOFindMatchingChild( IOService * service )
387{
388 // find a matching child service
389 IOService * child = 0;
390 OSIterator * iter = service->getClientIterator();
391 if ( iter ) {
392 while( ( child = (IOService *) iter->getNextObject() ) ) {
393 OSDictionary * dict = OSDictionary::withCapacity( 1 );
394 if( dict == 0 ) {
395 iter->release();
396 return 0;
397 }
398 const OSSymbol * str = OSSymbol::withCString( "Apple_HFS" );
399 if( str == 0 ) {
400 dict->release();
401 iter->release();
402 return 0;
403 }
404 dict->setObject( "Content", (OSObject *)str );
405 str->release();
406 if ( child->compareProperty( dict, "Content" ) ) {
407 dict->release();
408 break;
409 }
410 dict->release();
411 IOService * subchild = IOFindMatchingChild( child );
412 if ( subchild ) {
413 child = subchild;
414 break;
415 }
416 }
417 iter->release();
418 }
419 return child;
420}
421
422static int didRam = 0;
423
1c79356b
A
424kern_return_t IOFindBSDRoot( char * rootName,
425 dev_t * root, u_int32_t * oflags )
426{
427 mach_timespec_t t;
428 IOService * service;
429 IORegistryEntry * regEntry;
430 OSDictionary * matching = 0;
431 OSString * iostr;
432 OSNumber * off;
433 OSData * data = 0;
55e303ae 434 UInt32 *ramdParms = 0;
1c79356b
A
435
436 UInt32 flags = 0;
437 int minor, major;
55e303ae 438 bool findHFSChild = false;
91447636 439 char * mediaProperty = 0;
1c79356b
A
440 char * rdBootVar;
441 enum { kMaxPathBuf = 512, kMaxBootVar = 128 };
442 char * str;
443 const char * look = 0;
444 int len;
445 bool forceNet = false;
0b4e3aa0 446 bool debugInfoPrintedOnce = false;
91447636 447 const char * uuidStr = NULL;
1c79356b
A
448
449 static int mountAttempts = 0;
55e303ae 450
91447636 451 int xchar, dchar;
55e303ae 452
1c79356b
A
453
454 if( mountAttempts++)
455 IOSleep( 5 * 1000 );
456
457 str = (char *) IOMalloc( kMaxPathBuf + kMaxBootVar );
458 if( !str)
459 return( kIOReturnNoMemory );
460 rdBootVar = str + kMaxPathBuf;
461
462 if (!PE_parse_boot_arg("rd", rdBootVar )
463 && !PE_parse_boot_arg("rootdev", rdBootVar ))
464 rdBootVar[0] = 0;
465
466 do {
91447636
A
467 if( (regEntry = IORegistryEntry::fromPath( "/chosen", gIODTPlane ))) {
468 data = (OSData *) regEntry->getProperty( "boot-uuid" );
469 if( data) {
470 uuidStr = (const char*)data->getBytesNoCopy();
471 OSString *uuidString = OSString::withCString( uuidStr );
472
473 // match the boot-args boot-uuid processing below
474 if( uuidString) {
475 IOLog("rooting via boot-uuid from /chosen: %s\n", uuidStr);
476 IOService::publishResource( "boot-uuid", uuidString );
477 uuidString->release();
478 matching = IOUUIDMatching();
479 mediaProperty = "boot-uuid-media";
480 regEntry->release();
481 continue;
482 } else {
483 uuidStr = NULL;
55e303ae 484 }
91447636
A
485 }
486
487 // else try for an OF Path
488 data = (OSData *) regEntry->getProperty( "rootpath" );
489 regEntry->release();
490 if( data) continue;
491 }
1c79356b 492 if( (regEntry = IORegistryEntry::fromPath( "/options", gIODTPlane ))) {
91447636
A
493 data = (OSData *) regEntry->getProperty( "boot-file" );
494 regEntry->release();
495 if( data) continue;
496 }
1c79356b
A
497 } while( false );
498
91447636 499 if( data && !uuidStr)
1c79356b
A
500 look = (const char *) data->getBytesNoCopy();
501
502 if( rdBootVar[0] == '*') {
503 look = rdBootVar + 1;
55e303ae 504 forceNet = false;
1c79356b
A
505 } else {
506 if( (regEntry = IORegistryEntry::fromPath( "/", gIODTPlane ))) {
507 forceNet = (0 != regEntry->getProperty( "net-boot" ));
55e303ae
A
508 regEntry->release();
509 }
de355530 510 }
d7e50217 511
55e303ae
A
512
513
514//
515// See if we have a RAMDisk property in /chosen/memory-map. If so, make it into a device.
516// It will become /dev/mdx, where x is 0-f.
517//
518
519 if(!didRam) { /* Have we already build this ram disk? */
520 didRam = 1; /* Remember we did this */
521 if((regEntry = IORegistryEntry::fromPath( "/chosen/memory-map", gIODTPlane ))) { /* Find the map node */
522 data = (OSData *)regEntry->getProperty("RAMDisk"); /* Find the ram disk, if there */
523 if(data) { /* We found one */
524
525 ramdParms = (UInt32 *)data->getBytesNoCopy(); /* Point to the ram disk base and size */
526 (void)mdevadd(-1, ramdParms[0] >> 12, ramdParms[1] >> 12, 0); /* Initialize it and pass back the device number */
527 }
528 regEntry->release(); /* Toss the entry */
529 }
530 }
531
532//
533// Now check if we are trying to root on a memory device
534//
535
536 if((rdBootVar[0] == 'm') && (rdBootVar[1] == 'd') && (rdBootVar[3] == 0)) {
537 dchar = xchar = rdBootVar[2]; /* Get the actual device */
538 if((xchar >= '0') && (xchar <= '9')) xchar = xchar - '0'; /* If digit, convert */
539 else {
540 xchar = xchar & ~' '; /* Fold to upper case */
541 if((xchar >= 'A') && (xchar <= 'F')) { /* Is this a valid digit? */
542 xchar = (xchar & 0xF) + 9; /* Convert the hex digit */
543 dchar = dchar | ' '; /* Fold to lower case */
544 }
545 else xchar = -1; /* Show bogus */
546 }
547 if(xchar >= 0) { /* Do we have a valid memory device name? */
548 *root = mdevlookup(xchar); /* Find the device number */
549 if(*root >= 0) { /* Did we find one? */
550
551 rootName[0] = 'm'; /* Build root name */
552 rootName[1] = 'd'; /* Build root name */
553 rootName[2] = dchar; /* Build root name */
554 rootName[3] = 0; /* Build root name */
555 IOLog("BSD root: %s, major %d, minor %d\n", rootName, major(*root), minor(*root));
556 *oflags = 0; /* Show that this is not network */
557 goto iofrootx; /* Join common exit... */
558 }
559 panic("IOFindBSDRoot: specified root memory device, %s, has not been configured\n", rdBootVar); /* Not there */
560 }
561 }
562
1c79356b
A
563 if( look) {
564 // from OpenFirmware path
565 IOLog("From path: \"%s\", ", look);
566
0b4e3aa0
A
567 if( forceNet || (0 == strncmp( look, "enet", strlen( "enet" ))) ) {
568 matching = IONetworkMatching( look, str, kMaxPathBuf );
569 } else {
1c79356b 570 matching = IODiskMatching( look, str, kMaxPathBuf );
0b4e3aa0 571 }
1c79356b 572 }
55e303ae
A
573
574 if( (!matching) && rdBootVar[0] ) {
1c79356b
A
575 // by BSD name
576 look = rdBootVar;
577 if( look[0] == '*')
578 look++;
579
0b4e3aa0
A
580 if ( strncmp( look, "en", strlen( "en" )) == 0 ) {
581 matching = IONetworkNamePrefixMatching( "en" );
55e303ae
A
582 } else if ( strncmp( look, "cdrom", strlen( "cdrom" )) == 0 ) {
583 matching = IOCDMatching();
584 findHFSChild = true;
91447636
A
585 } else if ( strncmp( look, "uuid", strlen( "uuid" )) == 0 ) {
586 char *uuid;
587 OSString *uuidString;
588
589 uuid = (char *)IOMalloc( kMaxBootVar );
590
591 if ( uuid ) {
592 if (!PE_parse_boot_arg( "boot-uuid", uuid )) {
593 panic( "rd=uuid but no boot-uuid=<value> specified" );
594 }
595 uuidString = OSString::withCString( uuid );
596 if ( uuidString ) {
597 IOService::publishResource( "boot-uuid", uuidString );
598 uuidString->release();
599 IOLog( "\nWaiting for boot volume with UUID %s\n", uuid );
600 matching = IOUUIDMatching();
601 mediaProperty = "boot-uuid-media";
602 }
603 IOFree( uuid, kMaxBootVar );
604 }
0b4e3aa0
A
605 } else {
606 matching = IOBSDNameMatching( look );
607 }
1c79356b
A
608 }
609
610 if( !matching) {
611 OSString * astring;
55e303ae 612 // any HFS
1c79356b 613 matching = IOService::serviceMatching( "IOMedia" );
55e303ae 614 astring = OSString::withCStringNoCopy("Apple_HFS");
1c79356b 615 if ( astring ) {
0b4e3aa0 616 matching->setObject("Content", astring);
1c79356b
A
617 astring->release();
618 }
619 }
620
621 if( true && matching) {
622 OSSerialize * s = OSSerialize::withCapacity( 5 );
623
624 if( matching->serialize( s )) {
625 IOLog( "Waiting on %s\n", s->text() );
626 s->release();
627 }
628 }
629
1c79356b
A
630 do {
631 t.tv_sec = ROOTDEVICETIMEOUT;
632 t.tv_nsec = 0;
633 matching->retain();
634 service = IOService::waitForService( matching, &t );
635 if( (!service) || (mountAttempts == 10)) {
636 PE_display_icon( 0, "noroot");
637 IOLog( "Still waiting for root device\n" );
0b4e3aa0
A
638
639 if( !debugInfoPrintedOnce) {
640 debugInfoPrintedOnce = true;
641 if( gIOKitDebug & kIOLogDTree) {
642 IOLog("\nDT plane:\n");
643 IOPrintPlane( gIODTPlane );
644 }
645 if( gIOKitDebug & kIOLogServiceTree) {
646 IOLog("\nService plane:\n");
647 IOPrintPlane( gIOServicePlane );
648 }
649 if( gIOKitDebug & kIOLogMemory)
650 IOPrintMemory();
651 }
1c79356b
A
652 }
653 } while( !service);
654 matching->release();
655
55e303ae
A
656 if ( service && findHFSChild ) {
657 bool waiting = true;
658 // wait for children services to finish registering
659 while ( waiting ) {
660 t.tv_sec = ROOTDEVICETIMEOUT;
661 t.tv_nsec = 0;
662 if ( service->waitQuiet( &t ) == kIOReturnSuccess ) {
663 waiting = false;
664 } else {
665 IOLog( "Waiting for child registration\n" );
666 }
667 }
668 // look for a subservice with an Apple_HFS child
669 IOService * subservice = IOFindMatchingChild( service );
670 if ( subservice ) service = subservice;
91447636
A
671 } else if ( service && mediaProperty ) {
672 service = service->getProperty(mediaProperty);
55e303ae
A
673 }
674
1c79356b
A
675 major = 0;
676 minor = 0;
677
678 // If the IOService we matched to is a subclass of IONetworkInterface,
679 // then make sure it has been registered with BSD and has a BSD name
680 // assigned.
681
682 if ( service
683 && service->metaCast( "IONetworkInterface" )
0b4e3aa0 684 && !IORegisterNetworkInterface( service ) )
1c79356b
A
685 {
686 service = 0;
687 }
1c79356b
A
688
689 if( service) {
690
691 len = kMaxPathBuf;
692 service->getPath( str, &len, gIOServicePlane );
693 IOLog( "Got boot device = %s\n", str );
694
695 iostr = (OSString *) service->getProperty( kIOBSDNameKey );
696 if( iostr)
697 strcpy( rootName, iostr->getCStringNoCopy() );
698 off = (OSNumber *) service->getProperty( kIOBSDMajorKey );
699 if( off)
700 major = off->unsigned32BitValue();
701 off = (OSNumber *) service->getProperty( kIOBSDMinorKey );
702 if( off)
703 minor = off->unsigned32BitValue();
704
705 if( service->metaCast( "IONetworkInterface" ))
706 flags |= 1;
707
708 } else {
709
710 IOLog( "Wait for root failed\n" );
711 strcpy( rootName, "en0");
712 flags |= 1;
713 }
714
715 IOLog( "BSD root: %s", rootName );
716 if( major)
717 IOLog(", major %d, minor %d\n", major, minor );
718 else
719 IOLog("\n");
720
721 *root = makedev( major, minor );
722 *oflags = flags;
723
724 IOFree( str, kMaxPathBuf + kMaxBootVar );
725
55e303ae 726iofrootx:
0b4e3aa0 727 if( (gIOKitDebug & (kIOLogDTree | kIOLogServiceTree | kIOLogMemory)) && !debugInfoPrintedOnce) {
1c79356b 728
0b4e3aa0 729 IOService::getPlatform()->waitQuiet();
1c79356b
A
730 if( gIOKitDebug & kIOLogDTree) {
731 IOLog("\nDT plane:\n");
732 IOPrintPlane( gIODTPlane );
733 }
734 if( gIOKitDebug & kIOLogServiceTree) {
735 IOLog("\nService plane:\n");
736 IOPrintPlane( gIOServicePlane );
737 }
738 if( gIOKitDebug & kIOLogMemory)
739 IOPrintMemory();
740 }
741
742 return( kIOReturnSuccess );
743}
744
9bccf70c
A
745void *
746IOBSDRegistryEntryForDeviceTree(char * path)
747{
748 return (IORegistryEntry::fromPath(path, gIODTPlane));
749}
750
751void
752IOBSDRegistryEntryRelease(void * entry)
753{
754 IORegistryEntry * regEntry = (IORegistryEntry *)entry;
755
756 if (regEntry)
757 regEntry->release();
758 return;
759}
760
761const void *
762IOBSDRegistryEntryGetData(void * entry, char * property_name,
763 int * packet_length)
764{
765 OSData * data;
766 IORegistryEntry * regEntry = (IORegistryEntry *)entry;
767
768 data = (OSData *) regEntry->getProperty(property_name);
769 if (data) {
770 *packet_length = data->getLength();
771 return (data->getBytesNoCopy());
772 }
773 return (NULL);
774}
775
1c79356b 776} /* extern "C" */