Merge remote-tracking branch 'origin/master'
[unleashed/lotheac.git] / usr / src / uts / common / io / audio / impl / audio_sun.c
blobcee3f6ace4008d3dbbcec778ee7d7f6d46ee32e5
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
22 * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
26 * Sun audio(7I) and mixer(7I) personality.
28 * There are some "undocumented" details of how legacy Sun audio
29 * interfaces work. The following "rules" were derived from reading the
30 * legacy Sun mixer code, and to the best of our knowledge are not
31 * documented elsewhere.
33 * - We create a "fake" audio device, which behaves like a classic
34 * exclusive audio device, for each PID, as determined during open(2).
36 * - Different processes don't interfere with each other. Even though
37 * they are running concurrently, they each think they have exclusive
38 * control over the audio device.
40 * - Read and write directions operate independent of each other. That
41 * is, a device open for reading won't intefere with a future open for
42 * writing, and vice versa. This is true even within the same process.
44 * - Because the virtualization is by PID, strange behavior may occur
45 * if a process tries to open an audio device at the same time it
46 * has already received a file descriptor from another process (such
47 * through inheritence via fork()).
49 * - The "fake" audio device has no control over physical settings.
50 * It sees only the software attenuation-based volumes for play and
51 * record, and has no support for alternate input or output ports or
52 * access to the monitoring features of the hardware.
54 * - Explicit notificaton signals (SIGPOLL) are only ever sent up the
55 * audioctl node -- never up a regular audio node. (The stream head
56 * may still issue SIGPOLL based on readability/writability of
57 * course.)
59 * - Corollary: processes that want asynch. notifications will open
60 * /dev/audioctl as well as /dev/audio.
62 * - We don't support the MIXER mode at all.
64 * - By corollary, a process is only allowed to open /dev/audio once
65 * (in each direction.)
67 * - Attempts to open /dev/audio in duplex mode (O_RDWR) fail (EBUSY)
68 * if the device cannot support duplex operation.
70 * - Attempts to open a device with FREAD set fail if the device is not
71 * capable of recording. (Likewise for FWRITE and playback.)
73 * - No data transfer is permitted for audioctl nodes. (No actual
74 * record or play.)
76 * - Sun audio does not support any formats other than linear and
77 * ULAW/ALAW. I.e. it will never support AC3 or other "opaque"
78 * streams which require special handling.
80 * - Sun audio only supports stereo or monophonic data streams.
83 #include <sys/types.h>
84 #include <sys/open.h>
85 #include <sys/errno.h>
86 #include <sys/audio.h>
87 #include <sys/mixer.h>
88 #include <sys/file.h>
89 #include <sys/stropts.h>
90 #include <sys/strsun.h>
91 #include <sys/sysmacros.h>
92 #include <sys/list.h>
93 #include <sys/note.h>
94 #include <sys/stat.h>
95 #include <sys/ddi.h>
96 #include <sys/sunddi.h>
97 #include "audio_client.h"
99 typedef struct daclient daclient_t;
100 typedef struct dadev dadev_t;
101 typedef struct daproc daproc_t;
103 /* common structure shared between both audioctl and audio nodes */
104 struct daclient {
105 daproc_t *dc_proc;
106 dadev_t *dc_dev;
107 audio_client_t *dc_client;
108 queue_t *dc_wq;
109 unsigned dc_eof;
110 list_t dc_eofcnt;
111 kmutex_t dc_lock;
112 mblk_t *dc_draining;
115 struct eofcnt {
116 list_node_t linkage;
117 uint64_t tail;
120 struct dadev {
121 audio_dev_t *d_dev;
123 list_t d_procs;
124 kmutex_t d_mx;
125 kcondvar_t d_cv;
128 struct daproc {
129 pid_t p_id;
130 struct audio_info p_info;
131 int p_refcnt;
132 int p_oflag;
133 list_node_t p_linkage;
134 dadev_t *p_dev;
135 audio_client_t *p_writer;
136 audio_client_t *p_reader;
139 int devaudio_proc_hold(audio_client_t *, int);
140 void devaudio_proc_release(audio_client_t *);
141 static void devaudio_proc_update(daproc_t *);
144 static int
145 devaudio_compose_format(audio_prinfo_t *prinfo)
147 switch (prinfo->precision) {
148 case 8:
149 switch (prinfo->encoding) {
150 case AUDIO_ENCODING_ULAW:
151 return (AUDIO_FORMAT_ULAW);
152 case AUDIO_ENCODING_ALAW:
153 return (AUDIO_FORMAT_ALAW);
154 case AUDIO_ENCODING_LINEAR8:
155 return (AUDIO_FORMAT_U8);
156 case AUDIO_ENCODING_LINEAR:
157 return (AUDIO_FORMAT_S8);
159 break;
160 case 16:
161 if (prinfo->encoding == AUDIO_ENCODING_LINEAR)
162 return (AUDIO_FORMAT_S16_NE);
163 break;
164 case 32:
165 if (prinfo->encoding == AUDIO_ENCODING_LINEAR)
166 return (AUDIO_FORMAT_S32_NE);
167 break;
169 return (AUDIO_FORMAT_NONE);
173 static void
174 devaudio_decompose_format(audio_prinfo_t *prinfo, int afmt)
176 int e, p;
179 * N.B.: Even though some of the formats below can't be set by
180 * this personality, reporting them (using the closest match)
181 * allows this personality to roughly approximate settings for
182 * other streams. It would be incredibly poor form for any
183 * personality to modify the format settings for a different
184 * personality, so we don't worry about that case.
187 switch (afmt) {
188 case AUDIO_FORMAT_ULAW:
189 e = AUDIO_ENCODING_ULAW;
190 p = 8;
191 break;
193 case AUDIO_FORMAT_ALAW:
194 e = AUDIO_ENCODING_ALAW;
195 p = 8;
196 break;
198 case AUDIO_FORMAT_U8:
199 e = AUDIO_ENCODING_LINEAR8;
200 p = 8;
201 break;
203 case AUDIO_FORMAT_S8:
204 e = AUDIO_ENCODING_LINEAR;
205 p = 8;
206 break;
208 case AUDIO_FORMAT_S16_NE:
209 case AUDIO_FORMAT_S16_OE:
210 case AUDIO_FORMAT_U16_NE:
211 case AUDIO_FORMAT_U16_OE:
212 e = AUDIO_ENCODING_LINEAR;
213 p = 16;
214 break;
216 case AUDIO_FORMAT_S24_NE:
217 case AUDIO_FORMAT_S24_OE:
218 case AUDIO_FORMAT_S24_PACKED:
219 e = AUDIO_ENCODING_LINEAR;
220 p = 24;
221 break;
223 case AUDIO_FORMAT_S32_NE:
224 case AUDIO_FORMAT_S32_OE:
225 e = AUDIO_ENCODING_LINEAR;
226 p = 32;
227 break;
229 default:
230 /* all other formats (e.g. AC3) are uninterpreted */
231 e = AUDIO_ENCODING_NONE;
232 p = 32;
233 break;
236 prinfo->encoding = e;
237 prinfo->precision = p;
240 static daproc_t *
241 devaudio_proc_alloc(audio_client_t *c)
243 audio_info_t *info;
244 audio_prinfo_t *prinfo;
245 uint32_t caps;
246 daproc_t *proc;
248 if ((proc = kmem_zalloc(sizeof (*proc), KM_NOSLEEP)) == NULL) {
249 return (NULL);
251 info = &proc->p_info;
254 * audio(7I) says: Upon the initial open() of the audio
255 * device, the driver resets the data format of the device to
256 * the default state of 8-bit, 8Khz, mono u-Law data.
258 prinfo = &info->play;
259 prinfo->channels = 1;
260 prinfo->sample_rate = 8000;
261 prinfo->encoding = AUDIO_ENCODING_ULAW;
262 prinfo->precision = 8;
263 prinfo->gain = AUDIO_MAX_GAIN;
264 prinfo->balance = AUDIO_MID_BALANCE;
265 prinfo->buffer_size = 8192;
266 prinfo->pause = B_FALSE;
267 prinfo->waiting = B_FALSE;
268 prinfo->open = B_FALSE;
269 prinfo->active = B_FALSE;
270 prinfo->samples = 0;
271 prinfo->eof = 0;
272 prinfo->error = 0;
273 prinfo->minordev = 0;
274 prinfo->port = AUDIO_SPEAKER;
275 prinfo->avail_ports = AUDIO_SPEAKER;
276 prinfo->mod_ports = AUDIO_NONE;
277 prinfo->_xxx = 0;
279 prinfo = &info->record;
280 prinfo->channels = 1;
281 prinfo->sample_rate = 8000;
282 prinfo->encoding = AUDIO_ENCODING_ULAW;
283 prinfo->precision = 8;
284 prinfo->gain = AUDIO_MAX_GAIN;
285 prinfo->balance = AUDIO_MID_BALANCE;
286 prinfo->buffer_size = 8192;
287 prinfo->waiting = B_FALSE;
288 prinfo->open = B_FALSE;
289 prinfo->active = B_FALSE;
290 prinfo->samples = 0;
291 prinfo->eof = 0;
292 prinfo->error = 0;
293 prinfo->minordev = 0;
294 prinfo->port = AUDIO_MICROPHONE;
295 prinfo->avail_ports = AUDIO_MICROPHONE;
296 prinfo->mod_ports = AUDIO_MICROPHONE;
298 info->output_muted = B_FALSE;
299 /* pretend we don't have a software mixer - we don't support the API */
300 info->hw_features = 0;
301 info->sw_features = 0;
302 info->sw_features_enabled = 0;
304 caps = auclnt_get_dev_capab(auclnt_get_dev(c));
305 if (caps & AUDIO_CLIENT_CAP_PLAY)
306 info->hw_features |= AUDIO_HWFEATURE_PLAY;
307 if (caps & AUDIO_CLIENT_CAP_RECORD)
308 info->hw_features |= AUDIO_HWFEATURE_RECORD;
309 if (caps & AUDIO_CLIENT_CAP_DUPLEX)
310 info->hw_features |= AUDIO_HWFEATURE_DUPLEX;
312 return (proc);
315 static void
316 devaudio_proc_free(daproc_t *proc)
318 kmem_free(proc, sizeof (*proc));
322 devaudio_proc_hold(audio_client_t *c, int oflag)
324 pid_t pid;
325 daproc_t *proc;
326 dadev_t *dev;
327 daclient_t *dc;
328 list_t *l;
329 audio_dev_t *adev;
330 int rv;
332 adev = auclnt_get_dev(c);
334 /* first allocate and initialize the daclient private data */
335 if ((dc = kmem_zalloc(sizeof (*dc), KM_NOSLEEP)) == NULL) {
336 return (ENOMEM);
339 mutex_init(&dc->dc_lock, NULL, MUTEX_DRIVER, NULL);
340 list_create(&dc->dc_eofcnt, sizeof (struct eofcnt),
341 offsetof(struct eofcnt, linkage));
342 auclnt_set_private(c, dc);
344 dev = auclnt_get_dev_minor_data(adev, AUDIO_MINOR_DEVAUDIO);
345 l = &dev->d_procs;
346 pid = auclnt_get_pid(c);
348 /* set a couple of common fields */
349 dc->dc_client = c;
350 dc->dc_dev = dev;
352 mutex_enter(&dev->d_mx);
353 for (proc = list_head(l); proc != NULL; proc = list_next(l, proc)) {
354 if (proc->p_id == pid) {
355 proc->p_refcnt++;
356 break;
359 if (proc == NULL) {
360 if ((proc = devaudio_proc_alloc(c)) == NULL) {
361 rv = ENOMEM;
362 goto failed;
364 proc->p_refcnt = 1;
365 proc->p_id = pid;
366 proc->p_dev = dev;
367 list_insert_tail(l, proc);
370 while (proc->p_oflag & oflag) {
372 if (oflag & (FNDELAY|FNONBLOCK)) {
373 rv = EBUSY;
374 goto failed;
376 if (oflag & FWRITE)
377 proc->p_info.play.waiting++;
378 if (oflag & FREAD)
379 proc->p_info.record.waiting++;
380 if (cv_wait_sig(&dev->d_cv, &dev->d_mx) == 0) {
381 /* interrupted! */
382 if (oflag & FWRITE)
383 proc->p_info.play.waiting--;
384 if (oflag & FREAD)
385 proc->p_info.record.waiting--;
386 rv = EINTR;
387 goto failed;
389 if (oflag & FWRITE)
390 proc->p_info.play.waiting--;
391 if (oflag & FREAD)
392 proc->p_info.record.waiting--;
395 if (oflag & FWRITE) {
396 audio_prinfo_t *play = &proc->p_info.play;
397 audio_stream_t *sp = auclnt_output_stream(c);
399 if (((rv = auclnt_set_rate(sp, 8000)) != 0) ||
400 ((rv = auclnt_set_format(sp, AUDIO_FORMAT_ULAW)) != 0) ||
401 ((rv = auclnt_set_channels(sp, 1)) != 0)) {
402 goto failed;
405 auclnt_set_samples(sp, 0);
406 auclnt_set_errors(sp, 0);
407 play->eof = 0;
408 play->buffer_size = 8192;
410 auclnt_set_gain(sp, ((play->gain * 100) / AUDIO_MAX_GAIN));
411 auclnt_set_muted(sp, proc->p_info.output_muted);
412 play->open = B_TRUE;
413 proc->p_writer = c;
414 proc->p_oflag |= FWRITE;
417 if (oflag & FREAD) {
418 audio_prinfo_t *rec = &proc->p_info.record;
419 audio_stream_t *sp = auclnt_input_stream(c);
421 if (((rv = auclnt_set_rate(sp, 8000)) != 0) ||
422 ((rv = auclnt_set_format(sp, AUDIO_FORMAT_ULAW)) != 0) ||
423 ((rv = auclnt_set_channels(sp, 1)) != 0)) {
424 goto failed;
427 auclnt_set_samples(sp, 0);
428 auclnt_set_errors(sp, 0);
429 rec->eof = 0;
430 rec->buffer_size = 8192;
432 auclnt_set_gain(sp, ((rec->gain * 100) / AUDIO_MAX_GAIN));
433 rec->open = B_TRUE;
434 proc->p_reader = c;
435 proc->p_oflag |= FREAD;
439 dc->dc_wq = auclnt_get_wq(c);
441 /* we update the s_proc last to avoid a race */
442 dc->dc_proc = proc;
444 devaudio_proc_update(proc);
446 mutex_exit(&dev->d_mx);
448 return (0);
450 failed:
451 mutex_exit(&dev->d_mx);
452 devaudio_proc_release(c);
453 return (rv);
457 static void
458 devaudio_clear_eof(audio_client_t *c)
460 struct eofcnt *eof;
461 daclient_t *dc;
463 dc = auclnt_get_private(c);
464 mutex_enter(&dc->dc_lock);
465 while ((eof = list_remove_head(&dc->dc_eofcnt)) != NULL) {
466 kmem_free(eof, sizeof (*eof));
468 mutex_exit(&dc->dc_lock);
471 void
472 devaudio_proc_release(audio_client_t *c)
474 daproc_t *proc;
475 dadev_t *dev;
476 mblk_t *mp;
477 daclient_t *dc;
479 dc = auclnt_get_private(c);
480 proc = dc->dc_proc;
481 dev = dc->dc_dev;
482 dc->dc_proc = NULL;
484 mutex_enter(&dev->d_mx);
486 if (proc != NULL) {
487 proc->p_refcnt--;
488 ASSERT(proc->p_refcnt >= 0);
490 if (c == proc->p_writer) {
491 proc->p_oflag &= ~FWRITE;
492 proc->p_writer = NULL;
494 if (c == proc->p_reader) {
495 proc->p_oflag &= ~FREAD;
496 proc->p_reader = NULL;
498 cv_broadcast(&dev->d_cv);
500 if (proc->p_refcnt == 0) {
501 list_remove(&dev->d_procs, proc);
502 devaudio_proc_free(proc);
504 dc->dc_proc = NULL;
507 mutex_exit(&dev->d_mx);
509 devaudio_clear_eof(c);
511 while ((mp = dc->dc_draining) != NULL) {
512 dc->dc_draining = mp->b_next;
513 mp->b_next = NULL;
514 freemsg(mp);
517 mutex_destroy(&dc->dc_lock);
518 list_destroy(&dc->dc_eofcnt);
519 kmem_free(dc, sizeof (*dc));
522 static void
523 devaudio_input(audio_client_t *c)
525 audio_stream_t *sp = auclnt_input_stream(c);
526 daclient_t *dc = auclnt_get_private(c);
527 unsigned framesz = auclnt_get_framesz(sp);
528 queue_t *rq = auclnt_get_rq(c);
529 mblk_t *mp;
530 unsigned nbytes = dc->dc_proc->p_info.record.buffer_size;
531 unsigned count = nbytes / framesz;
534 * Potentially send a message upstream with the record data.
535 * We collect this up in chunks of the buffer size requested
536 * by the client.
539 while (auclnt_get_count(sp) >= count) {
541 if ((!canput(rq)) ||
542 ((mp = allocb(nbytes, BPRI_MED)) == NULL)) {
544 * This will apply back pressure to the
545 * buffer. We haven't yet lost any data, we
546 * just can't send it up. The point at which
547 * we have an unrecoverable overrun is in the
548 * buffer, not in the streams queue. So, no
549 * need to do anything right now.
551 * Note that since recording is enabled, we
552 * expect that the callback routine will be
553 * called repeatedly & regularly, so we don't
554 * have to worry about leaving data orphaned
555 * in the queue.
557 break;
560 (void) auclnt_consume_data(sp, (caddr_t)mp->b_wptr, count);
561 mp->b_wptr += nbytes;
562 (void) putq(rq, mp);
566 static void
567 devaudio_proc_update(daproc_t *proc)
569 audio_info_t *info;
570 audio_stream_t *sp;
571 audio_client_t *c;
573 info = &proc->p_info;
575 ASSERT(mutex_owned(&proc->p_dev->d_mx));
577 if ((c = proc->p_writer) != NULL) {
578 sp = auclnt_output_stream(c);
580 info->play.sample_rate = auclnt_get_rate(sp);
581 info->play.channels = auclnt_get_channels(sp);
582 devaudio_decompose_format(&info->play, auclnt_get_format(sp));
584 info->play.gain =
585 (auclnt_get_gain(sp) * AUDIO_MAX_GAIN) / 100;
586 info->play.pause = auclnt_is_paused(sp);
587 info->play.active = auclnt_is_running(sp);
588 info->play.samples = auclnt_get_samples(sp);
589 info->play.error = auclnt_get_errors(sp) ? B_TRUE : B_FALSE;
590 info->output_muted = auclnt_get_muted(sp);
591 } else {
592 info->play.encoding = AUDIO_ENCODING_NONE;
593 info->play.precision = 0;
594 info->play.sample_rate = 0;
595 info->play.pause = B_FALSE;
596 info->play.active = B_FALSE;
597 info->play.error = B_FALSE;
598 info->play.samples = 0;
601 if ((c = proc->p_reader) != NULL) {
602 sp = auclnt_input_stream(c);
604 info->record.sample_rate = auclnt_get_rate(sp);
605 info->record.channels = auclnt_get_channels(sp);
606 devaudio_decompose_format(&info->record, auclnt_get_format(sp));
608 info->record.gain =
609 (auclnt_get_gain(sp) * AUDIO_MAX_GAIN) / 100;
610 info->record.pause = auclnt_is_paused(sp);
611 info->record.active = auclnt_is_running(sp);
612 info->record.samples = auclnt_get_samples(sp);
613 info->record.error = auclnt_get_errors(sp) ? B_TRUE : B_FALSE;
614 } else {
615 info->record.encoding = AUDIO_ENCODING_NONE;
616 info->record.precision = 0;
617 info->record.sample_rate = 0;
618 info->record.pause = B_FALSE;
619 info->record.active = B_FALSE;
620 info->record.error = B_FALSE;
621 info->record.samples = 0;
625 static void
626 devaudio_ioc_getinfo(queue_t *wq, audio_client_t *c, mblk_t *mp)
628 daclient_t *dc = auclnt_get_private(c);
629 daproc_t *proc = dc->dc_proc;
630 mblk_t *bcont;
632 if ((bcont = allocb(sizeof (audio_info_t), BPRI_MED)) == NULL) {
633 miocnak(wq, mp, 0, ENOMEM);
634 return;
637 mutex_enter(&dc->dc_dev->d_mx);
638 devaudio_proc_update(proc);
639 bcopy(&proc->p_info, bcont->b_wptr, sizeof (audio_info_t));
640 mutex_exit(&dc->dc_dev->d_mx);
642 bcont->b_wptr += sizeof (audio_info_t);
644 mcopyout(mp, NULL, sizeof (audio_info_t), NULL, bcont);
645 qreply(wq, mp);
648 #define CHANGED(new, old, field) \
649 ((new->field != ((uint32_t)~0)) && (new->field != old->field))
650 #define CHANGED8(new, old, field) \
651 ((new->field != ((uint8_t)~0)) && (new->field != old->field))
653 static void
654 devaudio_ioc_setinfo(queue_t *wq, audio_client_t *c, mblk_t *mp)
656 daclient_t *dc;
657 daproc_t *proc;
658 audio_info_t *oinfo;
659 audio_info_t *ninfo;
660 audio_prinfo_t *npr;
661 audio_prinfo_t *opr;
663 int pfmt = AUDIO_FORMAT_NONE;
664 int rfmt = AUDIO_FORMAT_NONE;
666 boolean_t reader;
667 boolean_t writer;
668 boolean_t isctl;
669 audio_stream_t *sp;
670 int rv;
671 caddr_t uaddr;
672 mblk_t *bcont;
674 struct copyresp *csp;
676 if (DB_TYPE(mp) == M_IOCTL) {
677 /* the special value "1" indicates that this is a copyin */
678 uaddr = *(caddr_t *)(void *)mp->b_cont->b_rptr;
680 mcopyin(mp, uaddr, sizeof (audio_info_t), NULL);
681 qreply(wq, mp);
682 return;
685 ASSERT(DB_TYPE(mp) == M_IOCDATA);
686 if (((bcont = mp->b_cont) == NULL) ||
687 (MBLKL(mp->b_cont) != sizeof (audio_info_t))) {
688 miocnak(wq, mp, 0, EINVAL);
689 return;
692 mp->b_cont = NULL;
693 csp = (void *)mp->b_rptr;
694 uaddr = (void *)csp->cp_private;
695 dc = auclnt_get_private(c);
696 ninfo = (void *)bcont->b_rptr;
698 mutex_enter(&dc->dc_dev->d_mx);
700 proc = dc->dc_proc;
701 oinfo = &proc->p_info;
703 if (auclnt_get_minor_type(c) == AUDIO_MINOR_DEVAUDIOCTL) {
704 /* control node can do both read and write fields */
705 isctl = B_TRUE;
706 reader = B_TRUE;
707 writer = B_TRUE;
708 } else {
709 isctl = B_FALSE;
710 writer = (c == proc->p_writer);
711 reader = (c == proc->p_reader);
715 * Start by validating settings.
717 npr = &ninfo->play;
718 opr = &oinfo->play;
720 if (writer && CHANGED(npr, opr, sample_rate)) {
721 if ((isctl) ||
722 (npr->sample_rate < 5500) || (npr->sample_rate > 48000)) {
723 rv = EINVAL;
724 goto err;
727 if (writer && CHANGED(npr, opr, channels)) {
728 if ((isctl) || (npr->channels < 1) || (npr->channels > 2)) {
729 rv = EINVAL;
730 goto err;
733 if (writer &&
734 (CHANGED(npr, opr, encoding) || CHANGED(npr, opr, precision))) {
735 if (npr->encoding == (uint32_t)~0)
736 npr->encoding = opr->encoding;
737 if (npr->precision == (uint32_t)~0)
738 npr->precision = opr->precision;
739 pfmt = devaudio_compose_format(npr);
740 if ((isctl) || (pfmt == AUDIO_FORMAT_NONE)) {
741 rv = EINVAL;
742 goto err;
746 /* play fields that anyone can modify */
747 if (CHANGED(npr, opr, gain)) {
748 if (npr->gain > AUDIO_MAX_GAIN) {
749 rv = EINVAL;
750 goto err;
755 npr = &ninfo->record;
756 opr = &oinfo->record;
758 if (reader && CHANGED(npr, opr, sample_rate)) {
759 if ((isctl) ||
760 (npr->sample_rate < 5500) || (npr->sample_rate > 48000)) {
761 rv = EINVAL;
762 goto err;
765 if (reader && CHANGED(npr, opr, channels)) {
766 if ((isctl) || (npr->channels < 1) || (npr->channels > 2)) {
767 rv = EINVAL;
768 goto err;
771 if (reader &&
772 (CHANGED(npr, opr, encoding) || CHANGED(npr, opr, precision))) {
773 if (npr->encoding == (uint32_t)~0)
774 npr->encoding = opr->encoding;
775 if (npr->precision == (uint32_t)~0)
776 npr->precision = opr->precision;
777 rfmt = devaudio_compose_format(npr);
778 if ((isctl) || (rfmt == AUDIO_FORMAT_NONE)) {
779 rv = EINVAL;
780 goto err;
783 if (reader && CHANGED(npr, opr, buffer_size)) {
784 if (isctl) {
785 rv = EINVAL;
786 goto err;
788 /* make sure we can support 16-bit stereo samples */
789 if ((npr->buffer_size % 4) != 0) {
790 npr->buffer_size = (npr->buffer_size + 3) & ~3;
792 /* limit the maximum buffer size somewhat */
793 if (npr->buffer_size > 16384) {
794 npr->buffer_size = 16384;
798 /* record fields that anyone can modify */
799 if (CHANGED(npr, opr, gain)) {
800 if (npr->gain > AUDIO_MAX_GAIN) {
801 rv = EINVAL;
802 goto err;
807 * Now apply the changes.
809 if (proc->p_writer != NULL) {
810 sp = auclnt_output_stream(proc->p_writer);
811 npr = &ninfo->play;
812 opr = &oinfo->play;
814 if (CHANGED(npr, opr, sample_rate)) {
815 if ((rv = auclnt_set_rate(sp, npr->sample_rate)) != 0)
816 goto err;
818 if (CHANGED(npr, opr, channels)) {
819 if ((rv = auclnt_set_channels(sp, npr->channels)) != 0)
820 goto err;
822 if (pfmt != AUDIO_FORMAT_NONE) {
823 if ((rv = auclnt_set_format(sp, pfmt)) != 0)
824 goto err;
826 if (CHANGED(npr, opr, samples)) {
827 auclnt_set_samples(sp, npr->samples);
829 if (CHANGED(npr, opr, eof)) {
831 * This ugly special case code is required to
832 * prevent problems with realaudio.
834 if (npr->eof == 0) {
835 devaudio_clear_eof(proc->p_writer);
837 opr->eof = npr->eof;
839 if (CHANGED8(npr, opr, pause)) {
840 if (npr->pause) {
841 auclnt_set_paused(sp);
842 } else {
843 auclnt_clear_paused(sp);
845 /* qenable to start up the playback */
846 qenable(auclnt_get_wq(proc->p_writer));
849 if (CHANGED8(npr, opr, waiting) && (npr->waiting)) {
850 opr->waiting = npr->waiting;
852 if (CHANGED8(npr, opr, error)) {
853 auclnt_set_errors(sp, npr->error);
855 if (CHANGED(npr, opr, gain)) {
856 auclnt_set_gain(sp, (npr->gain * 100) / AUDIO_MAX_GAIN);
858 if (CHANGED8(ninfo, oinfo, output_muted)) {
859 auclnt_set_muted(sp, ninfo->output_muted);
861 if (CHANGED(npr, opr, buffer_size)) {
863 * No checks on the buffer size are performed
864 * for play side. The value of the buffer size
865 * is meaningless for play side anyway.
867 opr->buffer_size = npr->buffer_size;
869 } else {
870 /* these values are preserved even if /dev/audio not open */
871 if (CHANGED(npr, opr, gain)) {
872 opr->gain = npr->gain;
874 if (CHANGED8(ninfo, oinfo, output_muted)) {
875 oinfo->output_muted = ninfo->output_muted;
879 if (proc->p_reader != NULL) {
880 sp = auclnt_input_stream(proc->p_reader);
881 npr = &ninfo->record;
882 opr = &oinfo->record;
884 if (CHANGED(npr, opr, sample_rate)) {
885 if ((rv = auclnt_set_rate(sp, npr->sample_rate)) != 0)
886 goto err;
888 if (CHANGED(npr, opr, channels)) {
889 if ((rv = auclnt_set_channels(sp, npr->channels)) != 0)
890 goto err;
892 if (rfmt != AUDIO_FORMAT_NONE) {
893 if ((rv = auclnt_set_format(sp, rfmt)) != 0)
894 goto err;
896 if (CHANGED(npr, opr, samples)) {
897 auclnt_set_samples(sp, npr->samples);
899 if (CHANGED(npr, opr, eof)) {
900 opr->eof = npr->eof;
902 if (CHANGED8(npr, opr, pause)) {
903 if (npr->pause) {
904 auclnt_set_paused(sp);
905 } else {
906 auclnt_clear_paused(sp);
907 auclnt_start(sp);
910 if (CHANGED8(npr, opr, waiting) && (npr->waiting)) {
911 opr->waiting = npr->waiting;
913 if (CHANGED8(npr, opr, error)) {
914 auclnt_set_errors(sp, npr->error);
916 if (CHANGED(npr, opr, buffer_size)) {
917 opr->buffer_size = npr->buffer_size;
919 if (CHANGED(npr, opr, gain)) {
920 auclnt_set_gain(sp, (npr->gain * 100) / AUDIO_MAX_GAIN);
922 } else {
923 /* these values are preserved even if /dev/audio not open */
924 if (CHANGED(npr, opr, gain)) {
925 opr->gain = npr->gain;
929 devaudio_proc_update(dc->dc_proc);
930 bcopy(&dc->dc_proc->p_info, ninfo, sizeof (*ninfo));
932 mutex_exit(&dc->dc_dev->d_mx);
933 mcopyout(mp, NULL, sizeof (audio_info_t), uaddr, bcont);
934 qreply(wq, mp);
935 return;
937 err:
938 mutex_exit(&dc->dc_dev->d_mx);
939 miocnak(wq, mp, 0, rv);
942 static void
943 devaudio_ioc_getdev(queue_t *wq, audio_client_t *c, mblk_t *mp)
945 audio_dev_t *d = auclnt_get_dev(c);
946 mblk_t *bcont;
947 audio_device_t *a;
949 if ((bcont = allocb(sizeof (*a), BPRI_MED)) == NULL) {
950 miocnak(wq, mp, 0, ENOMEM);
951 return;
954 a = (void *)bcont->b_wptr;
955 (void) snprintf(a->name, sizeof (a->name),
956 "SUNW,%s", auclnt_get_dev_name(d));
957 (void) strlcpy(a->config,
958 auclnt_get_dev_description(d), sizeof (a->config));
959 (void) strlcpy(a->version,
960 auclnt_get_dev_version(d), sizeof (a->version));
961 bcont->b_wptr += sizeof (*a);
963 mcopyout(mp, NULL, sizeof (*a), NULL, bcont);
964 qreply(wq, mp);
967 static int
968 devaudio_sigpoll(audio_client_t *c, void *arg)
970 pid_t pid = (pid_t)(uintptr_t)arg;
972 if (auclnt_get_minor_type(c) == AUDIO_MINOR_DEVAUDIOCTL) {
973 /* we only need to notify peers in our own process */
974 if (auclnt_get_pid(c) == pid) {
975 (void) putctl1(auclnt_get_rq(c), M_PCSIG, SIGPOLL);
978 return (AUDIO_WALK_CONTINUE);
981 static void
982 devaudio_drain(audio_client_t *c)
984 daclient_t *dc = auclnt_get_private(c);
985 mblk_t *mplist, *mp;
987 mutex_enter(&dc->dc_lock);
988 mplist = dc->dc_draining;
989 dc->dc_draining = NULL;
990 mutex_exit(&dc->dc_lock);
992 while ((mp = mplist) != NULL) {
993 mplist = mp->b_next;
994 mp->b_next = NULL;
995 mioc2ack(mp, NULL, 0, 0);
996 (void) putq(auclnt_get_rq(c), mp);
1000 static void
1001 devaudio_output(audio_client_t *c)
1003 daclient_t *dc = auclnt_get_private(c);
1004 daproc_t *proc = dc->dc_proc;
1005 uint64_t tail;
1006 struct eofcnt *eof;
1007 int eofs = 0;
1009 tail = auclnt_get_tail(auclnt_output_stream(c));
1011 /* get more data! (do this early) */
1012 qenable(auclnt_get_wq(c));
1014 mutex_enter(&dc->dc_lock);
1015 while (((eof = list_head(&dc->dc_eofcnt)) != NULL) &&
1016 (eof->tail <= tail)) {
1017 list_remove(&dc->dc_eofcnt, eof);
1018 kmem_free(eof, sizeof (*eof));
1019 eofs++;
1021 proc->p_info.play.eof += eofs;
1022 mutex_exit(&dc->dc_lock);
1024 if (eofs) {
1025 auclnt_dev_walk_clients(auclnt_get_dev(c),
1026 devaudio_sigpoll, (void *)(uintptr_t)auclnt_get_pid(c));
1030 static void *
1031 devaudio_init(audio_dev_t *adev)
1033 dadev_t *dev;
1034 unsigned cap;
1036 cap = auclnt_get_dev_capab(adev);
1037 /* if not a play or record device, don't bother initializing it */
1038 if ((cap & (AUDIO_CLIENT_CAP_PLAY | AUDIO_CLIENT_CAP_RECORD)) == 0) {
1039 return (NULL);
1042 dev = kmem_zalloc(sizeof (*dev), KM_SLEEP);
1043 dev->d_dev = adev;
1044 mutex_init(&dev->d_mx, NULL, MUTEX_DRIVER, NULL);
1045 cv_init(&dev->d_cv, NULL, CV_DRIVER, NULL);
1046 list_create(&dev->d_procs, sizeof (struct daproc),
1047 offsetof(struct daproc, p_linkage));
1049 return (dev);
1052 static void
1053 devaudio_fini(void *arg)
1055 dadev_t *dev = arg;
1057 if (dev != NULL) {
1059 mutex_destroy(&dev->d_mx);
1060 cv_destroy(&dev->d_cv);
1061 list_destroy(&dev->d_procs);
1062 kmem_free(dev, sizeof (*dev));
1066 static int
1067 devaudio_open(audio_client_t *c, int oflag)
1069 int rv;
1071 if ((rv = auclnt_open(c, oflag)) != 0) {
1072 return (rv);
1075 if ((rv = devaudio_proc_hold(c, oflag)) != 0) {
1076 auclnt_close(c);
1077 return (rv);
1080 /* start up the input */
1081 if (oflag & FREAD) {
1082 auclnt_start(auclnt_input_stream(c));
1085 return (0);
1088 static int
1089 devaudioctl_open(audio_client_t *c, int oflag)
1091 int rv;
1093 _NOTE(ARGUNUSED(oflag));
1095 oflag &= ~(FWRITE | FREAD);
1097 if ((rv = auclnt_open(c, 0)) != 0) {
1098 return (rv);
1101 if ((rv = devaudio_proc_hold(c, oflag)) != 0) {
1102 auclnt_close(c);
1103 return (rv);
1106 return (0);
1109 static void
1110 devaudio_close(audio_client_t *c)
1112 auclnt_stop(auclnt_output_stream(c));
1113 auclnt_stop(auclnt_input_stream(c));
1115 auclnt_close(c);
1116 devaudio_proc_release(c);
1119 static void
1120 devaudioctl_close(audio_client_t *c)
1122 auclnt_close(c);
1123 devaudio_proc_release(c);
1126 static void
1127 devaudio_miocdata(audio_client_t *c, mblk_t *mp)
1129 struct copyresp *csp;
1130 queue_t *wq;
1132 csp = (void *)mp->b_rptr;
1133 wq = auclnt_get_wq(c);
1136 * If a transfer error occurred, the framework already
1137 * MIOCNAK'd it.
1139 if (csp->cp_rval != 0) {
1140 freemsg(mp);
1141 return;
1145 * If no state, then this is a response to M_COPYOUT, and we
1146 * are done. (Audio ioctls just copyout a single structure at
1147 * completion of work.)
1149 if (csp->cp_private == NULL) {
1150 miocack(wq, mp, 0, 0);
1151 return;
1154 /* now, call the handler ioctl */
1155 switch (csp->cp_cmd) {
1156 case AUDIO_SETINFO:
1157 devaudio_ioc_setinfo(wq, c, mp);
1158 break;
1159 default:
1160 miocnak(wq, mp, 0, EINVAL);
1161 break;
1165 static void
1166 devaudio_mioctl(audio_client_t *c, mblk_t *mp)
1168 struct iocblk *iocp = (void *)mp->b_rptr;
1169 queue_t *wq = auclnt_get_wq(c);
1171 /* BSD legacy here: we only support transparent ioctls */
1172 if (iocp->ioc_count != TRANSPARENT) {
1173 miocnak(wq, mp, 0, EINVAL);
1174 return;
1177 switch (iocp->ioc_cmd) {
1178 case AUDIO_GETINFO:
1179 devaudio_ioc_getinfo(wq, c, mp);
1180 break;
1182 case AUDIO_SETINFO:
1183 devaudio_ioc_setinfo(wq, c, mp);
1184 break;
1186 case AUDIO_GETDEV:
1187 devaudio_ioc_getdev(wq, c, mp);
1188 break;
1190 case AUDIO_DIAG_LOOPBACK:
1191 /* we don't support this one */
1192 miocnak(wq, mp, 0, ENOTTY);
1193 break;
1195 case AUDIO_MIXERCTL_GET_MODE:
1196 case AUDIO_MIXERCTL_SET_MODE:
1197 case AUDIO_MIXERCTL_GET_CHINFO:
1198 case AUDIO_MIXERCTL_SET_CHINFO:
1199 case AUDIO_MIXERCTL_GETINFO:
1200 case AUDIO_MIXERCTL_SETINFO:
1201 case AUDIO_GET_NUM_CHS:
1202 case AUDIO_GET_CH_NUMBER:
1203 case AUDIO_GET_CH_TYPE:
1204 case AUDIO_MIXER_SINGLE_OPEN:
1205 case AUDIO_MIXER_MULTIPLE_OPEN:
1206 case AUDIO_MIXER_GET_SAMPLE_RATES:
1207 default:
1208 miocnak(wq, mp, 0, EINVAL);
1209 break;
1213 static void
1214 devaudioctl_wput(audio_client_t *c, mblk_t *mp)
1216 queue_t *wq = auclnt_get_wq(c);
1218 switch (DB_TYPE(mp)) {
1219 case M_IOCTL:
1220 /* Drain ioctl needs to be handled on the service queue */
1221 devaudio_mioctl(c, mp);
1222 break;
1224 case M_IOCDATA:
1225 devaudio_miocdata(c, mp);
1226 break;
1228 case M_FLUSH:
1230 * We don't flush the engine. The reason is that
1231 * other streams might be using the engine. This is
1232 * fundamentally no different from the case where the
1233 * engine hardware has data buffered in an
1234 * inaccessible FIFO.
1236 * Clients that want to ensure no more data is coming
1237 * should stop the stream before flushing.
1239 if (*mp->b_rptr & FLUSHW) {
1240 *mp->b_rptr &= ~FLUSHW;
1242 if (*mp->b_rptr & FLUSHR) {
1243 qreply(wq, mp);
1244 } else {
1245 freemsg(mp);
1247 break;
1249 case M_DATA:
1251 * No audio data on control nodes!
1254 default:
1255 freemsg(mp);
1256 break;
1260 static void
1261 devaudio_wput(audio_client_t *c, mblk_t *mp)
1263 queue_t *wq = auclnt_get_wq(c);
1265 switch (DB_TYPE(mp)) {
1266 case M_IOCTL:
1267 /* Drain ioctl needs to be handled on the service queue */
1268 if (*(int *)(void *)mp->b_rptr == AUDIO_DRAIN) {
1269 (void) putq(wq, mp);
1270 } else {
1271 devaudio_mioctl(c, mp);
1273 break;
1275 case M_IOCDATA:
1276 devaudio_miocdata(c, mp);
1277 break;
1279 case M_FLUSH:
1281 * We don't flush the engine. The reason is that
1282 * other streams might be using the engine. This is
1283 * fundamentally no different from the case where the
1284 * engine hardware has data buffered in an
1285 * inaccessible FIFO.
1287 * Clients that want to ensure no more data is coming
1288 * should stop the stream before flushing.
1290 if (*mp->b_rptr & FLUSHW) {
1291 flushq(wq, FLUSHALL);
1292 auclnt_flush(auclnt_output_stream(c));
1293 *mp->b_rptr &= ~FLUSHW;
1295 if (*mp->b_rptr & FLUSHR) {
1296 flushq(RD(wq), FLUSHALL);
1297 auclnt_flush(auclnt_input_stream(c));
1298 qreply(wq, mp);
1299 } else {
1300 freemsg(mp);
1302 break;
1304 case M_DATA:
1306 * Defer processing to the queue. This keeps the data
1307 * ordered, and allows the wsrv routine to gather
1308 * multiple mblks at once.
1310 if (mp->b_cont != NULL) {
1313 * If we need to pullup, do it here to
1314 * simplify the rest of the processing later.
1315 * This should rarely (if ever) be necessary.
1317 mblk_t *nmp;
1319 if ((nmp = msgpullup(mp, -1)) == NULL) {
1320 freemsg(mp);
1321 } else {
1322 freemsg(mp);
1323 (void) putq(wq, nmp);
1325 } else {
1326 (void) putq(wq, mp);
1328 break;
1330 default:
1331 freemsg(mp);
1332 break;
1336 static void
1337 devaudio_rsrv(audio_client_t *c)
1339 queue_t *rq = auclnt_get_rq(c);
1340 mblk_t *mp;
1342 while ((mp = getq(rq)) != NULL) {
1344 if ((queclass(mp) != QPCTL) && (!canputnext(rq))) {
1346 * Put it back in the queue so we can apply
1347 * backpressure properly.
1349 (void) putbq(rq, mp);
1350 return;
1352 putnext(rq, mp);
1356 static void
1357 devaudio_wsrv(audio_client_t *c)
1359 queue_t *wq = auclnt_get_wq(c);
1360 daclient_t *dc = auclnt_get_private(c);
1361 audio_stream_t *sp;
1362 mblk_t *mp;
1363 unsigned framesz;
1365 sp = auclnt_output_stream(c);
1367 framesz = auclnt_get_framesz(sp);
1369 while ((mp = getq(wq)) != NULL) {
1371 unsigned count;
1373 /* got a message */
1375 /* if its a drain ioctl, we need to process it here */
1376 if (DB_TYPE(mp) == M_IOCTL) {
1377 ASSERT((*(int *)(void *)mp->b_rptr) == AUDIO_DRAIN);
1378 mutex_enter(&dc->dc_lock);
1379 mp->b_next = dc->dc_draining;
1380 dc->dc_draining = mp;
1381 mutex_exit(&dc->dc_lock);
1383 if (auclnt_start_drain(c) != 0) {
1384 devaudio_drain(c);
1386 continue;
1389 ASSERT(DB_TYPE(mp) == M_DATA);
1392 * Empty mblk require special handling, since they
1393 * indicate EOF. We treat them separate from the main
1394 * processing loop.
1396 if (MBLKL(mp) == 0) {
1397 struct eofcnt *eof;
1399 eof = kmem_zalloc(sizeof (*eof), KM_NOSLEEP);
1400 if (eof != NULL) {
1401 eof->tail = auclnt_get_head(sp);
1402 mutex_enter(&dc->dc_lock);
1403 list_insert_tail(&dc->dc_eofcnt, eof);
1404 mutex_exit(&dc->dc_lock);
1406 freemsg(mp);
1407 continue;
1410 count = auclnt_produce_data(sp, (caddr_t)mp->b_rptr,
1411 MBLKL(mp) / framesz);
1413 mp->b_rptr += count * framesz;
1415 if (MBLKL(mp) >= framesz) {
1416 (void) putbq(wq, mp);
1417 break;
1418 } else {
1419 freemsg(mp);
1423 /* if the stream isn't running yet, start it up */
1424 if (!auclnt_is_paused(sp))
1425 auclnt_start(sp);
1428 static struct audio_client_ops devaudio_ops = {
1429 "sound,audio",
1430 devaudio_init,
1431 devaudio_fini,
1432 devaudio_open,
1433 devaudio_close,
1434 NULL, /* read */
1435 NULL, /* write */
1436 NULL, /* ioctl */
1437 NULL, /* chpoll */
1438 NULL, /* mmap */
1439 devaudio_input,
1440 devaudio_output,
1441 devaudio_drain,
1442 devaudio_wput,
1443 devaudio_wsrv,
1444 devaudio_rsrv
1447 static struct audio_client_ops devaudioctl_ops = {
1448 "sound,audioctl",
1449 NULL, /* dev_init */
1450 NULL, /* dev_fini */
1451 devaudioctl_open,
1452 devaudioctl_close,
1453 NULL, /* read */
1454 NULL, /* write */
1455 NULL, /* ioctl */
1456 NULL, /* chpoll */
1457 NULL, /* mmap */
1458 NULL, /* output */
1459 NULL, /* input */
1460 NULL, /* drain */
1461 devaudioctl_wput,
1462 NULL,
1463 devaudio_rsrv
1466 void
1467 auimpl_sun_init(void)
1469 auclnt_register_ops(AUDIO_MINOR_DEVAUDIO, &devaudio_ops);
1470 auclnt_register_ops(AUDIO_MINOR_DEVAUDIOCTL, &devaudioctl_ops);