Merge remote-tracking branch 'origin/master'
[unleashed/lotheac.git] / usr / src / uts / common / io / audio / impl / audio_engine.c
blob2f5bd3075a55539fdd2d8dc544e47feec985a3ac
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) 4Front Technologies 1996-2008.
24 * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
25 * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
28 #include <sys/types.h>
29 #include <sys/list.h>
30 #include <sys/sysmacros.h>
31 #include <sys/ddi.h>
32 #include <sys/sunddi.h>
33 #include <sys/callb.h>
34 #include <sys/kstat.h>
35 #include <sys/note.h>
37 #include "audio_impl.h"
40 * Audio Engine functions.
44 * Globals
46 uint_t audio_intrhz = AUDIO_INTRHZ;
48 * We need to operate at fairly high interrupt priority to avoid
49 * underruns due to other less time sensitive processing.
51 int audio_priority = DDI_IPL_8;
53 audio_dev_t *
54 audio_dev_alloc(dev_info_t *dip, int instance)
56 audio_dev_t *d;
59 * For a card with multiple independent audio ports on it, we
60 * allow the driver to provide a different instance numbering
61 * scheme than the standard DDI instance number. (This is
62 * sort of like the PPA numbering scheme used by NIC drivers
63 * -- by default PPA == instance, but sometimes we need more
64 * flexibility.)
66 if (instance == 0) {
67 instance = ddi_get_instance(dip);
69 /* generally this shouldn't occur */
70 if (instance > AUDIO_MN_INST_MASK) {
71 audio_dev_warn(NULL, "bad instance number for %s (%d)",
72 ddi_driver_name(dip), instance);
73 return (NULL);
76 if ((d = kmem_zalloc(sizeof (*d), KM_NOSLEEP)) == NULL) {
77 audio_dev_warn(NULL, "unable to allocate audio device struct");
78 return (NULL);
80 d->d_dip = dip;
81 d->d_number = -1;
82 d->d_major = ddi_driver_major(dip);
83 d->d_instance = instance;
84 d->d_pcmvol = 100;
85 mutex_init(&d->d_lock, NULL, MUTEX_DRIVER, NULL);
86 cv_init(&d->d_cv, NULL, CV_DRIVER, NULL);
87 mutex_init(&d->d_ctrl_lock, NULL, MUTEX_DRIVER, NULL);
88 cv_init(&d->d_ctrl_cv, NULL, CV_DRIVER, NULL);
89 list_create(&d->d_clients, sizeof (struct audio_client),
90 offsetof(struct audio_client, c_dev_linkage));
91 list_create(&d->d_engines, sizeof (struct audio_engine),
92 offsetof(struct audio_engine, e_dev_linkage));
93 list_create(&d->d_controls, sizeof (struct audio_ctrl),
94 offsetof(struct audio_ctrl, ctrl_linkage));
95 list_create(&d->d_hwinfo, sizeof (struct audio_infostr),
96 offsetof(struct audio_infostr, i_linkage));
97 (void) snprintf(d->d_name, sizeof (d->d_name), "%s#%d",
98 ddi_driver_name(dip), instance);
100 return (d);
103 void
104 audio_dev_free(audio_dev_t *d)
106 struct audio_infostr *isp;
108 while ((isp = list_remove_head(&d->d_hwinfo)) != NULL) {
109 kmem_free(isp, sizeof (*isp));
111 if (d->d_pcmvol_ctrl != NULL) {
112 audio_dev_del_control(d->d_pcmvol_ctrl);
114 list_destroy(&d->d_hwinfo);
115 list_destroy(&d->d_engines);
116 list_destroy(&d->d_controls);
117 list_destroy(&d->d_clients);
118 mutex_destroy(&d->d_ctrl_lock);
119 mutex_destroy(&d->d_lock);
120 cv_destroy(&d->d_cv);
121 cv_destroy(&d->d_ctrl_cv);
122 kmem_free(d, sizeof (*d));
125 void
126 audio_dev_set_description(audio_dev_t *d, const char *desc)
128 (void) strlcpy(d->d_desc, desc, sizeof (d->d_desc));
131 void
132 audio_dev_set_version(audio_dev_t *d, const char *vers)
134 (void) strlcpy(d->d_vers, vers, sizeof (d->d_vers));
137 void
138 audio_dev_add_info(audio_dev_t *d, const char *info)
140 struct audio_infostr *isp;
142 /* failure to add information structure is not critical */
143 isp = kmem_zalloc(sizeof (*isp), KM_NOSLEEP);
144 if (isp == NULL) {
145 audio_dev_warn(d, "unable to allocate information structure");
146 } else {
147 (void) snprintf(isp->i_line, sizeof (isp->i_line), info);
148 list_insert_tail(&d->d_hwinfo, isp);
152 static void
153 auimpl_engine_reset(audio_engine_t *e)
155 char *buf;
156 char *ptr;
157 int nfr, resid, cnt;
158 int tidx;
160 tidx = e->e_tidx;
161 nfr = min(e->e_head - e->e_tail, e->e_nframes);
162 buf = kmem_alloc(nfr * e->e_framesz, KM_SLEEP);
163 ptr = buf;
164 cnt = 0;
166 ASSERT(e->e_nframes);
168 for (resid = nfr; resid; resid -= cnt) {
169 int nbytes;
171 cnt = min((e->e_nframes - tidx), resid);
172 nbytes = cnt * e->e_framesz;
174 bcopy(e->e_data + (tidx * e->e_framesz), ptr, nbytes);
175 ptr += nbytes;
176 tidx += cnt;
177 if (tidx == e->e_nframes) {
178 tidx = 0;
182 if (e->e_flags & ENGINE_INPUT) {
183 /* record */
184 e->e_hidx = 0;
185 e->e_tidx = (e->e_nframes - nfr) % e->e_nframes;
186 } else {
187 /* play */
188 e->e_hidx = nfr % e->e_nframes;
189 e->e_tidx = 0;
192 /* relocate from scratch area to destination */
193 bcopy(buf, e->e_data + (e->e_tidx * e->e_framesz), nfr * e->e_framesz);
194 kmem_free(buf, nfr * e->e_framesz);
197 static volatile uint_t auimpl_engno = 0;
199 audio_engine_t *
200 audio_engine_alloc(audio_engine_ops_t *ops, uint_t flags)
202 int i;
203 audio_engine_t *e;
204 char tname[32];
205 int num;
207 if (ops->audio_engine_version != AUDIO_ENGINE_VERSION) {
208 audio_dev_warn(NULL, "audio engine version mismatch: %d != %d",
209 ops->audio_engine_version, AUDIO_ENGINE_VERSION);
210 return (NULL);
213 /* NB: The ops vector must be held in persistent storage! */
214 e = kmem_zalloc(sizeof (audio_engine_t), KM_NOSLEEP);
215 if (e == NULL) {
216 audio_dev_warn(NULL, "unable to allocate engine struct");
217 return (NULL);
219 e->e_ops = *ops;
220 mutex_init(&e->e_lock, NULL, MUTEX_DRIVER,
221 DDI_INTR_PRI(audio_priority));
222 cv_init(&e->e_cv, NULL, CV_DRIVER, NULL);
223 list_create(&e->e_streams, sizeof (struct audio_stream),
224 offsetof(struct audio_stream, s_eng_linkage));
226 for (i = 0; i < AUDIO_MAX_CHANNELS; i++) {
227 e->e_chbufs[i] = kmem_zalloc(sizeof (int32_t) * AUDIO_CHBUFS,
228 KM_NOSLEEP);
229 if (e->e_chbufs[i] == NULL) {
230 audio_dev_warn(NULL, "unable to allocate channel buf");
231 audio_engine_free(e);
232 return (NULL);
236 num = atomic_inc_uint_nv(&auimpl_engno);
238 (void) snprintf(tname, sizeof (tname), "audio_engine_%d", num);
240 e->e_flags = flags & ENGINE_DRIVER_FLAGS;
241 return (e);
244 void
245 audio_engine_free(audio_engine_t *e)
247 int i;
249 for (i = 0; i < AUDIO_MAX_CHANNELS; i++) {
250 if (e->e_chbufs[i] != NULL) {
251 kmem_free(e->e_chbufs[i],
252 sizeof (int32_t) * AUDIO_CHBUFS);
256 list_destroy(&e->e_streams);
257 mutex_destroy(&e->e_lock);
258 cv_destroy(&e->e_cv);
259 kmem_free(e, sizeof (*e));
262 static list_t auimpl_devs_by_index;
263 static list_t auimpl_devs_by_number;
264 static krwlock_t auimpl_dev_lock;
267 * Not for public consumption: Private interfaces.
269 void
270 auimpl_dev_hold(audio_dev_t *d)
272 /* bump the reference count */
273 mutex_enter(&d->d_lock);
274 d->d_refcnt++;
275 mutex_exit(&d->d_lock);
278 audio_dev_t *
279 auimpl_dev_hold_by_devt(dev_t dev)
281 audio_dev_t *d;
282 major_t major;
283 int instance;
284 list_t *l = &auimpl_devs_by_index;
286 major = getmajor(dev);
287 instance = (getminor(dev) >> AUDIO_MN_INST_SHIFT) & AUDIO_MN_INST_MASK;
289 rw_enter(&auimpl_dev_lock, RW_READER);
291 for (d = list_head(l); d; d = list_next(l, d)) {
292 if ((d->d_major == major) && (d->d_instance == instance)) {
293 auimpl_dev_hold(d);
294 break;
298 rw_exit(&auimpl_dev_lock);
299 return (d);
302 audio_dev_t *
303 auimpl_dev_hold_by_index(int index)
305 audio_dev_t *d;
306 list_t *l = &auimpl_devs_by_index;
308 rw_enter(&auimpl_dev_lock, RW_READER);
310 for (d = list_head(l); d; d = list_next(l, d)) {
311 if (d->d_index == index) {
312 auimpl_dev_hold(d);
313 break;
317 rw_exit(&auimpl_dev_lock);
318 return (d);
321 void
322 auimpl_dev_release(audio_dev_t *d)
324 mutex_enter(&d->d_lock);
325 d->d_refcnt--;
326 mutex_exit(&d->d_lock);
330 auimpl_choose_format(int fmts)
333 * Choose the very best format we can. We choose 24 bit in
334 * preference to 32 bit because we mix in 24 bit. We do that
335 * to allow overflows to fit within 32-bits. (Very few humans
336 * can tell a difference between 24 and 32 bit audio anyway.)
338 if (fmts & AUDIO_FORMAT_S24_NE)
339 return (AUDIO_FORMAT_S24_NE);
341 if (fmts & AUDIO_FORMAT_S32_NE)
342 return (AUDIO_FORMAT_S32_NE);
344 if (fmts & AUDIO_FORMAT_S24_OE)
345 return (AUDIO_FORMAT_S24_OE);
347 if (fmts & AUDIO_FORMAT_S32_OE)
348 return (AUDIO_FORMAT_S32_OE);
350 if (fmts & AUDIO_FORMAT_S16_NE)
351 return (AUDIO_FORMAT_S16_NE);
353 if (fmts & AUDIO_FORMAT_S16_OE)
354 return (AUDIO_FORMAT_S16_OE);
356 if (fmts & AUDIO_FORMAT_AC3)
357 return (AUDIO_FORMAT_AC3);
359 return (AUDIO_FORMAT_NONE);
363 auimpl_engine_open(audio_stream_t *sp, int flags)
365 return (auimpl_engine_setup(sp, flags, NULL, FORMAT_MSK_NONE));
370 auimpl_engine_setup(audio_stream_t *sp, int flags, audio_parms_t *parms,
371 uint_t mask)
373 audio_dev_t *d = sp->s_client->c_dev;
374 audio_engine_t *e = NULL;
375 audio_parms_t uparms;
376 list_t *list;
377 uint_t cap;
378 int priority = 0;
379 int rv = ENODEV;
380 int sampsz;
381 int i;
382 int fragfr;
383 int fmts;
386 mutex_enter(&d->d_lock);
388 uparms = *sp->s_user_parms;
389 if (mask & FORMAT_MSK_FMT)
390 uparms.p_format = parms->p_format;
391 if (mask & FORMAT_MSK_RATE)
392 uparms.p_rate = parms->p_rate;
393 if (mask & FORMAT_MSK_CHAN)
394 uparms.p_nchan = parms->p_nchan;
397 * Which direction are we opening? (We must open exactly
398 * one direction, otherwise the open is meaningless.)
401 if (sp == &sp->s_client->c_ostream) {
402 cap = ENGINE_OUTPUT_CAP;
403 flags |= ENGINE_OUTPUT;
404 } else {
405 cap = ENGINE_INPUT_CAP;
406 flags |= ENGINE_INPUT;
409 if (uparms.p_format == AUDIO_FORMAT_AC3) {
410 fmts = AUDIO_FORMAT_AC3;
411 flags |= ENGINE_EXCLUSIVE;
412 } else {
413 fmts = AUDIO_FORMAT_PCM;
416 list = &d->d_engines;
419 /* If the device is suspended, wait for it to resume. */
420 while (d->d_suspended) {
421 cv_wait(&d->d_ctrl_cv, &d->d_lock);
424 again:
426 for (audio_engine_t *t = list_head(list); t; t = list_next(list, t)) {
427 int mypri;
428 int r;
430 /* Make sure the engine can do what we want it to. */
431 mutex_enter(&t->e_lock);
433 if ((t->e_flags & cap) == 0) {
434 mutex_exit(&t->e_lock);
435 continue;
439 * Open the engine early, as the inquiries to rate and format
440 * may not be accurate until this is done.
442 if (list_is_empty(&t->e_streams)) {
443 if (ENG_OPEN(t, flags, &t->e_nframes, &t->e_data)) {
444 mutex_exit(&t->e_lock);
445 rv = EIO;
446 continue;
450 if ((ENG_FORMAT(t) & fmts) == 0) {
451 if (list_is_empty(&t->e_streams))
452 ENG_CLOSE(t);
453 mutex_exit(&t->e_lock);
454 continue;
458 /* If it is in failed state, don't use this engine. */
459 if (t->e_failed) {
460 if (list_is_empty(&t->e_streams))
461 ENG_CLOSE(t);
462 mutex_exit(&t->e_lock);
463 rv = rv ? EIO : 0;
464 continue;
468 * If the engine is in exclusive use, we can't use it.
469 * This is intended for use with AC3 or digital
470 * streams that cannot tolerate mixing.
472 if ((t->e_flags & ENGINE_EXCLUSIVE) && (t != sp->s_engine)) {
473 if (list_is_empty(&t->e_streams))
474 ENG_CLOSE(t);
475 mutex_exit(&t->e_lock);
476 rv = rv ? EBUSY : 0;
477 continue;
481 * If the engine is in use incompatibly, we can't use
482 * it. This should only happen for half-duplex audio
483 * devices. I've not seen any of these that are
484 * recent enough to be supported by Solaris.
486 if (((flags & ENGINE_INPUT) && (t->e_flags & ENGINE_OUTPUT)) ||
487 ((flags & ENGINE_OUTPUT) && (t->e_flags & ENGINE_INPUT))) {
488 if (list_is_empty(&t->e_streams))
489 ENG_CLOSE(t);
490 mutex_exit(&t->e_lock);
491 /* Only override the ENODEV or EIO. */
492 rv = rv ? EBUSY : 0;
493 continue;
497 * In order to support as many different possible
498 * output streams (e.g. AC3 passthru or AC3 decode),
499 * or multiple exclusive outputs, we treat audio
500 * engines as *precious*.
502 * This means that we will try hard to reuse an
503 * existing allocated engine. This may not be the
504 * optimal performance configuration (especially if we
505 * wanted to avoid rate conversion, for example), but
506 * it should have fewer cases where the configuration
507 * results in denying service to any client.
511 * This engine *can* support us, so we should no longer
512 * have a failure mode.
514 rv = 0;
515 mypri = (1U << 0);
519 * Mixing is cheap, so try not to pick on idle
520 * engines. This avoids burning bus bandwidth (which
521 * may be precious for certain classes of traffic).
522 * Note that idleness is given a low priority compared
523 * to the other considerations.
525 * We also use this opportunity open the engine, if
526 * not already done so, so that our parameter
527 * inquiries will be valid.
529 if (!list_is_empty(&t->e_streams))
530 mypri |= (1U << 1);
533 * Slight preference is given to reuse an engine that
534 * we might already be using.
536 if (t == sp->s_engine)
537 mypri |= (1U << 2);
541 * Sample rate conversion avoidance. Upsampling
542 * requires multiplications and is moderately
543 * expensive. Downsampling requires division and is
544 * quite expensive, and hence to be avoided if at all
545 * possible.
547 r = ENG_RATE(t);
548 if (uparms.p_rate == r) {
550 * No conversion needed at all. This is ideal.
552 mypri |= (1U << 4) | (1U << 3);
553 } else {
554 int src, dst;
556 if (flags & ENGINE_INPUT) {
557 src = r;
558 dst = uparms.p_rate;
559 } else {
560 src = uparms.p_rate;
561 dst = r;
563 if ((src < dst) && ((dst % src) == 0)) {
565 * Pure upsampling only. This
566 * penalizes any engine which requires
567 * downsampling.
569 mypri |= (1U << 3);
574 * Try not to pick on duplex engines. This way we
575 * leave engines that can be used for recording or
576 * playback available as such. All modern drivers
577 * use separate unidirectional engines for playback
578 * and record.
580 if ((t->e_flags & ENGINE_CAPS) == cap) {
581 mypri |= (1U << 5);
585 * Try not to pick on engines that can do other
586 * formats. This will generally be false, but if it
587 * happens we pretty strongly avoid using a limited
588 * resource.
590 if ((t->e_format & ~fmts) == 0) {
591 mypri |= (1U << 6);
594 if (mypri > priority) {
595 if (e != NULL) {
597 * If we opened this for our own use
598 * and we are no longer using it, then
599 * close it back down.
601 if (list_is_empty(&e->e_streams))
602 ENG_CLOSE(e);
603 mutex_exit(&e->e_lock);
605 e = t;
606 priority = mypri;
607 } else {
608 mutex_exit(&t->e_lock);
612 * Locking: at this point, if we have an engine, "e", it is
613 * locked. No other engines should have a lock held.
617 if ((rv == EBUSY) && ((flags & ENGINE_NDELAY) == 0)) {
618 ASSERT(e == NULL);
619 if (cv_wait_sig(&d->d_cv, &d->d_lock) == 0) {
620 mutex_exit(&d->d_lock);
621 return (EINTR);
623 goto again;
626 if (rv != 0) {
627 ASSERT(e == NULL);
628 mutex_exit(&d->d_lock);
629 return (rv);
632 ASSERT(e != NULL);
633 ASSERT(mutex_owned(&e->e_lock));
635 if (sp->s_engine && (sp->s_engine != e)) {
637 * If this represents a potential engine change, then
638 * we close off everything, and start anew. This turns
639 * out to be vastly simpler than trying to close all
640 * the races associated with a true hand off. This
641 * ought to be relatively uncommon (changing engines).
644 /* Drop the new reference. */
645 if (list_is_empty(&e->e_streams))
646 ENG_CLOSE(e);
647 mutex_exit(&e->e_lock);
648 mutex_exit(&d->d_lock);
650 auimpl_engine_close(sp);
652 /* Try again. */
653 return (auimpl_engine_setup(sp, flags, parms, mask));
656 if (sp->s_engine == NULL) {
658 * Add a reference to this engine if we don't already
659 * have one.
661 sp->s_engine = e;
663 if (!list_is_empty(&e->e_streams)) {
665 * If the engine is already open, there is no
666 * need for further work. The first open will
667 * be relatively expensive, but subsequent
668 * opens should be as cheap as possible.
670 list_insert_tail(&e->e_streams, sp);
671 goto ok;
673 list_insert_tail(&e->e_streams, sp);
675 } else {
676 ASSERT(sp->s_engine == e);
678 * No change in engine... hence don't reprogram the
679 * engine, and don't change references.
681 goto ok;
684 e->e_format = ENG_FORMAT(e);
685 e->e_nchan = ENG_CHANNELS(e);
686 e->e_rate = ENG_RATE(e);
688 /* Select format converters for the engine. */
689 switch (e->e_format) {
690 case AUDIO_FORMAT_S24_NE:
691 e->e_export = auimpl_export_24ne;
692 e->e_import = auimpl_import_24ne;
693 sampsz = 4;
694 break;
695 case AUDIO_FORMAT_S32_NE:
696 e->e_export = auimpl_export_32ne;
697 e->e_import = auimpl_import_32ne;
698 sampsz = 4;
699 break;
700 case AUDIO_FORMAT_S24_OE:
701 e->e_export = auimpl_export_24oe;
702 e->e_import = auimpl_import_24oe;
703 sampsz = 4;
704 break;
705 case AUDIO_FORMAT_S32_OE:
706 e->e_export = auimpl_export_32oe;
707 e->e_import = auimpl_import_32oe;
708 sampsz = 4;
709 break;
710 case AUDIO_FORMAT_S16_NE:
711 e->e_export = auimpl_export_16ne;
712 e->e_import = auimpl_import_16ne;
713 sampsz = 2;
714 break;
715 case AUDIO_FORMAT_S16_OE:
716 e->e_export = auimpl_export_16oe;
717 e->e_import = auimpl_import_16oe;
718 sampsz = 2;
719 break;
720 case AUDIO_FORMAT_AC3:
721 e->e_export = auimpl_export_24ne;
722 e->e_import = auimpl_import_24ne;
723 flags |= ENGINE_EXCLUSIVE;
724 sampsz = 2;
725 break;
726 default:
727 audio_dev_warn(d, "bad format");
728 rv = ENOTSUP;
729 goto done;
732 fragfr = e->e_rate / audio_intrhz;
733 if ((fragfr > AUDIO_CHBUFS) || (fragfr < 1)) {
734 audio_dev_warn(d, "invalid fragment configration");
735 rv = EINVAL;
736 goto done;
739 /* Sanity test a few values. */
740 if ((e->e_nchan < 0) || (e->e_nchan > AUDIO_MAX_CHANNELS) ||
741 (e->e_rate < 5000) || (e->e_rate > 192000)) {
742 audio_dev_warn(d, "bad engine channels or rate");
743 rv = EINVAL;
744 goto done;
747 if ((e->e_nframes <= (fragfr * 2)) || (e->e_data == NULL)) {
748 audio_dev_warn(d, "improper engine configuration");
749 rv = EINVAL;
750 goto done;
753 e->e_framesz = e->e_nchan * sampsz;
754 e->e_fragfr = fragfr;
755 e->e_head = 0;
756 e->e_tail = 0;
757 e->e_hidx = 0;
758 e->e_tidx = 0;
759 e->e_limiter_state = 0x10000;
760 bzero(e->e_data, e->e_nframes * e->e_framesz);
762 if (e->e_ops.audio_engine_playahead == NULL) {
763 e->e_playahead = (fragfr * 3) / 2;
764 } else {
765 e->e_playahead = ENG_PLAYAHEAD(e);
767 * Need to have at least a fragment plus some extra to
768 * avoid underruns.
770 if (e->e_playahead < ((fragfr * 3) / 2)) {
771 e->e_playahead = (fragfr * 3) / 2;
775 * Impossible to queue more frames than FIFO can hold.
777 if (e->e_playahead > e->e_nframes) {
778 e->e_playahead = (fragfr * 3) / 2;
782 for (i = 0; i < e->e_nchan; i++) {
783 if (e->e_ops.audio_engine_chinfo == NULL) {
784 e->e_choffs[i] = i;
785 e->e_chincr[i] = e->e_nchan;
786 } else {
787 ENG_CHINFO(e, i, &e->e_choffs[i], &e->e_chincr[i]);
791 e->e_flags |= flags;
794 * Arrange for the engine to be started. We defer this to the
795 * periodic callback, to ensure that the start happens near
796 * the edge of the periodic callback. This is necessary to
797 * ensure that the first fragment processed is about the same
798 * size as the usual fragment size. (Basically, the problem
799 * is that we have only 10 msec resolution with the periodic
800 * interface, whch is rather unfortunate.)
802 e->e_need_start = B_TRUE;
804 if (flags & ENGINE_OUTPUT) {
806 * Start the output callback to populate the engine on
807 * startup. This avoids a false underrun when we're
808 * first starting up.
810 auimpl_output_preload(e);
812 e->e_periodic = ddi_periodic_add(auimpl_output_callback, e,
813 NANOSEC / audio_intrhz, audio_priority);
814 } else {
815 e->e_periodic = ddi_periodic_add(auimpl_input_callback, e,
816 NANOSEC / audio_intrhz, audio_priority);
820 sp->s_phys_parms->p_rate = e->e_rate;
821 sp->s_phys_parms->p_nchan = e->e_nchan;
823 /* Configure the engine. */
824 mutex_enter(&sp->s_lock);
825 rv = auimpl_format_setup(sp, parms, mask);
826 mutex_exit(&sp->s_lock);
828 done:
829 mutex_exit(&e->e_lock);
830 mutex_exit(&d->d_lock);
832 return (rv);
835 void
836 auimpl_engine_close(audio_stream_t *sp)
838 audio_engine_t *e = sp->s_engine;
839 audio_dev_t *d;
840 ddi_periodic_t ep;
842 if (e == NULL)
843 return;
845 d = e->e_dev;
846 ep = 0;
848 mutex_enter(&d->d_lock);
849 while (d->d_suspended) {
850 cv_wait(&d->d_ctrl_cv, &d->d_lock);
853 mutex_enter(&e->e_lock);
854 sp->s_engine = NULL;
855 list_remove(&e->e_streams, sp);
856 if (list_is_empty(&e->e_streams)) {
857 ENG_STOP(e);
858 ep = e->e_periodic;
859 e->e_periodic = 0;
860 e->e_flags &= ENGINE_DRIVER_FLAGS;
861 ENG_CLOSE(e);
863 mutex_exit(&e->e_lock);
865 if (ep != 0)
866 ddi_periodic_delete(ep);
868 cv_broadcast(&d->d_cv);
869 mutex_exit(&d->d_lock);
873 audio_dev_register(audio_dev_t *d)
875 list_t *l;
876 audio_dev_t *srch;
877 int start;
880 * Make sure we don't automatically unload. This prevents
881 * loss of hardware settings when no audio clients are
882 * running.
884 (void) ddi_prop_update_int(DDI_DEV_T_NONE, d->d_dip,
885 DDI_NO_AUTODETACH, 1);
888 * This does an in-order insertion, finding the first available
889 * free index. "Special" devices (ones without any actual engines)
890 * are all numbered 0. There should only be one of them anyway.
891 * All others start at one.
893 if (d->d_flags & DEV_SNDSTAT_CAP) {
894 start = 0;
895 } else {
896 start = 1;
898 d->d_index = start;
900 rw_enter(&auimpl_dev_lock, RW_WRITER);
901 l = &auimpl_devs_by_index;
902 for (srch = list_head(l); srch; srch = list_next(l, srch)) {
903 /* skip over special nodes */
904 if (srch->d_index < start)
905 continue;
906 if (srch->d_index > d->d_index) {
907 /* found a free spot! */
908 break;
910 d->d_index++;
913 * NB: If srch is NULL, then list_insert_before puts
914 * it on the tail of the list. So if we didn't find a
915 * hole, then that's where we want it.
917 list_insert_before(l, srch, d);
919 /* insert in order by number */
920 l = &auimpl_devs_by_number;
921 for (srch = list_head(l); srch; srch = list_next(l, srch)) {
922 if (srch->d_number >= d->d_number) {
923 break;
926 list_insert_before(l, srch, d);
928 rw_exit(&auimpl_dev_lock);
930 if (auimpl_create_minors(d) != 0) {
931 rw_enter(&auimpl_dev_lock, RW_WRITER);
932 auimpl_remove_minors(d);
933 list_remove(&auimpl_devs_by_index, d);
934 list_remove(&auimpl_devs_by_number, d);
935 rw_exit(&auimpl_dev_lock);
936 return (DDI_FAILURE);
939 return (DDI_SUCCESS);
943 audio_dev_unregister(audio_dev_t *d)
945 rw_enter(&auimpl_dev_lock, RW_WRITER);
947 mutex_enter(&d->d_lock);
948 /* if we are still in use, we can't unregister */
949 if (d->d_refcnt) {
950 mutex_exit(&d->d_lock);
951 rw_exit(&auimpl_dev_lock);
952 return (DDI_FAILURE);
954 auimpl_remove_minors(d);
955 list_remove(&auimpl_devs_by_index, d);
956 list_remove(&auimpl_devs_by_number, d);
957 mutex_exit(&d->d_lock);
959 rw_exit(&auimpl_dev_lock);
961 return (DDI_SUCCESS);
964 static int
965 auimpl_engine_ksupdate(kstat_t *ksp, int rw)
967 audio_engine_t *e = ksp->ks_private;
968 struct audio_stats *st = &e->e_stats;
970 if (rw == KSTAT_WRITE) {
971 return (EACCES);
974 mutex_enter(&e->e_lock);
975 st->st_head.value.ui64 = e->e_head;
976 st->st_tail.value.ui64 = e->e_tail;
977 st->st_flags.value.ui32 = e->e_flags;
978 st->st_nbytes.value.ui32 = e->e_framesz * e->e_nframes;
979 st->st_framesz.value.ui32 = e->e_framesz;
980 st->st_hidx.value.ui32 = e->e_hidx;
981 st->st_tidx.value.ui32 = e->e_tidx;
982 st->st_format.value.ui32 = e->e_format;
983 st->st_nchan.value.ui32 = e->e_nchan;
984 st->st_rate.value.ui32 = e->e_rate;
985 st->st_errors.value.ui32 = e->e_errors;
986 st->st_engine_underruns.value.ui32 = e->e_underruns;
987 st->st_engine_overruns.value.ui32 = e->e_overruns;
988 st->st_stream_underruns.value.ui32 = e->e_stream_underruns;
989 st->st_stream_overruns.value.ui32 = e->e_stream_overruns;
990 st->st_suspended.value.ui32 = e->e_suspended;
991 st->st_failed.value.ui32 = e->e_failed;
992 st->st_playahead.value.ui32 = e->e_playahead;
993 mutex_exit(&e->e_lock);
995 return (0);
998 static void
999 auimpl_engine_ksinit(audio_dev_t *d, audio_engine_t *e)
1001 char name[32];
1002 struct audio_stats *st;
1004 (void) snprintf(name, sizeof (name), "engine_%d", e->e_num);
1006 e->e_ksp = kstat_create(ddi_driver_name(d->d_dip), d->d_instance,
1007 name, "misc", KSTAT_TYPE_NAMED,
1008 sizeof (struct audio_stats) / sizeof (kstat_named_t), 0);
1010 if (e->e_ksp == NULL) {
1011 audio_dev_warn(d, "unable to initialize kstats");
1012 return;
1015 st = &e->e_stats;
1016 e->e_ksp->ks_data = st;
1017 e->e_ksp->ks_private = e;
1018 e->e_ksp->ks_lock = NULL;
1019 e->e_ksp->ks_update = auimpl_engine_ksupdate;
1020 kstat_named_init(&st->st_head, "head", KSTAT_DATA_UINT64);
1021 kstat_named_init(&st->st_tail, "tail", KSTAT_DATA_UINT64);
1022 kstat_named_init(&st->st_flags, "flags", KSTAT_DATA_UINT32);
1023 kstat_named_init(&st->st_nbytes, "nbytes", KSTAT_DATA_UINT32);
1024 kstat_named_init(&st->st_framesz, "framesz", KSTAT_DATA_UINT32);
1025 kstat_named_init(&st->st_hidx, "hidx", KSTAT_DATA_UINT32);
1026 kstat_named_init(&st->st_tidx, "tidx", KSTAT_DATA_UINT32);
1027 kstat_named_init(&st->st_format, "format", KSTAT_DATA_UINT32);
1028 kstat_named_init(&st->st_nchan, "channels", KSTAT_DATA_UINT32);
1029 kstat_named_init(&st->st_rate, "rate", KSTAT_DATA_UINT32);
1030 kstat_named_init(&st->st_errors, "errors", KSTAT_DATA_UINT32);
1031 kstat_named_init(&st->st_engine_overruns, "engine_overruns",
1032 KSTAT_DATA_UINT32);
1033 kstat_named_init(&st->st_engine_underruns, "engine_underruns",
1034 KSTAT_DATA_UINT32);
1035 kstat_named_init(&st->st_stream_overruns, "stream_overruns",
1036 KSTAT_DATA_UINT32);
1037 kstat_named_init(&st->st_stream_underruns, "stream_underruns",
1038 KSTAT_DATA_UINT32);
1039 kstat_named_init(&st->st_playahead, "playahead", KSTAT_DATA_UINT32);
1040 kstat_named_init(&st->st_suspended, "suspended", KSTAT_DATA_UINT32);
1041 kstat_named_init(&st->st_failed, "failed", KSTAT_DATA_UINT32);
1042 kstat_install(e->e_ksp);
1045 void
1046 audio_dev_add_engine(audio_dev_t *d, audio_engine_t *e)
1048 mutex_enter(&d->d_lock);
1050 e->e_num = d->d_engno++;
1052 auimpl_engine_ksinit(d, e);
1054 /* check for duplex */
1055 if ((e->e_flags & ENGINE_OUTPUT_CAP) && (d->d_flags & DEV_INPUT_CAP)) {
1056 d->d_flags |= DEV_DUPLEX_CAP;
1058 if ((e->e_flags & ENGINE_INPUT_CAP) && (d->d_flags & DEV_OUTPUT_CAP)) {
1059 d->d_flags |= DEV_DUPLEX_CAP;
1061 /* add in the direction caps -- must be done after duplex above */
1062 if (e->e_flags & ENGINE_OUTPUT_CAP) {
1063 d->d_flags |= DEV_OUTPUT_CAP;
1065 if (e->e_flags & ENGINE_INPUT_CAP) {
1066 d->d_flags |= DEV_INPUT_CAP;
1069 list_insert_tail(&d->d_engines, e);
1070 e->e_dev = d;
1071 mutex_exit(&d->d_lock);
1074 void
1075 audio_dev_remove_engine(audio_dev_t *d, audio_engine_t *e)
1077 mutex_enter(&d->d_lock);
1078 list_remove(&d->d_engines, e);
1079 e->e_dev = NULL;
1080 if (e->e_ksp)
1081 kstat_delete(e->e_ksp);
1082 e->e_ksp = NULL;
1083 mutex_exit(&d->d_lock);
1087 * Change the number.
1089 void
1090 auclnt_set_dev_number(audio_dev_t *d, int num)
1092 list_t *l = &auimpl_devs_by_number;
1093 audio_dev_t *srch;
1095 /* reorder our list */
1096 rw_enter(&auimpl_dev_lock, RW_WRITER);
1097 d->d_number = num;
1098 list_remove(l, d);
1099 for (srch = list_head(l); srch; srch = list_next(l, srch)) {
1100 if (srch->d_number >= d->d_number) {
1101 break;
1104 list_insert_before(l, srch, d);
1106 rw_exit(&auimpl_dev_lock);
1109 void
1110 auclnt_walk_devs(int (*walker)(audio_dev_t *, void *), void *arg)
1112 audio_dev_t *d;
1113 boolean_t cont;
1114 list_t *l;
1116 l = &auimpl_devs_by_index;
1117 rw_enter(&auimpl_dev_lock, RW_READER);
1118 for (d = list_head(l); d; d = list_next(l, d)) {
1119 cont = walker(d, arg);
1120 if (cont == AUDIO_WALK_STOP)
1121 break;
1123 rw_exit(&auimpl_dev_lock);
1126 void
1127 auclnt_walk_devs_by_number(int (*walker)(audio_dev_t *, void *), void *arg)
1129 audio_dev_t *d;
1130 boolean_t cont;
1131 list_t *l;
1133 l = &auimpl_devs_by_number;
1134 rw_enter(&auimpl_dev_lock, RW_READER);
1135 for (d = list_head(l); d; d = list_next(l, d)) {
1136 cont = walker(d, arg);
1137 if (cont == AUDIO_WALK_STOP)
1138 break;
1140 rw_exit(&auimpl_dev_lock);
1143 void
1144 auclnt_dev_walk_engines(audio_dev_t *d,
1145 int (*walker)(audio_engine_t *, void *),
1146 void *arg)
1148 audio_engine_t *e;
1149 list_t *l = &d->d_engines;
1151 mutex_enter(&d->d_lock);
1152 for (e = list_head(l); e != NULL; e = list_next(l, e)) {
1153 if (walker(e, arg) == AUDIO_WALK_STOP) {
1154 break;
1157 mutex_exit(&d->d_lock);
1161 auclnt_engine_get_format(audio_engine_t *e)
1163 return (ENG_FORMAT(e));
1167 auclnt_engine_get_channels(audio_engine_t *e)
1169 return (ENG_CHANNELS(e));
1173 auclnt_engine_get_rate(audio_engine_t *e)
1175 return (ENG_RATE(e));
1178 uint_t
1179 auclnt_engine_get_capab(audio_engine_t *e)
1181 uint_t capab = 0;
1183 if (e->e_flags & ENGINE_INPUT_CAP) {
1184 capab |= AUDIO_CLIENT_CAP_RECORD;
1186 if (e->e_flags & ENGINE_OUTPUT_CAP) {
1187 capab |= AUDIO_CLIENT_CAP_PLAY;
1189 return (capab);
1193 * This function suspends an engine. The intent is to pause the
1194 * engine temporarily so that it does not underrun while user threads
1195 * are suspended. The driver is still responsible for actually doing
1196 * the driver suspend work -- all this does is put the engine in a
1197 * paused state. It does not prevent, for example, threads from
1198 * accessing the hardware.
1200 * A properly implemented driver won't even be aware of the existence
1201 * of this routine -- the driver will just handle the suspend &
1202 * resume. At the point of suspend & resume, the driver will see that
1203 * the engines are not running (as if all threads had "paused" it).
1205 * Failure to execute either of the routines below is not critical,
1206 * but will probably lead to underruns and overflows as the kernel
1207 * driver gets resumed well in advance of the time when user threads
1208 * are ready to start operation.
1210 static void
1211 auimpl_engine_suspend(audio_engine_t *e)
1213 ASSERT(mutex_owned(&e->e_lock));
1215 if (e->e_failed || e->e_suspended) {
1216 e->e_suspended = B_TRUE;
1217 return;
1219 e->e_suspended = B_TRUE;
1220 if (e->e_flags & ENGINE_INPUT) {
1221 e->e_head = ENG_COUNT(e);
1222 ENG_STOP(e);
1224 if (e->e_flags & ENGINE_OUTPUT) {
1225 e->e_tail = ENG_COUNT(e);
1226 ENG_STOP(e);
1230 static void
1231 auimpl_engine_resume(audio_engine_t *e)
1233 ASSERT(mutex_owned(&e->e_lock));
1234 ASSERT(e->e_suspended);
1236 if (e->e_failed) {
1237 /* No longer suspended, but still failed! */
1238 e->e_suspended = B_FALSE;
1239 return;
1242 if (e->e_flags & (ENGINE_INPUT | ENGINE_OUTPUT)) {
1244 auimpl_engine_reset(e);
1246 if (e->e_flags & ENGINE_OUTPUT) {
1247 auimpl_output_preload(e);
1250 e->e_need_start = B_TRUE;
1252 e->e_suspended = B_FALSE;
1253 cv_broadcast(&e->e_cv);
1256 static int
1257 auimpl_dev_suspend(audio_dev_t *d, void *dontcare)
1259 list_t *l;
1260 audio_engine_t *e;
1262 _NOTE(ARGUNUSED(dontcare));
1264 mutex_enter(&d->d_lock);
1265 mutex_enter(&d->d_ctrl_lock);
1266 if (d->d_suspended) {
1267 d->d_suspended++;
1268 mutex_exit(&d->d_ctrl_lock);
1269 mutex_exit(&d->d_lock);
1270 return (AUDIO_WALK_CONTINUE);
1273 d->d_suspended++;
1275 (void) auimpl_save_controls(d);
1276 mutex_exit(&d->d_ctrl_lock);
1278 l = &d->d_engines;
1279 for (e = list_head(l); e != NULL; e = list_next(l, e)) {
1280 mutex_enter(&e->e_lock);
1281 auimpl_engine_suspend(e);
1282 mutex_exit(&e->e_lock);
1284 mutex_exit(&d->d_lock);
1286 return (AUDIO_WALK_CONTINUE);
1289 static int
1290 auimpl_dev_resume(audio_dev_t *d, void *dontcare)
1292 list_t *l;
1293 audio_engine_t *e;
1295 _NOTE(ARGUNUSED(dontcare));
1297 mutex_enter(&d->d_lock);
1298 mutex_enter(&d->d_ctrl_lock);
1300 ASSERT(d->d_suspended);
1301 d->d_suspended--;
1302 if (d->d_suspended) {
1303 mutex_exit(&d->d_ctrl_lock);
1304 mutex_exit(&d->d_lock);
1305 return (AUDIO_WALK_CONTINUE);
1308 (void) auimpl_restore_controls(d);
1309 cv_broadcast(&d->d_ctrl_cv);
1310 mutex_exit(&d->d_ctrl_lock);
1312 l = &d->d_engines;
1313 for (e = list_head(l); e != NULL; e = list_next(l, e)) {
1314 mutex_enter(&e->e_lock);
1315 auimpl_engine_resume(e);
1316 mutex_exit(&e->e_lock);
1318 mutex_exit(&d->d_lock);
1320 return (AUDIO_WALK_CONTINUE);
1323 boolean_t
1324 auimpl_cpr(void *arg, int code)
1326 _NOTE(ARGUNUSED(arg));
1328 switch (code) {
1329 case CB_CODE_CPR_CHKPT:
1330 auclnt_walk_devs(auimpl_dev_suspend, NULL);
1331 return (B_TRUE);
1333 case CB_CODE_CPR_RESUME:
1334 auclnt_walk_devs(auimpl_dev_resume, NULL);
1335 return (B_TRUE);
1337 default:
1338 return (B_FALSE);
1342 void
1343 audio_dev_suspend(audio_dev_t *d)
1345 (void) auimpl_dev_suspend(d, NULL);
1348 void
1349 audio_dev_resume(audio_dev_t *d)
1351 (void) auimpl_dev_resume(d, NULL);
1354 static callb_id_t auimpl_cpr_id = 0;
1356 void
1357 auimpl_dev_init(void)
1359 rw_init(&auimpl_dev_lock, NULL, RW_DRIVER, NULL);
1360 list_create(&auimpl_devs_by_index, sizeof (struct audio_dev),
1361 offsetof(struct audio_dev, d_by_index));
1362 list_create(&auimpl_devs_by_number, sizeof (struct audio_dev),
1363 offsetof(struct audio_dev, d_by_number));
1366 * We "borrow" the CB_CL_CPR_PM class, which gets executed at
1367 * about the right time for us. It would be nice to have a
1368 * new CB_CL_CPR_AUDIO class, but it isn't critical at this
1369 * point.
1371 * Note that we don't care about our thread id.
1373 auimpl_cpr_id = callb_add(auimpl_cpr, NULL, CB_CL_CPR_PM, "audio_cpr");
1376 void
1377 auimpl_dev_fini(void)
1379 (void) callb_delete(auimpl_cpr_id);
1380 list_destroy(&auimpl_devs_by_index);
1381 list_destroy(&auimpl_devs_by_number);
1382 rw_destroy(&auimpl_dev_lock);
1385 void
1386 audio_engine_set_private(audio_engine_t *eng, void *prv)
1388 eng->e_private = prv;
1391 void *
1392 audio_engine_get_private(audio_engine_t *eng)
1394 return (eng->e_private);
1397 void
1398 audio_dump_bytes(const uint8_t *w, int dcount)
1400 char line[64];
1401 char *s;
1402 int i;
1403 const int wrap = 16;
1405 s = line;
1406 line[0] = 0;
1408 cmn_err(CE_NOTE, "starting @ %p", (void *)w);
1409 for (i = 0; i < dcount; i++) {
1411 (void) sprintf(s, " %02x", *w);
1412 s += strlen(s);
1413 w++;
1415 if ((i % wrap) == (wrap - 1)) {
1416 cmn_err(CE_NOTE, "%08x:%s", i - (wrap - 1), line);
1417 line[0] = 0;
1418 s = line;
1422 if ((i % wrap) != 0) {
1423 cmn_err(CE_NOTE, "%08x:%s", i - (i % wrap), line);
1427 void
1428 audio_dump_words(const uint16_t *w, int dcount)
1430 char line[64];
1431 char *s;
1432 int i;
1433 const int wrap = 8;
1435 s = line;
1436 line[0] = 0;
1438 cmn_err(CE_NOTE, "starting @ %p", (void *)w);
1439 for (i = 0; i < dcount; i++) {
1441 (void) sprintf(s, " %04x", *w);
1442 s += strlen(s);
1443 w++;
1445 if ((i % wrap) == (wrap - 1)) {
1446 cmn_err(CE_NOTE, "%08x:%s", i - (wrap - 1), line);
1447 line[0] = 0;
1448 s = line;
1452 if ((i % wrap) != 0) {
1453 cmn_err(CE_NOTE, "%08x:%s", i - (i % wrap), line);
1457 void
1458 audio_dump_dwords(const uint32_t *w, int dcount)
1460 char line[128];
1461 char *s;
1462 int i;
1463 const int wrap = 4;
1465 s = line;
1466 line[0] = 0;
1468 cmn_err(CE_NOTE, "starting @ %p", (void *)w);
1469 for (i = 0; i < dcount; i++) {
1471 (void) sprintf(s, " %08x", *w);
1472 s += strlen(s);
1473 w++;
1475 if ((i % wrap) == (wrap - 1)) {
1476 cmn_err(CE_NOTE, "%08x:%s", i - (wrap - 1), line);
1477 line[0] = 0;
1478 s = line;
1482 if ((i % wrap) != 0) {
1483 cmn_err(CE_NOTE, "%08x:%s", i - (i % wrap), line);