|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.