#include <IOKit/IOService.h>
#include <IOKit/IODeviceTreeSupport.h>
#include <IOKit/IOKitKeys.h>
-#include <IOKit/storage/IOMedia.h>
-#include <IOKit/network/IONetworkStack.h>
-#include <IOKit/network/IONetworkInterface.h>
#include <IOKit/IOPlatformExpert.h>
#include <sys/disklabel.h>
return( 0 );
}
+OSDictionary * IOCDMatching( const char * name )
+{
+ OSDictionary * dict;
+ const OSSymbol * str;
+
+ dict = IOService::serviceMatching( "IOMedia" );
+ if( dict == 0 ) {
+ IOLog("Unable to find IOMedia\n");
+ return 0;
+ }
+
+ str = OSSymbol::withCString( "CD_ROM_Mode_1" );
+ if( str == 0 ) {
+ dict->release();
+ return 0;
+ }
+
+ dict->setObject( "Content", (OSObject *)str );
+ str->release();
+ return( dict );
+}
+
OSDictionary * IONetworkMatching( const char * path,
char * buf, int maxLen )
{
if ( str == 0 )
continue;
- propDict->setObject( kIOInterfaceNamePrefix, (OSObject *) str );
+ propDict->setObject( "IOInterfaceNamePrefix", (OSObject *) str );
str->release();
str = 0;
return( 0 );
}
-static bool IORegisterNetworkInterface( IONetworkInterface * netif )
+static bool IORegisterNetworkInterface( IOService * netif )
{
- IONetworkStack * stack;
+ // A network interface is typically named and registered
+ // with BSD after receiving a request from a user space
+ // "namer". However, for cases when the system needs to
+ // root from the network, this registration task must be
+ // done inside the kernel and completed before the root
+ // device is handed to BSD.
+
+ IOService * stack;
+ OSNumber * zero = 0;
+ OSString * path = 0;
+ OSDictionary * dict = 0;
+ char * pathBuf = 0;
+ int len;
+ enum { kMaxPathLen = 512 };
- if (( stack = IONetworkStack::getNetworkStack() ))
- {
- stack->registerInterface( netif, netif->getNamePrefix() );
- }
+ do {
+ stack = IOService::waitForService(
+ IOService::serviceMatching("IONetworkStack") );
+ if ( stack == 0 ) break;
- return ( netif->getProperty( kIOBSDNameKey ) != 0 );
-}
+ dict = OSDictionary::withCapacity(3);
+ if ( dict == 0 ) break;
-static void IORegisterPrimaryNetworkInterface()
-{
- IONetworkStack * stack;
+ zero = OSNumber::withNumber((UInt64) 0, 32);
+ if ( zero == 0 ) break;
- if (( stack = IONetworkStack::getNetworkStack() ))
- {
- stack->registerPrimaryInterface( true );
- }
+ pathBuf = (char *) IOMalloc( kMaxPathLen );
+ if ( pathBuf == 0 ) break;
+
+ len = kMaxPathLen;
+ if ( netif->getPath( pathBuf, &len, gIOServicePlane )
+ == false ) break;
+
+ path = OSString::withCStringNoCopy( pathBuf );
+ if ( path == 0 ) break;
+
+ dict->setObject( "IOInterfaceUnit", zero );
+ dict->setObject( kIOPathMatchKey, path );
+
+ stack->setProperties( dict );
+ }
+ while ( false );
+
+ if ( zero ) zero->release();
+ if ( path ) path->release();
+ if ( dict ) dict->release();
+ if ( pathBuf ) IOFree(pathBuf, kMaxPathLen);
+
+ return ( netif->getProperty( kIOBSDNameKey ) != 0 );
}
OSDictionary * IODiskMatching( const char * path, char * buf, int maxLen )
const char * look = 0;
int len;
bool forceNet = false;
+ bool debugInfoPrintedOnce = false;
static int mountAttempts = 0;
// from OpenFirmware path
IOLog("From path: \"%s\", ", look);
- if( forceNet || (0 == strncmp( look, "enet", strlen( "enet" ))) )
- matching = IONetworkMatching( look, str, kMaxPathBuf );
- else
+ if( forceNet || (0 == strncmp( look, "enet", strlen( "enet" ))) ) {
+ matching = IONetworkMatching( look, str, kMaxPathBuf );
+ } else {
matching = IODiskMatching( look, str, kMaxPathBuf );
+ }
}
if( (!matching) && rdBootVar[0] ) {
if( look[0] == '*')
look++;
- if ( strncmp( look, "en", strlen( "en" )) == 0 )
- matching = IONetworkNamePrefixMatching( "en" );
- else
- matching = IOBSDNameMatching( look );
+ if ( strncmp( look, "en", strlen( "en" )) == 0 ) {
+ matching = IONetworkNamePrefixMatching( "en" );
+ } else if ( strncmp( look, "cdrom", strlen( "cdrom" )) == 0 ) {
+ matching = IOCDMatching( look );
+ } else {
+ matching = IOBSDNameMatching( look );
+ }
}
if( !matching) {
matching = IOService::serviceMatching( "IOMedia" );
astring = OSString::withCStringNoCopy("Apple_UFS");
if ( astring ) {
- matching->setObject(kIOMediaContentKey, astring);
+ matching->setObject("Content", astring);
astring->release();
}
}
}
}
- IOService::waitForService(IOService::serviceMatching("IOMediaBSDClient"));
-
do {
t.tv_sec = ROOTDEVICETIMEOUT;
t.tv_nsec = 0;
if( (!service) || (mountAttempts == 10)) {
PE_display_icon( 0, "noroot");
IOLog( "Still waiting for root device\n" );
+
+ if( !debugInfoPrintedOnce) {
+ debugInfoPrintedOnce = true;
+ if( gIOKitDebug & kIOLogDTree) {
+ IOLog("\nDT plane:\n");
+ IOPrintPlane( gIODTPlane );
+ }
+ if( gIOKitDebug & kIOLogServiceTree) {
+ IOLog("\nService plane:\n");
+ IOPrintPlane( gIOServicePlane );
+ }
+ if( gIOKitDebug & kIOLogMemory)
+ IOPrintMemory();
+ }
}
} while( !service);
matching->release();
if ( service
&& service->metaCast( "IONetworkInterface" )
- && !IORegisterNetworkInterface( (IONetworkInterface *) service ) )
+ && !IORegisterNetworkInterface( service ) )
{
service = 0;
}
- IORegisterPrimaryNetworkInterface();
if( service) {
IOFree( str, kMaxPathBuf + kMaxBootVar );
- if( gIOKitDebug & (kIOLogDTree | kIOLogServiceTree | kIOLogMemory)) {
+ if( (gIOKitDebug & (kIOLogDTree | kIOLogServiceTree | kIOLogMemory)) && !debugInfoPrintedOnce) {
- IOSleep(10 * 1000);
-// IOService::getPlatform()->waitQuiet();
+ IOService::getPlatform()->waitQuiet();
if( gIOKitDebug & kIOLogDTree) {
IOLog("\nDT plane:\n");
IOPrintPlane( gIODTPlane );
return( kIOReturnSuccess );
}
+void *
+IOBSDRegistryEntryForDeviceTree(char * path)
+{
+ return (IORegistryEntry::fromPath(path, gIODTPlane));
+}
+
+void
+IOBSDRegistryEntryRelease(void * entry)
+{
+ IORegistryEntry * regEntry = (IORegistryEntry *)entry;
+
+ if (regEntry)
+ regEntry->release();
+ return;
+}
+
+const void *
+IOBSDRegistryEntryGetData(void * entry, char * property_name,
+ int * packet_length)
+{
+ OSData * data;
+ IORegistryEntry * regEntry = (IORegistryEntry *)entry;
+
+ data = (OSData *) regEntry->getProperty(property_name);
+ if (data) {
+ *packet_length = data->getLength();
+ return (data->getBytesNoCopy());
+ }
+ return (NULL);
+}
+
} /* extern "C" */