xref: /freebsd/sys/dev/sound/pcm/channel.c (revision f0a75d274af375d15b97b830966b99a02b7db911)
1 /*-
2  * Copyright (c) 1999 Cameron Grant <cg@freebsd.org>
3  * Portions Copyright by Luigi Rizzo - 1997-99
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27 
28 #include "opt_isa.h"
29 
30 #include <dev/sound/pcm/sound.h>
31 
32 #include "feeder_if.h"
33 
34 SND_DECLARE_FILE("$FreeBSD$");
35 
36 #define MIN_CHUNK_SIZE 		256	/* for uiomove etc. */
37 #if 0
38 #define	DMA_ALIGN_THRESHOLD	4
39 #define	DMA_ALIGN_MASK		(~(DMA_ALIGN_THRESHOLD - 1))
40 #endif
41 
42 #define CHN_STARTED(c)		((c)->flags & CHN_F_TRIGGERED)
43 #define CHN_STOPPED(c)		(!CHN_STARTED(c))
44 #define CHN_DIRSTR(c)		(((c)->direction == PCMDIR_PLAY) ? \
45 				"PCMDIR_PLAY" : "PCMDIR_REC")
46 
47 #define BUF_PARENT(c, b)	\
48 	(((c) != NULL && (c)->parentchannel != NULL && \
49 	(c)->parentchannel->bufhard != NULL) ? \
50 	(c)->parentchannel->bufhard : (b))
51 
52 #define CHN_TIMEOUT	5
53 #define CHN_TIMEOUT_MIN	1
54 #define CHN_TIMEOUT_MAX	10
55 
56 /*
57 #define DEB(x) x
58 */
59 
60 int report_soft_formats = 1;
61 SYSCTL_INT(_hw_snd, OID_AUTO, report_soft_formats, CTLFLAG_RW,
62 	&report_soft_formats, 1, "report software-emulated formats");
63 
64 int chn_latency = CHN_LATENCY_DEFAULT;
65 TUNABLE_INT("hw.snd.latency", &chn_latency);
66 
67 static int
68 sysctl_hw_snd_latency(SYSCTL_HANDLER_ARGS)
69 {
70 	int err, val;
71 
72 	val = chn_latency;
73 	err = sysctl_handle_int(oidp, &val, sizeof(val), req);
74 	if (err != 0 || req->newptr == NULL)
75 		return err;
76 	if (val < CHN_LATENCY_MIN || val > CHN_LATENCY_MAX)
77 		err = EINVAL;
78 	else
79 		chn_latency = val;
80 
81 	return err;
82 }
83 SYSCTL_PROC(_hw_snd, OID_AUTO, latency, CTLTYPE_INT | CTLFLAG_RW,
84 	0, sizeof(int), sysctl_hw_snd_latency, "I",
85 	"buffering latency (0=low ... 10=high)");
86 
87 int chn_latency_profile = CHN_LATENCY_PROFILE_DEFAULT;
88 TUNABLE_INT("hw.snd.latency_profile", &chn_latency_profile);
89 
90 static int
91 sysctl_hw_snd_latency_profile(SYSCTL_HANDLER_ARGS)
92 {
93 	int err, val;
94 
95 	val = chn_latency_profile;
96 	err = sysctl_handle_int(oidp, &val, sizeof(val), req);
97 	if (err != 0 || req->newptr == NULL)
98 		return err;
99 	if (val < CHN_LATENCY_PROFILE_MIN || val > CHN_LATENCY_PROFILE_MAX)
100 		err = EINVAL;
101 	else
102 		chn_latency_profile = val;
103 
104 	return err;
105 }
106 SYSCTL_PROC(_hw_snd, OID_AUTO, latency_profile, CTLTYPE_INT | CTLFLAG_RW,
107 	0, sizeof(int), sysctl_hw_snd_latency_profile, "I",
108 	"buffering latency profile (0=aggresive 1=safe)");
109 
110 static int chn_timeout = CHN_TIMEOUT;
111 TUNABLE_INT("hw.snd.timeout", &chn_timeout);
112 #ifdef SND_DEBUG
113 static int
114 sysctl_hw_snd_timeout(SYSCTL_HANDLER_ARGS)
115 {
116 	int err, val;
117 
118 	val = chn_timeout;
119 	err = sysctl_handle_int(oidp, &val, sizeof(val), req);
120 	if (err != 0 || req->newptr == NULL)
121 		return err;
122 	if (val < CHN_TIMEOUT_MIN || val > CHN_TIMEOUT_MAX)
123 		err = EINVAL;
124 	else
125 		chn_timeout = val;
126 
127 	return err;
128 }
129 SYSCTL_PROC(_hw_snd, OID_AUTO, timeout, CTLTYPE_INT | CTLFLAG_RW,
130 	0, sizeof(int), sysctl_hw_snd_timeout, "I",
131 	"interrupt timeout (1 - 10) seconds");
132 #endif
133 
134 static int chn_usefrags = 0;
135 TUNABLE_INT("hw.snd.usefrags", &chn_usefrags);
136 static int chn_syncdelay = -1;
137 TUNABLE_INT("hw.snd.syncdelay", &chn_syncdelay);
138 #ifdef SND_DEBUG
139 SYSCTL_INT(_hw_snd, OID_AUTO, usefrags, CTLFLAG_RW,
140 	&chn_usefrags, 1, "prefer setfragments() over setblocksize()");
141 SYSCTL_INT(_hw_snd, OID_AUTO, syncdelay, CTLFLAG_RW,
142 	&chn_syncdelay, 1,
143 	"append (0-1000) millisecond trailing buffer delay on each sync");
144 #endif
145 
146 /**
147  * @brief Channel sync group lock
148  *
149  * Clients should acquire this lock @b without holding any channel locks
150  * before touching syncgroups or the main syncgroup list.
151  */
152 struct mtx snd_pcm_syncgroups_mtx;
153 MTX_SYSINIT(pcm_syncgroup, &snd_pcm_syncgroups_mtx, "PCM channel sync group lock", MTX_DEF);
154 /**
155  * @brief syncgroups' master list
156  *
157  * Each time a channel syncgroup is created, it's added to this list.  This
158  * list should only be accessed with @sa snd_pcm_syncgroups_mtx held.
159  *
160  * See SNDCTL_DSP_SYNCGROUP for more information.
161  */
162 struct pcm_synclist snd_pcm_syncgroups = SLIST_HEAD_INITIALIZER(head);
163 
164 static int chn_buildfeeder(struct pcm_channel *c);
165 
166 static void
167 chn_lockinit(struct pcm_channel *c, int dir)
168 {
169 	switch(dir) {
170 	case PCMDIR_PLAY:
171 		c->lock = snd_mtxcreate(c->name, "pcm play channel");
172 		break;
173 	case PCMDIR_REC:
174 		c->lock = snd_mtxcreate(c->name, "pcm record channel");
175 		break;
176 	case PCMDIR_VIRTUAL:
177 		c->lock = snd_mtxcreate(c->name, "pcm virtual play channel");
178 		break;
179 	case 0:
180 		c->lock = snd_mtxcreate(c->name, "pcm fake channel");
181 		break;
182 	}
183 
184 	cv_init(&c->cv, c->name);
185 }
186 
187 static void
188 chn_lockdestroy(struct pcm_channel *c)
189 {
190 	snd_mtxfree(c->lock);
191 	cv_destroy(&c->cv);
192 }
193 
194 /**
195  * @brief Determine channel is ready for I/O
196  *
197  * @retval 1 = ready for I/O
198  * @retval 0 = not ready for I/O
199  */
200 static int
201 chn_polltrigger(struct pcm_channel *c)
202 {
203 	struct snd_dbuf *bs = c->bufsoft;
204 	unsigned amt, lim;
205 
206 	CHN_LOCKASSERT(c);
207 	if (c->flags & CHN_F_MAPPED) {
208 		if (sndbuf_getprevblocks(bs) == 0)
209 			return 1;
210 		else
211 			return (sndbuf_getblocks(bs) > sndbuf_getprevblocks(bs))? 1 : 0;
212 	} else {
213 		amt = (c->direction == PCMDIR_PLAY)? sndbuf_getfree(bs) : sndbuf_getready(bs);
214 #if 0
215 		lim = (c->flags & CHN_F_HAS_SIZE)? sndbuf_getblksz(bs) : 1;
216 #endif
217 		lim = c->lw;
218 		return (amt >= lim) ? 1 : 0;
219 	}
220 	return 0;
221 }
222 
223 static int
224 chn_pollreset(struct pcm_channel *c)
225 {
226 	struct snd_dbuf *bs = c->bufsoft;
227 
228 	CHN_LOCKASSERT(c);
229 	sndbuf_updateprevtotal(bs);
230 	return 1;
231 }
232 
233 static void
234 chn_wakeup(struct pcm_channel *c)
235 {
236 	struct snd_dbuf *bs = c->bufsoft;
237 	struct pcmchan_children *pce;
238 
239 	CHN_LOCKASSERT(c);
240 	if (SLIST_EMPTY(&c->children)) {
241 		if (SEL_WAITING(sndbuf_getsel(bs)) && chn_polltrigger(c))
242 			selwakeuppri(sndbuf_getsel(bs), PRIBIO);
243 		wakeup_one(bs);
244 	} else {
245 		SLIST_FOREACH(pce, &c->children, link) {
246 			CHN_LOCK(pce->channel);
247 			chn_wakeup(pce->channel);
248 			CHN_UNLOCK(pce->channel);
249 		}
250 	}
251 }
252 
253 static int
254 chn_sleep(struct pcm_channel *c, char *str, int timeout)
255 {
256     	struct snd_dbuf *bs = c->bufsoft;
257 	int ret;
258 
259 	CHN_LOCKASSERT(c);
260 #ifdef USING_MUTEX
261 	ret = msleep(bs, c->lock, PRIBIO | PCATCH, str, timeout);
262 #else
263 	ret = tsleep(bs, PRIBIO | PCATCH, str, timeout);
264 #endif
265 
266 	return ret;
267 }
268 
269 /*
270  * chn_dmaupdate() tracks the status of a dma transfer,
271  * updating pointers.
272  */
273 
274 static unsigned int
275 chn_dmaupdate(struct pcm_channel *c)
276 {
277 	struct snd_dbuf *b = c->bufhard;
278 	unsigned int delta, old, hwptr, amt;
279 
280 	KASSERT(sndbuf_getsize(b) > 0, ("bufsize == 0"));
281 	CHN_LOCKASSERT(c);
282 
283 	old = sndbuf_gethwptr(b);
284 	hwptr = chn_getptr(c);
285 	delta = (sndbuf_getsize(b) + hwptr - old) % sndbuf_getsize(b);
286 	sndbuf_sethwptr(b, hwptr);
287 
288 	DEB(
289 	if (delta >= ((sndbuf_getsize(b) * 15) / 16)) {
290 		if (!(c->flags & (CHN_F_CLOSING | CHN_F_ABORTING)))
291 			device_printf(c->dev, "hwptr went backwards %d -> %d\n", old, hwptr);
292 	}
293 	);
294 
295 	if (c->direction == PCMDIR_PLAY) {
296 		amt = min(delta, sndbuf_getready(b));
297 		amt -= amt % sndbuf_getbps(b);
298 		if (amt > 0)
299 			sndbuf_dispose(b, NULL, amt);
300 	} else {
301 		amt = min(delta, sndbuf_getfree(b));
302 		amt -= amt % sndbuf_getbps(b);
303 		if (amt > 0)
304 		       sndbuf_acquire(b, NULL, amt);
305 	}
306 	if (snd_verbose > 3 && CHN_STARTED(c) && delta == 0) {
307 		device_printf(c->dev, "WARNING: %s DMA completion "
308 			"too fast/slow ! hwptr=%u, old=%u "
309 			"delta=%u amt=%u ready=%u free=%u\n",
310 			CHN_DIRSTR(c), hwptr, old, delta, amt,
311 			sndbuf_getready(b), sndbuf_getfree(b));
312 	}
313 
314 	return delta;
315 }
316 
317 void
318 chn_wrupdate(struct pcm_channel *c)
319 {
320 	int ret;
321 
322 	CHN_LOCKASSERT(c);
323 	KASSERT(c->direction == PCMDIR_PLAY, ("chn_wrupdate on bad channel"));
324 
325 	if ((c->flags & (CHN_F_MAPPED | CHN_F_VIRTUAL)) || CHN_STOPPED(c))
326 		return;
327 	chn_dmaupdate(c);
328 	ret = chn_wrfeed(c);
329 	/* tell the driver we've updated the primary buffer */
330 	chn_trigger(c, PCMTRIG_EMLDMAWR);
331 	DEB(if (ret)
332 		printf("chn_wrupdate: chn_wrfeed returned %d\n", ret);)
333 
334 }
335 
336 int
337 chn_wrfeed(struct pcm_channel *c)
338 {
339     	struct snd_dbuf *b = c->bufhard;
340     	struct snd_dbuf *bs = c->bufsoft;
341 	unsigned int ret, amt;
342 
343 	CHN_LOCKASSERT(c);
344 #if 0
345     	DEB(
346 	if (c->flags & CHN_F_CLOSING) {
347 		sndbuf_dump(b, "b", 0x02);
348 		sndbuf_dump(bs, "bs", 0x02);
349 	})
350 #endif
351 
352 	if ((c->flags & CHN_F_MAPPED) && !(c->flags & CHN_F_CLOSING))
353 		sndbuf_acquire(bs, NULL, sndbuf_getfree(bs));
354 
355 	amt = sndbuf_getfree(b);
356 	DEB(if (amt > sndbuf_getsize(bs) &&
357 		    sndbuf_getbps(bs) >= sndbuf_getbps(b)) {
358 		printf("%s(%s): amt %d > source size %d, flags 0x%x", __func__, c->name,
359 		    amt, sndbuf_getsize(bs), c->flags);
360 	});
361 
362 	ret = (amt > 0) ? sndbuf_feed(bs, b, c, c->feeder, amt) : ENOSPC;
363 	/*
364 	 * Possible xruns. There should be no empty space left in buffer.
365 	 */
366 	if (sndbuf_getfree(b) > 0)
367 		c->xruns++;
368 
369 	if (sndbuf_getfree(b) < amt)
370 		chn_wakeup(c);
371 
372 	return ret;
373 }
374 
375 static void
376 chn_wrintr(struct pcm_channel *c)
377 {
378 	int ret;
379 
380 	CHN_LOCKASSERT(c);
381 	/* update pointers in primary buffer */
382 	chn_dmaupdate(c);
383 	/* ...and feed from secondary to primary */
384 	ret = chn_wrfeed(c);
385 	/* tell the driver we've updated the primary buffer */
386 	chn_trigger(c, PCMTRIG_EMLDMAWR);
387 	DEB(if (ret)
388 		printf("chn_wrintr: chn_wrfeed returned %d\n", ret);)
389 }
390 
391 /*
392  * user write routine - uiomove data into secondary buffer, trigger if necessary
393  * if blocking, sleep, rinse and repeat.
394  *
395  * called externally, so must handle locking
396  */
397 
398 int
399 chn_write(struct pcm_channel *c, struct uio *buf)
400 {
401 	struct snd_dbuf *bs = c->bufsoft;
402 	void *off;
403 	int ret, timeout, sz, t, p;
404 
405 	CHN_LOCKASSERT(c);
406 
407 	ret = 0;
408 	timeout = chn_timeout * hz;
409 
410 	while (ret == 0 && buf->uio_resid > 0) {
411 		sz = min(buf->uio_resid, sndbuf_getfree(bs));
412 		if (sz > 0) {
413 			/*
414 			 * The following assumes that the free space in
415 			 * the buffer can never be less around the
416 			 * unlock-uiomove-lock sequence.
417 			 */
418 			while (ret == 0 && sz > 0) {
419 				p = sndbuf_getfreeptr(bs);
420 				t = min(sz, sndbuf_getsize(bs) - p);
421 				off = sndbuf_getbufofs(bs, p);
422 				CHN_UNLOCK(c);
423 				ret = uiomove(off, t, buf);
424 				CHN_LOCK(c);
425 				sz -= t;
426 				sndbuf_acquire(bs, NULL, t);
427 			}
428 			ret = 0;
429 			if (CHN_STOPPED(c))
430 				chn_start(c, 0);
431 		} else if (c->flags & (CHN_F_NBIO | CHN_F_NOTRIGGER)) {
432 			/**
433 			 * @todo Evaluate whether EAGAIN is truly desirable.
434 			 * 	 4Front drivers behave like this, but I'm
435 			 * 	 not sure if it at all violates the "write
436 			 * 	 should be allowed to block" model.
437 			 *
438 			 * 	 The idea is that, while set with CHN_F_NOTRIGGER,
439 			 * 	 a channel isn't playing, *but* without this we
440 			 * 	 end up with "interrupt timeout / channel dead".
441 			 */
442 			ret = EAGAIN;
443 		} else {
444    			ret = chn_sleep(c, "pcmwr", timeout);
445 			if (ret == EAGAIN) {
446 				ret = EINVAL;
447 				c->flags |= CHN_F_DEAD;
448 				printf("%s: play interrupt timeout, "
449 				    "channel dead\n", c->name);
450 			} else if (ret == ERESTART || ret == EINTR)
451 				c->flags |= CHN_F_ABORTING;
452 		}
453 	}
454 
455 	return ret;
456 }
457 
458 #if 0
459 static int
460 chn_rddump(struct pcm_channel *c, unsigned int cnt)
461 {
462     	struct snd_dbuf *b = c->bufhard;
463 
464 	CHN_LOCKASSERT(c);
465 #if 0
466 	static u_int32_t kk = 0;
467 	printf("%u: dumping %d bytes\n", ++kk, cnt);
468 #endif
469 	c->xruns++;
470 	sndbuf_setxrun(b, sndbuf_getxrun(b) + cnt);
471 	return sndbuf_dispose(b, NULL, cnt);
472 }
473 #endif
474 
475 /*
476  * Feed new data from the read buffer. Can be called in the bottom half.
477  */
478 int
479 chn_rdfeed(struct pcm_channel *c)
480 {
481     	struct snd_dbuf *b = c->bufhard;
482     	struct snd_dbuf *bs = c->bufsoft;
483 	unsigned int ret, amt;
484 
485 	CHN_LOCKASSERT(c);
486     	DEB(
487 	if (c->flags & CHN_F_CLOSING) {
488 		sndbuf_dump(b, "b", 0x02);
489 		sndbuf_dump(bs, "bs", 0x02);
490 	})
491 
492 #if 0
493 	amt = sndbuf_getready(b);
494 	if (sndbuf_getfree(bs) < amt) {
495 		c->xruns++;
496 		amt = sndbuf_getfree(bs);
497 	}
498 #endif
499 	amt = sndbuf_getfree(bs);
500 	ret = (amt > 0) ? sndbuf_feed(b, bs, c, c->feeder, amt) : 0;
501 
502 	amt = sndbuf_getready(b);
503 	if (amt > 0) {
504 		c->xruns++;
505 		sndbuf_dispose(b, NULL, amt);
506 	}
507 
508 	if (sndbuf_getready(bs) > 0)
509 		chn_wakeup(c);
510 
511 	return ret;
512 }
513 
514 void
515 chn_rdupdate(struct pcm_channel *c)
516 {
517 	int ret;
518 
519 	CHN_LOCKASSERT(c);
520 	KASSERT(c->direction == PCMDIR_REC, ("chn_rdupdate on bad channel"));
521 
522 	if ((c->flags & CHN_F_MAPPED) || CHN_STOPPED(c))
523 		return;
524 	chn_trigger(c, PCMTRIG_EMLDMARD);
525 	chn_dmaupdate(c);
526 	ret = chn_rdfeed(c);
527 	DEB(if (ret)
528 		printf("chn_rdfeed: %d\n", ret);)
529 
530 }
531 
532 /* read interrupt routine. Must be called with interrupts blocked. */
533 static void
534 chn_rdintr(struct pcm_channel *c)
535 {
536 	int ret;
537 
538 	CHN_LOCKASSERT(c);
539 	/* tell the driver to update the primary buffer if non-dma */
540 	chn_trigger(c, PCMTRIG_EMLDMARD);
541 	/* update pointers in primary buffer */
542 	chn_dmaupdate(c);
543 	/* ...and feed from primary to secondary */
544 	ret = chn_rdfeed(c);
545 }
546 
547 /*
548  * user read routine - trigger if necessary, uiomove data from secondary buffer
549  * if blocking, sleep, rinse and repeat.
550  *
551  * called externally, so must handle locking
552  */
553 
554 int
555 chn_read(struct pcm_channel *c, struct uio *buf)
556 {
557 	struct snd_dbuf *bs = c->bufsoft;
558 	void *off;
559 	int ret, timeout, sz, t, p;
560 
561 	CHN_LOCKASSERT(c);
562 
563 	if (CHN_STOPPED(c))
564 		chn_start(c, 0);
565 
566 	ret = 0;
567 	timeout = chn_timeout * hz;
568 
569 	while (ret == 0 && buf->uio_resid > 0) {
570 		sz = min(buf->uio_resid, sndbuf_getready(bs));
571 		if (sz > 0) {
572 			/*
573 			 * The following assumes that the free space in
574 			 * the buffer can never be less around the
575 			 * unlock-uiomove-lock sequence.
576 			 */
577 			while (ret == 0 && sz > 0) {
578 				p = sndbuf_getreadyptr(bs);
579 				t = min(sz, sndbuf_getsize(bs) - p);
580 				off = sndbuf_getbufofs(bs, p);
581 				CHN_UNLOCK(c);
582 				ret = uiomove(off, t, buf);
583 				CHN_LOCK(c);
584 				sz -= t;
585 				sndbuf_dispose(bs, NULL, t);
586 			}
587 			ret = 0;
588 		} else if (c->flags & (CHN_F_NBIO | CHN_F_NOTRIGGER))
589 			ret = EAGAIN;
590 		else {
591    			ret = chn_sleep(c, "pcmrd", timeout);
592 			if (ret == EAGAIN) {
593 				ret = EINVAL;
594 				c->flags |= CHN_F_DEAD;
595 				printf("%s: record interrupt timeout, "
596 				    "channel dead\n", c->name);
597 			} else if (ret == ERESTART || ret == EINTR)
598 				c->flags |= CHN_F_ABORTING;
599 		}
600 	}
601 
602 	return ret;
603 }
604 
605 void
606 chn_intr(struct pcm_channel *c)
607 {
608 	CHN_LOCK(c);
609 	c->interrupts++;
610 	if (c->direction == PCMDIR_PLAY)
611 		chn_wrintr(c);
612 	else
613 		chn_rdintr(c);
614 	CHN_UNLOCK(c);
615 }
616 
617 u_int32_t
618 chn_start(struct pcm_channel *c, int force)
619 {
620 	u_int32_t i, j;
621 	struct snd_dbuf *b = c->bufhard;
622 	struct snd_dbuf *bs = c->bufsoft;
623 
624 	CHN_LOCKASSERT(c);
625 	/* if we're running, or if we're prevented from triggering, bail */
626 	if (CHN_STARTED(c) || ((c->flags & CHN_F_NOTRIGGER) && !force))
627 		return EINVAL;
628 
629 	if (force) {
630 		i = 1;
631 		j = 0;
632 	} else {
633 		if (c->direction == PCMDIR_REC) {
634 			i = sndbuf_getfree(bs);
635 			j = (i > 0) ? 1 : sndbuf_getready(b);
636 		} else {
637 			if (sndbuf_getfree(bs) == 0) {
638 				i = 1;
639 				j = 0;
640 			} else {
641 				struct snd_dbuf *pb;
642 
643 				pb = BUF_PARENT(c, b);
644 				i = sndbuf_xbytes(sndbuf_getready(bs), bs, pb);
645 				j = sndbuf_getbps(pb);
646 			}
647 		}
648 		if (snd_verbose > 3 && SLIST_EMPTY(&c->children))
649 			printf("%s: %s (%s) threshold i=%d j=%d\n",
650 			    __func__, CHN_DIRSTR(c),
651 			    (c->flags & CHN_F_VIRTUAL) ? "virtual" : "hardware",
652 			    i, j);
653 	}
654 
655 	if (i >= j) {
656 		c->flags |= CHN_F_TRIGGERED;
657 		sndbuf_setrun(b, 1);
658 		c->feedcount = (c->flags & CHN_F_CLOSING) ? 2 : 0;
659 		c->interrupts = 0;
660 		c->xruns = 0;
661 		if (c->direction == PCMDIR_PLAY && c->parentchannel == NULL) {
662 			sndbuf_fillsilence(b);
663 			if (snd_verbose > 3)
664 				printf("%s: %s starting! (%s) (ready=%d "
665 				    "force=%d i=%d j=%d intrtimeout=%u "
666 				    "latency=%dms)\n",
667 				    __func__,
668 				    (c->flags & CHN_F_HAS_VCHAN) ?
669 				    "VCHAN" : "HW",
670 				    (c->flags & CHN_F_CLOSING) ? "closing" :
671 				    "running",
672 				    sndbuf_getready(b),
673 				    force, i, j, c->timeout,
674 				    (sndbuf_getsize(b) * 1000) /
675 				    (sndbuf_getbps(b) * sndbuf_getspd(b)));
676 		}
677 	    	chn_trigger(c, PCMTRIG_START);
678 		return 0;
679 	}
680 
681 	return 0;
682 }
683 
684 void
685 chn_resetbuf(struct pcm_channel *c)
686 {
687 	struct snd_dbuf *b = c->bufhard;
688 	struct snd_dbuf *bs = c->bufsoft;
689 
690 	c->blocks = 0;
691 	sndbuf_reset(b);
692 	sndbuf_reset(bs);
693 }
694 
695 /*
696  * chn_sync waits until the space in the given channel goes above
697  * a threshold. The threshold is checked against fl or rl respectively.
698  * Assume that the condition can become true, do not check here...
699  */
700 int
701 chn_sync(struct pcm_channel *c, int threshold)
702 {
703     	struct snd_dbuf *b, *bs;
704 	int ret, count, hcount, minflush, resid, residp, syncdelay, blksz;
705 	u_int32_t cflag;
706 
707 	CHN_LOCKASSERT(c);
708 
709 	bs = c->bufsoft;
710 
711 	if ((c->flags & (CHN_F_DEAD | CHN_F_ABORTING)) ||
712 	    (threshold < 1 && sndbuf_getready(bs) < 1))
713 		return 0;
714 
715 	if (c->direction != PCMDIR_PLAY)
716 		return EINVAL;
717 
718 	/* if we haven't yet started and nothing is buffered, else start*/
719 	if (CHN_STOPPED(c)) {
720 		if (threshold > 0 || sndbuf_getready(bs) > 0) {
721 			ret = chn_start(c, 1);
722 			if (ret)
723 				return ret;
724 		} else
725 			return 0;
726 	}
727 
728 	b = BUF_PARENT(c, c->bufhard);
729 
730 	minflush = threshold + sndbuf_xbytes(sndbuf_getready(b), b, bs);
731 
732 	syncdelay = chn_syncdelay;
733 
734 	if (syncdelay < 0 && (threshold > 0 || sndbuf_getready(bs) > 0))
735 		minflush += sndbuf_xbytes(sndbuf_getsize(b), b, bs);
736 
737 	/*
738 	 * Append (0-1000) millisecond trailing buffer (if needed)
739 	 * for slower / high latency hardwares (notably USB audio)
740 	 * to avoid audible truncation.
741 	 */
742 	if (syncdelay > 0)
743 		minflush += (sndbuf_getbps(bs) * sndbuf_getspd(bs) *
744 		    ((syncdelay > 1000) ? 1000 : syncdelay)) / 1000;
745 
746 	minflush -= minflush % sndbuf_getbps(bs);
747 
748 	if (minflush > 0) {
749 		threshold = min(minflush, sndbuf_getfree(bs));
750 		sndbuf_clear(bs, threshold);
751 		sndbuf_acquire(bs, NULL, threshold);
752 		minflush -= threshold;
753 	}
754 
755 	resid = sndbuf_getready(bs);
756 	residp = resid;
757 	blksz = sndbuf_getblksz(b);
758 	if (blksz < 1) {
759 		printf("%s: WARNING: blksz < 1 ! maxsize=%d [%d/%d/%d]\n",
760 		    __func__, sndbuf_getmaxsize(b), sndbuf_getsize(b),
761 		    sndbuf_getblksz(b), sndbuf_getblkcnt(b));
762 		if (sndbuf_getblkcnt(b) > 0)
763 			blksz = sndbuf_getsize(b) / sndbuf_getblkcnt(b);
764 		if (blksz < 1)
765 			blksz = 1;
766 	}
767 	count = sndbuf_xbytes(minflush + resid, bs, b) / blksz;
768 	hcount = count;
769 	ret = 0;
770 
771 	if (snd_verbose > 3)
772 		printf("%s: [begin] timeout=%d count=%d "
773 		    "minflush=%d resid=%d\n", __func__, c->timeout, count,
774 		    minflush, resid);
775 
776 	cflag = c->flags & CHN_F_CLOSING;
777 	c->flags |= CHN_F_CLOSING;
778 	while (count > 0 && (resid > 0 || minflush > 0)) {
779 		ret = chn_sleep(c, "pcmsyn", c->timeout);
780     		if (ret == ERESTART || ret == EINTR) {
781 			c->flags |= CHN_F_ABORTING;
782 			break;
783 		}
784 		if (ret == 0 || ret == EAGAIN) {
785 			resid = sndbuf_getready(bs);
786 			if (resid == residp) {
787 				--count;
788 				if (snd_verbose > 3)
789 					printf("%s: [stalled] timeout=%d "
790 					    "count=%d hcount=%d "
791 					    "resid=%d minflush=%d\n",
792 					    __func__, c->timeout, count,
793 					    hcount, resid, minflush);
794 			} else if (resid < residp && count < hcount) {
795 				++count;
796 				if (snd_verbose > 3)
797 					printf("%s: [resume] timeout=%d "
798 					    "count=%d hcount=%d "
799 					    "resid=%d minflush=%d\n",
800 					    __func__, c->timeout, count,
801 					    hcount, resid, minflush);
802 			}
803 			if (minflush > 0 && sndbuf_getfree(bs) > 0) {
804 				threshold = min(minflush,
805 				    sndbuf_getfree(bs));
806 				sndbuf_clear(bs, threshold);
807 				sndbuf_acquire(bs, NULL, threshold);
808 				resid = sndbuf_getready(bs);
809 				minflush -= threshold;
810 			}
811 			residp = resid;
812 		}
813 	}
814 	c->flags &= ~CHN_F_CLOSING;
815 	c->flags |= cflag;
816 
817 	if (snd_verbose > 3)
818 		printf("%s: timeout=%d count=%d hcount=%d resid=%d residp=%d "
819 		    "minflush=%d ret=%d\n",
820 		    __func__, c->timeout, count, hcount, resid, residp,
821 		    minflush, ret);
822 
823     	return 0;
824 }
825 
826 /* called externally, handle locking */
827 int
828 chn_poll(struct pcm_channel *c, int ev, struct thread *td)
829 {
830 	struct snd_dbuf *bs = c->bufsoft;
831 	int ret;
832 
833 	CHN_LOCKASSERT(c);
834     	if (!(c->flags & (CHN_F_MAPPED | CHN_F_TRIGGERED)))
835 		chn_start(c, 1);
836 	ret = 0;
837 	if (chn_polltrigger(c) && chn_pollreset(c))
838 		ret = ev;
839 	else
840 		selrecord(td, sndbuf_getsel(bs));
841 	return ret;
842 }
843 
844 /*
845  * chn_abort terminates a running dma transfer.  it may sleep up to 200ms.
846  * it returns the number of bytes that have not been transferred.
847  *
848  * called from: dsp_close, dsp_ioctl, with channel locked
849  */
850 int
851 chn_abort(struct pcm_channel *c)
852 {
853     	int missing = 0;
854     	struct snd_dbuf *b = c->bufhard;
855     	struct snd_dbuf *bs = c->bufsoft;
856 
857 	CHN_LOCKASSERT(c);
858 	if (CHN_STOPPED(c))
859 		return 0;
860 	c->flags |= CHN_F_ABORTING;
861 
862 	c->flags &= ~CHN_F_TRIGGERED;
863 	/* kill the channel */
864 	chn_trigger(c, PCMTRIG_ABORT);
865 	sndbuf_setrun(b, 0);
866 	if (!(c->flags & CHN_F_VIRTUAL))
867 		chn_dmaupdate(c);
868     	missing = sndbuf_getready(bs);
869 
870 	c->flags &= ~CHN_F_ABORTING;
871 	return missing;
872 }
873 
874 /*
875  * this routine tries to flush the dma transfer. It is called
876  * on a close of a playback channel.
877  * first, if there is data in the buffer, but the dma has not yet
878  * begun, we need to start it.
879  * next, we wait for the play buffer to drain
880  * finally, we stop the dma.
881  *
882  * called from: dsp_close, not valid for record channels.
883  */
884 
885 int
886 chn_flush(struct pcm_channel *c)
887 {
888     	struct snd_dbuf *b = c->bufhard;
889 
890 	CHN_LOCKASSERT(c);
891 	KASSERT(c->direction == PCMDIR_PLAY, ("chn_flush on bad channel"));
892     	DEB(printf("chn_flush: c->flags 0x%08x\n", c->flags));
893 
894 	c->flags |= CHN_F_CLOSING;
895 	chn_sync(c, 0);
896 	c->flags &= ~CHN_F_TRIGGERED;
897 	/* kill the channel */
898 	chn_trigger(c, PCMTRIG_ABORT);
899 	sndbuf_setrun(b, 0);
900 
901     	c->flags &= ~CHN_F_CLOSING;
902     	return 0;
903 }
904 
905 int
906 fmtvalid(u_int32_t fmt, u_int32_t *fmtlist)
907 {
908 	int i;
909 
910 	for (i = 0; fmtlist[i]; i++)
911 		if (fmt == fmtlist[i])
912 			return 1;
913 	return 0;
914 }
915 
916 static struct afmtstr_table default_afmtstr_table[] = {
917 	{  "alaw", AFMT_A_LAW  }, { "mulaw", AFMT_MU_LAW },
918 	{    "u8", AFMT_U8     }, {    "s8", AFMT_S8     },
919 	{ "s16le", AFMT_S16_LE }, { "s16be", AFMT_S16_BE },
920 	{ "u16le", AFMT_U16_LE }, { "u16be", AFMT_U16_BE },
921 	{ "s24le", AFMT_S24_LE }, { "s24be", AFMT_S24_BE },
922 	{ "u24le", AFMT_U24_LE }, { "u24be", AFMT_U24_BE },
923 	{ "s32le", AFMT_S32_LE }, { "s32be", AFMT_S32_BE },
924 	{ "u32le", AFMT_U32_LE }, { "u32be", AFMT_U32_BE },
925 	{    NULL, 0           },
926 };
927 
928 int
929 afmtstr_swap_sign(char *s)
930 {
931 	if (s == NULL || strlen(s) < 2) /* full length of "s8" */
932 		return 0;
933 	if (*s == 's')
934 		*s = 'u';
935 	else if (*s == 'u')
936 		*s = 's';
937 	else
938 		return 0;
939 	return 1;
940 }
941 
942 int
943 afmtstr_swap_endian(char *s)
944 {
945 	if (s == NULL || strlen(s) < 5) /* full length of "s16le" */
946 		return 0;
947 	if (s[3] == 'l')
948 		s[3] = 'b';
949 	else if (s[3] == 'b')
950 		s[3] = 'l';
951 	else
952 		return 0;
953 	return 1;
954 }
955 
956 u_int32_t
957 afmtstr2afmt(struct afmtstr_table *tbl, const char *s, int stereo)
958 {
959 	size_t fsz, sz;
960 
961 	sz = (s == NULL) ? 0 : strlen(s);
962 
963 	if (sz > 1) {
964 
965 		if (tbl == NULL)
966 			tbl = default_afmtstr_table;
967 
968 		for (; tbl->fmtstr != NULL; tbl++) {
969 			fsz = strlen(tbl->fmtstr);
970 			if (sz < fsz)
971 				continue;
972 			if (strncmp(s, tbl->fmtstr, fsz) != 0)
973 				continue;
974 			if (fsz == sz)
975 				return tbl->format |
976 					    ((stereo) ? AFMT_STEREO : 0);
977 			if ((sz - fsz) < 2 || s[fsz] != ':')
978 				break;
979 			/*
980 			 * For now, just handle mono/stereo.
981 			 */
982 			if ((s[fsz + 2] == '\0' && (s[fsz + 1] == 'm' ||
983 				    s[fsz + 1] == '1')) ||
984 				    strcmp(s + fsz + 1, "mono") == 0)
985 				return tbl->format;
986 			if ((s[fsz + 2] == '\0' && (s[fsz + 1] == 's' ||
987 				    s[fsz + 1] == '2')) ||
988 				    strcmp(s + fsz + 1, "stereo") == 0)
989 				return tbl->format | AFMT_STEREO;
990 			break;
991 		}
992 	}
993 
994 	return 0;
995 }
996 
997 u_int32_t
998 afmt2afmtstr(struct afmtstr_table *tbl, u_int32_t afmt, char *dst,
999 					size_t len, int type, int stereo)
1000 {
1001 	u_int32_t fmt = 0;
1002 	char *fmtstr = NULL, *tag = "";
1003 
1004 	if (tbl == NULL)
1005 		tbl = default_afmtstr_table;
1006 
1007 	for (; tbl->format != 0; tbl++) {
1008 		if (tbl->format == 0)
1009 			break;
1010 		if ((afmt & ~AFMT_STEREO) != tbl->format)
1011 			continue;
1012 		fmt = afmt;
1013 		fmtstr = tbl->fmtstr;
1014 		break;
1015 	}
1016 
1017 	if (fmt != 0 && fmtstr != NULL && dst != NULL && len > 0) {
1018 		strlcpy(dst, fmtstr, len);
1019 		switch (type) {
1020 		case AFMTSTR_SIMPLE:
1021 			tag = (fmt & AFMT_STEREO) ? ":s" : ":m";
1022 			break;
1023 		case AFMTSTR_NUM:
1024 			tag = (fmt & AFMT_STEREO) ? ":2" : ":1";
1025 			break;
1026 		case AFMTSTR_FULL:
1027 			tag = (fmt & AFMT_STEREO) ? ":stereo" : ":mono";
1028 			break;
1029 		case AFMTSTR_NONE:
1030 		default:
1031 			break;
1032 		}
1033 		if (strlen(tag) > 0 && ((stereo && !(fmt & AFMT_STEREO)) || \
1034 			    (!stereo && (fmt & AFMT_STEREO))))
1035 			strlcat(dst, tag, len);
1036 	}
1037 
1038 	return fmt;
1039 }
1040 
1041 int
1042 chn_reset(struct pcm_channel *c, u_int32_t fmt)
1043 {
1044 	int hwspd, r;
1045 
1046 	CHN_LOCKASSERT(c);
1047 	c->feedcount = 0;
1048 	c->flags &= CHN_F_RESET;
1049 	c->interrupts = 0;
1050 	c->timeout = 1;
1051 	c->xruns = 0;
1052 
1053 	r = CHANNEL_RESET(c->methods, c->devinfo);
1054 	if (fmt != 0) {
1055 #if 0
1056 		hwspd = DSP_DEFAULT_SPEED;
1057 		/* only do this on a record channel until feederbuilder works */
1058 		if (c->direction == PCMDIR_REC)
1059 			RANGE(hwspd, chn_getcaps(c)->minspeed, chn_getcaps(c)->maxspeed);
1060 		c->speed = hwspd;
1061 #endif
1062 		hwspd = chn_getcaps(c)->minspeed;
1063 		c->speed = hwspd;
1064 
1065 		if (r == 0)
1066 			r = chn_setformat(c, fmt);
1067 		if (r == 0)
1068 			r = chn_setspeed(c, hwspd);
1069 #if 0
1070 		if (r == 0)
1071 			r = chn_setvolume(c, 100, 100);
1072 #endif
1073 	}
1074 	if (r == 0)
1075 		r = chn_setlatency(c, chn_latency);
1076 	if (r == 0) {
1077 		chn_resetbuf(c);
1078 		r = CHANNEL_RESETDONE(c->methods, c->devinfo);
1079 	}
1080 	return r;
1081 }
1082 
1083 int
1084 chn_init(struct pcm_channel *c, void *devinfo, int dir, int direction)
1085 {
1086 	struct feeder_class *fc;
1087 	struct snd_dbuf *b, *bs;
1088 	int ret;
1089 
1090 	if (chn_timeout < CHN_TIMEOUT_MIN || chn_timeout > CHN_TIMEOUT_MAX)
1091 		chn_timeout = CHN_TIMEOUT;
1092 
1093 	chn_lockinit(c, dir);
1094 
1095 	b = NULL;
1096 	bs = NULL;
1097 	c->devinfo = NULL;
1098 	c->feeder = NULL;
1099 	c->latency = -1;
1100 	c->timeout = 1;
1101 
1102 	ret = ENOMEM;
1103 	b = sndbuf_create(c->dev, c->name, "primary", c);
1104 	if (b == NULL)
1105 		goto out;
1106 	bs = sndbuf_create(c->dev, c->name, "secondary", c);
1107 	if (bs == NULL)
1108 		goto out;
1109 
1110 	CHN_LOCK(c);
1111 
1112 	ret = EINVAL;
1113 	fc = feeder_getclass(NULL);
1114 	if (fc == NULL)
1115 		goto out;
1116 	if (chn_addfeeder(c, fc, NULL))
1117 		goto out;
1118 
1119 	/*
1120 	 * XXX - sndbuf_setup() & sndbuf_resize() expect to be called
1121 	 *	 with the channel unlocked because they are also called
1122 	 *	 from driver methods that don't know about locking
1123 	 */
1124 	CHN_UNLOCK(c);
1125 	sndbuf_setup(bs, NULL, 0);
1126 	CHN_LOCK(c);
1127 	c->bufhard = b;
1128 	c->bufsoft = bs;
1129 	c->flags = 0;
1130 	c->feederflags = 0;
1131 	c->sm = NULL;
1132 
1133 	ret = ENODEV;
1134 	CHN_UNLOCK(c); /* XXX - Unlock for CHANNEL_INIT() malloc() call */
1135 	c->devinfo = CHANNEL_INIT(c->methods, devinfo, b, c, direction);
1136 	CHN_LOCK(c);
1137 	if (c->devinfo == NULL)
1138 		goto out;
1139 
1140 	ret = ENOMEM;
1141 	if ((sndbuf_getsize(b) == 0) && ((c->flags & CHN_F_VIRTUAL) == 0))
1142 		goto out;
1143 
1144 	ret = chn_setdir(c, direction);
1145 	if (ret)
1146 		goto out;
1147 
1148 	ret = sndbuf_setfmt(b, AFMT_U8);
1149 	if (ret)
1150 		goto out;
1151 
1152 	ret = sndbuf_setfmt(bs, AFMT_U8);
1153 	if (ret)
1154 		goto out;
1155 
1156 	/**
1157 	 * @todo Should this be moved somewhere else?  The primary buffer
1158 	 * 	 is allocated by the driver or via DMA map setup, and tmpbuf
1159 	 * 	 seems to only come into existence in sndbuf_resize().
1160 	 */
1161 	if (c->direction == PCMDIR_PLAY) {
1162 		bs->sl = sndbuf_getmaxsize(bs);
1163 		bs->shadbuf = malloc(bs->sl, M_DEVBUF, M_NOWAIT);
1164 		if (bs->shadbuf == NULL) {
1165 			ret = ENOMEM;
1166 			goto out;
1167 		}
1168 	}
1169 
1170 out:
1171 	CHN_UNLOCK(c);
1172 	if (ret) {
1173 		if (c->devinfo) {
1174 			if (CHANNEL_FREE(c->methods, c->devinfo))
1175 				sndbuf_free(b);
1176 		}
1177 		if (bs)
1178 			sndbuf_destroy(bs);
1179 		if (b)
1180 			sndbuf_destroy(b);
1181 		c->flags |= CHN_F_DEAD;
1182 		chn_lockdestroy(c);
1183 
1184 		return ret;
1185 	}
1186 
1187 	return 0;
1188 }
1189 
1190 int
1191 chn_kill(struct pcm_channel *c)
1192 {
1193     	struct snd_dbuf *b = c->bufhard;
1194     	struct snd_dbuf *bs = c->bufsoft;
1195 
1196 	if (CHN_STARTED(c))
1197 		chn_trigger(c, PCMTRIG_ABORT);
1198 	while (chn_removefeeder(c) == 0);
1199 	if (CHANNEL_FREE(c->methods, c->devinfo))
1200 		sndbuf_free(b);
1201 	c->flags |= CHN_F_DEAD;
1202 	sndbuf_destroy(bs);
1203 	sndbuf_destroy(b);
1204 	chn_lockdestroy(c);
1205 	return 0;
1206 }
1207 
1208 int
1209 chn_setdir(struct pcm_channel *c, int dir)
1210 {
1211 #ifdef DEV_ISA
1212     	struct snd_dbuf *b = c->bufhard;
1213 #endif
1214 	int r;
1215 
1216 	CHN_LOCKASSERT(c);
1217 	c->direction = dir;
1218 	r = CHANNEL_SETDIR(c->methods, c->devinfo, c->direction);
1219 #ifdef DEV_ISA
1220 	if (!r && SND_DMA(b))
1221 		sndbuf_dmasetdir(b, c->direction);
1222 #endif
1223 	return r;
1224 }
1225 
1226 int
1227 chn_setvolume(struct pcm_channel *c, int left, int right)
1228 {
1229 	CHN_LOCKASSERT(c);
1230 	/* should add a feeder for volume changing if channel returns -1 */
1231 	if (left > 100)
1232 		left = 100;
1233 	if (left < 0)
1234 		left = 0;
1235 	if (right > 100)
1236 		right = 100;
1237 	if (right < 0)
1238 		right = 0;
1239 	c->volume = left | (right << 8);
1240 	return 0;
1241 }
1242 
1243 static u_int32_t
1244 round_pow2(u_int32_t v)
1245 {
1246 	u_int32_t ret;
1247 
1248 	if (v < 2)
1249 		v = 2;
1250 	ret = 0;
1251 	while (v >> ret)
1252 		ret++;
1253 	ret = 1 << (ret - 1);
1254 	while (ret < v)
1255 		ret <<= 1;
1256 	return ret;
1257 }
1258 
1259 static u_int32_t
1260 round_blksz(u_int32_t v, int round)
1261 {
1262 	u_int32_t ret, tmp;
1263 
1264 	if (round < 1)
1265 		round = 1;
1266 
1267 	ret = min(round_pow2(v), CHN_2NDBUFMAXSIZE >> 1);
1268 
1269 	if (ret > v && (ret >> 1) > 0 && (ret >> 1) >= ((v * 3) >> 2))
1270 		ret >>= 1;
1271 
1272 	tmp = ret - (ret % round);
1273 	while (tmp < 16 || tmp < round) {
1274 		ret <<= 1;
1275 		tmp = ret - (ret % round);
1276 	}
1277 
1278 	return ret;
1279 }
1280 
1281 /*
1282  * 4Front call it DSP Policy, while we call it "Latency Profile". The idea
1283  * is to keep 2nd buffer short so that it doesn't cause long queue during
1284  * buffer transfer.
1285  *
1286  *    Latency reference table for 48khz stereo 16bit: (PLAY)
1287  *
1288  *      +---------+------------+-----------+------------+
1289  *      | Latency | Blockcount | Blocksize | Buffersize |
1290  *      +---------+------------+-----------+------------+
1291  *      |     0   |       2    |   64      |    128     |
1292  *      +---------+------------+-----------+------------+
1293  *      |     1   |       4    |   128     |    512     |
1294  *      +---------+------------+-----------+------------+
1295  *      |     2   |       8    |   512     |    4096    |
1296  *      +---------+------------+-----------+------------+
1297  *      |     3   |      16    |   512     |    8192    |
1298  *      +---------+------------+-----------+------------+
1299  *      |     4   |      32    |   512     |    16384   |
1300  *      +---------+------------+-----------+------------+
1301  *      |     5   |      32    |   1024    |    32768   |
1302  *      +---------+------------+-----------+------------+
1303  *      |     6   |      16    |   2048    |    32768   |
1304  *      +---------+------------+-----------+------------+
1305  *      |     7   |       8    |   4096    |    32768   |
1306  *      +---------+------------+-----------+------------+
1307  *      |     8   |       4    |   8192    |    32768   |
1308  *      +---------+------------+-----------+------------+
1309  *      |     9   |       2    |   16384   |    32768   |
1310  *      +---------+------------+-----------+------------+
1311  *      |    10   |       2    |   32768   |    65536   |
1312  *      +---------+------------+-----------+------------+
1313  *
1314  * Recording need a different reference table. All we care is
1315  * gobbling up everything within reasonable buffering threshold.
1316  *
1317  *    Latency reference table for 48khz stereo 16bit: (REC)
1318  *
1319  *      +---------+------------+-----------+------------+
1320  *      | Latency | Blockcount | Blocksize | Buffersize |
1321  *      +---------+------------+-----------+------------+
1322  *      |     0   |     512    |   32      |    16384   |
1323  *      +---------+------------+-----------+------------+
1324  *      |     1   |     256    |   64      |    16384   |
1325  *      +---------+------------+-----------+------------+
1326  *      |     2   |     128    |   128     |    16384   |
1327  *      +---------+------------+-----------+------------+
1328  *      |     3   |      64    |   256     |    16384   |
1329  *      +---------+------------+-----------+------------+
1330  *      |     4   |      32    |   512     |    16384   |
1331  *      +---------+------------+-----------+------------+
1332  *      |     5   |      32    |   1024    |    32768   |
1333  *      +---------+------------+-----------+------------+
1334  *      |     6   |      16    |   2048    |    32768   |
1335  *      +---------+------------+-----------+------------+
1336  *      |     7   |       8    |   4096    |    32768   |
1337  *      +---------+------------+-----------+------------+
1338  *      |     8   |       4    |   8192    |    32768   |
1339  *      +---------+------------+-----------+------------+
1340  *      |     9   |       2    |   16384   |    32768   |
1341  *      +---------+------------+-----------+------------+
1342  *      |    10   |       2    |   32768   |    65536   |
1343  *      +---------+------------+-----------+------------+
1344  *
1345  * Calculations for other data rate are entirely based on these reference
1346  * tables. For normal operation, Latency 5 seems give the best, well
1347  * balanced performance for typical workload. Anything below 5 will
1348  * eat up CPU to keep up with increasing context switches because of
1349  * shorter buffer space and usually require the application to handle it
1350  * aggresively through possibly real time programming technique.
1351  *
1352  */
1353 #define CHN_LATENCY_PBLKCNT_REF				\
1354 	{{1, 2, 3, 4, 5, 5, 4, 3, 2, 1, 1},		\
1355 	{1, 2, 3, 4, 5, 5, 4, 3, 2, 1, 1}}
1356 #define CHN_LATENCY_PBUFSZ_REF				\
1357 	{{7, 9, 12, 13, 14, 15, 15, 15, 15, 15, 16},	\
1358 	{11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 17}}
1359 
1360 #define CHN_LATENCY_RBLKCNT_REF				\
1361 	{{9, 8, 7, 6, 5, 5, 4, 3, 2, 1, 1},		\
1362 	{9, 8, 7, 6, 5, 5, 4, 3, 2, 1, 1}}
1363 #define CHN_LATENCY_RBUFSZ_REF				\
1364 	{{14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 16},	\
1365 	{15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 17}}
1366 
1367 #define CHN_LATENCY_DATA_REF	192000 /* 48khz stereo 16bit ~ 48000 x 2 x 2 */
1368 
1369 static int
1370 chn_calclatency(int dir, int latency, int bps, u_int32_t datarate,
1371 				u_int32_t max, int *rblksz, int *rblkcnt)
1372 {
1373 	static int pblkcnts[CHN_LATENCY_PROFILE_MAX + 1][CHN_LATENCY_MAX + 1] =
1374 	    CHN_LATENCY_PBLKCNT_REF;
1375 	static int  pbufszs[CHN_LATENCY_PROFILE_MAX + 1][CHN_LATENCY_MAX + 1] =
1376 	    CHN_LATENCY_PBUFSZ_REF;
1377 	static int rblkcnts[CHN_LATENCY_PROFILE_MAX + 1][CHN_LATENCY_MAX + 1] =
1378 	    CHN_LATENCY_RBLKCNT_REF;
1379 	static int  rbufszs[CHN_LATENCY_PROFILE_MAX + 1][CHN_LATENCY_MAX + 1] =
1380 	    CHN_LATENCY_RBUFSZ_REF;
1381 	u_int32_t bufsz;
1382 	int lprofile, blksz, blkcnt;
1383 
1384 	if (latency < CHN_LATENCY_MIN || latency > CHN_LATENCY_MAX ||
1385 	    bps < 1 || datarate < 1 ||
1386 	    !(dir == PCMDIR_PLAY || dir == PCMDIR_REC)) {
1387 		if (rblksz != NULL)
1388 			*rblksz = CHN_2NDBUFMAXSIZE >> 1;
1389 		if (rblkcnt != NULL)
1390 			*rblkcnt = 2;
1391 		printf("%s: FAILED dir=%d latency=%d bps=%d "
1392 		    "datarate=%u max=%u\n",
1393 		    __func__, dir, latency, bps, datarate, max);
1394 		return CHN_2NDBUFMAXSIZE;
1395 	}
1396 
1397 	lprofile = chn_latency_profile;
1398 
1399 	if (dir == PCMDIR_PLAY) {
1400 		blkcnt = pblkcnts[lprofile][latency];
1401 		bufsz = pbufszs[lprofile][latency];
1402 	} else {
1403 		blkcnt = rblkcnts[lprofile][latency];
1404 		bufsz = rbufszs[lprofile][latency];
1405 	}
1406 
1407 	bufsz = round_pow2(snd_xbytes(1 << bufsz, CHN_LATENCY_DATA_REF,
1408 	    datarate));
1409 	if (bufsz > max)
1410 		bufsz = max;
1411 	blksz = round_blksz(bufsz >> blkcnt, bps);
1412 
1413 	if (rblksz != NULL)
1414 		*rblksz = blksz;
1415 	if (rblkcnt != NULL)
1416 		*rblkcnt = 1 << blkcnt;
1417 
1418 	return blksz << blkcnt;
1419 }
1420 
1421 static int
1422 chn_resizebuf(struct pcm_channel *c, int latency,
1423 					int blkcnt, int blksz)
1424 {
1425 	struct snd_dbuf *b, *bs, *pb;
1426 	int sblksz, sblkcnt, hblksz, hblkcnt, limit = 1;
1427 	int ret;
1428 
1429 	CHN_LOCKASSERT(c);
1430 
1431 	if ((c->flags & (CHN_F_MAPPED | CHN_F_TRIGGERED)) ||
1432 	    !(c->direction == PCMDIR_PLAY || c->direction == PCMDIR_REC))
1433 		return EINVAL;
1434 
1435 	if (latency == -1) {
1436 		c->latency = -1;
1437 		latency = chn_latency;
1438 	} else if (latency == -2) {
1439 		latency = c->latency;
1440 		if (latency < CHN_LATENCY_MIN || latency > CHN_LATENCY_MAX)
1441 			latency = chn_latency;
1442 	} else if (latency < CHN_LATENCY_MIN || latency > CHN_LATENCY_MAX)
1443 		return EINVAL;
1444 	else {
1445 		c->latency = latency;
1446 		limit = 0;
1447 	}
1448 
1449 	bs = c->bufsoft;
1450 	b = c->bufhard;
1451 
1452 	if (!(blksz == 0 || blkcnt == -1) &&
1453 	    (blksz < 16 || blksz < sndbuf_getbps(bs) || blkcnt < 2 ||
1454 	    (blksz * blkcnt) > CHN_2NDBUFMAXSIZE))
1455 		return EINVAL;
1456 
1457 	chn_calclatency(c->direction, latency, sndbuf_getbps(bs),
1458 	    sndbuf_getbps(bs) * sndbuf_getspd(bs), CHN_2NDBUFMAXSIZE,
1459 	    &sblksz, &sblkcnt);
1460 
1461 	if (blksz == 0 || blkcnt == -1) {
1462 		if (blkcnt == -1)
1463 			c->flags &= ~CHN_F_HAS_SIZE;
1464 		if (c->flags & CHN_F_HAS_SIZE) {
1465 			blksz = sndbuf_getblksz(bs);
1466 			blkcnt = sndbuf_getblkcnt(bs);
1467 		}
1468 	} else
1469 		c->flags |= CHN_F_HAS_SIZE;
1470 
1471 	if (c->flags & CHN_F_HAS_SIZE) {
1472 		/*
1473 		 * The application has requested their own blksz/blkcnt.
1474 		 * Just obey with it, and let them toast alone. We can
1475 		 * clamp it to the nearest latency profile, but that would
1476 		 * defeat the purpose of having custom control. The least
1477 		 * we can do is round it to the nearest ^2 and align it.
1478 		 */
1479 		sblksz = round_blksz(blksz, sndbuf_getbps(bs));
1480 		sblkcnt = round_pow2(blkcnt);
1481 		limit = 0;
1482 	}
1483 
1484 	if (c->parentchannel != NULL) {
1485 		pb = BUF_PARENT(c, NULL);
1486 		CHN_UNLOCK(c);
1487 		chn_notify(c->parentchannel, CHN_N_BLOCKSIZE);
1488 		CHN_LOCK(c);
1489 		limit = (limit != 0 && pb != NULL) ?
1490 		    sndbuf_xbytes(sndbuf_getsize(pb), pb, bs) : 0;
1491 		c->timeout = c->parentchannel->timeout;
1492 	} else {
1493 		hblkcnt = 2;
1494 		if (c->flags & CHN_F_HAS_SIZE) {
1495 			hblksz = round_blksz(sndbuf_xbytes(sblksz, bs, b),
1496 			    sndbuf_getbps(b));
1497 			hblkcnt = round_pow2(sndbuf_getblkcnt(bs));
1498 		} else
1499 			chn_calclatency(c->direction, latency,
1500 			    sndbuf_getbps(b),
1501 			    sndbuf_getbps(b) * sndbuf_getspd(b),
1502 			    CHN_2NDBUFMAXSIZE, &hblksz, &hblkcnt);
1503 
1504 		if ((hblksz << 1) > sndbuf_getmaxsize(b))
1505 			hblksz = round_blksz(sndbuf_getmaxsize(b) >> 1,
1506 			    sndbuf_getbps(b));
1507 
1508 		while ((hblksz * hblkcnt) > sndbuf_getmaxsize(b)) {
1509 			if (hblkcnt < 4)
1510 				hblksz >>= 1;
1511 			else
1512 				hblkcnt >>= 1;
1513 		}
1514 
1515 		hblksz -= hblksz % sndbuf_getbps(b);
1516 
1517 #if 0
1518 		hblksz = sndbuf_getmaxsize(b) >> 1;
1519 		hblksz -= hblksz % sndbuf_getbps(b);
1520 		hblkcnt = 2;
1521 #endif
1522 
1523 		CHN_UNLOCK(c);
1524 		if (chn_usefrags == 0 ||
1525 		    CHANNEL_SETFRAGMENTS(c->methods, c->devinfo,
1526 		    hblksz, hblkcnt) < 1)
1527 			sndbuf_setblksz(b, CHANNEL_SETBLOCKSIZE(c->methods,
1528 			    c->devinfo, hblksz));
1529 		CHN_LOCK(c);
1530 
1531 		if (!SLIST_EMPTY(&c->children)) {
1532 			sblksz = round_blksz(
1533 			    sndbuf_xbytes(sndbuf_getsize(b) >> 1, b, bs),
1534 			    sndbuf_getbps(bs));
1535 			sblkcnt = 2;
1536 			limit = 0;
1537 		} else if (limit != 0)
1538 			limit = sndbuf_xbytes(sndbuf_getsize(b), b, bs);
1539 
1540 		/*
1541 		 * Interrupt timeout
1542 		 */
1543 		c->timeout = ((u_int64_t)hz * sndbuf_getsize(b)) /
1544 		    ((u_int64_t)sndbuf_getspd(b) * sndbuf_getbps(b));
1545 		if (c->timeout < 1)
1546 			c->timeout = 1;
1547 	}
1548 
1549 	if (limit > CHN_2NDBUFMAXSIZE)
1550 		limit = CHN_2NDBUFMAXSIZE;
1551 
1552 #if 0
1553 	while (limit > 0 && (sblksz * sblkcnt) > limit) {
1554 		if (sblkcnt < 4)
1555 			break;
1556 		sblkcnt >>= 1;
1557 	}
1558 #endif
1559 
1560 	while ((sblksz * sblkcnt) < limit)
1561 		sblkcnt <<= 1;
1562 
1563 	while ((sblksz * sblkcnt) > CHN_2NDBUFMAXSIZE) {
1564 		if (sblkcnt < 4)
1565 			sblksz >>= 1;
1566 		else
1567 			sblkcnt >>= 1;
1568 	}
1569 
1570 	sblksz -= sblksz % sndbuf_getbps(bs);
1571 
1572 	if (sndbuf_getblkcnt(bs) != sblkcnt || sndbuf_getblksz(bs) != sblksz ||
1573 	    sndbuf_getsize(bs) != (sblkcnt * sblksz)) {
1574 		ret = sndbuf_remalloc(bs, sblkcnt, sblksz);
1575 		if (ret != 0) {
1576 			printf("%s: Failed: %d %d\n", __func__,
1577 			    sblkcnt, sblksz);
1578 			return ret;
1579 		}
1580 	}
1581 
1582 	/*
1583 	 * OSSv4 docs: "By default OSS will set the low water level equal
1584 	 * to the fragment size which is optimal in most cases."
1585 	 */
1586 	c->lw = sndbuf_getblksz(bs);
1587 	chn_resetbuf(c);
1588 
1589 	if (snd_verbose > 3)
1590 		printf("%s: %s (%s) timeout=%u "
1591 		    "b[%d/%d/%d] bs[%d/%d/%d] limit=%d\n",
1592 		    __func__, CHN_DIRSTR(c),
1593 		    (c->flags & CHN_F_VIRTUAL) ? "virtual" : "hardware",
1594 		    c->timeout,
1595 		    sndbuf_getsize(b), sndbuf_getblksz(b),
1596 		    sndbuf_getblkcnt(b),
1597 		    sndbuf_getsize(bs), sndbuf_getblksz(bs),
1598 		    sndbuf_getblkcnt(bs), limit);
1599 
1600 	return 0;
1601 }
1602 
1603 int
1604 chn_setlatency(struct pcm_channel *c, int latency)
1605 {
1606 	CHN_LOCKASSERT(c);
1607 	/* Destroy blksz/blkcnt, enforce latency profile. */
1608 	return chn_resizebuf(c, latency, -1, 0);
1609 }
1610 
1611 int
1612 chn_setblocksize(struct pcm_channel *c, int blkcnt, int blksz)
1613 {
1614 	CHN_LOCKASSERT(c);
1615 	/* Destroy latency profile, enforce blksz/blkcnt */
1616 	return chn_resizebuf(c, -1, blkcnt, blksz);
1617 }
1618 
1619 static int
1620 chn_tryspeed(struct pcm_channel *c, int speed)
1621 {
1622 	struct pcm_feeder *f;
1623     	struct snd_dbuf *b = c->bufhard;
1624     	struct snd_dbuf *bs = c->bufsoft;
1625     	struct snd_dbuf *x;
1626 	int r, delta;
1627 
1628 	CHN_LOCKASSERT(c);
1629 	DEB(printf("setspeed, channel %s\n", c->name));
1630 	DEB(printf("want speed %d, ", speed));
1631 	if (speed <= 0)
1632 		return EINVAL;
1633 	if (CHN_STOPPED(c)) {
1634 		r = 0;
1635 		c->speed = speed;
1636 		sndbuf_setspd(bs, speed);
1637 		RANGE(speed, chn_getcaps(c)->minspeed, chn_getcaps(c)->maxspeed);
1638 		DEB(printf("try speed %d, ", speed));
1639 		sndbuf_setspd(b, CHANNEL_SETSPEED(c->methods, c->devinfo, speed));
1640 		DEB(printf("got speed %d\n", sndbuf_getspd(b)));
1641 
1642 		delta = sndbuf_getspd(b) - sndbuf_getspd(bs);
1643 		if (delta < 0)
1644 			delta = -delta;
1645 
1646 		c->feederflags &= ~(1 << FEEDER_RATE);
1647 		/*
1648 		 * Used to be 500. It was too big!
1649 		 */
1650 		if (delta > feeder_rate_round)
1651 			c->feederflags |= 1 << FEEDER_RATE;
1652 		else
1653 			sndbuf_setspd(bs, sndbuf_getspd(b));
1654 
1655 		r = chn_buildfeeder(c);
1656 		DEB(printf("r = %d\n", r));
1657 		if (r)
1658 			goto out;
1659 
1660 		if (!(c->feederflags & (1 << FEEDER_RATE)))
1661 			goto out;
1662 
1663 		r = EINVAL;
1664 		f = chn_findfeeder(c, FEEDER_RATE);
1665 		DEB(printf("feedrate = %p\n", f));
1666 		if (f == NULL)
1667 			goto out;
1668 
1669 		x = (c->direction == PCMDIR_REC)? b : bs;
1670 		r = FEEDER_SET(f, FEEDRATE_SRC, sndbuf_getspd(x));
1671 		DEB(printf("feeder_set(FEEDRATE_SRC, %d) = %d\n", sndbuf_getspd(x), r));
1672 		if (r)
1673 			goto out;
1674 
1675 		x = (c->direction == PCMDIR_REC)? bs : b;
1676 		r = FEEDER_SET(f, FEEDRATE_DST, sndbuf_getspd(x));
1677 		DEB(printf("feeder_set(FEEDRATE_DST, %d) = %d\n", sndbuf_getspd(x), r));
1678 out:
1679 		if (!r)
1680 			r = CHANNEL_SETFORMAT(c->methods, c->devinfo,
1681 							sndbuf_getfmt(b));
1682 		if (!r)
1683 			sndbuf_setfmt(bs, c->format);
1684 		if (!r)
1685 			r = chn_resizebuf(c, -2, 0, 0);
1686 		DEB(printf("setspeed done, r = %d\n", r));
1687 		return r;
1688 	} else
1689 		return EINVAL;
1690 }
1691 
1692 int
1693 chn_setspeed(struct pcm_channel *c, int speed)
1694 {
1695 	int r, oldspeed = c->speed;
1696 
1697 	r = chn_tryspeed(c, speed);
1698 	if (r) {
1699 		if (snd_verbose > 3)
1700 			printf("Failed to set speed %d falling back to %d\n",
1701 			    speed, oldspeed);
1702 		r = chn_tryspeed(c, oldspeed);
1703 	}
1704 	return r;
1705 }
1706 
1707 static int
1708 chn_tryformat(struct pcm_channel *c, u_int32_t fmt)
1709 {
1710 	struct snd_dbuf *b = c->bufhard;
1711 	struct snd_dbuf *bs = c->bufsoft;
1712 	int r;
1713 
1714 	CHN_LOCKASSERT(c);
1715 	if (CHN_STOPPED(c)) {
1716 		DEB(printf("want format %d\n", fmt));
1717 		c->format = fmt;
1718 		r = chn_buildfeeder(c);
1719 		if (r == 0) {
1720 			sndbuf_setfmt(bs, c->format);
1721 			chn_resetbuf(c);
1722 			r = CHANNEL_SETFORMAT(c->methods, c->devinfo, sndbuf_getfmt(b));
1723 			if (r == 0)
1724 				r = chn_tryspeed(c, c->speed);
1725 		}
1726 		return r;
1727 	} else
1728 		return EINVAL;
1729 }
1730 
1731 int
1732 chn_setformat(struct pcm_channel *c, u_int32_t fmt)
1733 {
1734 	u_int32_t oldfmt = c->format;
1735 	int r;
1736 
1737 	r = chn_tryformat(c, fmt);
1738 	if (r) {
1739 		if (snd_verbose > 3)
1740 			printf("Format change 0x%08x failed, reverting to 0x%08x\n",
1741 			    fmt, oldfmt);
1742 		chn_tryformat(c, oldfmt);
1743 	}
1744 	return r;
1745 }
1746 
1747 int
1748 chn_trigger(struct pcm_channel *c, int go)
1749 {
1750 #ifdef DEV_ISA
1751     	struct snd_dbuf *b = c->bufhard;
1752 #endif
1753 	int ret;
1754 
1755 	CHN_LOCKASSERT(c);
1756 #ifdef DEV_ISA
1757 	if (SND_DMA(b) && (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD))
1758 		sndbuf_dmabounce(b);
1759 #endif
1760 	ret = CHANNEL_TRIGGER(c->methods, c->devinfo, go);
1761 
1762 	return ret;
1763 }
1764 
1765 /**
1766  * @brief Queries sound driver for sample-aligned hardware buffer pointer index
1767  *
1768  * This function obtains the hardware pointer location, then aligns it to
1769  * the current bytes-per-sample value before returning.  (E.g., a channel
1770  * running in 16 bit stereo mode would require 4 bytes per sample, so a
1771  * hwptr value ranging from 32-35 would be returned as 32.)
1772  *
1773  * @param c	PCM channel context
1774  * @returns 	sample-aligned hardware buffer pointer index
1775  */
1776 int
1777 chn_getptr(struct pcm_channel *c)
1778 {
1779 #if 0
1780 	int hwptr;
1781 	int a = (1 << c->align) - 1;
1782 
1783 	CHN_LOCKASSERT(c);
1784 	hwptr = (c->flags & CHN_F_TRIGGERED)? CHANNEL_GETPTR(c->methods, c->devinfo) : 0;
1785 	/* don't allow unaligned values in the hwa ptr */
1786 #if 1
1787 	hwptr &= ~a ; /* Apply channel align mask */
1788 #endif
1789 	hwptr &= DMA_ALIGN_MASK; /* Apply DMA align mask */
1790 	return hwptr;
1791 #endif
1792 	int hwptr;
1793 
1794 	CHN_LOCKASSERT(c);
1795 	hwptr = (CHN_STARTED(c)) ? CHANNEL_GETPTR(c->methods, c->devinfo) : 0;
1796 	return (hwptr - (hwptr % sndbuf_getbps(c->bufhard)));
1797 }
1798 
1799 struct pcmchan_caps *
1800 chn_getcaps(struct pcm_channel *c)
1801 {
1802 	CHN_LOCKASSERT(c);
1803 	return CHANNEL_GETCAPS(c->methods, c->devinfo);
1804 }
1805 
1806 u_int32_t
1807 chn_getformats(struct pcm_channel *c)
1808 {
1809 	u_int32_t *fmtlist, fmts;
1810 	int i;
1811 
1812 	fmtlist = chn_getcaps(c)->fmtlist;
1813 	fmts = 0;
1814 	for (i = 0; fmtlist[i]; i++)
1815 		fmts |= fmtlist[i];
1816 
1817 	/* report software-supported formats */
1818 	if (report_soft_formats)
1819 		fmts |= AFMT_MU_LAW|AFMT_A_LAW|AFMT_U32_LE|AFMT_U32_BE|
1820 		    AFMT_S32_LE|AFMT_S32_BE|AFMT_U24_LE|AFMT_U24_BE|
1821 		    AFMT_S24_LE|AFMT_S24_BE|AFMT_U16_LE|AFMT_U16_BE|
1822 		    AFMT_S16_LE|AFMT_S16_BE|AFMT_U8|AFMT_S8;
1823 
1824 	return fmts;
1825 }
1826 
1827 static int
1828 chn_buildfeeder(struct pcm_channel *c)
1829 {
1830 	struct feeder_class *fc;
1831 	struct pcm_feederdesc desc;
1832 	u_int32_t tmp[2], type, flags, hwfmt, *fmtlist;
1833 	int err;
1834 	char fmtstr[AFMTSTR_MAXSZ];
1835 
1836 	CHN_LOCKASSERT(c);
1837 	while (chn_removefeeder(c) == 0)
1838 		;
1839 	KASSERT((c->feeder == NULL), ("feeder chain not empty"));
1840 
1841 	c->align = sndbuf_getalign(c->bufsoft);
1842 
1843 	if (SLIST_EMPTY(&c->children)) {
1844 		fc = feeder_getclass(NULL);
1845 		KASSERT(fc != NULL, ("can't find root feeder"));
1846 
1847 		err = chn_addfeeder(c, fc, NULL);
1848 		if (err) {
1849 			DEB(printf("can't add root feeder, err %d\n", err));
1850 
1851 			return err;
1852 		}
1853 		c->feeder->desc->out = c->format;
1854 	} else {
1855 		if (c->flags & CHN_F_HAS_VCHAN) {
1856 			desc.type = FEEDER_MIXER;
1857 			desc.in = c->format;
1858 		} else {
1859 			DEB(printf("can't decide which feeder type to use!\n"));
1860 			return EOPNOTSUPP;
1861 		}
1862 		desc.out = c->format;
1863 		desc.flags = 0;
1864 		fc = feeder_getclass(&desc);
1865 		if (fc == NULL) {
1866 			DEB(printf("can't find vchan feeder\n"));
1867 
1868 			return EOPNOTSUPP;
1869 		}
1870 
1871 		err = chn_addfeeder(c, fc, &desc);
1872 		if (err) {
1873 			DEB(printf("can't add vchan feeder, err %d\n", err));
1874 
1875 			return err;
1876 		}
1877 	}
1878 	c->feederflags &= ~(1 << FEEDER_VOLUME);
1879 	if (c->direction == PCMDIR_PLAY &&
1880 	    !(c->flags & CHN_F_VIRTUAL) && c->parentsnddev &&
1881 	    (c->parentsnddev->flags & SD_F_SOFTPCMVOL) &&
1882 	    c->parentsnddev->mixer_dev)
1883 		c->feederflags |= 1 << FEEDER_VOLUME;
1884 	if (!(c->flags & CHN_F_VIRTUAL) && c->parentsnddev &&
1885 	    ((c->direction == PCMDIR_PLAY &&
1886 	    (c->parentsnddev->flags & SD_F_PSWAPLR)) ||
1887 	    (c->direction == PCMDIR_REC &&
1888 	    (c->parentsnddev->flags & SD_F_RSWAPLR))))
1889 		c->feederflags |= 1 << FEEDER_SWAPLR;
1890 	flags = c->feederflags;
1891 	fmtlist = chn_getcaps(c)->fmtlist;
1892 
1893 	DEB(printf("feederflags %x\n", flags));
1894 
1895 	for (type = FEEDER_RATE; type < FEEDER_LAST; type++) {
1896 		if (flags & (1 << type)) {
1897 			desc.type = type;
1898 			desc.in = 0;
1899 			desc.out = 0;
1900 			desc.flags = 0;
1901 			DEB(printf("find feeder type %d, ", type));
1902 			if (type == FEEDER_VOLUME || type == FEEDER_RATE) {
1903 				if (c->feeder->desc->out & AFMT_32BIT)
1904 					strlcpy(fmtstr,"s32le", sizeof(fmtstr));
1905 				else if (c->feeder->desc->out & AFMT_24BIT)
1906 					strlcpy(fmtstr, "s24le", sizeof(fmtstr));
1907 				else {
1908 					/*
1909 					 * 8bit doesn't provide enough headroom
1910 					 * for proper processing without
1911 					 * creating too much noises. Force to
1912 					 * 16bit instead.
1913 					 */
1914 					strlcpy(fmtstr, "s16le", sizeof(fmtstr));
1915 				}
1916 				if (!(c->feeder->desc->out & AFMT_8BIT) &&
1917 					    c->feeder->desc->out & AFMT_BIGENDIAN)
1918 					afmtstr_swap_endian(fmtstr);
1919 				if (!(c->feeder->desc->out & (AFMT_A_LAW | AFMT_MU_LAW)) &&
1920 					    !(c->feeder->desc->out & AFMT_SIGNED))
1921 					afmtstr_swap_sign(fmtstr);
1922 				desc.in = afmtstr2afmt(NULL, fmtstr, AFMTSTR_MONO_RETURN);
1923 				if (desc.in == 0)
1924 					desc.in = AFMT_S16_LE;
1925 				/* feeder_volume need stereo processing */
1926 				if (type == FEEDER_VOLUME ||
1927 					    c->feeder->desc->out & AFMT_STEREO)
1928 					desc.in |= AFMT_STEREO;
1929 				desc.out = desc.in;
1930 			} else if (type == FEEDER_SWAPLR) {
1931 				desc.in = c->feeder->desc->out;
1932 				desc.in |= AFMT_STEREO;
1933 				desc.out = desc.in;
1934 			}
1935 
1936 			fc = feeder_getclass(&desc);
1937 			DEB(printf("got %p\n", fc));
1938 			if (fc == NULL) {
1939 				DEB(printf("can't find required feeder type %d\n", type));
1940 
1941 				return EOPNOTSUPP;
1942 			}
1943 
1944 			if (desc.in == 0 || desc.out == 0)
1945 				desc = *fc->desc;
1946 
1947  			DEB(printf("build fmtchain from 0x%08x to 0x%08x: ", c->feeder->desc->out, fc->desc->in));
1948 			tmp[0] = desc.in;
1949 			tmp[1] = 0;
1950 			if (chn_fmtchain(c, tmp) == 0) {
1951 				DEB(printf("failed\n"));
1952 
1953 				return ENODEV;
1954 			}
1955  			DEB(printf("ok\n"));
1956 
1957 			err = chn_addfeeder(c, fc, &desc);
1958 			if (err) {
1959 				DEB(printf("can't add feeder %p, output 0x%x, err %d\n", fc, fc->desc->out, err));
1960 
1961 				return err;
1962 			}
1963 			DEB(printf("added feeder %p, output 0x%x\n", fc, c->feeder->desc->out));
1964 		}
1965 	}
1966 
1967  	if (c->direction == PCMDIR_REC) {
1968 	 	tmp[0] = c->format;
1969  		tmp[1] = 0;
1970  		hwfmt = chn_fmtchain(c, tmp);
1971  	} else
1972  		hwfmt = chn_fmtchain(c, fmtlist);
1973 
1974 	if (hwfmt == 0 || !fmtvalid(hwfmt, fmtlist)) {
1975 		DEB(printf("Invalid hardware format: 0x%08x\n", hwfmt));
1976 		return ENODEV;
1977 	}
1978 
1979 	sndbuf_setfmt(c->bufhard, hwfmt);
1980 
1981 	if ((flags & (1 << FEEDER_VOLUME))) {
1982 		u_int32_t parent = SOUND_MIXER_NONE;
1983 		int vol, left, right;
1984 
1985 		vol = 100 | (100 << 8);
1986 
1987 		CHN_UNLOCK(c);
1988 		/*
1989 		 * XXX This is ugly! The way mixer subs being so secretive
1990 		 * about its own internals force us to use this silly
1991 		 * monkey trick.
1992 		 */
1993 		if (mixer_ioctl(c->parentsnddev->mixer_dev,
1994 				MIXER_READ(SOUND_MIXER_PCM), (caddr_t)&vol, -1, NULL) != 0)
1995 			device_printf(c->dev, "Soft PCM Volume: Failed to read default value\n");
1996 		left = vol & 0x7f;
1997 		right = (vol >> 8) & 0x7f;
1998 		if (c->parentsnddev != NULL &&
1999 		    c->parentsnddev->mixer_dev != NULL &&
2000 		    c->parentsnddev->mixer_dev->si_drv1 != NULL)
2001 			parent = mix_getparent(
2002 			    c->parentsnddev->mixer_dev->si_drv1,
2003 			    SOUND_MIXER_PCM);
2004 		if (parent != SOUND_MIXER_NONE) {
2005 			vol = 100 | (100 << 8);
2006 			if (mixer_ioctl(c->parentsnddev->mixer_dev,
2007 					MIXER_READ(parent),
2008 					(caddr_t)&vol, -1, NULL) != 0)
2009 				device_printf(c->dev, "Soft Volume: Failed to read parent default value\n");
2010 			left = (left * (vol & 0x7f)) / 100;
2011 			right = (right * ((vol >> 8) & 0x7f)) / 100;
2012 		}
2013 		CHN_LOCK(c);
2014 		chn_setvolume(c, left, right);
2015 	}
2016 
2017 	return 0;
2018 }
2019 
2020 int
2021 chn_notify(struct pcm_channel *c, u_int32_t flags)
2022 {
2023 	struct pcmchan_children *pce;
2024 	struct pcm_channel *child;
2025 	int run;
2026 
2027 	CHN_LOCK(c);
2028 
2029 	if (SLIST_EMPTY(&c->children)) {
2030 		CHN_UNLOCK(c);
2031 		return ENODEV;
2032 	}
2033 
2034 	run = (CHN_STARTED(c)) ? 1 : 0;
2035 	/*
2036 	 * if the hwchan is running, we can't change its rate, format or
2037 	 * blocksize
2038 	 */
2039 	if (run)
2040 		flags &= CHN_N_VOLUME | CHN_N_TRIGGER;
2041 
2042 	if (flags & CHN_N_RATE) {
2043 		/*
2044 		 * we could do something here, like scan children and decide on
2045 		 * the most appropriate rate to mix at, but we don't for now
2046 		 */
2047 	}
2048 	if (flags & CHN_N_FORMAT) {
2049 		/*
2050 		 * we could do something here, like scan children and decide on
2051 		 * the most appropriate mixer feeder to use, but we don't for now
2052 		 */
2053 	}
2054 	if (flags & CHN_N_VOLUME) {
2055 		/*
2056 		 * we could do something here but we don't for now
2057 		 */
2058 	}
2059 	if (flags & CHN_N_BLOCKSIZE) {
2060 		/*
2061 		 * Set to default latency profile
2062 		 */
2063 		chn_setlatency(c, chn_latency);
2064 	}
2065 	if (flags & CHN_N_TRIGGER) {
2066 		int nrun;
2067 		/*
2068 		 * scan the children, and figure out if any are running
2069 		 * if so, we need to be running, otherwise we need to be stopped
2070 		 * if we aren't in our target sstate, move to it
2071 		 */
2072 		nrun = 0;
2073 		SLIST_FOREACH(pce, &c->children, link) {
2074 			child = pce->channel;
2075 			CHN_LOCK(child);
2076 			nrun = CHN_STARTED(child);
2077 			CHN_UNLOCK(child);
2078 			if (nrun)
2079 				break;
2080 		}
2081 		if (nrun && !run)
2082 			chn_start(c, 1);
2083 		if (!nrun && run)
2084 			chn_abort(c);
2085 	}
2086 	CHN_UNLOCK(c);
2087 	return 0;
2088 }
2089 
2090 /**
2091  * @brief Fetch array of supported discrete sample rates
2092  *
2093  * Wrapper for CHANNEL_GETRATES.  Please see channel_if.m:getrates() for
2094  * detailed information.
2095  *
2096  * @note If the operation isn't supported, this function will just return 0
2097  *       (no rates in the array), and *rates will be set to NULL.  Callers
2098  *       should examine rates @b only if this function returns non-zero.
2099  *
2100  * @param c	pcm channel to examine
2101  * @param rates	pointer to array of integers; rate table will be recorded here
2102  *
2103  * @return number of rates in the array pointed to be @c rates
2104  */
2105 int
2106 chn_getrates(struct pcm_channel *c, int **rates)
2107 {
2108 	KASSERT(rates != NULL, ("rates is null"));
2109 	CHN_LOCKASSERT(c);
2110 	return CHANNEL_GETRATES(c->methods, c->devinfo, rates);
2111 }
2112 
2113 /**
2114  * @brief Remove channel from a sync group, if there is one.
2115  *
2116  * This function is initially intended for the following conditions:
2117  *   - Starting a syncgroup (@c SNDCTL_DSP_SYNCSTART ioctl)
2118  *   - Closing a device.  (A channel can't be destroyed if it's still in use.)
2119  *
2120  * @note Before calling this function, the syncgroup list mutex must be
2121  * held.  (Consider pcm_channel::sm protected by the SG list mutex
2122  * whether @c c is locked or not.)
2123  *
2124  * @param c	channel device to be started or closed
2125  * @returns	If this channel was the only member of a group, the group ID
2126  * 		is returned to the caller so that the caller can release it
2127  * 		via free_unr() after giving up the syncgroup lock.  Else it
2128  * 		returns 0.
2129  */
2130 int
2131 chn_syncdestroy(struct pcm_channel *c)
2132 {
2133 	struct pcmchan_syncmember *sm;
2134 	struct pcmchan_syncgroup *sg;
2135 	int sg_id;
2136 
2137 	sg_id = 0;
2138 
2139 	PCM_SG_LOCKASSERT(MA_OWNED);
2140 
2141 	if (c->sm != NULL) {
2142 		sm = c->sm;
2143 		sg = sm->parent;
2144 		c->sm = NULL;
2145 
2146 		KASSERT(sg != NULL, ("syncmember has null parent"));
2147 
2148 		SLIST_REMOVE(&sg->members, sm, pcmchan_syncmember, link);
2149 		free(sm, M_DEVBUF);
2150 
2151 		if (SLIST_EMPTY(&sg->members)) {
2152 			SLIST_REMOVE(&snd_pcm_syncgroups, sg, pcmchan_syncgroup, link);
2153 			sg_id = sg->id;
2154 			free(sg, M_DEVBUF);
2155 		}
2156 	}
2157 
2158 	return sg_id;
2159 }
2160 
2161 void
2162 chn_lock(struct pcm_channel *c)
2163 {
2164 	CHN_LOCK(c);
2165 }
2166 
2167 void
2168 chn_unlock(struct pcm_channel *c)
2169 {
2170 	CHN_UNLOCK(c);
2171 }
2172 
2173 #ifdef OSSV4_EXPERIMENT
2174 int
2175 chn_getpeaks(struct pcm_channel *c, int *lpeak, int *rpeak)
2176 {
2177 	CHN_LOCKASSERT(c);
2178 	return CHANNEL_GETPEAKS(c->methods, c->devinfo, lpeak, rpeak);
2179 }
2180 #endif
2181