Annotation of kernel/driverkit/autoconfCommon.m, revision 1.1.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: /*     Copyright (c) 1991 NeXT Computer, Inc.  All rights reserved. 
                     26:  *
                     27:  * autoconfCommon.m - machine-independent driverkit-style 
                     28:  *                   autoconfiguration routines.
                     29:  *
                     30:  * HISTORY
                     31:  * 23-Jan-93    Doug Mitchell at NeXT
                     32:  *      Created.
                     33:  */
                     34: 
                     35: #import <mach/mach_types.h>
                     36: 
                     37: #import <driverkit/autoconfCommon.h>
                     38: #import <driverkit/Device_ddm.h>
                     39: #import <driverkit/generalFuncs.h>
                     40: #import <driverkit/kernelDriver.h>
                     41: #import <machkit/NXLock.h>
                     42: #import <driverkit/driverTypes.h>
                     43: #import <driverkit/volCheck.h>
                     44: 
                     45: #import <vm/vm_kern.h>
                     46: 
                     47: #import <sys/param.h>
                     48: #import <sys/proc.h>
                     49: #import <sys/user.h>
                     50: #import <sys/buf.h>
                     51: #import <sys/systm.h>
                     52: #import <dev/busvar.h>
                     53: 
                     54: extern task_t IOTask_kern;           // kernel internal version of IOTask
                     55: extern port_t IOTask;               // IOTask port name in IOTask space.
                     56: 
                     57: /*
                     58:  * Static data.
                     59:  */
                     60: static id autoconfLock;
                     61: 
                     62: /*
                     63:  * Static routines.
                     64:  */
                     65: static void registerIndirClasses();
                     66: static void autoconfInt();
                     67: static void probePseudoDevices();
                     68: 
                     69: /* Forward declaration */
                     70: extern port_name_t _io_task_get_port(void *kport);
                     71: 
                     72: /*
                     73:  * Top-level autoconf routine.
                     74:  */
                     75: void autoconf(void)
                     76: {
                     77:        struct pseudo_init *pi;
                     78:        static void IOTaskInit(void);
                     79: 
                     80:        xpr_conf("autoconf\n", 1,2,3,4,5);
                     81:        IOTaskInit();
                     82:        IOInitGeneralFuncs();
                     83:        volCheckInit();
                     84:        xpr_conf("autoconf: libIO initialized\n", 1,2,3,4,5);
                     85: 
                     86:        /* 
                     87:         * Early startup for bsd pseudodevices.
                     88:         */
                     89:        for (pi = pseudo_inits; pi->ps_func; pi++)
                     90:                (*pi->ps_func) (pi->ps_count);
                     91: 
                     92:        /*
                     93:         * Set up a lock so we know when autoconf is complete.
                     94:         */
                     95:        autoconfLock = [NXConditionLock alloc];
                     96:        [autoconfLock initWith:NO];
                     97:        xpr_conf("autoconf: forking off thread\n", 1,2,3,4,5);
                     98:        
                     99:        /*
                    100:         * Note since we are not currently in the IOTask context, we
                    101:         * can't use IOForkThread.
                    102:         */
                    103:        kernel_thread(IOTask_kern, autoconfInt, (void *)0);
                    104:        [autoconfLock lockWhen:YES];
                    105:        [autoconfLock free];
                    106: }
                    107: 
                    108: /*
                    109:  * One-time only init for this module. 
                    110:  */
                    111: #ifdef i386
                    112: extern queue_head_t dmaBufQueue;
                    113: #endif i386
                    114: 
                    115: static void IOTaskInit(void)
                    116: {
                    117:        kern_return_t krtn;
                    118:        extern task_t           IOTask_kern;
                    119:        extern port_name_t      IOTask;
                    120: 
                    121: #ifdef i386
                    122:        queue_init(&dmaBufQueue);
                    123: #endif i386    
                    124: 
                    125:        /*
                    126:         * Start up IOTask. No threads needed yet, just the task.
                    127:         */
                    128: #undef task_create
                    129:        krtn = task_create(kernel_task, 
                    130:                FALSE,
                    131:                &IOTask_kern);
                    132:        if(krtn != KERN_SUCCESS) {
                    133:                IOLog("IOLibIOInit task_create returned %d\n", krtn);
                    134:                return;
                    135:        }
                    136:        task_deallocate(IOTask_kern); // extra ref for convert_task_to_port()
                    137:        (void) vm_map_deallocate(IOTask_kern->map);
                    138:        IOTask_kern->map = kernel_map;
                    139:        
                    140:        /*
                    141:         * This allows use of mach RPCs as if from user space, while running
                    142:         * in the kernel's pmap.
                    143:         */
                    144:        IOTask_kern->kernel_vm_space = TRUE;
                    145:        
                    146:        IOTask_kern->proc = kernproc;
                    147:        
                    148:        (void) processor_set_policy_enable(&default_pset, POLICY_FIXEDPRI);
                    149:        
                    150:        /*
                    151:         * Get IOTask's task port in its own IPC space. 
                    152:         */
                    153:        IOTask = _io_task_get_port(IOTask_kern->itk_sself);
                    154: }
                    155: 
                    156: void *_io_vm_task_buf(
                    157:        struct buf      *bp
                    158: )
                    159: {
                    160:        task_t          task;
                    161: 
                    162:        if((bp->b_flags & (B_PHYS|B_KERNSPACE)) == B_PHYS) {
                    163:                /*
                    164:                 * Physical I/O to user space.
                    165:                 */
                    166:                task = bp->b_proc->task;
                    167:        }
                    168:        else {
                    169:                /*
                    170:                 * Either block I/O (always kernel space) or physical I/O
                    171:                 * to kernel space (e.g., loadable file system).
                    172:                 */
                    173:                task = IOTask_kern;
                    174:        }
                    175: 
                    176:        return task->map;
                    177: }
                    178: 
                    179: void *_io_vm_task_self(void)
                    180: {
                    181:        return (IOTask_kern->map);
                    182: }
                    183: 
                    184: void *_io_vm_task_current(void)
                    185: {
                    186:        return (current_task()->map);
                    187: }
                    188: 
                    189: void *_io_vm_task(
                    190:        task_t          task
                    191: )
                    192: {
                    193:        return (task->map);
                    194: }
                    195: 
                    196: void *_io_vm_task_pmap(
                    197:        vm_map_t        map
                    198: )
                    199: {
                    200:        return (vm_map_pmap(map));
                    201: }
                    202: 
                    203: port_name_t _io_task_get_port(
                    204:     void *             kport
                    205: )
                    206: {
                    207:        /* External references to the mach system */
                    208:        extern void port_reference();
                    209:        extern void object_copyout();
                    210: 
                    211:        port_name_t     port_name;
                    212: 
                    213:        port_reference(kport);
                    214:        object_copyout(IOTask_kern,
                    215:                kport,
                    216:                MSG_TYPE_PORT,
                    217:                &port_name);
                    218: 
                    219:        return (port_name);
                    220: }
                    221: 
                    222: void *_io_get_kern_port(
                    223:     port_name_t                port
                    224: )
                    225: {
                    226:        /* External references to the mach system */
                    227:        extern boolean_t object_copyin();
                    228: 
                    229:        void *          kport;
                    230: 
                    231:        if (!object_copyin(IOTask_kern,
                    232:                                port,
                    233:                                MSG_TYPE_PORT,
                    234:                                FALSE,
                    235:                                &kport))
                    236:                return (0);
                    237:                
                    238:        return (kport);
                    239: }
                    240: 
                    241: void *_io_convert_port_in(
                    242:     port_name_t                port
                    243: )
                    244: {
                    245:        /* External references to the mach system */
                    246:        extern boolean_t object_copyin();
                    247: 
                    248:        void *          kport;
                    249: 
                    250:        if (!object_copyin(current_task(),
                    251:                                port,
                    252:                                MSG_TYPE_PORT,
                    253:                                FALSE,
                    254:                                &kport))
                    255:                return (0);
                    256:                
                    257:        return (kport);
                    258: }
                    259: 
                    260: port_name_t _io_convert_port_out(
                    261:     void               *kport
                    262: )
                    263: {
                    264:        /* External references to the mach system */
                    265:        extern void port_reference();
                    266:        extern void object_copyout();
                    267: 
                    268:        port_name_t     port_name;
                    269: 
                    270:        port_reference(kport);
                    271:        object_copyout(current_task(),
                    272:                        kport,
                    273:                        MSG_TYPE_PORT,
                    274:                        &port_name);
                    275:                        
                    276:        return (port_name);
                    277: }
                    278: 
                    279: port_t _io_host_priv_self(void)
                    280: {
                    281:        return _io_convert_port_out((void *)realhost.host_priv_self);
                    282: }
                    283: 
                    284: /*
                    285:  * This rest of this module runs as a thread in IOTask to allow for 
                    286:  * each driver's startup code to execute in an IOTask thread context, 
                    287:  * so standard Mach calls can be executed during probe.
                    288:  * 
                    289:  * Note that all of the +probe: calls below may result in indirect classes
                    290:  * being probed via IODevice's +connectToIndirectDevices method.
                    291:  */
                    292: 
                    293: static void autoconfInt(void)
                    294: {
                    295:        
                    296:        xpr_conf("autoconf_int: starting\n", 1,2,3,4,5);
                    297:                  
                    298:        /*
                    299:         * Register indirect device classes.
                    300:         */
                    301:        registerIndirClasses();
                    302:        
                    303:        /*
                    304:         * Start up drivers for native devices.
                    305:         */
                    306:        probeNativeDevices();
                    307:          
                    308:        /*
                    309:         * Perform machine dependent hardware probe/config.
                    310:         */
                    311:        probeHardware();
                    312:        
                    313:        /*
                    314:         * Start up non-native direct drivers.
                    315:         */
                    316:        probeDirectDevices();
                    317:        
                    318:        /*
                    319:         * Start up pseuododevices.
                    320:         */
                    321:        probePseudoDevices();
                    322:        
                    323:        /*
                    324:         * Notify parent that we're finished, then terminate.
                    325:         */
                    326:        [autoconfLock lock];
                    327:        [autoconfLock unlockWith:YES];
                    328:        IOExitThread();
                    329: }
                    330: 
                    331: static void registerIndirClasses(void)
                    332: {
                    333:        char    **indClassName = indirectDevList;
                    334:        id      indClassId;
                    335:        for(indClassName=indirectDevList; 
                    336:            *indClassName;
                    337:            indClassName++) {
                    338:                indClassId = objc_getClass(*indClassName);
                    339:                if(indClassId == nil) {
                    340:                        IOLog("registerIndirectClasses: Class %s does not "
                    341:                                "exist\n", *indClassName);
                    342:                        continue;
                    343:                }
                    344:                /*
                    345:                 * Objc runtime does an +initialize on the class here; the 
                    346:                 * class must call registerClass at that time.
                    347:                 */
                    348:                xpr_conf("init'ing indirect class %s\n", *indClassName,
                    349:                        2,3,4,5);
                    350:                [indClassId name];
                    351:        }
                    352: }
                    353: 
                    354: static void probePseudoDevices(void)
                    355: {
                    356:        char                    **pseudoClassName;
                    357:        id                      driverClass;
                    358:                        
                    359:        for(pseudoClassName = pseudoDevList;
                    360:            *pseudoClassName;
                    361:            pseudoClassName++) {
                    362:                xpr_conf("pseudo dev %s found\n",
                    363:                        *pseudoClassName, 2,3,4,5);
                    364:                driverClass = objc_getClass(*pseudoClassName);
                    365:                if(driverClass == nil) {
                    366:                        IOLog("probePseudoDevices: class %s not found\n",
                    367:                                *pseudoClassName);
                    368:                        continue;
                    369:                }
                    370:                [IODevice addLoadedClass:driverClass
                    371:                        description:nil];       
                    372:        }
                    373: }
                    374: 
                    375: #import <driverkit/IODeviceParams.h>
                    376: #import <driverkit/IOPower.h>
                    377: 
                    378: static void
                    379: 
                    380: _io_sendPowerMessage(
                    381:     SEL selector,
                    382:     void *arg
                    383: )
                    384: {
                    385:     IOObjectNumber i = 0;
                    386:     id driverObject;
                    387:     IOReturn rtn;
                    388:     
                    389:     /* Look for devices that conform to IOPower protocol */
                    390:     while ((rtn = [IODevice lookupByObjectNumber:i++
                    391:                            instance:&driverObject]) != IO_R_NO_DEVICE) {
                    392:        if (rtn == IO_R_OFFLINE)
                    393:            continue;
                    394:        if ([[driverObject class] conformsTo:@protocol(IOPower)]) {
                    395:            [driverObject perform:selector with:arg];
                    396:        }
                    397:     }
                    398: }
                    399: 
                    400: 
                    401: void
                    402: _io_setDriverPowerState(
                    403:     PMPowerState state
                    404: )
                    405: {
                    406:     _io_sendPowerMessage(@selector(setPowerState:), (void *)state);
                    407: }
                    408: 
                    409: void
                    410: _ioSetDriverPowerManagementState(
                    411:     PMPowerManagementState state
                    412: )
                    413: {
                    414:     _io_sendPowerMessage(@selector(setPowerManagement:), (void *)state);
                    415: }
                    416: 

unix.superglobalmegacorp.com

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