darwin-xnu/iokit/bsddev/IOKitBSDInit.cpp
<<
>>
Prefs
   1/*
   2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
   3 *
   4 * @APPLE_LICENSE_HEADER_START@
   5 * 
   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.
  11 * 
  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
  14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
  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.
  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>
  27#include <IOKit/IOPlatformExpert.h>
  28
  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
  37extern dev_t mdevadd(int devid, ppnum_t base, unsigned int size, int phys);
  38extern dev_t mdevlookup(int devid);
  39
  40kern_return_t
  41IOKitBSDInit( void )
  42{
  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
  76OSDictionary * IOUUIDMatching( void )
  77{
  78    return IOService::resourceMatching( "boot-uuid-media" );
  79}
  80
  81
  82OSDictionary * IOCDMatching( void )
  83{
  84    OSDictionary *      dict;
  85    const OSSymbol *    str;
  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 );
 102}
 103
 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
 178        propDict->setObject( "IOInterfaceNamePrefix", (OSObject *) str );
 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
 200static bool IORegisterNetworkInterface( IOService * netif )
 201{
 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 };
 216
 217    do {
 218        stack = IOService::waitForService(
 219                IOService::serviceMatching("IONetworkStack") );
 220        if ( stack == 0 ) break;
 221
 222        dict = OSDictionary::withCapacity(3);
 223        if ( dict == 0 ) break;
 224
 225        zero = OSNumber::withNumber((UInt64) 0, 32);
 226        if ( zero == 0 ) break;
 227
 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 );
 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;
 260    long                 lun = -1;
 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 );
 268                
 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 == '@') {
 277                    unit = strtol( look + 1, &comp, 16 );
 278
 279                    if( *comp == ',') {
 280                        lun = strtol( comp + 1, 0, 16 );
 281                    }
 282                    
 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;
 298                
 299        maxLen -= strlen( "{" kIOPathMatchKey "='" kIODeviceTreePlane ":" );
 300        maxLen -= ( alias ? strlen( alias ) : 0 ) + (look - path);
 301        maxLen -= strlen( "/@hhhhhhhh,hhhhhhhh:dddddddddd';}" );
 302
 303        if( maxLen > 0) {
 304            sprintf( buf, "{" kIOPathMatchKey "='" kIODeviceTreePlane ":" );
 305            comp = buf + strlen( buf );
 306                        
 307            if( alias) {
 308                strcpy( comp, alias );
 309                comp += strlen( alias );
 310            }
 311                        
 312            if ( (look - path)) {
 313                strncpy( comp, path, look - path);
 314                comp += look - path;
 315            }
 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            }
 325        } else
 326            continue;
 327                
 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{
 337    OSDictionary *      matching;
 338    OSString *          str;
 339    char *              comp;
 340    int                 len;
 341
 342    /* need to look up path, get device type,
 343        call matching help based on device type */
 344
 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 );
 379
 380    if( matching)
 381        matching->release();
 382
 383    return( 0 );
 384}
 385
 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
 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;
 434    UInt32              *ramdParms = 0;
 435
 436    UInt32              flags = 0;
 437    int                 minor, major;
 438    bool                findHFSChild = false;
 439    char *              mediaProperty = 0;
 440    char *              rdBootVar;
 441    enum {              kMaxPathBuf = 512, kMaxBootVar = 128 };
 442    char *              str;
 443    const char *        look = 0;
 444    int                 len;
 445    bool                forceNet = false;
 446    bool                debugInfoPrintedOnce = false;
 447    const char *        uuidStr = NULL;
 448
 449    static int          mountAttempts = 0;
 450                                
 451    int xchar, dchar;
 452                                    
 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 {
 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;
 484                }
 485            }
 486
 487            // else try for an OF Path
 488            data = (OSData *) regEntry->getProperty( "rootpath" );
 489            regEntry->release();
 490            if( data) continue;
 491        }
 492        if( (regEntry = IORegistryEntry::fromPath( "/options", gIODTPlane ))) {
 493            data = (OSData *) regEntry->getProperty( "boot-file" );
 494            regEntry->release();
 495            if( data) continue;
 496        }
 497    } while( false );
 498
 499    if( data && !uuidStr)
 500        look = (const char *) data->getBytesNoCopy();
 501
 502    if( rdBootVar[0] == '*') {
 503        look = rdBootVar + 1;
 504                forceNet = false;
 505    } else {
 506        if( (regEntry = IORegistryEntry::fromPath( "/", gIODTPlane ))) {
 507            forceNet = (0 != regEntry->getProperty( "net-boot" ));
 508                regEntry->release();
 509                }
 510    }
 511
 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
 563    if( look) {
 564        // from OpenFirmware path
 565        IOLog("From path: \"%s\", ", look);
 566
 567        if( forceNet || (0 == strncmp( look, "enet", strlen( "enet" ))) ) {
 568            matching = IONetworkMatching( look, str, kMaxPathBuf );
 569        } else {
 570            matching = IODiskMatching( look, str, kMaxPathBuf );
 571        }
 572    }
 573    
 574      if( (!matching) && rdBootVar[0] ) {
 575        // by BSD name
 576        look = rdBootVar;
 577        if( look[0] == '*')
 578            look++;
 579    
 580        if ( strncmp( look, "en", strlen( "en" )) == 0 ) {
 581            matching = IONetworkNamePrefixMatching( "en" );
 582        } else if ( strncmp( look, "cdrom", strlen( "cdrom" )) == 0 ) {
 583            matching = IOCDMatching();
 584            findHFSChild = true;
 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            }
 605        } else {
 606            matching = IOBSDNameMatching( look );
 607        }
 608    }
 609
 610    if( !matching) {
 611        OSString * astring;
 612        // any HFS
 613        matching = IOService::serviceMatching( "IOMedia" );
 614        astring = OSString::withCStringNoCopy("Apple_HFS");
 615        if ( astring ) {
 616            matching->setObject("Content", astring);
 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
 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" );
 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            }
 652        }
 653    } while( !service);
 654    matching->release();
 655
 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;
 671    } else if ( service && mediaProperty ) {
 672        service = service->getProperty(mediaProperty);
 673    }
 674
 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" )
 684    &&   !IORegisterNetworkInterface( service ) )
 685    {
 686        service = 0;
 687    }
 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
 726iofrootx:
 727    if( (gIOKitDebug & (kIOLogDTree | kIOLogServiceTree | kIOLogMemory)) && !debugInfoPrintedOnce) {
 728
 729        IOService::getPlatform()->waitQuiet();
 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
 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
 776} /* extern "C" */
 777
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.