Annotation of kernel/driverkit/ppc/autoconf_ppc.m, revision 1.1

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: /*
        !            26:  * Copyright (c) 1993 NeXT Computer, Inc.
        !            27:  *
        !            28:  * PPC Driverkit configuration.
        !            29:  *
        !            30:  * HISTORY
        !            31:  *
        !            32:  * 10 Dec 1998 Adam Wang
        !            33:  *  Added USB matching
        !            34:  * 27 Oct 1997 Simon Douglas
        !            35:  *     Added support for tree probe, name matching.
        !            36:  * 28 June 1994
        !            37:  *     Derived from i386 version.
        !            38:  * 28 Jan 1993  Brian Pinkerton at NeXT
        !            39:  *     Added support for new, MI autoconf logic, and new driverkit API.
        !            40:  * 10 Nov 1992 Brian Pinkerton at NeXT
        !            41:  *     Added indirect probe logic.
        !            42:  * 20 Aug 1992 Joe Pasqua
        !            43:  *     Init intrReq & intrAttached of kern_dev in configure_device_class().
        !            44:  * 3 August 1992 ? at NeXT
        !            45:  *     Created.
        !            46:  */
        !            47: 
        !            48: #import <mach/mach_types.h>
        !            49: 
        !            50: #import <machkit/NXLock.h>
        !            51: #import <objc/List.h>
        !            52: #import <driverkit/KernDeviceDescription.h>
        !            53: #import <driverkit/KernStringList.h>
        !            54: #import <driverkit/ppc/IOPPCDeviceDescription.h>
        !            55: #import <driverkit/IODeviceDescriptionPrivate.h>
        !            56: #import <driverkit/IODirectDevice.h>
        !            57: #import <driverkit/IODeviceKernPrivate.h>
        !            58: #import <driverkit/IODeviceParams.h>
        !            59: #import <driverkit/Device_ddm.h>
        !            60: #import <driverkit/configTableKern.h>
        !            61: #import <driverkit/KernDevice.h>
        !            62: #import <driverkit/IOConfigTable.h>
        !            63: #import <driverkit/driverTypesPrivate.h>
        !            64: #import <driverkit/autoconfCommon.h>
        !            65: #import <driverkit/ppc/PPCKernBus.h>
        !            66: #import <driverkit/ppc/PPCKernBusPrivate.h>
        !            67: 
        !            68: #import <machdep/ppc/kernBootStruct.h>
        !            69: #import <machdep/ppc/DeviceTree.h>
        !            70: #import <driverkit/ppc/IOTreeDevice.h>
        !            71: 
        !            72: /* Used for machine determination */
        !            73: #import <machdep/ppc/powermac.h>
        !            74: #import <machdep/ppc/powermac_gestalt.h>
        !            75: #import <string.h>
        !            76: 
        !            77: // config tables passed by booter in /AAPL,loadables dir
        !            78: static char ** allConfigTables;
        !            79: static int numConfigTables;
        !            80: 
        !            81: #define BUS_LOAD_PRI_PROP      "\"Load Priority\" = \"10000\";"
        !            82: // for debugging
        !            83: #define ENET_LOAD_PRI_PROP     "\"Load Priority\" = \"7000\";"
        !            84: #define VIA_LOAD_PRI_PROP      "\"Load Priority\" = \"6800\";"
        !            85: // slightly higher than default so they come before any PCI SCSI
        !            86: #define INT_IDE_LOAD_PRI_PROP   "\"Load Priority\" = \"5050\";"
        !            87: #define INT_SCSI_LOAD_PRI_PROP "\"Load Priority\" = \"5100\";"
        !            88: #define EXT_SCSI_LOAD_PRI_PROP "\"Load Priority\" = \"5200\";"
        !            89: #define DISPLAY_LOAD_PRI       6000
        !            90: #define DEFAULT_LOAD_PRI       5000
        !            91: #define USBCMD_LOAD_PRI_PROP    "\"Load Priority\" = \"4000\";"
        !            92: 
        !            93: static const char * inKernelConfigTables =
        !            94: 
        !            95: "\"Bus Class\" = \"PPCKernBus\";"
        !            96: "\"Class Names\" = \"\";"
        !            97: "\"Family\" = \"Bus\";"
        !            98: "\"Instance\" = \"0\";"
        !            99: "\"Version\" = \"5.0\";"
        !           100: "\0"
        !           101: #if            MK_HASDRIVERS
        !           102: "\"Driver Name\" = \"BMacEnet\";"
        !           103: "\"Matching\" = \"bmac bmac+\";"
        !           104: ENET_LOAD_PRI_PROP
        !           105: "\0"
        !           106: "\"Driver Name\" = \"MaceEnet\";"
        !           107: "\"Matching\" = \"mace\";"
        !           108: ENET_LOAD_PRI_PROP
        !           109: "\0"
        !           110: "\"Driver Name\" = \"DECchip21041\";"
        !           111: "\"Matching\" = \"pci1011,14\";"
        !           112: "\"Share IRQ Levels\" = \"YES\";"
        !           113: "\"Network Interface\" = \"AUTO\";"
        !           114: ENET_LOAD_PRI_PROP
        !           115: "\0"
        !           116: "\"Driver Name\" = \"Apple96_SCSI\";"
        !           117: "\"Matching\" = \"53c94\";"
        !           118: "\"Bus Type\" = \"PPC\";"              // why do they look for it?
        !           119: EXT_SCSI_LOAD_PRI_PROP
        !           120: "\0"
        !           121: "\"Driver Name\" = \"AppleMesh_SCSI\";"
        !           122: "\"Matching\" = \"mesh\";"
        !           123: "\"Bus Type\" = \"PPC\";"              // why do they look for it?
        !           124: INT_SCSI_LOAD_PRI_PROP
        !           125: "\0"
        !           126: "\"Family\" = \"Disk\";"
        !           127: "\"Driver Name\" = \"EIDE\";"
        !           128: "\"Matching\" = \"ide ata ATA pci1095,646\";"
        !           129: "\"Class Names\" = \"IdeController AtapiController\";"
        !           130: "\"Block Major\" = \"3\";"
        !           131: "\"Character Major\" = \"15\";"
        !           132: INT_IDE_LOAD_PRI_PROP
        !           133: "\0"
        !           134: "\"Driver Name\" = \"ApplePMU\";"
        !           135: "\"Matching\" = \"via-pmu\";"
        !           136: VIA_LOAD_PRI_PROP
        !           137: "\0"
        !           138: "\"Driver Name\" = \"AppleCuda\";"
        !           139: "\"Matching\" = \"via-cuda\";"
        !           140: VIA_LOAD_PRI_PROP
        !           141: "\0"
        !           142: "\"Driver Name\" = \"AppleUSBCMD\";"
        !           143: "\"Matching\" = \"pci1095,670\";"
        !           144: USBCMD_LOAD_PRI_PROP
        !           145: "\0"
        !           146: "\"Driver Name\" = \"AppleUSBCMD\";"
        !           147: "\"Matching\" = \"pci11c1,5801\";"
        !           148: USBCMD_LOAD_PRI_PROP   
        !           149: "\0"
        !           150: "\"Driver Name\" = \"AppleUSBCMD\";"
        !           151: "\"Matching\" = \"pciclass,0c0310\";"
        !           152: USBCMD_LOAD_PRI_PROP  
        !           153: "\0"
        !           154: "\"Driver Name\" = \"AppleUSBCMD\";"
        !           155: "\"Matching\" = \"usb\";"
        !           156: USBCMD_LOAD_PRI_PROP  
        !           157: "\0"
        !           158: "\"Driver Name\" = \"AppleOHare\";"
        !           159: "\"Matching\" = \"pci106b,7\";"
        !           160: BUS_LOAD_PRI_PROP
        !           161: "\0"
        !           162: "\"Driver Name\" = \"Symbios8xx\";"
        !           163: "\"Matching\" = \"apple53C8xx Apple53C875Card\";"
        !           164: "\"Class Names\" = \"Sym8xxController\";"
        !           165: "\"Bus Type\" = \"PPC\";"
        !           166: "\0"
        !           167: "\"Driver Name\" = \"AdaptecU2SCSI\";"
        !           168: "\"Matching\" = \"ADPT,2940U2B ADPT,3950U2B ADPT,2930CU ADPT,2930U\";"
        !           169: "\"Class Names\" = \"AdaptecU2SCSI\";"
        !           170: "\"Bus Type\" = \"PPC\";"
        !           171: INT_SCSI_LOAD_PRI_PROP
        !           172: "\0"
        !           173: #endif         /* MK_HASDRIVERS */
        !           174: 
        !           175: #if            DK_HASDRIVERS
        !           176: "\"Driver Name\" = \"IOMacRiscPCIBridge\";"
        !           177: "\"Matching\" = \"bandit\";"
        !           178: BUS_LOAD_PRI_PROP
        !           179: "\0"
        !           180: "\"Driver Name\" = \"IOMacRiscVCIBridge\";"
        !           181: "\"Matching\" = \"chaos\";"
        !           182: BUS_LOAD_PRI_PROP
        !           183: "\0"
        !           184: "\"Driver Name\" = \"IOGracklePCIBridge\";"
        !           185: "\"Matching\" = \"grackle\";"
        !           186: BUS_LOAD_PRI_PROP
        !           187: "\0"
        !           188: "\"Driver Name\" = \"IOPCIBridge\";"
        !           189: "\"Matching\" = \"pci-bridge\";"
        !           190: BUS_LOAD_PRI_PROP
        !           191: "\0"
        !           192: "\"Driver Name\" = \"IONDRVFramebuffer\";"             /* shim for ndrv's */
        !           193: "\"Matching\" = \"display\";"                          /* matches device_type */
        !           194: "\"Load Priority\" = \"6000\";"
        !           195: "\0"
        !           196: #endif         /* DK_HASDRIVERS */
        !           197: "\"Driver Name\" = \"IODeviceTreeBus\";"
        !           198: "\"Matching\" = \"cpu cpus l2-cache\";"                        /* matches device_type */
        !           199: "\0"
        !           200: /************ must be last ************/
        !           201: "\"Driver Name\" = \"IODeviceTreeBus\";"
        !           202: "\"Matching\" = \"device-tree\";"                      /* matches any tree "bus" node */
        !           203: BUS_LOAD_PRI_PROP
        !           204: "\0"
        !           205: "\0"
        !           206: ;
        !           207: 
        !           208: void DeviceTreeProbe( void );
        !           209: static int
        !           210: MatchDriversForDevice( id ioDevice );
        !           211: static char *
        !           212: FindStringKey( const char * config, const char * key, char * value );
        !           213: IOReturn
        !           214: PublishDevice( id ioDevice );
        !           215: static BOOL
        !           216: StartDriver( IOConfigTable * configTable, id ioDeviceDescription );
        !           217: BOOL
        !           218: NewLoadDriver( const char * configData );
        !           219: 
        !           220: static void probe_indirect(const char **indirectNamep, id driverInstance);
        !           221: const char *findBootConfigString(int n);
        !           222: static void bootDriverInit(void);
        !           223: 
        !           224: id             defaultBus, defaultBusClass;
        !           225: id             autoConfigTables;
        !           226: 
        !           227: /*
        !           228:  * Native indirect driver classes.
        !           229:  */
        !           230: char *indirectDevList[] = {
        !           231:         "ATADisk",
        !           232:        "SCSIDisk",
        !           233:        "SCSIGeneric",
        !           234:        "IODiskPartition",
        !           235:        "IOADBBus",
        !           236:        "PPCKeyboard",
        !           237:        "PPCMouse",
        !           238:        NULL
        !           239: };
        !           240: 
        !           241: /*
        !           242:  * Pseudo device list.
        !           243:  */
        !           244: char *pseudoDevList[] = {
        !           245:        "EventDriver",
        !           246:        "kmDevice",
        !           247:        NULL
        !           248: };
        !           249: 
        !           250: #define SERVER_NAME_KEY                "Server Name"
        !           251: #define CLASS_NAMES_KEY        "Class Names"
        !           252: #define DRIVER_NAME_KEY        "Driver Name"
        !           253: #define BUS_CLASS_KEY          "Bus Class"
        !           254: #define BUS_TYPE_KEY           "Bus Type"
        !           255: #define FAMILY_KEY             "Family"
        !           256: #define BUS_FAMILY             "Bus"
        !           257: #define KERN_BUS_FORMAT                "%sKernBus"
        !           258: #define DEVICE_DESCR_FORMAT    "IO%sDeviceDescription"
        !           259: #define DEFAULT_BUS            "PPC"
        !           260: #define NAME_BUF_LEN           128
        !           261: 
        !           262: 
        !           263: static BOOL
        !           264: versionIsOK(const char *serverName)
        !           265: {
        !           266:     int version;
        !           267: 
        !           268:        return YES;    
        !           269:     /*
        !           270:      * Right now, if serverName is NULL, that means the driver
        !           271:      * is compiled into the kernel, so don't check the version.
        !           272:      * This may change later, however.
        !           273:      */
        !           274:     
        !           275:     if (serverName != NULL) {
        !           276:        version = [IODevice
        !           277:                driverKitVersionForDriverNamed:(char *)serverName];
        !           278:        if (version == -1)
        !           279:            version = 310;
        !           280:        /*
        !           281:         * TODO: revisit this policy decision if DriverKit
        !           282:         * compatibility changes in the future.
        !           283:         */
        !           284:        if (version <= 310) {
        !           285:            IOLog("WARNING: driver %s uses incompatible DriverKit version %d\n", serverName, version);
        !           286:            IOLog("Driver %s could not be configured\n", 
        !           287:                serverName);
        !           288:            return NO;
        !           289:        }
        !           290:     }
        !           291:     return YES;
        !           292: }
        !           293: 
        !           294: #define BUILTIN_BUS_CLASS "PPCKernBus" // XXX
        !           295: 
        !           296: /*
        !           297:  * Eventually, this routine will only initialize the boot device(s) per 
        !           298:  * input from the booter via KERNBOOTSTRUCT. 
        !           299:  * For now, configure all native devices enumerated in the various
        !           300:  * tables in device_configuration.c.
        !           301:  */
        !           302: 
        !           303: void
        !           304: probeNativeDevices(void)
        !           305: {
        !           306:        int             i;
        !           307:        const char      *config;
        !           308:        IOConfigTable   *configTable = nil;
        !           309:        const char      *family, *busName;
        !           310:        id              busClass;
        !           311:        BOOL            gotBuiltinBus = NO;
        !           312:        
        !           313:        autoConfigTables = [[List alloc] init];
        !           314: 
        !           315:        //
        !           316:        // Initialize drivers and modules loaded by booter.
        !           317: 
        !           318:        bootDriverInit();
        !           319: 
        !           320:        //
        !           321:        // Find all bus drivers.
        !           322:        //
        !           323: 
        !           324:        for(i=1; (config = findBootConfigString(i)); i++) {
        !           325: 
        !           326:                configTable = [IOConfigTable newForConfigData:config];
        !           327:                family = [configTable valueForStringKey:FAMILY_KEY];
        !           328:                if (family && strcmp(family, BUS_FAMILY) == 0) {
        !           329:                    busName = [configTable valueForStringKey:BUS_CLASS_KEY];
        !           330:                    if (!busName) {
        !           331:                        printf("autoconf: missing \"%s\" key\n",
        !           332:                               BUS_CLASS_KEY);
        !           333:                        continue;
        !           334:                    }
        !           335:                    if (strcmp(busName, BUILTIN_BUS_CLASS) == 0) {
        !           336:                        gotBuiltinBus = YES;
        !           337:                    }
        !           338:                    busClass = objc_getClass(busName);
        !           339:                    (void)[busClass probeBus:configTable];
        !           340:                    [configTable freeString:busName];
        !           341:                    [configTable freeString:family];
        !           342:                } else {
        !           343:                    if (family)
        !           344:                        [configTable freeString:family];
        !           345:                    [configTable free];
        !           346:                }
        !           347:        }
        !           348: 
        !           349:        if (gotBuiltinBus == NO) {      // XXX
        !           350:                busClass = objc_getClass(BUILTIN_BUS_CLASS);
        !           351:                (void)[busClass probeBus:nil];
        !           352:        }
        !           353:        
        !           354:        defaultBusClass = [KernBus lookupBusClassWithName:DEFAULT_BUS]; // XXX
        !           355:        if (defaultBusClass == nil) {
        !           356:                panic("Missing default kernel bus class");
        !           357:        }
        !           358:        defaultBus = [KernBus lookupBusInstanceWithName:DEFAULT_BUS busId:0];
        !           359: 
        !           360:        /*
        !           361:         */
        !           362:         for( i = 1; (config = findBootConfigString(i)); i++) {
        !           363:             NewLoadDriver( config );
        !           364:        }
        !           365: 
        !           366:        /*
        !           367:         * Probe the device tree
        !           368:         */
        !           369:        DeviceTreeProbe();
        !           370: 
        !           371: }
        !           372: 
        !           373: 
        !           374: @protocol OldProbeMethods
        !           375: + probe;
        !           376: + probe:(int)a deviceMaster:(port_t) b;
        !           377: @end
        !           378: 
        !           379: /* 
        !           380:  * Called from MD probeNativeDevices() and from configureThread(), the
        !           381:  * IOTask version of IOProbeDriver().
        !           382:  *
        !           383:  * Given a class name and an ASCII representation of a config file,
        !           384:  * create a kern_dev and an IODeviceDescription and probe the class. 
        !           385:  * This is used both at boot time - for the boot device and (temporarily) 
        !           386:  * any native drivers with static config tables - and by IOProbeDriver().
        !           387:  * 
        !           388:  * Returns YES if driver was started successfully, else returns NO.
        !           389: */
        !           390: 
        !           391: static BOOL
        !           392: StartDriver( IOConfigTable * configTable, id ioDeviceDescription )
        !           393: {
        !           394:        const char      *className, *classNames;
        !           395:        KernStringList  *classNameList = nil;
        !           396:        const char      *serverName = NULL;
        !           397:        Class           theClass;
        !           398:        id              deviceDescription = nil;
        !           399:        id              device = nil;
        !           400:        id              newDescription;
        !           401:        int             index, classesLoaded;
        !           402:        BOOL            versionChecked = NO;
        !           403:        const char      *placeholder;
        !           404:        const char      *busType, *busTypeString;
        !           405:        char            *nameBuf;
        !           406:        id              busClass, busDescriptionClass;
        !           407: 
        !           408: 
        !           409:        nameBuf = (char *)IOMalloc(NAME_BUF_LEN);
        !           410: 
        !           411:        serverName = [configTable valueForStringKey:SERVER_NAME_KEY];
        !           412: 
        !           413:        /*
        !           414:         * Check for a placeholder config table
        !           415:         * that represents a dynamically configured device.
        !           416:         * NOTE: this skips the driverkit version check. XXX
        !           417:         */
        !           418:        if ((placeholder = [configTable valueForStringKey:"Dynamic"])) {
        !           419:            if (*placeholder == 'Y' || *placeholder == 'y') {
        !           420:                [autoConfigTables addObject:configTable];
        !           421:                [configTable freeString:placeholder];
        !           422:                return YES;
        !           423:            } else {
        !           424:                [configTable freeString:placeholder];
        !           425:            }
        !           426:        }
        !           427:        
        !           428:         classNames = (char *)[configTable valueForStringKey:CLASS_NAMES_KEY];
        !           429:         if (classNames == NULL) {
        !           430:             classNames = (char *)[configTable
        !           431:                                     valueForStringKey:DRIVER_NAME_KEY];
        !           432:             if (classNames == NULL)
        !           433:                     goto abort;
        !           434:         }
        !           435:        classNameList = [[KernStringList alloc]
        !           436:                            initWithWhitespaceDelimitedString:classNames];
        !           437:        [configTable freeString:classNames];
        !           438: 
        !           439:        busTypeString = [configTable valueForStringKey:BUS_TYPE_KEY];
        !           440:        if (busTypeString == NULL || *busTypeString == '\0')
        !           441:            busType = DEFAULT_BUS;
        !           442:        else
        !           443:            busType = busTypeString;
        !           444: 
        !           445:        sprintf(nameBuf, KERN_BUS_FORMAT, busType);
        !           446:        busClass = objc_getClass((const char *)nameBuf);
        !           447:        if (busClass == nil)
        !           448:            busClass = defaultBusClass;
        !           449: 
        !           450:        classesLoaded = 0;
        !           451:        for (index = 0; index < [classNameList count]; index++) {
        !           452:            className = [classNameList stringAt:index];
        !           453:            theClass = objc_getClass(className);
        !           454: 
        !           455:            if (theClass == nil) {
        !           456:                    IOLog("configureDriver: "
        !           457:                          "driver class '%s' was not loaded\n", className);
        !           458:                    if( serverName)
        !           459:                        IOLog("Driver %s could not be configured\n", serverName);
        !           460:                    goto abort;
        !           461:            }
        !           462: 
        !           463: #if DEBUG
        !           464:            if( ioDeviceDescription)
        !           465:                kprintf("Probing class %s on device %s\n",
        !           466:                    className, [ioDeviceDescription nodeName]);
        !           467: #endif
        !           468:            
        !           469:            if (versionChecked == NO) {
        !           470:                /*
        !           471:                 * Right now, if serverName is NULL, that means the driver
        !           472:                 * is compiled into the kernel, so don't check the version.
        !           473:                 * This may change later, however.
        !           474:                 */
        !           475:     
        !           476:                if (serverName != NULL) {
        !           477:                    if (versionIsOK(serverName) == NO)
        !           478:                        goto abort;
        !           479:                }
        !           480:                versionChecked = YES;
        !           481:            }
        !           482: 
        !           483:            /*
        !           484:             * Check to see if bus wants to configure driver itself.
        !           485:             */
        !           486:            if ([busClass configureDriverWithTable:configTable]) {
        !           487:                classesLoaded = 1;
        !           488:                /* Return success. */
        !           489:                break;
        !           490:            }
        !           491: 
        !           492:            /*
        !           493:             *  Depending on the deviceStyle, we either make
        !           494:             *  an DeviceDescription or an PPCDeviceDescription.
        !           495:             */
        !           496: 
        !           497:            switch ([theClass deviceStyle]) {
        !           498:                case IO_DirectDevice:
        !           499:                    deviceDescription = [busClass
        !           500:                        deviceDescriptionFromConfigTable:configTable];  
        !           501:     
        !           502:                    if (deviceDescription == nil) {
        !           503:                            IOLog("configureDriver: initFromConfigTable "
        !           504:                                        "failed for class %s\n", className);
        !           505:                                goto abort;
        !           506:                    }
        !           507:                    
        !           508:                    if ([deviceDescription bus] == nil) {
        !           509:                        [deviceDescription setBus:defaultBus];
        !           510:                    }
        !           511:                    
        !           512:                    if ([[deviceDescription bus] allocateResourcesForDeviceDescription:
        !           513:                                    deviceDescription] == nil) {
        !           514:                            IOLog("configureDriver: could not allocate "
        !           515:                                  "resources for class %s\n", className);
        !           516:                                goto abort;
        !           517:                    }
        !           518: 
        !           519:                    device = [[KernDevice alloc]
        !           520:                        initWithDeviceDescription:deviceDescription];
        !           521:     
        !           522:                    if (device == nil) {
        !           523:                            IOLog("configureDriver: initFromDeviceDescription "
        !           524:                                        "failed for class %s\n", className);
        !           525:                                goto abort;
        !           526:                    }
        !           527:                    
        !           528:                    [deviceDescription setDevice:device];
        !           529: 
        !           530:                     if( nil == ioDeviceDescription) {          
        !           531:                         sprintf(nameBuf, "IO%sDeviceDescription", busType);
        !           532:                         busDescriptionClass = objc_getClass((const char *)nameBuf);
        !           533:                         newDescription = [[busDescriptionClass alloc]
        !           534:                             _initWithDelegate:deviceDescription];
        !           535:                         if (newDescription == nil)
        !           536:                                     goto abort;
        !           537:                     } else {
        !           538:                        newDescription = ioDeviceDescription;
        !           539:                         [newDescription setDelegate:deviceDescription];
        !           540:                    }
        !           541:                    [newDescription setDevicePort:create_dev_port(device)];
        !           542:                    break;
        !           543:     
        !           544:                case IO_IndirectDevice:
        !           545:                case IO_PseudoDevice:
        !           546:                
        !           547:                    deviceDescription = [[KernDeviceDescription alloc]
        !           548:                                            initFromConfigTable:configTable];
        !           549:                    if (deviceDescription == nil) {
        !           550:                            goto abort;
        !           551:                    }
        !           552:                    
        !           553:                    newDescription = [[IODeviceDescription alloc]
        !           554:                        _initWithDelegate:deviceDescription];
        !           555:                        
        !           556:                    if (newDescription == nil)
        !           557:                                goto abort;
        !           558: 
        !           559:                    break;
        !           560: 
        !           561:                default:
        !           562:                    IOLog("Invalid style for class %s", className);
        !           563:                    goto abort;
        !           564:            }
        !           565:     
        !           566:            /*
        !           567:             *  Now that we have a valid device description for the device,
        !           568:             *  probe the sucker.
        !           569:             */
        !           570: 
        !           571:            if (![theClass respondsTo:@selector(probe:)]) {
        !           572:                    IOLog("configureDriver: Class %s does not respond "
        !           573:                          "to probe:\n", className);
        !           574:                    continue;
        !           575:            }
        !           576:     
        !           577:            if( [IODevice addLoadedClass:theClass 
        !           578:                            description:newDescription] == IO_R_SUCCESS) {
        !           579:                    classesLoaded++;
        !           580:            }
        !           581:        }
        !           582: 
        !           583:        /*
        !           584:         * Only free resources if there was a fatal error before
        !           585:         * addLoadedClass: was called, because the class may cache
        !           586:         * the device description and config table for later use.
        !           587:         */
        !           588:        IOFree(nameBuf, NAME_BUF_LEN);
        !           589:        [classNameList free];
        !           590:        if (serverName)
        !           591:            [configTable freeString:serverName];
        !           592:        if (busTypeString)
        !           593:            [configTable freeString:busTypeString];
        !           594:        if (classesLoaded) {
        !           595:            return YES;
        !           596:        } else {
        !           597:            [deviceDescription free];
        !           598:            [device free];
        !           599:            return NO;
        !           600:        }
        !           601: 
        !           602: abort:
        !           603: 
        !           604:        if (serverName)
        !           605:                [configTable freeString:serverName];
        !           606:        if (busTypeString)
        !           607:                [configTable freeString:busTypeString];
        !           608: 
        !           609:        if (deviceDescription) {
        !           610:                [deviceDescription free];
        !           611:        }
        !           612:        if (device) {
        !           613:                [device free];
        !           614:        }
        !           615: 
        !           616:        return NO;
        !           617: }
        !           618: 
        !           619: 
        !           620: 
        !           621: 
        !           622: /*
        !           623:  * probe all indirect drivers associated with specified driver.
        !           624:  * As of mk-149.10, this is only used for IdeDisk.
        !           625:  */
        !           626: static void
        !           627: probe_indirect(const char **indirectNamep, id driverInstance)
        !           628: {
        !           629:        id driverClass;
        !           630:        
        !           631:        if(indirectNamep == NULL) {
        !           632:                return;
        !           633:        }
        !           634:        for(;  *indirectNamep; indirectNamep++) {
        !           635:                driverClass = objc_getClass(*indirectNamep);
        !           636:                if(driverClass == nil) {
        !           637:                        printf("probe_indirect: Class %s does not exist\n",
        !           638:                                *indirectNamep);
        !           639:                        continue;
        !           640:                }
        !           641:                if(![driverClass respondsTo:@selector(probe:)]) {
        !           642:                        printf("probe_indirect: Class %s does not respond to"
        !           643:                                " probe:\n", *indirectNamep);
        !           644:                        continue;
        !           645:                }
        !           646: 
        !           647:                [driverClass probe:driverInstance]; 
        !           648:        }
        !           649: }
        !           650: 
        !           651: IOReturn
        !           652: PublishDevice( id ioDevice )
        !           653: {
        !           654:     struct PendingProbe {
        !           655:             struct PendingProbe   *    next;
        !           656:             struct PendingProbe   *    prev;
        !           657:            int                         priority;
        !           658:             id                         device;
        !           659:     };
        !           660:     struct PendingProbeQueue {
        !           661:             struct PendingProbe   *    head;
        !           662:             struct PendingProbe   *    zero;
        !           663:             struct PendingProbe   *    tail;
        !           664:     };
        !           665:     int                                        priority;
        !           666:     struct PendingProbe *              newProbe;
        !           667:     struct PendingProbe *              elem;
        !           668:     static struct PendingProbeQueue    probeQueue;
        !           669:     static int                         outstanding = 0;
        !           670:     static                             probing = 0;
        !           671: 
        !           672:     priority = MatchDriversForDevice( ioDevice);
        !           673:     if( priority < 0)
        !           674:        return( IO_R_SUCCESS);          // no match, no probe now
        !           675: 
        !           676:     if( probing) {
        !           677:         newProbe = IOMalloc( sizeof( struct PendingProbe));
        !           678:        if( newProbe == NULL)
        !           679:            return( IO_R_NO_MEMORY);
        !           680:         newProbe->device = ioDevice;
        !           681:         newProbe->priority = priority;
        !           682: 
        !           683:         // queue it behind those with same priority
        !           684:         for( elem = probeQueue.head;
        !           685:             ( elem->next && (elem->priority >= priority));
        !           686:             elem = elem->next )
        !           687:                {}
        !           688:        // queue before elem
        !           689:        newProbe->next = elem;
        !           690:        newProbe->prev = elem->prev;
        !           691:        elem->prev->next = newProbe;
        !           692:        elem->prev = newProbe;
        !           693:         outstanding++;
        !           694: 
        !           695:     } else {
        !           696: 
        !           697:        probing++;
        !           698:        probeQueue.head = (struct PendingProbe *) &probeQueue.zero;
        !           699:        probeQueue.tail = (struct PendingProbe *) &probeQueue.head;
        !           700: 
        !           701:         StartDriver( [ioDevice configTable], ioDevice );
        !           702: 
        !           703:        while( outstanding) {
        !           704:             // dequeue highest - must be one
        !           705:            newProbe = probeQueue.head;
        !           706:            probeQueue.head = newProbe->next;
        !           707:             newProbe->next->prev = &probeQueue.head;
        !           708: 
        !           709:            outstanding--;
        !           710:            ioDevice = newProbe->device;
        !           711:            priority = newProbe->priority;
        !           712:            IOFree( newProbe, sizeof( struct PendingProbe));
        !           713: 
        !           714:            // start it
        !           715: #if DEBUG
        !           716:             kprintf("---- [%d] Driver probe on device %s\n", priority, [ioDevice nodeName] );
        !           717: #endif
        !           718:             StartDriver( [ioDevice configTable], ioDevice );
        !           719:        }
        !           720:        probing--;
        !           721:     }
        !           722: 
        !           723:     return( IO_R_SUCCESS);
        !           724: }
        !           725: 
        !           726: BOOL
        !           727: NewLoadDriver( const char * configData )
        !           728: {
        !           729:     BOOL               ret = NO;
        !           730:     id                 ioDevice;
        !           731:     IOConfigTable *    configTable;
        !           732:     char *             tryMatch;
        !           733:     char *             tryLoc;
        !           734:     char *             location;
        !           735:     enum {             kStringSize = 128 };
        !           736:     id *               failedList = nil;
        !           737:     int                        numFailed = 0;
        !           738:     int                        i;
        !           739: 
        !           740:     tryMatch = IOMalloc( kStringSize * 2);
        !           741:     if( ! tryMatch)
        !           742:        return( NO);
        !           743:     tryLoc = tryMatch + kStringSize;
        !           744: 
        !           745:     if( FindStringKey( configData, "\"Location\"", tryLoc) && tryLoc[0] )
        !           746:         location = tryLoc;
        !           747:     else
        !           748:         location = NULL;
        !           749: 
        !           750:     if( FindStringKey( configData, "\"Matching\"", tryMatch)) {
        !           751: 
        !           752:         while( (ioDevice = [IOTreeDevice findMatchingDevice:tryMatch location:location]) ) {
        !           753:            // Start the driver on all matching devices
        !           754:             [ioDevice taken:YES];
        !           755:             [[ioDevice propertyTable] addConfigData:configData];
        !           756: #if DEBUG
        !           757:            kprintf("---- Driver probe on device %s\n", [ioDevice nodeName] );
        !           758: #endif
        !           759:             ret = StartDriver( [ioDevice configTable], ioDevice );
        !           760: 
        !           761:            if( NO == ret) {
        !           762:                numFailed++;
        !           763:                failedList = realloc( failedList, numFailed * sizeof( id));
        !           764:                if( failedList)
        !           765:                    failedList[ numFailed - 1 ] = ioDevice;
        !           766:            }
        !           767:         }
        !           768:        if( failedList) {
        !           769:             for( i = 0; i < numFailed; i++ )
        !           770:                 [failedList[ i ] taken:NO];
        !           771:            free( failedList );
        !           772:        }
        !           773: 
        !           774:     } else {
        !           775:        configTable = [IOConfigTable newForConfigData:configData];
        !           776:         if( configTable) {
        !           777:             ret = StartDriver( configTable, nil );
        !           778:             if( ret == NO)
        !           779:                 [configTable free];
        !           780:         }
        !           781:     }
        !           782: 
        !           783:     IOFree( tryMatch, kStringSize * 2);
        !           784:     return( ret);
        !           785: }
        !           786: 
        !           787: static int
        !           788: MatchDriversForDevice( id ioDevice )
        !           789: {
        !           790:     int                                i, propLen;
        !           791:     void       *               prop;
        !           792:     int                                priority = DEFAULT_LOAD_PRI;
        !           793:     BOOL                       found;
        !           794:     const char *               configData;
        !           795:     IOPropertyTable    *       propTable = [ioDevice propertyTable];
        !           796:     char *                     tryMatch;
        !           797:     char *                     tryLoc;
        !           798:     char *                     location;
        !           799:     enum {                     kStringSize = 128 };
        !           800: 
        !           801:     tryMatch = IOMalloc( kStringSize * 2);
        !           802:     if( ! tryMatch)
        !           803:        return( -1);
        !           804:     tryLoc = tryMatch + kStringSize;
        !           805: 
        !           806:     found = NO; // NDRVForDevice( ioDevice);
        !           807: 
        !           808:     // look in tree for priority
        !           809:     propLen = sizeof( priority);
        !           810:     prop = &priority;
        !           811:     if( [propTable getProperty:"AAPL,load-priority"
        !           812:             flags:0 value:&prop length:&propLen] ) {
        !           813:        // else defaults - different for ndrv's
        !           814:        if( found)
        !           815:             priority = DISPLAY_LOAD_PRI;
        !           816:        else
        !           817:             priority = DEFAULT_LOAD_PRI;
        !           818:     }
        !           819: 
        !           820:     // look for a native XXXKit driver...
        !           821:     for( i = 1; (NO == found) && (configData = findBootConfigString(i)); i++ ) {
        !           822: 
        !           823:         if( FindStringKey( configData, "\"Location\"", tryLoc) && tryLoc[0] )
        !           824:            location = tryLoc;
        !           825:        else
        !           826:            location = NULL;
        !           827: 
        !           828:         if( FindStringKey( configData, "\"Matching\"", tryMatch)) {
        !           829:             if( (found = [ioDevice match:tryMatch location:location])) {
        !           830: 
        !           831:                 [propTable addConfigData:configData];
        !           832:                 // look in driver table for priority - overrides tree
        !           833:                 if( FindStringKey( configData, "\"Load Priority\"", tryMatch))
        !           834:                     priority = strtol( tryMatch, 0, 10);
        !           835:             }
        !           836:         }
        !           837:     }
        !           838:     if( found)
        !           839:         [ioDevice taken:YES];
        !           840: 
        !           841:     IOFree( tryMatch, kStringSize * 2);
        !           842:     return( found ? priority : (-1));
        !           843: }
        !           844: 
        !           845: 
        !           846: 
        !           847: /*
        !           848:  *  Configure a driver based on some config information.  This is really just
        !           849:  *  a wrapper around configureDriver that runs in its own thread, and needs to
        !           850:  *  be called in the IOTask context.
        !           851:  */
        !           852: void
        !           853: configureThread(struct probeDriverArgs *args)
        !           854: {
        !           855: 
        !           856:        args->rtn = NewLoadDriver(args->configData);
        !           857:        
        !           858:        /*
        !           859:         * Notify parent that we're finished, then terminate.
        !           860:         */
        !           861:        [args->waitLock lock];
        !           862:        [args->waitLock unlockWith:YES];
        !           863:        IOExitThread();
        !           864: }
        !           865: 
        !           866: /*
        !           867:  * Perform machine dependent hardware probe/config.
        !           868:  */
        !           869: void probeHardware(void)
        !           870: {
        !           871:        /* nope */
        !           872: }
        !           873: 
        !           874: /*
        !           875:  * Start up all non-native direct drivers. Called after probeHardware(). 
        !           876:  */
        !           877: void probeDirectDevices(void)
        !           878: {
        !           879:        /* nope */
        !           880: }
        !           881: 
        !           882: /*
        !           883:  * Obtain n'th boot config table.
        !           884:  */
        !           885: const char *findBootConfigString(int n)
        !           886: {
        !           887:     if( n < numConfigTables)
        !           888:        return( allConfigTables[ n ]);
        !           889:     else
        !           890:        return( NULL);
        !           891: }
        !           892: 
        !           893: static char *
        !           894: FindStringKey( const char * config, const char * key, char * value )
        !           895: {
        !           896:     char       * match;
        !           897:     char       * prop;
        !           898:     char       * end;
        !           899: 
        !           900:     do {
        !           901:         match = strstr( config, key );
        !           902:         if( match == NULL)
        !           903:             continue;
        !           904:         prop = strchr( match + strlen( key ), '\"');
        !           905:         if( prop == NULL)
        !           906:             continue;
        !           907:         prop++;
        !           908:         end = strchr( prop, '\"');
        !           909:         if( end == NULL)
        !           910:             continue;
        !           911: 
        !           912:         strncpy( value, prop, end - prop);
        !           913:         value[ end - prop ] = 0;
        !           914:         return( value);
        !           915: 
        !           916:     } while( NO);
        !           917: 
        !           918:     return( NULL);
        !           919: }
        !           920: 
        !           921: 
        !           922: /*
        !           923:  * Make a list of config tables in the kernel and loaded by the booter.
        !           924:  * Register objective-C code loaded by the booter.
        !           925:  */
        !           926: 
        !           927: static void
        !           928: bootDriverInit(void)
        !           929: {
        !           930:     IOReturn           err;
        !           931:     DTEntry            rootEntry, dtEntry;
        !           932:     DTEntryIterator    dtIter;
        !           933:     int                        i, size, allocedTables;
        !           934:     char       *       prop;
        !           935:     char       *       bundleName;
        !           936:     void       **      module;
        !           937:     char       *       nextTable;
        !           938: 
        !           939:     if( (kSuccess != DTLookupEntry( 0, "/AAPL,loadables", &rootEntry))
        !           940:     ||  (kSuccess != DTCreateEntryIterator ( rootEntry, &dtIter)))
        !           941: 
        !           942:        dtIter = NULL;
        !           943: 
        !           944:     for( i = 0; i < 2; i++) {
        !           945:         numConfigTables = 1;           // System assumed
        !           946:         if( dtIter) while( kSuccess == DTIterateEntries( dtIter, &dtEntry)) {
        !           947: 
        !           948:             // look for reloc on second pass
        !           949:             if(   allConfigTables
        !           950:                         && (kSuccess == DTGetProperty( dtEntry, "_reloc", &module, &size ))
        !           951:                         && (size == sizeof( void *)) ) {
        !           952: 
        !           953:                 err = objc_registerModule( *module, 0);
        !           954: #if DEBUG
        !           955:                 kprintf("Registered objc @ %x\n", *module);
        !           956: #endif
        !           957:             }
        !           958: 
        !           959:             if( kSuccess != DTGetProperty( dtEntry, "name", &bundleName, &size ))
        !           960:                 continue;
        !           961:             if( (kSuccess != DTGetProperty( dtEntry, "Instance0.table", &prop, &size ))
        !           962:             &&  (kSuccess != DTGetProperty( dtEntry, "Default.table", &prop, &size )) )
        !           963:                 continue;
        !           964: 
        !           965:             if( 0 == strcmp( "System", bundleName)) {
        !           966:                 if( allConfigTables)
        !           967:                     allConfigTables[ 0 ] = prop;
        !           968: 
        !           969:             } else for(     nextTable = prop;
        !           970:                             (nextTable - prop) < size;
        !           971:                             nextTable = nextTable + strlen( nextTable) + 1) {
        !           972:                 if( allConfigTables && (numConfigTables < allocedTables))
        !           973:                     allConfigTables[ numConfigTables ] = (char *) nextTable;
        !           974:                 numConfigTables++;
        !           975:             }
        !           976:         }
        !           977: 
        !           978:         // now the linked in kernel tables
        !           979:         for(    nextTable = inKernelConfigTables;
        !           980:                 *nextTable;
        !           981:                 nextTable = nextTable + strlen( nextTable) + 1) {
        !           982:             if( allConfigTables && (numConfigTables < allocedTables))
        !           983:                 allConfigTables[ numConfigTables ] = (char *) nextTable;
        !           984:             numConfigTables++;
        !           985:         }
        !           986: 
        !           987:         // allocate for second pass
        !           988:         if( nil == allConfigTables) {
        !           989:             allocedTables = numConfigTables;
        !           990:             allConfigTables = IOMalloc( allocedTables * sizeof( char *));
        !           991:             if( allConfigTables)
        !           992:                 bzero( allConfigTables, allocedTables * sizeof( char *));
        !           993:             if( dtIter)
        !           994:                 DTRestartEntryIteration( dtIter);
        !           995:         }
        !           996:     }
        !           997:     if( dtIter)
        !           998:         DTDisposeEntryIterator( dtIter);
        !           999: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.