xref: /illumos-gate/usr/src/uts/common/io/audio/impl/audio_engine.c (revision 96d9f183facd90dbbc2268c9a51689be0b6a0b46)
1 /*
2  * CDDL HEADER START
3  *
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.
7  *
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.
12  *
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]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright (C) 4Front Technologies 1996-2008.
23  *
24  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
25  * Use is subject to license terms.
26  */
27 
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>
36 
37 #include "audio_impl.h"
38 
39 /*
40  * Audio Engine functions.
41  */
42 
43 audio_dev_t *
44 audio_dev_alloc(dev_info_t *dip, int instance)
45 {
46 	audio_dev_t *d;
47 
48 	/*
49 	 * For a card with multiple independent audio ports on it, we
50 	 * allow the driver to provide a different instance numbering
51 	 * scheme than the standard DDI instance number.  (This is
52 	 * sort of like the PPA numbering scheme used by NIC drivers
53 	 * -- by default PPA == instance, but sometimes we need more
54 	 * flexibility.)
55 	 */
56 	if (instance == 0) {
57 		instance = ddi_get_instance(dip);
58 	}
59 	/* generally this shouldn't occur */
60 	if (instance > AUDIO_MN_INST_MASK) {
61 		audio_dev_warn(NULL, "bad instance number for %s (%d)",
62 		    ddi_driver_name(dip), instance);
63 		return (NULL);
64 	}
65 
66 	if ((d = kmem_zalloc(sizeof (*d), KM_NOSLEEP)) == NULL) {
67 		audio_dev_warn(NULL, "unable to allocate audio device struct");
68 		return (NULL);
69 	}
70 	d->d_dip = dip;
71 	d->d_number = -1;
72 	d->d_major = ddi_driver_major(dip);
73 	d->d_instance = instance;
74 	d->d_pcmvol = 100;
75 	mutex_init(&d->d_lock, NULL, MUTEX_DRIVER, NULL);
76 	cv_init(&d->d_cv, NULL, CV_DRIVER, NULL);
77 	rw_init(&d->d_ctrl_lock, NULL, RW_DRIVER, NULL);
78 	list_create(&d->d_clients, sizeof (struct audio_client),
79 	    offsetof(struct audio_client, c_dev_linkage));
80 	list_create(&d->d_engines, sizeof (struct audio_engine),
81 	    offsetof(struct audio_engine, e_dev_linkage));
82 	list_create(&d->d_controls, sizeof (struct audio_ctrl),
83 	    offsetof(struct audio_ctrl, ctrl_linkage));
84 	list_create(&d->d_hwinfo, sizeof (struct audio_infostr),
85 	    offsetof(struct audio_infostr, i_linkage));
86 	(void) snprintf(d->d_name, sizeof (d->d_name), "%s#%d",
87 	    ddi_driver_name(dip), instance);
88 
89 	return (d);
90 }
91 
92 void
93 audio_dev_free(audio_dev_t *d)
94 {
95 	struct audio_infostr *isp;
96 	while ((isp = list_remove_head(&d->d_hwinfo)) != NULL) {
97 		kmem_free(isp, sizeof (*isp));
98 	}
99 	if (d->d_pcmvol_ctrl != NULL) {
100 		audio_dev_del_control(d->d_pcmvol_ctrl);
101 	}
102 	list_destroy(&d->d_hwinfo);
103 	list_destroy(&d->d_engines);
104 	list_destroy(&d->d_controls);
105 	list_destroy(&d->d_clients);
106 	rw_destroy(&d->d_ctrl_lock);
107 	mutex_destroy(&d->d_lock);
108 	cv_destroy(&d->d_cv);
109 	kmem_free(d, sizeof (*d));
110 }
111 
112 void
113 audio_dev_set_description(audio_dev_t *d, const char *desc)
114 {
115 	(void) strlcpy(d->d_desc, desc, sizeof (d->d_desc));
116 }
117 
118 void
119 audio_dev_set_version(audio_dev_t *d, const char *vers)
120 {
121 	(void) strlcpy(d->d_vers, vers, sizeof (d->d_vers));
122 }
123 
124 void
125 audio_dev_add_info(audio_dev_t *d, const char *info)
126 {
127 	struct audio_infostr *isp;
128 
129 	/* failure to add information structure is not critical */
130 	isp = kmem_zalloc(sizeof (*isp), KM_NOSLEEP);
131 	if (isp == NULL) {
132 		audio_dev_warn(d, "unable to allocate information structure");
133 	} else {
134 		(void) snprintf(isp->i_line, sizeof (isp->i_line), info);
135 		list_insert_tail(&d->d_hwinfo, isp);
136 	}
137 }
138 
139 void
140 audio_engine_consume(audio_engine_t *e)
141 {
142 	mutex_enter(&e->e_lock);
143 	e->e_tail = ENG_COUNT(e);
144 	if (e->e_tail > e->e_head) {
145 		/* want more data than we have, not much we can do */
146 		e->e_errors++;
147 		e->e_underruns++;
148 	}
149 	auimpl_output_callback(e);
150 	mutex_exit(&e->e_lock);
151 }
152 
153 void
154 audio_engine_produce(audio_engine_t *e)
155 {
156 	mutex_enter(&e->e_lock);
157 	e->e_head = ENG_COUNT(e);
158 	if ((e->e_head - e->e_tail) > e->e_nframes) {
159 		/* no room for engine data, not much we can do */
160 		e->e_errors++;
161 		e->e_overruns++;
162 	}
163 	auimpl_input_callback(e);
164 	mutex_exit(&e->e_lock);
165 }
166 
167 void
168 audio_engine_reset(audio_engine_t *e)
169 {
170 	char	*buf;
171 	char	*ptr;
172 	int	nfr;
173 	int	tail;
174 
175 
176 	if ((e->e_flags & (ENGINE_INPUT | ENGINE_OUTPUT)) == 0) {
177 		/* engine not open, nothing to do */
178 		return;
179 	}
180 
181 	buf = kmem_alloc(e->e_nbytes, KM_SLEEP);
182 	ptr = buf;
183 
184 	mutex_enter(&e->e_lock);
185 
186 	tail = e->e_tidx;
187 	nfr = min(e->e_head - e->e_tail, e->e_nframes);
188 	while (nfr) {
189 		int	cnt;
190 		int	nbytes;
191 
192 		cnt = min((e->e_nframes - tail), nfr);
193 		nbytes = cnt * e->e_framesz;
194 
195 		bcopy(e->e_data + (tail * e->e_framesz), ptr, nbytes);
196 		ptr += nbytes;
197 		tail += cnt;
198 		if (tail >= e->e_framesz) {
199 			tail -= e->e_framesz;
200 		}
201 		nfr -= cnt;
202 	}
203 
204 	nfr = min(e->e_head - e->e_tail, e->e_nframes);
205 	if (e->e_flags & ENGINE_INPUT) {
206 		/* record */
207 		e->e_hidx = 0;
208 		e->e_tidx = (e->e_nframes - nfr) % e->e_nframes;
209 	} else {
210 		/* play */
211 		e->e_hidx = nfr % e->e_nframes;
212 		e->e_tidx = 0;
213 	}
214 
215 	/* relocate from scratch area to destination */
216 	bcopy(buf, e->e_data + (e->e_tidx * e->e_framesz), nfr * e->e_framesz);
217 	mutex_exit(&e->e_lock);
218 
219 	kmem_free(buf, e->e_nbytes);
220 }
221 
222 audio_engine_t *
223 audio_engine_alloc(audio_engine_ops_t *ops, unsigned flags)
224 {
225 	int i;
226 	audio_engine_t *e;
227 
228 	if (ops->audio_engine_version != AUDIO_ENGINE_VERSION) {
229 		audio_dev_warn(NULL, "audio engine version mismatch: %d != %d",
230 		    ops->audio_engine_version, AUDIO_ENGINE_VERSION);
231 		return (NULL);
232 	}
233 
234 	/* NB: The ops vector must be held in persistent storage! */
235 	e = kmem_zalloc(sizeof (audio_engine_t), KM_NOSLEEP);
236 	if (e == NULL) {
237 		audio_dev_warn(NULL, "unable to allocate engine struct");
238 		return (NULL);
239 	}
240 	e->e_ops = *ops;
241 	mutex_init(&e->e_lock, NULL, MUTEX_DRIVER, NULL);
242 	list_create(&e->e_streams, sizeof (struct audio_stream),
243 	    offsetof(struct audio_stream, s_eng_linkage));
244 
245 	for (i = 0; i < AUDIO_MAX_CHANNELS; i++) {
246 		e->e_chbufs[i] = kmem_zalloc(sizeof (int32_t) * AUDIO_CHBUFS,
247 		    KM_NOSLEEP);
248 		if (e->e_chbufs[i] == NULL) {
249 			audio_dev_warn(NULL, "unable to allocate channel buf");
250 			audio_engine_free(e);
251 			return (NULL);
252 		}
253 	}
254 
255 	e->e_flags = flags & ENGINE_DRIVER_FLAGS;
256 	return (e);
257 }
258 
259 void
260 audio_engine_free(audio_engine_t *e)
261 {
262 	int i;
263 
264 	for (i = 0; i < AUDIO_MAX_CHANNELS; i++) {
265 		if (e->e_chbufs[i] != NULL) {
266 			kmem_free(e->e_chbufs[i],
267 			    sizeof (int32_t) * AUDIO_CHBUFS);
268 		}
269 	}
270 	list_destroy(&e->e_streams);
271 	mutex_destroy(&e->e_lock);
272 	kmem_free(e, sizeof (*e));
273 }
274 
275 static list_t auimpl_devs_by_index;
276 static list_t auimpl_devs_by_number;
277 static krwlock_t auimpl_dev_lock;
278 
279 /*
280  * Not for public consumption: Private interfaces.
281  */
282 void
283 auimpl_dev_hold(audio_dev_t *d)
284 {
285 	/* bump the reference count */
286 	mutex_enter(&d->d_lock);
287 	d->d_refcnt++;
288 	mutex_exit(&d->d_lock);
289 }
290 
291 audio_dev_t *
292 auimpl_dev_hold_by_devt(dev_t dev)
293 {
294 	audio_dev_t *d;
295 	major_t major;
296 	int instance;
297 	list_t *l = &auimpl_devs_by_index;
298 
299 	major = getmajor(dev);
300 	instance = (getminor(dev) >> AUDIO_MN_INST_SHIFT) & AUDIO_MN_INST_MASK;
301 
302 	rw_enter(&auimpl_dev_lock, RW_READER);
303 
304 	for (d = list_head(l); d; d = list_next(l, d)) {
305 		if ((d->d_major == major) && (d->d_instance == instance)) {
306 			auimpl_dev_hold(d);
307 			break;
308 		}
309 	}
310 
311 	rw_exit(&auimpl_dev_lock);
312 	return (d);
313 }
314 
315 audio_dev_t *
316 auimpl_dev_hold_by_index(int index)
317 {
318 	audio_dev_t *d;
319 	list_t *l = &auimpl_devs_by_index;
320 
321 	rw_enter(&auimpl_dev_lock, RW_READER);
322 
323 	for (d = list_head(l); d; d = list_next(l, d)) {
324 		if (d->d_index == index) {
325 			auimpl_dev_hold(d);
326 			break;
327 		}
328 	}
329 
330 	rw_exit(&auimpl_dev_lock);
331 	return (d);
332 }
333 
334 void
335 auimpl_dev_release(audio_dev_t *d)
336 {
337 	mutex_enter(&d->d_lock);
338 	d->d_refcnt--;
339 	mutex_exit(&d->d_lock);
340 }
341 
342 int
343 auimpl_choose_format(int fmts)
344 {
345 	/*
346 	 * Choose the very best format we can.  We choose 24 bit in
347 	 * preference to 32 bit because we mix in 24 bit.  We do that
348 	 * to allow overflows to fit within 32-bits.  (Very few humans
349 	 * can tell a difference between 24 and 32 bit audio anyway.)
350 	 */
351 	if (fmts & AUDIO_FORMAT_S24_NE)
352 		return (AUDIO_FORMAT_S24_NE);
353 
354 	if (fmts & AUDIO_FORMAT_S32_NE)
355 		return (AUDIO_FORMAT_S32_NE);
356 
357 	if (fmts & AUDIO_FORMAT_S24_OE)
358 		return (AUDIO_FORMAT_S24_OE);
359 
360 	if (fmts & AUDIO_FORMAT_S32_OE)
361 		return (AUDIO_FORMAT_S32_OE);
362 
363 	if (fmts & AUDIO_FORMAT_S16_NE)
364 		return (AUDIO_FORMAT_S16_NE);
365 
366 	if (fmts & AUDIO_FORMAT_S16_OE)
367 		return (AUDIO_FORMAT_S16_OE);
368 
369 	if (fmts & AUDIO_FORMAT_AC3)
370 		return (AUDIO_FORMAT_AC3);
371 
372 	return (AUDIO_FORMAT_NONE);
373 }
374 
375 int
376 auimpl_engine_open(audio_dev_t *d, int fmts, int flags, audio_stream_t *sp)
377 {
378 	audio_engine_t	*e = NULL;
379 	list_t		*list;
380 	unsigned	caps;
381 	int		priority = 0;
382 	int		rv = ENODEV;
383 	int		sampsz;
384 	int		i;
385 
386 	/*
387 	 * Engine selection:
388 	 *
389 	 * We try hard to avoid consuming an engine that can be used
390 	 * for another purpose.
391 	 *
392 	 */
393 
394 	/*
395 	 * Which direction are we opening.  (We must open exactly
396 	 * one direction, otherwise the open is meaningless.)
397 	 */
398 	if (flags & ENGINE_OUTPUT)
399 		caps = ENGINE_OUTPUT_CAP;
400 	else if (flags & ENGINE_INPUT)
401 		caps = ENGINE_INPUT_CAP;
402 	else
403 		return (EINVAL);
404 
405 	list = &d->d_engines;
406 
407 	mutex_enter(&d->d_lock);
408 
409 	/*
410 	 * First we want to know if we already have "default" input
411 	 * and output engines.
412 	 */
413 
414 again:
415 
416 	for (audio_engine_t *t = list_head(list); t; t = list_next(list, t)) {
417 		int	mypri;
418 
419 		/* make sure the engine can do what we want it to */
420 		mutex_enter(&t->e_lock);
421 		if ((((t->e_flags & caps) & caps) == 0) ||
422 		    ((ENG_FORMAT(t) & fmts) == 0)) {
423 			mutex_exit(&t->e_lock);
424 			continue;
425 		}
426 
427 		/* if engine is in exclusive use, can't do it */
428 		if (t->e_flags & ENGINE_EXCLUSIVE) {
429 			mutex_exit(&t->e_lock);
430 			rv = EBUSY;
431 			continue;
432 		}
433 
434 		/* if engine is in incompatible use, can't do it */
435 		if (((flags & ENGINE_INPUT) && (t->e_flags & ENGINE_OUTPUT)) ||
436 		    ((flags & ENGINE_OUTPUT) && (t->e_flags & ENGINE_INPUT))) {
437 			mutex_exit(&t->e_lock);
438 			rv = EBUSY;
439 			continue;
440 		}
441 
442 		/*
443 		 * In order to support as many different possible
444 		 * output streams (e.g. AC3 passthru or AC3 decode),
445 		 * or multiple exclusive outputs, we treat audio
446 		 * engines as *precious*.
447 		 *
448 		 * This means that we will try hard to reuse an
449 		 * existing allocated engine.  This may not be the
450 		 * optimal performance configuration (especially if we
451 		 * wanted to avoid rate conversion, for example), but
452 		 * it should have fewer cases where the configuration
453 		 * results in denying service to any client.
454 		 */
455 
456 		rv = 0;
457 		mypri = 2000;
458 
459 		/* try not to pick on idle engines */
460 		if (list_is_empty(&t->e_streams)) {
461 			mypri -= 1000;
462 		}
463 
464 		/* try not to pick on duplex engines first */
465 		if ((t->e_flags & ENGINE_CAPS) != caps) {
466 			mypri -= 100;
467 		}
468 
469 		/* try not to pick on engines that can do other formats */
470 		if (t->e_format & ~fmts) {
471 			mypri -= 10;
472 		}
473 
474 		if (mypri > priority) {
475 			if (e != NULL) {
476 				mutex_exit(&e->e_lock);
477 			}
478 			e = t;
479 			priority = mypri;
480 		} else {
481 			mutex_exit(&t->e_lock);
482 		}
483 	}
484 
485 	if ((rv == EBUSY) && ((flags & ENGINE_NDELAY) == 0)) {
486 		ASSERT(e == NULL);
487 		if (cv_wait_sig(&d->d_cv, &d->d_lock) == 0) {
488 			mutex_exit(&d->d_lock);
489 			return (EINTR);
490 		}
491 		goto again;
492 	}
493 
494 	if (rv != 0) {
495 		ASSERT(e == NULL);
496 		mutex_exit(&d->d_lock);
497 		return (rv);
498 	}
499 
500 	ASSERT(e != NULL);
501 	ASSERT(mutex_owned(&e->e_lock));
502 
503 	/*
504 	 * If the engine is already open, there is no need for further
505 	 * work.  The first open will be relatively expensive, but
506 	 * subsequent opens should be as cheap as possible.
507 	 */
508 	if (!list_is_empty(&e->e_streams)) {
509 		rv = 0;
510 		goto ok;
511 	}
512 
513 	e->e_format = ENG_FORMAT(e);
514 	e->e_nchan = ENG_CHANNELS(e);
515 	e->e_rate = ENG_RATE(e);
516 
517 	/* Find out the "best" sample format supported by the device */
518 	switch (e->e_format) {
519 	case AUDIO_FORMAT_S24_NE:
520 		e->e_export = auimpl_export_24ne;
521 		e->e_import = auimpl_import_24ne;
522 		sampsz = 4;
523 		break;
524 	case AUDIO_FORMAT_S32_NE:
525 		e->e_export = auimpl_export_32ne;
526 		e->e_import = auimpl_import_32ne;
527 		sampsz = 4;
528 		break;
529 	case AUDIO_FORMAT_S24_OE:
530 		e->e_export = auimpl_export_24oe;
531 		e->e_import = auimpl_import_24oe;
532 		sampsz = 4;
533 		break;
534 	case AUDIO_FORMAT_S32_OE:
535 		e->e_export = auimpl_export_32oe;
536 		e->e_import = auimpl_import_32oe;
537 		sampsz = 4;
538 		break;
539 	case AUDIO_FORMAT_S16_NE:
540 		e->e_export = auimpl_export_16ne;
541 		e->e_import = auimpl_import_16ne;
542 		sampsz = 2;
543 		break;
544 	case AUDIO_FORMAT_S16_OE:
545 		e->e_export = auimpl_export_16oe;
546 		e->e_import = auimpl_import_16oe;
547 		sampsz = 2;
548 		break;
549 	case AUDIO_FORMAT_AC3:
550 		e->e_export = auimpl_export_24ne;
551 		e->e_import = auimpl_import_24ne;
552 		flags |= ENGINE_EXCLUSIVE;
553 		sampsz = 2;
554 		break;
555 	default:
556 		audio_dev_warn(d, "bad format");
557 		rv = ENOTSUP;
558 		goto done;
559 	}
560 
561 	/* sanity test a few values */
562 	if ((e->e_nchan < 0) || (e->e_nchan > AUDIO_MAX_CHANNELS) ||
563 	    (e->e_rate < 5000) || (e->e_rate > 192000)) {
564 		audio_dev_warn(d, "bad engine channels or rate");
565 		rv = EINVAL;
566 		goto done;
567 	}
568 
569 	rv = ENG_OPEN(e, &e->e_fragfr, &e->e_nfrags, &e->e_data);
570 	if (rv != 0) {
571 		audio_dev_warn(d, "unable to open engine");
572 		goto done;
573 	}
574 	if ((e->e_fragfr < 1) || (e->e_data == NULL)) {
575 		audio_dev_warn(d, "improper engine configuration");
576 		rv = EINVAL;
577 		goto done;
578 	}
579 
580 	if ((e->e_fragfr > AUDIO_CHBUFS) || (e->e_nfrags < 2)) {
581 		rv = EINVAL;
582 		audio_dev_warn(d, "invalid fragment configuration");
583 		goto done;
584 	}
585 
586 	e->e_framesz = e->e_nchan * sampsz;
587 	e->e_fragbytes = e->e_fragfr * e->e_framesz;
588 	e->e_nframes = e->e_nfrags * e->e_fragfr;
589 	e->e_intrs = e->e_rate / e->e_fragfr;
590 	e->e_nbytes = e->e_nframes * e->e_framesz;
591 	e->e_head = 0;
592 	e->e_tail = 0;
593 	e->e_hidx = 0;
594 	e->e_tidx = 0;
595 	e->e_limiter_state = 0x10000;
596 	bzero(e->e_data, e->e_nbytes);
597 
598 	if (e->e_ops.audio_engine_playahead == NULL) {
599 		e->e_playahead = (e->e_fragfr * 3) / 2;
600 	} else {
601 		e->e_playahead = ENG_PLAYAHEAD(e);
602 		/*
603 		 * Need to have at least a fragment plus some extra to
604 		 * avoid underruns.
605 		 */
606 		if (e->e_playahead < ((e->e_fragfr * 3) / 2)) {
607 			e->e_playahead = (e->e_fragfr * 3) / 2;
608 		}
609 
610 		/*
611 		 * Impossible to queue more frames than FIFO can hold.
612 		 */
613 		if (e->e_playahead > e->e_nframes) {
614 			e->e_playahead = (e->e_fragfr * 3) / 2;
615 		}
616 	}
617 
618 	for (i = 0; i < e->e_nchan; i++) {
619 		if (e->e_ops.audio_engine_chinfo == NULL) {
620 			e->e_choffs[i] = i;
621 			e->e_chincr[i] = e->e_nchan;
622 		} else {
623 			ENG_CHINFO(e, i, &e->e_choffs[i], &e->e_chincr[i]);
624 		}
625 	}
626 
627 	e->e_flags |= (ENGINE_OPEN | (flags & (ENGINE_OUTPUT | ENGINE_INPUT)));
628 
629 	/*
630 	 * Start the output callback to populate the engine on
631 	 * startup.  This avoids a false underrun when we're first
632 	 * starting up.
633 	 */
634 	if (flags & ENGINE_OUTPUT) {
635 		auimpl_output_callback(e);
636 	}
637 
638 	/*
639 	 * Start the engine up now.
640 	 *
641 	 * AC3: Note that this will need to be modified for AC3, since
642 	 * for AC3 we can't start the device until we actually have
643 	 * some data for it from the application.  Probably the best
644 	 * way to do this would be to add a flag, ENGINE_DEFERRED or
645 	 * somesuch.
646 	 */
647 	if (e->e_ops.audio_engine_start != NULL) {
648 		rv = ENG_START(e);
649 		if (rv != 0) {
650 			ENG_CLOSE(e);
651 			goto done;
652 		}
653 	}
654 
655 ok:
656 	sp->s_phys_parms->p_rate = e->e_rate;
657 	sp->s_phys_parms->p_nchan = e->e_nchan;
658 
659 	list_insert_tail(&e->e_streams, sp);
660 	sp->s_engine = e;
661 
662 done:
663 	mutex_exit(&e->e_lock);
664 	mutex_exit(&d->d_lock);
665 	return (rv);
666 }
667 
668 void
669 auimpl_engine_close(audio_stream_t *sp)
670 {
671 	audio_engine_t	*e = sp->s_engine;
672 	audio_dev_t	*d;
673 
674 	if (e == NULL)
675 		return;
676 
677 	d = e->e_dev;
678 
679 	mutex_enter(&d->d_lock);
680 	mutex_enter(&e->e_lock);
681 	sp->s_engine = NULL;
682 	list_remove(&e->e_streams, sp);
683 	if (list_is_empty(&e->e_streams)) {
684 		/* if last client holding engine open, close it all down */
685 		if (e->e_ops.audio_engine_stop != NULL)
686 			ENG_STOP(e);
687 		e->e_flags &= ENGINE_DRIVER_FLAGS;
688 		ENG_CLOSE(e);
689 	}
690 	mutex_exit(&e->e_lock);
691 
692 	cv_broadcast(&d->d_cv);
693 	mutex_exit(&d->d_lock);
694 }
695 
696 int
697 audio_dev_register(audio_dev_t *d)
698 {
699 	list_t *l;
700 	audio_dev_t *srch;
701 	int start;
702 
703 	/*
704 	 * Make sure we don't automatically unload.  This prevents
705 	 * loss of hardware settings when no audio clients are
706 	 * running.
707 	 */
708 	(void) ddi_prop_update_int(DDI_DEV_T_NONE, d->d_dip,
709 	    DDI_NO_AUTODETACH, 1);
710 
711 	/*
712 	 * This does an in-order insertion, finding the first available
713 	 * free index.  "Special" devices (ones without any actual engines)
714 	 * are all numbered 0.  There should only be one of them anyway.
715 	 * All others start at one.
716 	 */
717 	if (d->d_flags & DEV_SNDSTAT_CAP) {
718 		start = 0;
719 	} else {
720 		start = 1;
721 	}
722 	d->d_index = start;
723 	rw_enter(&auimpl_dev_lock, RW_WRITER);
724 	l = &auimpl_devs_by_index;
725 	for (srch = list_head(l); srch; srch = list_next(l, srch)) {
726 		/* skip over special nodes */
727 		if (srch->d_index < start)
728 			continue;
729 		if (srch->d_index > d->d_index) {
730 			/* found a free spot! */
731 			break;
732 		}
733 		d->d_index++;
734 	}
735 	/*
736 	 * NB: If srch is NULL, then list_insert_before puts
737 	 * it on the tail of the list.  So if we didn't find a
738 	 * hole, then that's where we want it.
739 	 */
740 	list_insert_before(l, srch, d);
741 
742 	/* insert in order by number */
743 	l = &auimpl_devs_by_number;
744 	for (srch = list_head(l); srch; srch = list_next(l, srch)) {
745 		if (srch->d_number >= d->d_number) {
746 			break;
747 		}
748 	}
749 	list_insert_before(l, srch, d);
750 
751 	rw_exit(&auimpl_dev_lock);
752 
753 	if (auimpl_create_minors(d) != 0) {
754 		rw_enter(&auimpl_dev_lock, RW_WRITER);
755 		auimpl_remove_minors(d);
756 		list_remove(&auimpl_devs_by_index, d);
757 		list_remove(&auimpl_devs_by_number, d);
758 		rw_exit(&auimpl_dev_lock);
759 		return (DDI_FAILURE);
760 	}
761 
762 	return (DDI_SUCCESS);
763 }
764 
765 int
766 audio_dev_unregister(audio_dev_t *d)
767 {
768 	rw_enter(&auimpl_dev_lock, RW_WRITER);
769 
770 	mutex_enter(&d->d_lock);
771 	/* if we are still in use, we can't unregister */
772 	if (d->d_refcnt) {
773 		mutex_exit(&d->d_lock);
774 		rw_exit(&auimpl_dev_lock);
775 		return (DDI_FAILURE);
776 	}
777 	auimpl_remove_minors(d);
778 	list_remove(&auimpl_devs_by_index, d);
779 	list_remove(&auimpl_devs_by_number, d);
780 	mutex_exit(&d->d_lock);
781 
782 	rw_exit(&auimpl_dev_lock);
783 
784 	return (DDI_SUCCESS);
785 }
786 
787 static int
788 auimpl_engine_ksupdate(kstat_t *ksp, int rw)
789 {
790 	audio_engine_t *e = ksp->ks_private;
791 	struct audio_stats *st = &e->e_stats;
792 
793 	if (rw == KSTAT_WRITE) {
794 		return (EACCES);
795 	}
796 
797 	mutex_enter(&e->e_lock);
798 	st->st_head.value.ui64 = e->e_head;
799 	st->st_tail.value.ui64 = e->e_tail;
800 	st->st_flags.value.ui32 = e->e_flags;
801 	st->st_fragfr.value.ui32 = e->e_fragfr;
802 	st->st_nfrags.value.ui32 = e->e_nfrags;
803 	st->st_framesz.value.ui32 = e->e_framesz;
804 	st->st_nbytes.value.ui32 = e->e_nbytes;
805 	st->st_hidx.value.ui32 = e->e_hidx;
806 	st->st_tidx.value.ui32 = e->e_tidx;
807 	st->st_format.value.ui32 = e->e_format;
808 	st->st_nchan.value.ui32 = e->e_nchan;
809 	st->st_rate.value.ui32 = e->e_rate;
810 	st->st_intrs.value.ui32 = e->e_intrs;
811 	st->st_errors.value.ui32 = e->e_errors;
812 	st->st_engine_underruns.value.ui32 = e->e_underruns;
813 	st->st_engine_overruns.value.ui32 = e->e_overruns;
814 	st->st_stream_underruns.value.ui32 = e->e_stream_underruns;
815 	st->st_stream_overruns.value.ui32 = e->e_stream_overruns;
816 	st->st_suspended.value.ui32 = e->e_suspended;
817 	mutex_exit(&e->e_lock);
818 
819 	return (0);
820 }
821 
822 static void
823 auimpl_engine_ksinit(audio_dev_t *d, audio_engine_t *e)
824 {
825 	char			name[32];
826 	struct audio_stats	*st;
827 
828 	(void) snprintf(name, sizeof (name), "engine_%d", e->e_num);
829 
830 	e->e_ksp = kstat_create(ddi_driver_name(d->d_dip), d->d_instance,
831 	    name, "misc", KSTAT_TYPE_NAMED,
832 	    sizeof (struct audio_stats) / sizeof (kstat_named_t), 0);
833 
834 	if (e->e_ksp == NULL) {
835 		audio_dev_warn(d, "unable to initialize kstats");
836 		return;
837 	}
838 
839 	st = &e->e_stats;
840 	e->e_ksp->ks_data = st;
841 	e->e_ksp->ks_private = e;
842 	e->e_ksp->ks_lock = NULL;
843 	e->e_ksp->ks_update = auimpl_engine_ksupdate;
844 	kstat_named_init(&st->st_head, "head", KSTAT_DATA_UINT64);
845 	kstat_named_init(&st->st_tail, "tail", KSTAT_DATA_UINT64);
846 	kstat_named_init(&st->st_flags, "flags", KSTAT_DATA_UINT32);
847 	kstat_named_init(&st->st_fragfr, "fragfr", KSTAT_DATA_UINT32);
848 	kstat_named_init(&st->st_nfrags, "nfrags", KSTAT_DATA_UINT32);
849 	kstat_named_init(&st->st_framesz, "framesz", KSTAT_DATA_UINT32);
850 	kstat_named_init(&st->st_nbytes, "nbytes", KSTAT_DATA_UINT32);
851 	kstat_named_init(&st->st_hidx, "hidx", KSTAT_DATA_UINT32);
852 	kstat_named_init(&st->st_tidx, "tidx", KSTAT_DATA_UINT32);
853 	kstat_named_init(&st->st_format, "format", KSTAT_DATA_UINT32);
854 	kstat_named_init(&st->st_nchan, "channels", KSTAT_DATA_UINT32);
855 	kstat_named_init(&st->st_rate, "rate", KSTAT_DATA_UINT32);
856 	kstat_named_init(&st->st_intrs, "intrhz", KSTAT_DATA_UINT32);
857 	kstat_named_init(&st->st_errors, "errors", KSTAT_DATA_UINT32);
858 	kstat_named_init(&st->st_engine_overruns, "engine_overruns",
859 	    KSTAT_DATA_UINT32);
860 	kstat_named_init(&st->st_engine_underruns, "engine_underruns",
861 	    KSTAT_DATA_UINT32);
862 	kstat_named_init(&st->st_stream_overruns, "stream_overruns",
863 	    KSTAT_DATA_UINT32);
864 	kstat_named_init(&st->st_stream_underruns, "stream_underruns",
865 	    KSTAT_DATA_UINT32);
866 	kstat_named_init(&st->st_suspended, "suspended", KSTAT_DATA_UINT32);
867 	kstat_install(e->e_ksp);
868 }
869 
870 void
871 audio_dev_add_engine(audio_dev_t *d, audio_engine_t *e)
872 {
873 	e->e_num = d->d_engno++;
874 
875 	mutex_enter(&d->d_lock);
876 
877 	auimpl_engine_ksinit(d, e);
878 
879 	/* check for duplex */
880 	if ((e->e_flags & ENGINE_OUTPUT_CAP) && (d->d_flags & DEV_INPUT_CAP)) {
881 		d->d_flags |= DEV_DUPLEX_CAP;
882 	}
883 	if ((e->e_flags & ENGINE_INPUT_CAP) && (d->d_flags & DEV_OUTPUT_CAP)) {
884 		d->d_flags |= DEV_DUPLEX_CAP;
885 	}
886 	/* add in the direction caps -- must be done after duplex above */
887 	if (e->e_flags & ENGINE_OUTPUT_CAP) {
888 		d->d_flags |= DEV_OUTPUT_CAP;
889 	}
890 	if (e->e_flags & ENGINE_INPUT_CAP) {
891 		d->d_flags |= DEV_INPUT_CAP;
892 	}
893 
894 	list_insert_tail(&d->d_engines, e);
895 	e->e_dev = d;
896 	mutex_exit(&d->d_lock);
897 }
898 
899 void
900 audio_dev_remove_engine(audio_dev_t *d, audio_engine_t *e)
901 {
902 	mutex_enter(&d->d_lock);
903 	list_remove(&d->d_engines, e);
904 	e->e_dev = NULL;
905 	if (e->e_ksp)
906 		kstat_delete(e->e_ksp);
907 	e->e_ksp = NULL;
908 	mutex_exit(&d->d_lock);
909 }
910 
911 /*
912  * Change the number.
913  */
914 void
915 auclnt_set_dev_number(audio_dev_t *d, int num)
916 {
917 	list_t		*l = &auimpl_devs_by_number;
918 	audio_dev_t	*srch;
919 
920 	/* reorder our list */
921 	rw_enter(&auimpl_dev_lock, RW_WRITER);
922 	d->d_number = num;
923 	list_remove(l, d);
924 	for (srch = list_head(l); srch; srch = list_next(l, srch)) {
925 		if (srch->d_number >= d->d_number) {
926 			break;
927 		}
928 	}
929 	list_insert_before(l, srch, d);
930 
931 	rw_exit(&auimpl_dev_lock);
932 }
933 
934 void
935 auclnt_walk_devs(int (*walker)(audio_dev_t *, void *), void *arg)
936 {
937 	audio_dev_t	*d;
938 	boolean_t	cont;
939 	list_t		*l;
940 
941 	l = &auimpl_devs_by_index;
942 	rw_enter(&auimpl_dev_lock, RW_READER);
943 	for (d = list_head(l); d; d = list_next(l, d)) {
944 		mutex_enter(&d->d_lock);
945 		cont = walker(d, arg);
946 		mutex_exit(&d->d_lock);
947 		if (cont == AUDIO_WALK_STOP)
948 			break;
949 	}
950 	rw_exit(&auimpl_dev_lock);
951 }
952 
953 void
954 auclnt_walk_devs_by_number(int (*walker)(audio_dev_t *, void *), void *arg)
955 {
956 	audio_dev_t	*d;
957 	boolean_t	cont;
958 	list_t		*l;
959 
960 	l = &auimpl_devs_by_number;
961 	rw_enter(&auimpl_dev_lock, RW_READER);
962 	for (d = list_head(l); d; d = list_next(l, d)) {
963 		mutex_enter(&d->d_lock);
964 		cont = walker(d, arg);
965 		mutex_exit(&d->d_lock);
966 		if (cont == AUDIO_WALK_STOP)
967 			break;
968 	}
969 	rw_exit(&auimpl_dev_lock);
970 }
971 
972 void
973 auclnt_dev_walk_engines(audio_dev_t *d,
974     int (*walker)(audio_engine_t *, void *),
975     void *arg)
976 {
977 	audio_engine_t *e;
978 	list_t *l = &d->d_engines;
979 
980 	mutex_enter(&d->d_lock);
981 	for (e = list_head(l); e != NULL; e = list_next(l, e)) {
982 		if (walker(e, arg) == AUDIO_WALK_STOP) {
983 			break;
984 		}
985 	}
986 	mutex_exit(&d->d_lock);
987 }
988 
989 int
990 auclnt_engine_get_format(audio_engine_t *e)
991 {
992 	return (ENG_FORMAT(e));
993 }
994 
995 int
996 auclnt_engine_get_channels(audio_engine_t *e)
997 {
998 	return (ENG_CHANNELS(e));
999 }
1000 
1001 int
1002 auclnt_engine_get_rate(audio_engine_t *e)
1003 {
1004 	return (ENG_RATE(e));
1005 }
1006 
1007 unsigned
1008 auclnt_engine_get_capab(audio_engine_t *e)
1009 {
1010 	unsigned capab = 0;
1011 
1012 	if (e->e_flags & ENGINE_INPUT_CAP) {
1013 		capab |= AUDIO_CLIENT_CAP_RECORD;
1014 	}
1015 	if (e->e_flags & ENGINE_OUTPUT_CAP) {
1016 		capab |= AUDIO_CLIENT_CAP_PLAY;
1017 	}
1018 	return (capab);
1019 }
1020 
1021 static void
1022 auimpl_walk_engines(int (*walker)(audio_engine_t *, void *), void *arg)
1023 {
1024 	audio_dev_t	*d;
1025 	audio_engine_t	*e;
1026 	list_t		*l1;
1027 	list_t		*l2;
1028 	boolean_t	done = B_FALSE;
1029 
1030 	rw_enter(&auimpl_dev_lock, RW_READER);
1031 	l1 = &auimpl_devs_by_index;
1032 	for (d = list_head(l1); d; d = list_next(l1, d)) {
1033 		mutex_enter(&d->d_lock);
1034 		l2 = &d->d_engines;
1035 		for (e = list_head(l2); e; e = list_next(l2, e)) {
1036 			if (walker(e, arg) == AUDIO_WALK_STOP) {
1037 				done = B_TRUE;
1038 				break;
1039 			}
1040 		}
1041 		mutex_exit(&d->d_lock);
1042 		if (done)
1043 			break;
1044 	}
1045 	rw_exit(&auimpl_dev_lock);
1046 }
1047 
1048 /*
1049  * This function suspends an engine.  The intent is to pause the
1050  * engine temporarily so that it does not underrun while user threads
1051  * are suspended.  The driver is still responsible for actually doing
1052  * the driver suspend work -- all this does is put the engine in a
1053  * paused state.  It does not prevent, for example, threads from
1054  * accessing the hardware.
1055  *
1056  * A properly implemented driver won't even be aware of the existence
1057  * of this routine -- the driver will just handle the suspend &
1058  * resume.  At the point of suspend & resume, the driver will see that
1059  * the engines are not running (as if all threads had "paused" it).
1060  *
1061  * Failure to execute either of the routines below is not critical,
1062  * but will probably lead to underruns and overflows as the kernel
1063  * driver gets resumed well in advance of the time when user threads
1064  * are ready to start operation.
1065  */
1066 static int
1067 auimpl_engine_suspend(audio_engine_t *e, void *dontcare)
1068 {
1069 	_NOTE(ARGUNUSED(dontcare));
1070 
1071 	mutex_enter(&e->e_lock);
1072 	e->e_suspended = B_TRUE;
1073 	mutex_exit(&e->e_lock);
1074 
1075 	return (AUDIO_WALK_CONTINUE);
1076 }
1077 
1078 static int
1079 auimpl_engine_resume(audio_engine_t *e, void *dontcare)
1080 {
1081 	_NOTE(ARGUNUSED(dontcare));
1082 	mutex_enter(&e->e_lock);
1083 	e->e_suspended = B_FALSE;
1084 	mutex_exit(&e->e_lock);
1085 	return (AUDIO_WALK_CONTINUE);
1086 }
1087 
1088 boolean_t
1089 auimpl_cpr(void *arg, int code)
1090 {
1091 	_NOTE(ARGUNUSED(arg));
1092 
1093 	switch (code) {
1094 	case CB_CODE_CPR_CHKPT:
1095 		auimpl_walk_engines(auimpl_engine_suspend, NULL);
1096 		return (B_TRUE);
1097 
1098 	case CB_CODE_CPR_RESUME:
1099 		auimpl_walk_engines(auimpl_engine_resume, NULL);
1100 		return (B_TRUE);
1101 
1102 	default:
1103 		return (B_FALSE);
1104 	}
1105 }
1106 
1107 static callb_id_t	auimpl_cpr_id = 0;
1108 
1109 void
1110 auimpl_dev_init(void)
1111 {
1112 	rw_init(&auimpl_dev_lock, NULL, RW_DRIVER, NULL);
1113 	list_create(&auimpl_devs_by_index, sizeof (struct audio_dev),
1114 	    offsetof(struct audio_dev, d_by_index));
1115 	list_create(&auimpl_devs_by_number, sizeof (struct audio_dev),
1116 	    offsetof(struct audio_dev, d_by_number));
1117 
1118 	/*
1119 	 * We "borrow" the CB_CL_CPR_PM class, which gets executed at
1120 	 * about the right time for us.  It would be nice to have a
1121 	 * new CB_CL_CPR_AUDIO class, but it isn't critical at this
1122 	 * point.
1123 	 *
1124 	 * Note that we don't care about our thread id.
1125 	 */
1126 	auimpl_cpr_id = callb_add(auimpl_cpr, NULL, CB_CL_CPR_PM, "audio_cpr");
1127 }
1128 
1129 void
1130 auimpl_dev_fini(void)
1131 {
1132 	(void) callb_delete(auimpl_cpr_id);
1133 	list_destroy(&auimpl_devs_by_index);
1134 	list_destroy(&auimpl_devs_by_number);
1135 	rw_destroy(&auimpl_dev_lock);
1136 }
1137 
1138 void
1139 audio_engine_set_private(audio_engine_t *eng, void *prv)
1140 {
1141 	eng->e_private = prv;
1142 }
1143 
1144 void *
1145 audio_engine_get_private(audio_engine_t *eng)
1146 {
1147 	return (eng->e_private);
1148 }
1149 
1150 void
1151 audio_dump_bytes(const uint8_t *w, int dcount)
1152 {
1153 	char		line[64];
1154 	char		*s;
1155 	int		i;
1156 	const int	wrap = 16;
1157 
1158 	s = line;
1159 	line[0] = 0;
1160 
1161 	cmn_err(CE_NOTE, "starting @ %p", (void *)w);
1162 	for (i = 0; i < dcount; i++) {
1163 
1164 		(void) sprintf(s, " %02x", *w);
1165 		s += strlen(s);
1166 		w++;
1167 
1168 		if ((i % wrap) == (wrap - 1)) {
1169 			cmn_err(CE_NOTE, "%08x:%s", i - (wrap - 1), line);
1170 			line[0] = 0;
1171 			s = line;
1172 		}
1173 	}
1174 
1175 	if ((i % wrap) != 0) {
1176 		cmn_err(CE_NOTE, "%08x:%s", i - (i % wrap), line);
1177 	}
1178 }
1179 
1180 void
1181 audio_dump_words(const uint16_t *w, int dcount)
1182 {
1183 	char		line[64];
1184 	char		*s;
1185 	int		i;
1186 	const int	wrap = 8;
1187 
1188 	s = line;
1189 	line[0] = 0;
1190 
1191 	cmn_err(CE_NOTE, "starting @ %p", (void *)w);
1192 	for (i = 0; i < dcount; i++) {
1193 
1194 		(void) sprintf(s, " %04x", *w);
1195 		s += strlen(s);
1196 		w++;
1197 
1198 		if ((i % wrap) == (wrap - 1)) {
1199 			cmn_err(CE_NOTE, "%08x:%s", i - (wrap - 1), line);
1200 			line[0] = 0;
1201 			s = line;
1202 		}
1203 	}
1204 
1205 	if ((i % wrap) != 0) {
1206 		cmn_err(CE_NOTE, "%08x:%s", i - (i % wrap), line);
1207 	}
1208 }
1209 
1210 void
1211 audio_dump_dwords(const uint32_t *w, int dcount)
1212 {
1213 	char		line[128];
1214 	char		*s;
1215 	int		i;
1216 	const int	wrap = 4;
1217 
1218 	s = line;
1219 	line[0] = 0;
1220 
1221 	cmn_err(CE_NOTE, "starting @ %p", (void *)w);
1222 	for (i = 0; i < dcount; i++) {
1223 
1224 		(void) sprintf(s, " %08x", *w);
1225 		s += strlen(s);
1226 		w++;
1227 
1228 		if ((i % wrap) == (wrap - 1)) {
1229 			cmn_err(CE_NOTE, "%08x:%s", i - (wrap - 1), line);
1230 			line[0] = 0;
1231 			s = line;
1232 		}
1233 	}
1234 
1235 	if ((i % wrap) != 0) {
1236 		cmn_err(CE_NOTE, "%08x:%s", i - (i % wrap), line);
1237 	}
1238 }
1239