Annotation of driverkit/libDriver/Kernel/audio_kern_server.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:  * audio_kern_server.m
        !            26:  *
        !            27:  * Copyright (c) 1993, NeXT Computer, Inc.  All rights reserved.
        !            28:  *
        !            29:  */
        !            30: 
        !            31: #import <mach/mach_types.h>
        !            32: #import <kern/lock.h>
        !            33: #import <kernserv/kern_server_types.h>
        !            34: #import <kernserv/prototypes.h>
        !            35: #import <kernserv/kern_server_reply.h>
        !            36: #import <driverkit/kernelDriver.h>
        !            37: #import <driverkit/generalFuncs.h>
        !            38: #import "audio_server.h"
        !            39: #import "snd_server.h"
        !            40: #import "audio_kern_server.h"
        !            41: 
        !            42: /*
        !            43:  * definitions for audioMessages
        !            44:  */
        !            45: #define SERVER_SEND_OPTIONS    SEND_TIMEOUT
        !            46: #define SERVER_SEND_TIMEOUT    1000
        !            47: 
        !            48: /*
        !            49:  * for IOAudio instance
        !            50:  */
        !            51: #import <driverkit/IOAudioPrivate.h>
        !            52: 
        !            53: /*
        !            54:  * imported for handleControl
        !            55:  */
        !            56: #import <audio/audio_msgs.h>
        !            57: #import "portFuncs.h"
        !            58: 
        !            59: /*
        !            60:  * imported for snd_server
        !            61:  */
        !            62: #import <bsd/dev/snd_msgs.h>
        !            63: #import "snd_reply.h"
        !            64: 
        !            65: #import <mach/mig_errors.h>                    // death_pill_t
        !            66: 
        !            67: /*
        !            68:  * declaration for createAudioPorts()
        !            69:  */
        !            70: void audioMessages(msg_header_t *in_msg, msg_header_t *out_msg);
        !            71: 
        !            72: /*
        !            73:  * these are initialized at load time but not used until after
        !            74:  * the device is probed.
        !            75:  */
        !            76: port_t outPort = PORT_NULL, inPort = PORT_NULL, sndPort = PORT_NULL;
        !            77: 
        !            78: static kern_server_t   *instance;      /* kernserv instance */
        !            79: 
        !            80: /*
        !            81:  * Allocate user message listen ports.
        !            82:  */
        !            83: static void createAudioPorts()
        !            84: {
        !            85:     kern_return_t      krtn;
        !            86:     
        !            87:     /*
        !            88:      * Kern_server passes the last argument of kern_serv_port_serv()
        !            89:      * as the first argument to the MIG-generated interface
        !            90:      * functions (in audio_server.m).  In this case, it is the
        !            91:      * port the message was received on.
        !            92:      */
        !            93:     
        !            94:     outPort = allocatePort();
        !            95:     krtn = kern_serv_port_serv(instance, outPort,
        !            96:                               (port_map_proc_t) audioMessages, outPort);
        !            97:     if (krtn != KERN_SUCCESS) 
        !            98:        IOLog("Audio: createAudioPorts error %d\n", krtn);
        !            99:     
        !           100:     inPort = allocatePort();
        !           101:     krtn = kern_serv_port_serv(instance, inPort,
        !           102:                               (port_map_proc_t) audioMessages, inPort);
        !           103:     if (krtn != KERN_SUCCESS) 
        !           104:        IOLog("Audio: createAudioPorts error %d\n", krtn);
        !           105:     
        !           106:     sndPort = allocatePort();
        !           107:     krtn = kern_serv_port_serv(instance, sndPort,
        !           108:                               (port_map_proc_t) audioMessages, sndPort);
        !           109:     if (krtn != KERN_SUCCESS) 
        !           110:        IOLog("Audio: createAudioPorts error %d\n", krtn);
        !           111: }
        !           112: 
        !           113: /*
        !           114:  * Called when an audio driver instance is initialized.
        !           115:  */
        !           116: void audioKernServInit(kern_server_t *instance_var)
        !           117: {
        !           118: #ifdef DEBUG
        !           119:     IOLog("Audio server loaded, inst=0x%x\n", (unsigned int)instance_var);
        !           120: #endif DEBUG
        !           121: 
        !           122:     instance = instance_var;
        !           123: }
        !           124: 
        !           125: 
        !           126: /*
        !           127:  * Register stream port - exported for Audio.
        !           128:  */
        !           129: boolean_t audio_enroll_stream_port(port_t stream_port, boolean_t enroll)
        !           130: {
        !           131:     kern_return_t      krtn;
        !           132:     
        !           133:     if (enroll) {
        !           134:        krtn = kern_serv_port_serv(instance, stream_port,
        !           135:            (port_map_proc_t) audioMessages, stream_port);
        !           136:        if (krtn != KERN_SUCCESS)
        !           137:            IOLog("Audio: kern_serv_port_serv returns %d\n", krtn);
        !           138:     } else {
        !           139:         kern_serv_port_gone(instance, stream_port);
        !           140:        krtn = KERN_SUCCESS;
        !           141:     }
        !           142: 
        !           143:     return (krtn == KERN_SUCCESS ? TRUE : FALSE);
        !           144: }
        !           145: 
        !           146: /*
        !           147:  * Realloc just the snd device port - exported for snd_server.m.
        !           148:  */
        !           149: port_t audio_reset_snd_dev_port(IOAudio *dev, port_t priv_port)
        !           150: {
        !           151:     port_t kern_port, sndPort;
        !           152: 
        !           153:     if ((kern_port = IOHostPrivSelf()) == PORT_NULL) {
        !           154:        IOLog("Audio: cannot get kernel port (must run as root)\n");
        !           155:        IOLog("reset_snd_dev_port");
        !           156:     }
        !           157:     if (priv_port != kern_port)
        !           158:        return PORT_NULL;
        !           159: 
        !           160:     /* snd input and output share the same user port */
        !           161:     deallocatePort([[dev _outputChannel] userSndPort]);
        !           162:     sndPort = allocatePort();
        !           163:     [[dev _inputChannel] setUserSndPort:sndPort];
        !           164:     [[dev _outputChannel] setUserSndPort:sndPort];
        !           165: 
        !           166:     return sndPort;
        !           167: }
        !           168: 
        !           169: /*
        !           170:  * Handle privileged control message.
        !           171:  */
        !           172: static boolean_t handleControl(msg_header_t *in_msg,
        !           173:                                msg_header_t *out_msg)
        !           174: {
        !           175:     audio_get_ports_t *get_ports = (audio_get_ports_t *)in_msg;
        !           176:     audio_ret_ports_t *ret_ports = (audio_ret_ports_t *)out_msg;
        !           177:     port_t kern_port;
        !           178:     
        !           179:     IOAudio            *dev = [IOAudio _instance];
        !           180:     static boolean_t   initialized = FALSE;
        !           181: 
        !           182:     /*
        !           183:      * Standard reply header.
        !           184:      */
        !           185:     out_msg->msg_simple = TRUE;
        !           186:     out_msg->msg_size = sizeof(msg_header_t);
        !           187:     out_msg->msg_type = MSG_TYPE_NORMAL;
        !           188:     out_msg->msg_local_port = PORT_NULL;
        !           189:     out_msg->msg_remote_port = in_msg->msg_remote_port;
        !           190:     out_msg->msg_id = 0;
        !           191: 
        !           192:     if (in_msg->msg_id != AUDIO_MSG_GET_PORTS)
        !           193:        return FALSE;
        !           194: 
        !           195:     /*
        !           196:      * If the IOAudio instance fails to load, the control ports are
        !           197:      * never returned. The kernel server instance variable is guaranteed to
        !           198:      * be set when an audio device is successfully instantiated.
        !           199:      */
        !           200:     if (dev == nil)
        !           201:         return TRUE;
        !           202: 
        !           203:     if (! initialized) {
        !           204:        kern_serv_port_death_proc(instance,
        !           205:            (port_death_proc_t)audio_port_gone);
        !           206:        createAudioPorts();
        !           207:        initialized = TRUE;
        !           208:     }
        !           209:        
        !           210:     out_msg->msg_simple = FALSE;
        !           211:     out_msg->msg_size = sizeof(audio_ret_ports_t);
        !           212:     out_msg->msg_id = AUDIO_MSG_RET_PORTS;
        !           213:     ret_ports->portsType.msg_type_name = MSG_TYPE_PORT;
        !           214:     ret_ports->portsType.msg_type_size = 32;
        !           215:     ret_ports->portsType.msg_type_number = 3;
        !           216:     ret_ports->portsType.msg_type_inline = TRUE;
        !           217:     ret_ports->portsType.msg_type_longform = FALSE;
        !           218:     ret_ports->portsType.msg_type_deallocate = FALSE;
        !           219:     ret_ports->portsType.msg_type_unused = 0;
        !           220: 
        !           221:     if ((kern_port = IOHostPrivSelf()) == PORT_NULL) {
        !           222:        IOLog("Audio: cannot get kernel port (must run as root)\n");
        !           223:        return TRUE;
        !           224:     }
        !           225:     
        !           226:     if (get_ports->priv != kern_port) {
        !           227:     
        !           228: #ifdef DEBUG
        !           229:         IOLog("handleControl: returning NULL ports\n");
        !           230: #endif DEBUG
        !           231: 
        !           232:        ret_ports->inputPort = PORT_NULL;
        !           233:        ret_ports->outputPort = PORT_NULL;
        !           234:        ret_ports->sndPort = PORT_NULL;
        !           235:     } else {
        !           236:        if (get_ports->reset) {
        !           237:        
        !           238: #ifdef DEBUG
        !           239:            IOLog("handleControl: resetting ports\n");
        !           240: #endif DEBUG
        !           241: 
        !           242:            if (inPort != PORT_NULL) {
        !           243:                kern_serv_port_gone(instance, inPort);
        !           244:                deallocatePort(inPort);
        !           245:            }
        !           246:            if (outPort != PORT_NULL) {
        !           247:                kern_serv_port_gone(instance, outPort);
        !           248:                deallocatePort(outPort);
        !           249:            }
        !           250:            /* snd input and output share the same user port */
        !           251:            if (sndPort != PORT_NULL) {
        !           252:                kern_serv_port_gone(instance, sndPort);
        !           253:                deallocatePort(sndPort);
        !           254:            }
        !           255:            createAudioPorts();
        !           256:        }
        !           257:        
        !           258:        ret_ports->inputPort = inPort;
        !           259:        ret_ports->outputPort = outPort;
        !           260:        ret_ports->sndPort = sndPort;
        !           261:        
        !           262: #ifdef DEBUG
        !           263:        IOLog("handleControl: returning ports %d %d %d\n",
        !           264:              ret_ports->inputPort, ret_ports->outputPort,
        !           265:              ret_ports->sndPort);
        !           266: #endif DEBUG
        !           267:     }
        !           268:     
        !           269:     [[dev _outputChannel] setUserChannelPort:outPort];
        !           270:     [[dev _outputChannel] setUserSndPort:sndPort];
        !           271:     [[dev _inputChannel] setUserChannelPort:inPort];
        !           272:     [[dev _inputChannel] setUserSndPort:sndPort];
        !           273: 
        !           274:     return TRUE;
        !           275: }
        !           276: 
        !           277: /*
        !           278:  * Called when messages arrive on registered ports
        !           279:  */
        !           280: void audioMessages(msg_header_t *in_msg, msg_header_t *out_msg)
        !           281: {
        !           282:     kern_return_t krtn;
        !           283:     
        !           284: #ifdef DEBUG
        !           285: //    IOLog("Audio: message received id: %d\n", in_msg->msg_id);
        !           286: #endif DEBUG
        !           287: 
        !           288:     if (in_msg->msg_local_port == 0) {
        !           289:        if (! (handleControl(in_msg, out_msg)))
        !           290:            IOLog("Audio: unrecognized control message %d\n",
        !           291:                  in_msg->msg_id);
        !           292:     } else if (in_msg->msg_id < AUDIO_USER_MSG_BASE) {
        !           293:        /*
        !           294:         * Handle old style SoundDSP driver message.
        !           295:         */
        !           296:        if (!snd_server(in_msg, out_msg))
        !           297:            IOLog("Audio: unrecognized snd user message %d\n",
        !           298:                        in_msg->msg_id);
        !           299:     } else {
        !           300:        /*
        !           301:         * Handle new style NXSoundDevice message.
        !           302:         */
        !           303:        if (!audio_server(in_msg, out_msg))
        !           304:            IOLog("Audio: unrecognized audio user message %d\n",
        !           305:                        in_msg->msg_id);
        !           306:     }
        !           307:     /*
        !           308:      * Send a reply message, even if error.
        !           309:      */
        !           310:     krtn = msg_send(out_msg, SERVER_SEND_OPTIONS, SERVER_SEND_TIMEOUT);
        !           311:     if (krtn != KERN_SUCCESS) {
        !           312:        IOLog("msg_send failed %d\n", krtn);
        !           313:     }
        !           314:     
        !           315:     /*
        !           316:      * Under normal circumstances, kernserv sends the reply message. In this 
        !           317:      * case, both the control and snd interfaces are not generated by MiG. We
        !           318:      * must send the response and then set MIG_NO_REPLY to prevent kernserv
        !           319:      * from sending a response on our behalf.
        !           320:      */
        !           321:     ((death_pill_t *)out_msg)->RetCode = MIG_NO_REPLY;
        !           322: }

unix.superglobalmegacorp.com

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