Annotation of driverkit/libDriver/Kernel/audio_kern_server.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:  * 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.