channel.c revision 68413
1/*
2 * Copyright (c) 1999 Cameron Grant <gandalf@vilnya.demon.co.uk>
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 * $FreeBSD: head/sys/dev/sound/pcm/channel.c 68413 2000-11-07 00:32:35Z cg $
28 */
29
30#include <dev/sound/pcm/sound.h>
31
32#define MIN_CHUNK_SIZE 		256	/* for uiomove etc. */
33#define	DMA_ALIGN_THRESHOLD	4
34#define	DMA_ALIGN_MASK		(~(DMA_ALIGN_THRESHOLD - 1))
35
36#define ISA_DMA(b) (((b)->chan >= 0 && (b)->chan != 4 && (b)->chan < 8))
37#define CANCHANGE(c) (!(c)->buffer.dl)
38#define ROUND(x) ((x) & DMA_ALIGN_MASK)
39
40/*
41#define DEB(x) x
42*/
43
44static void buf_clear(snd_dbuf *b, u_int32_t fmt, int length);
45static void chn_dmaupdate(pcm_channel *c);
46static void chn_wrintr(pcm_channel *c);
47static void chn_rdintr(pcm_channel *c);
48static int chn_buildfeeder(pcm_channel *c);
49/*
50 * SOUND OUTPUT
51
52We use a circular buffer to store samples directed to the DAC.
53The buffer is split into two variable-size regions, each identified
54by an offset in the buffer (rp,fp) and a length (rl,fl):
55
56      0          rp,rl        fp,fl    bufsize
57      |__________>____________>________|
58	  FREE   d   READY    w FREE
59
60  READY: data written from the process and ready to be sent to the DAC;
61  FREE: free part of the buffer.
62
63Both regions can wrap around the end of the buffer.  At initialization,
64READY is empty, FREE takes all the available space, and dma is
65idle.  dl contains the length of the current DMA transfer, dl=0
66means that the dma is idle.
67
68The two boundaries (rp,fp) in the buffers are advanced by DMA [d]
69and write() [w] operations. The first portion of the READY region
70is used for DMA transfers. The transfer is started at rp and with
71chunks of length dl. During DMA operations, dsp_wr_dmaupdate()
72updates rp, rl and fl tracking the ISA DMA engine as the transfer
73makes progress.
74When a new block is written, fp advances and rl,fl are updated
75accordingly.
76
77The code works as follows: the user write routine dsp_write_body()
78fills up the READY region with new data (reclaiming space from the
79FREE region) and starts the write DMA engine if inactive.  When a
80DMA transfer is complete, an interrupt causes dsp_wrintr() to be
81called which extends the FREE region and possibly starts the next
82transfer.
83
84In some cases, the code tries to track the current status of DMA
85operations by calling dsp_wr_dmaupdate() which changes rp, rl and fl.
86
87The system tries to make all DMA transfers use the same size,
88play_blocksize or rec_blocksize. The size is either selected by
89the user, or computed by the system to correspond to about .25s of
90audio. The blocksize must be within a range which is currently:
91
92	min(5ms, 40 bytes) ... 1/2 buffer size.
93
94When there aren't enough data (write) or space (read), a transfer
95is started with a reduced size.
96
97To reduce problems in case of overruns, the routine which fills up
98the buffer should initialize (e.g. by repeating the last value) a
99reasonably long area after the last block so that no noise is
100produced on overruns.
101
102  *
103  */
104
105
106/* XXX  this is broken: in the event a bounce buffer is used, data never
107 * gets copied in or out of the real buffer.  fix requires mods to isa_dma.c
108 * and possibly fixes to other autodma mode clients
109 */
110static void
111chn_isadmabounce(pcm_channel *c)
112{
113	if (ISA_DMA(&c->buffer)) {
114		/* tell isa_dma to bounce data in/out */
115    	} else KASSERT(1, ("chn_isadmabounce called on invalid channel"));
116}
117
118static int
119chn_polltrigger(pcm_channel *c)
120{
121	snd_dbuf *bs = &c->buffer2nd;
122	unsigned lim = (c->flags & CHN_F_HAS_SIZE)? bs->blksz : 0;
123	int trig = 0;
124
125	if (c->flags & CHN_F_MAPPED)
126		trig = ((bs->int_count > bs->prev_int_count) || bs->prev_int_count == 0);
127	else
128		trig = (((c->direction == PCMDIR_PLAY)? bs->fl : bs->rl) > lim);
129	return trig;
130}
131
132static int
133chn_pollreset(pcm_channel *c)
134{
135	snd_dbuf *bs = &c->buffer2nd;
136
137	if (c->flags & CHN_F_MAPPED)
138		bs->prev_int_count = bs->int_count;
139	return 1;
140}
141
142/*
143 * chn_dmadone() updates pointers and wakes up any process waiting
144 * on a select(). Must be called at spltty().
145 */
146static void
147chn_dmadone(pcm_channel *c)
148{
149	snd_dbuf *b = &c->buffer;
150
151	if (c->direction == PCMDIR_PLAY)
152		chn_checkunderflow(c);
153	else
154		chn_dmaupdate(c);
155	if (ISA_DMA(b))
156		chn_isadmabounce(c); /* sync bounce buffer */
157	b->int_count++;
158}
159
160/*
161 * chn_dmawakeup() wakes up any process sleeping. Separated from
162 * chn_dmadone() so that wakeup occurs only when feed from a
163 * secondary buffer to a DMA buffer takes place. Must be called
164 * at spltty().
165 */
166static void
167chn_dmawakeup(pcm_channel *c)
168{
169	snd_dbuf *b = &c->buffer;
170
171	wakeup(b);
172}
173
174/*
175 * chn_dmaupdate() tracks the status of a dma transfer,
176 * updating pointers. It must be called at spltty().
177 *
178 * NOTE: when we are using auto dma in the device, rl might become
179 * negative.
180 */
181DEB (static int chn_updatecount=0);
182
183static void
184chn_dmaupdate(pcm_channel *c)
185{
186	snd_dbuf *b = &c->buffer;
187	int delta, hwptr;
188	DEB (int b_rl=b->rl; int b_fl=b->fl; int b_rp=b->rp; int b_fp=b->fp);
189
190	hwptr = chn_getptr(c);
191	delta = (b->bufsize + hwptr - b->hp) % b->bufsize;
192	if (delta >= ((b->bufsize * 15) / 16)) {
193		if (!(c->flags & (CHN_F_CLOSING | CHN_F_ABORTING)))
194			device_printf(c->parent->dev, "hwptr went backwards %d -> %d\n", b->hp, hwptr);
195	}
196	if (c->direction == PCMDIR_PLAY) {
197		delta = (b->bufsize + hwptr - b->rp) % b->bufsize;
198		b->rp = hwptr;
199		b->rl -= delta;
200		b->fl += delta;
201
202		if (b->rl < 0) {
203			DEB(printf("OUCH!(%d) rl %d(%d) delta %d bufsize %d hwptr %d rp %d(%d)\n", chn_updatecount++, b->rl, b_rl, delta, b->bufsize, hwptr, b->rp, b_rp));
204		}
205	} else {
206		delta = (b->bufsize + hwptr - b->fp) % b->bufsize;
207		b->fp = hwptr;
208		b->rl += delta;
209		b->fl -= delta;
210		if (b->fl < 0) {
211			DEB(printf("OUCH!(%d) fl %d(%d) delta %d bufsize %d hwptr %d fp %d(%d)\n", chn_updatecount++, b->fl, b_fl, delta, b->bufsize, hwptr, b->fp, b_fp));
212		}
213	}
214	b->hp = hwptr;
215	b->total += delta;
216}
217
218/*
219 * Check channel for underflow occured. Reset DMA buffer in case of
220 * underflow, so that new data can go into the buffer. It must be
221 * called at spltty().
222 */
223void
224chn_checkunderflow(pcm_channel *c)
225{
226    	snd_dbuf *b = &c->buffer;
227
228	if (b->underflow) {
229		DEB(printf("Clear underflow condition\n"));
230		/*
231		 * The DMA keeps running even after underflow occurs.
232		 * Hence the value returned by chn_getptr() here soon
233		 * gets a lag when we get back to chn_write(). Although
234		 * there are no easy and precise methods to figure out
235		 * the lag, a quarter of b->bufsize would be a fair
236		 * choice, provided that a DMA interrupt generates upon
237		 * each transfer of a half b->bufsize.
238		 */
239		b->rp = chn_getptr(c);
240		b->fp = (b->rp + b->bufsize / 4) % b->bufsize;
241		b->rl = b->bufsize / 4;
242		b->fl = b->bufsize - b->rl;
243	  	b->underflow = 0;
244	} else {
245		chn_dmaupdate(c);
246	}
247}
248
249/*
250 * Feeds new data to the write dma buffer. Can be called in the bottom half.
251 * Hence must be called at spltty.
252 */
253int
254chn_wrfeed(pcm_channel *c)
255{
256    	snd_dbuf *b = &c->buffer;
257    	snd_dbuf *bs = &c->buffer2nd;
258	int a, l, lacc;
259
260	/* ensure we always have a whole number of samples */
261	a = (1 << c->align) - 1;
262	lacc = 0;
263    	if (c->flags & CHN_F_MAPPED) {
264		bs->rl = min(b->blksz, b->fl);
265		bs->fl = 0;
266		a = 0;
267	}
268    	DEB(if (c->flags & CHN_F_CLOSING)
269		printf("b: [rl: %d, rp %d, fl %d, fp %d]; bs: [rl: %d, rp %d, fl %d, fp %d]\n",
270			b->rl, b->rp, b->fl, b->fp, bs->rl, bs->rp, bs->fl, bs->fp));
271	/* Don't allow write unaligned data */
272	while (bs->rl > a && b->fl > a) {
273		/* ensure we always have a whole number of samples */
274		l = min(min(bs->rl, bs->bufsize - bs->rp), min(b->fl, b->bufsize - b->fp)) & ~a;
275		if (l == 0)
276			return lacc;
277		/* Move the samples, update the markers and pointers. */
278		bcopy(bs->buf + bs->rp, b->buf + b->fp, l);
279		bs->fl += l;
280		bs->rl -= l;
281		bs->rp = (bs->rp + l) % bs->bufsize;
282		b->rl += l;
283		b->fl -= l;
284		b->fp = (b->fp + l) % b->bufsize;
285		/* Clear the new space in the secondary buffer. */
286		buf_clear(bs, bs->fmt, l);
287		/* Accumulate the total bytes of the moved samples. */
288		lacc += l;
289		/* A feed to the DMA buffer is equivalent to an interrupt. */
290		bs->total += l;
291    		if (c->flags & CHN_F_MAPPED) {
292			if (bs->total - bs->prev_total >= bs->blksz) {
293				bs->prev_total = bs->total;
294				bs->int_count++;
295				c->blocks++;
296			}
297		} else
298			bs->int_count++;
299		if (bs->sel.si_pid && chn_polltrigger(c))
300			selwakeup(&bs->sel);
301	}
302
303	return lacc;
304}
305
306/* Feeds new data to the secondary write buffer. */
307static int
308chn_wrfeed2nd(pcm_channel *c, struct uio *buf)
309{
310    	snd_dbuf *bs = &c->buffer2nd;
311	int l, w, wacc, hl;
312	u_int8_t hackbuf[64];
313
314	/* The DMA buffer may have some space. */
315	while (chn_wrfeed(c) > 0);
316
317	/* ensure we always have a whole number of samples */
318	wacc = 0;
319	hl = 0;
320	while (buf->uio_resid > 0 && bs->fl > 64) {
321		/*
322		 * The size of the data to move here does not have to be
323		 * aligned. We take care of it upon moving the data to a
324		 * DMA buffer.
325		 */
326		l = min(bs->fl, bs->bufsize - bs->fp);
327		/* Move the samples, update the markers and pointers. */
328		if (l < 64) {
329			w = c->feeder->feed(c->feeder, c, hackbuf, 64, buf);
330			l = min(w, bs->bufsize - bs->fp);
331			bcopy(hackbuf, bs->buf + bs->fp, l);
332			if (w > l)
333				bcopy(hackbuf + l, bs->buf, w - l);
334		} else
335			w = c->feeder->feed(c->feeder, c, bs->buf + bs->fp, l, buf);
336		if (w == 0)
337			panic("no feed");
338		bs->rl += w;
339		bs->fl -= w;
340		bs->fp = (bs->fp + w) % bs->bufsize;
341		/* Accumulate the total bytes of the moved samples. */
342		wacc += w;
343
344		/* If any pcm data gets moved, push it to the DMA buffer. */
345		if (w > 0)
346			while (chn_wrfeed(c) > 0);
347	}
348
349	return wacc;
350}
351
352/*
353 * Write interrupt routine. Can be called from other places (e.g.
354 * to start a paused transfer), but with interrupts disabled.
355 */
356static void
357chn_wrintr(pcm_channel *c)
358{
359    	snd_dbuf *b = &c->buffer;
360
361    	if (b->underflow && !(c->flags & CHN_F_MAPPED)) {
362/*		printf("underflow return\n");
363*/		return; /* nothing new happened */
364	}
365	if (b->dl)
366		chn_dmadone(c);
367
368    	/*
369	 * start another dma operation only if have ready data in the buffer,
370	 * there is no pending abort, have a full-duplex device, or have a
371	 * half duplex device and there is no pending op on the other side.
372	 *
373	 * Force transfers to be aligned to a boundary of 4, which is
374	 * needed when doing stereo and 16-bit.
375	 */
376
377	/* Check underflow and update the pointers. */
378	chn_checkunderflow(c);
379
380	/*
381	 * Fill up the DMA buffer, followed by waking up the top half.
382	 * If some of the pcm data in uio are still left, the top half
383	 * goes to sleep by itself.
384	 */
385	if (c->flags & CHN_F_MAPPED)
386		chn_wrfeed(c);
387	else {
388		while (chn_wrfeed(c) > 0);
389		buf_clear(b, b->fmt, b->fl);
390	}
391	chn_dmawakeup(c);
392    	if (c->flags & CHN_F_TRIGGERED) {
393		chn_dmaupdate(c);
394		/*
395	 	 * check if we need to reprogram the DMA on the sound card.
396	 	 * This happens if the size has changed from zero
397	 	 */
398		if (b->dl == 0) {
399			/* Start DMA operation */
400	    		b->dl = b->blksz; /* record new transfer size */
401	    		chn_trigger(c, PCMTRIG_START);
402		}
403 		/*
404 		 * Emulate writing by DMA, i.e. transfer the pcm data from
405 		 * the emulated-DMA buffer to the device itself.
406 		 */
407 		chn_trigger(c, PCMTRIG_EMLDMAWR);
408		if (b->rl < b->dl) {
409			DEB(printf("near underflow (%d < %d), %d\n", b->rl, b->dl, b->fl));
410			/*
411			 * we are near to underflow condition, so to prevent
412			 * audio 'clicks' clear next b->fl bytes
413			 */
414			buf_clear(b, b->fmt, b->fl);
415			if (b->rl < DMA_ALIGN_THRESHOLD)
416				b->underflow = 1;
417		}
418    	} else {
419		/* cannot start a new dma transfer */
420		DEB(printf("underflow, flags 0x%08x rp %d rl %d\n", c->flags, b->rp, b->rl));
421		if (b->dl) { /* DMA was active */
422			b->underflow = 1; /* set underflow flag */
423			buf_clear(b, b->fmt, b->bufsize);
424		}
425    	}
426}
427
428/*
429 * user write routine
430 *
431 * advance the boundary between READY and FREE, fill the space with
432 * uiomove(), and possibly start DMA. Do the above until the transfer
433 * is complete.
434 *
435 * To minimize latency in case a pending DMA transfer is about to end,
436 * we do the transfer in pieces of increasing sizes, extending the
437 * READY area at every checkpoint. In the (necessary) assumption that
438 * memory bandwidth is larger than the rate at which the dma consumes
439 * data, we reduce the latency to something proportional to the length
440 * of the first piece, while keeping the overhead low and being able
441 * to feed the DMA with large blocks.
442 */
443
444int
445chn_write(pcm_channel *c, struct uio *buf)
446{
447	int 		ret = 0, timeout, res, newsize, count;
448	long		s;
449	snd_dbuf       *b = &c->buffer;
450	snd_dbuf       *bs = &c->buffer2nd;
451
452	if (c->flags & CHN_F_WRITING) {
453		/* This shouldn't happen and is actually silly
454		 * - will never wake up, just timeout; why not sleep on b?
455		 */
456	       	tsleep(&s, PZERO, "pcmwrW", hz);
457		return EBUSY;
458	}
459	c->flags |= CHN_F_WRITING;
460	c->flags &= ~CHN_F_ABORTING;
461	s = spltty();
462
463	/*
464	 * XXX Certain applications attempt to write larger size
465	 * of pcm data than c->blocksize2nd without blocking,
466	 * resulting partial write. Expand the block size so that
467	 * the write operation avoids blocking.
468	 */
469	if ((c->flags & CHN_F_NBIO) && buf->uio_resid > bs->blksz) {
470		DEB(printf("pcm warning: broken app, nbio and tried to write %d bytes with fragsz %d\n",
471			buf->uio_resid, bs->blksz));
472		newsize = 16;
473		while (newsize < min(buf->uio_resid, CHN_2NDBUFMAXSIZE / 2))
474			newsize <<= 1;
475		chn_setblocksize(c, bs->blkcnt, newsize);
476		DEB(printf("pcm warning: frags reset to %d x %d\n", bs->blkcnt, bs->blksz));
477	}
478
479	/*
480	 * Fill up the secondary and DMA buffer.
481	 * chn_wrfeed*() takes care of the alignment.
482	 */
483
484	/* Check for underflow before writing into the buffers. */
485	chn_checkunderflow(c);
486  	while (chn_wrfeed2nd(c, buf) > 0);
487   	if ((c->flags & CHN_F_NBIO) && (buf->uio_resid > 0))
488		ret = EAGAIN;
489
490	/* Start playing if not yet. */
491	if (!b->dl)
492		chn_start(c, 0);
493
494	if (ret == 0) {
495		count = hz;
496		/* Wait until all samples are played in blocking mode. */
497   		while ((buf->uio_resid > 0) && (count > 0)) {
498			/* Check for underflow before writing into the buffers. */
499			chn_checkunderflow(c);
500			/* Fill up the buffers with new pcm data. */
501			res = buf->uio_resid;
502  			while (chn_wrfeed2nd(c, buf) > 0);
503			if (buf->uio_resid < res)
504				count = hz;
505			else
506				count--;
507
508			/* Have we finished to feed the secondary buffer? */
509			if (buf->uio_resid == 0)
510				break;
511
512			/* Wait for new free space to write new pcm samples. */
513			/* splx(s); */
514			timeout = 1; /*(buf->uio_resid >= b->dl)? hz / 20 : 1; */
515   			ret = tsleep(b, PRIBIO | PCATCH, "pcmwr", timeout);
516   			/* s = spltty(); */
517 			/* if (ret == EINTR) chn_abort(c); */
518 			if (ret == EINTR || ret == ERESTART)
519				break;
520 		}
521		if (count == 0) {
522			c->flags |= CHN_F_DEAD;
523			device_printf(c->parent->dev, "play interrupt timeout, channel dead\n");
524		}
525	} else
526		ret = 0;
527	c->flags &= ~CHN_F_WRITING;
528   	splx(s);
529	return ret;
530}
531
532/*
533 * SOUND INPUT
534 *
535
536The input part is similar to the output one, with a circular buffer
537split in two regions, and boundaries advancing because of read() calls
538[r] or dma operation [d].  At initialization, as for the write
539routine, READY is empty, and FREE takes all the space.
540
541      0          rp,rl        fp,fl    bufsize
542      |__________>____________>________|
543	  FREE   r   READY    d  FREE
544
545Operation is as follows: upon user read (dsp_read_body()) a DMA read
546is started if not already active (marked by b->dl > 0),
547then as soon as data are available in the READY region they are
548transferred to the user buffer, thus advancing the boundary between FREE
549and READY. Upon interrupts, caused by a completion of a DMA transfer,
550the READY region is extended and possibly a new transfer is started.
551
552When necessary, dsp_rd_dmaupdate() is called to advance fp (and update
553rl,fl accordingly). Upon user reads, rp is advanced and rl,fl are
554updated accordingly.
555
556The rules to choose the size of the new DMA area are similar to
557the other case, with a preferred constant transfer size equal to
558rec_blocksize, and fallback to smaller sizes if no space is available.
559
560 */
561
562static int
563chn_rddump(pcm_channel *c, int cnt)
564{
565    	snd_dbuf *b = &c->buffer;
566	int maxover, ss;
567
568	ss = 1;
569	ss <<= (b->fmt & AFMT_STEREO)? 1 : 0;
570	ss <<= (b->fmt & AFMT_16BIT)? 1 : 0;
571	maxover = c->speed * ss;
572
573	b->overrun += cnt;
574	if (b->overrun > maxover) {
575		device_printf(c->parent->dev, "record overrun, dumping %d bytes\n",
576			b->overrun);
577		b->overrun = 0;
578	}
579	b->rl -= cnt;
580	b->fl += cnt;
581	b->rp = (b->rp + cnt) % b->bufsize;
582	return cnt;
583}
584
585/*
586 * Feed new data from the read buffer. Can be called in the bottom half.
587 * Hence must be called at spltty.
588 */
589int
590chn_rdfeed(pcm_channel *c)
591{
592    	snd_dbuf *b = &c->buffer;
593    	snd_dbuf *bs = &c->buffer2nd;
594	int l, lacc;
595
596	/*
597	printf("b: [rl: %d, rp %d, fl %d, fp %d]; bs: [rl: %d, rp %d, fl %d, fp %d]\n",
598		b->rl, b->rp, b->fl, b->fp, bs->rl, bs->rp, bs->fl, bs->fp);
599	 */
600	/* ensure we always have a whole number of samples */
601	lacc = 0;
602	while (bs->fl >= DMA_ALIGN_THRESHOLD && b->rl >= DMA_ALIGN_THRESHOLD) {
603		l = min(min(bs->fl, bs->bufsize - bs->fp), min(b->rl, b->bufsize - b->rp)) & DMA_ALIGN_MASK;
604		/* Move the samples, update the markers and pointers. */
605		bcopy(b->buf + b->rp, bs->buf + bs->fp, l);
606		bs->fl -= l;
607		bs->rl += l;
608		bs->fp = (bs->fp + l) % bs->bufsize;
609		b->rl -= l;
610		b->fl += l;
611		b->rp = (b->rp + l) % b->bufsize;
612		/* Accumulate the total bytes of the moved samples. */
613		lacc += l;
614		/* A feed from the DMA buffer is equivalent to an interrupt. */
615		bs->int_count++;
616		if (bs->sel.si_pid && chn_polltrigger(c))
617			selwakeup(&bs->sel);
618	}
619
620	return lacc;
621}
622
623/* Feeds new data from the secondary read buffer. */
624static int
625chn_rdfeed2nd(pcm_channel *c, struct uio *buf)
626{
627    	snd_dbuf *bs = &c->buffer2nd;
628	int l, w, wacc;
629
630	/* ensure we always have a whole number of samples */
631	wacc = 0;
632	while ((buf->uio_resid > 0) && (bs->rl > 0)) {
633		/* The DMA buffer may have pcm data. */
634		/* while (chn_rdfeed(c) > 0); */
635		/*
636		 * The size of the data to move here does not have to be
637		 * aligned. We take care of it upon moving the data to a
638		 * DMA buffer.
639		 */
640		l = min(bs->rl, bs->bufsize - bs->rp);
641		/* Move the samples, update the markers and pointers. */
642		w = c->feeder->feed(c->feeder, c, bs->buf + bs->rp, l, buf);
643		if (w == 0)
644			panic("no feed");
645		bs->fl += w;
646		bs->rl -= w;
647		bs->rp = (bs->rp + w) % bs->bufsize;
648		/* Clear the new space in the secondary buffer. */
649		buf_clear(bs, bs->fmt, l);
650		/* Accumulate the total bytes of the moved samples. */
651		bs->total += w;
652		wacc += w;
653	}
654
655	return wacc;
656}
657
658/* read interrupt routine. Must be called with interrupts blocked. */
659static void
660chn_rdintr(pcm_channel *c)
661{
662    	snd_dbuf *b = &c->buffer;
663
664    	if (b->dl) chn_dmadone(c);
665
666    	DEB(printf("rdintr: start dl %d, rp:rl %d:%d, fp:fl %d:%d\n",
667		b->dl, b->rp, b->rl, b->fp, b->fl));
668
669	/* Update the pointers. */
670	chn_dmaupdate(c);
671
672	/*
673	 * Suck up the DMA buffer, followed by waking up the top half.
674	 * If some of the pcm data in the secondary buffer are still left,
675	 * the top half goes to sleep by itself.
676	 */
677	while(chn_rdfeed(c) > 0);
678	chn_dmawakeup(c);
679
680	if (b->fl < b->dl) {
681		DEB(printf("near overflow (%d < %d), %d\n", b->fl, b->dl, b->rl));
682		chn_rddump(c, b->blksz - b->fl);
683	}
684
685	if (c->flags & CHN_F_TRIGGERED) {
686		/*
687	 	 * check if we need to reprogram the DMA on the sound card.
688	 	 * This happens if the size has changed from zero
689	 	 */
690		if (b->dl == 0) {
691			/* Start DMA operation */
692	    		b->dl = b->blksz; /* record new transfer size */
693	    		chn_trigger(c, PCMTRIG_START);
694		}
695 		/*
696 		 * Emulate writing by DMA, i.e. transfer the pcm data from
697 		 * the emulated-DMA buffer to the device itself.
698 		 */
699 		chn_trigger(c, PCMTRIG_EMLDMARD);
700    	} else {
701		if (b->dl) { /* was active */
702	    		b->dl = 0;
703	    		chn_trigger(c, PCMTRIG_STOP);
704	    		chn_dmaupdate(c);
705		}
706    	}
707}
708
709/*
710 * body of user-read routine
711 *
712 * Start DMA if not active; wait for READY not empty.
713 * Transfer data from READY region using uiomove(), advance boundary
714 * between FREE and READY. Repeat until transfer is complete.
715 *
716 * To avoid excessive latency in freeing up space for the DMA
717 * engine, transfers are done in blocks of increasing size, so that
718 * the latency is proportional to the size of the smallest block, but
719 * we have a low overhead and are able to feed the dma engine with
720 * large blocks.
721 *
722 * NOTE: in the current version, read will not return more than
723 * blocksize bytes at once (unless more are already available), to
724 * avoid that requests using very large buffers block for too long.
725 */
726
727int
728chn_read(pcm_channel *c, struct uio *buf)
729{
730	int		ret = 0, timeout, limit, res, count;
731	long		s;
732	snd_dbuf       *b = &c->buffer;
733	snd_dbuf       *bs = &c->buffer2nd;
734
735	if (c->flags & CHN_F_READING) {
736		/* This shouldn't happen and is actually silly */
737		tsleep(&s, PZERO, "pcmrdR", hz);
738		return (EBUSY);
739	}
740
741  	s = spltty();
742
743	/* Store the initial size in the uio. */
744	res = buf->uio_resid;
745
746	c->flags |= CHN_F_READING;
747	c->flags &= ~CHN_F_ABORTING;
748
749	/* suck up the DMA and secondary buffers. */
750 	while (chn_rdfeed2nd(c, buf) > 0);
751
752	if (buf->uio_resid == 0)
753		goto skip;
754
755	limit = res - b->blksz;
756	if (limit < 0)
757		limit = 0;
758
759	/* Start capturing if not yet. */
760  	if ((!bs->rl || !b->rl) && !b->dl)
761		chn_start(c, 0);
762
763  	if (!(c->flags & CHN_F_NBIO)) {
764		count = hz;
765  		/* Wait until all samples are captured. */
766  		while ((buf->uio_resid > 0) && (count > 0)) {
767			/* Suck up the DMA and secondary buffers. */
768			chn_dmaupdate(c);
769			res = buf->uio_resid;
770			while (chn_rdfeed(c) > 0);
771 			while (chn_rdfeed2nd(c, buf) > 0);
772			if (buf->uio_resid < res)
773				count = hz;
774			else
775				count--;
776
777			/* Have we finished to feed the uio? */
778			if (buf->uio_resid == 0)
779				break;
780
781			/* Wait for new pcm samples. */
782			/* splx(s); */
783			timeout = (buf->uio_resid - limit >= b->dl)? hz / 20 : 1;
784  			ret = tsleep(b, PRIBIO | PCATCH, "pcmrd", 1);
785  			/* s = spltty(); */
786			/* if (ret == EINTR) chn_abort(c); */
787			if (ret == EINTR || ret == ERESTART)
788				break;
789		}
790		if (count == 0) {
791			c->flags |= CHN_F_DEAD;
792			device_printf(c->parent->dev, "record interrupt timeout, channel dead\n");
793		}
794	} else {
795		/* If no pcm data was read on nonblocking, return EAGAIN. */
796		if (buf->uio_resid == res)
797			ret = EAGAIN;
798	}
799
800skip:
801	c->flags &= ~CHN_F_READING;
802  	splx(s);
803	return ret;
804}
805
806void
807chn_intr(pcm_channel *c)
808{
809	if (c->flags & CHN_F_INIT)
810		chn_reinit(c);
811	if (c->direction == PCMDIR_PLAY)
812		chn_wrintr(c);
813	else
814		chn_rdintr(c);
815}
816
817u_int32_t
818chn_start(pcm_channel *c, int force)
819{
820	u_int32_t r, s;
821	snd_dbuf *b = &c->buffer;
822
823	r = 0;
824	s = spltty();
825    	if (b->dl == 0 && !(c->flags & CHN_F_NOTRIGGER)) {
826		if (c->direction == PCMDIR_PLAY) {
827			if (!(c->flags & CHN_F_MAPPED))
828				while (chn_wrfeed(c) > 0); /* Fill up the DMA buffer. */
829			if (force || (b->rl >= b->blksz))
830				r = CHN_F_TRIGGERED;
831		} else {
832			if (!(c->flags & CHN_F_MAPPED))
833				while (chn_rdfeed(c) > 0); /* Suck up the DMA buffer. */
834			if (force || (b->fl >= b->blksz))
835				r = CHN_F_TRIGGERED;
836		}
837		c->flags |= r;
838		chn_intr(c);
839	}
840	splx(s);
841	return r;
842}
843
844static void
845chn_dma_setmap(void *arg, bus_dma_segment_t *segs, int nseg, int error)
846{
847	snd_dbuf *b = (snd_dbuf *)arg;
848
849	if (bootverbose) {
850		printf("pcm: setmap %lx, %lx; ", (unsigned long)segs->ds_addr,
851		       (unsigned long)segs->ds_len);
852		printf("%p -> %lx\n", b->buf, (unsigned long)vtophys(b->buf));
853	}
854}
855
856/*
857 * Allocate memory for DMA buffer. If the device do not perform DMA transfer,
858 * the drvier can call malloc(9) by its own.
859 */
860int
861chn_allocbuf(snd_dbuf *b, bus_dma_tag_t parent_dmat)
862{
863	b->parent_dmat = parent_dmat;
864	if (bus_dmamem_alloc(b->parent_dmat, (void **)&b->buf,
865			     BUS_DMA_NOWAIT, &b->dmamap)) return -1;
866	if (bus_dmamap_load(b->parent_dmat, b->dmamap, b->buf,
867			    b->bufsize, chn_dma_setmap, b, 0)) return -1;
868	return 0;
869}
870
871void
872chn_freebuf(snd_dbuf *b)
873{
874	bus_dmamem_free(b->parent_dmat, b->buf, b->dmamap);
875}
876
877static void
878buf_clear(snd_dbuf *b, u_int32_t fmt, int length)
879{
880	int i;
881	u_int16_t data, *p;
882
883	if (length == 0)
884		return;
885
886	if (fmt & AFMT_SIGNED)
887		data = 0x00;
888	else
889		data = 0x80;
890
891	if (fmt & AFMT_16BIT)
892		data <<= 8;
893	else
894		data |= data << 8;
895
896	if (fmt & AFMT_BIGENDIAN)
897		data = ((data >> 8) & 0x00ff) | ((data << 8) & 0xff00);
898
899	i = b->fp;
900	p = (u_int16_t *)(b->buf + b->fp);
901	while (length > 1) {
902		*p++ = data;
903		length -= 2;
904		i += 2;
905		if (i >= b->bufsize) {
906			p = (u_int16_t *)b->buf;
907			i = 0;
908		}
909	}
910	if (length == 1)
911		*(b->buf + i) = data & 0xff;
912}
913
914void
915chn_resetbuf(pcm_channel *c)
916{
917	snd_dbuf *b = &c->buffer;
918	snd_dbuf *bs = &c->buffer2nd;
919
920	c->blocks = 0;
921	b->rp = b->fp = 0;
922	b->dl = b->rl = 0;
923	b->fl = b->bufsize;
924	b->prev_total = b->total = 0;
925	b->prev_int_count = b->int_count = 0;
926	b->underflow = 0;
927	if (b->buf && b->bufsize > 0)
928		buf_clear(b, b->fmt, b->bufsize);
929
930	bs->rp = bs->fp = 0;
931	bs->dl = bs->rl = 0;
932	bs->fl = bs->bufsize;
933	bs->prev_total = bs->total = 0;
934	bs->prev_int_count = bs->int_count = 0;
935	bs->underflow = 0;
936	if (bs->buf && bs->bufsize > 0)
937		buf_clear(bs, bs->fmt, bs->bufsize);
938}
939
940void
941buf_isadma(snd_dbuf *b, int go)
942{
943	KASSERT(b, ("buf_isadma called with b == NULL"));
944	KASSERT(ISA_DMA(b), ("buf_isadma called on non-ISA channel"));
945
946	switch (go) {
947	case PCMTRIG_START:
948		isa_dmastart(b->dir | ISADMA_RAW, b->buf, b->bufsize, b->chan);
949		break;
950
951	case PCMTRIG_STOP:
952	case PCMTRIG_ABORT:
953		isa_dmastop(b->chan);
954		isa_dmadone(b->dir | ISADMA_RAW, b->buf, b->bufsize, b->chan);
955		break;
956	}
957
958	DEB(printf("buf 0x%p ISA DMA %s, channel %d\n",
959		b,
960		(go == PCMTRIG_START)? "started" : "stopped",
961		b->chan));
962}
963
964int
965buf_isadmaptr(snd_dbuf *b)
966{
967	if (ISA_DMA(b)) {
968		int i = b->dl? isa_dmastatus(b->chan) : b->bufsize;
969		if (i < 0)
970			i = 0;
971		return b->bufsize - i;
972    	} else KASSERT(1, ("buf_isadmaptr called on invalid channel"));
973	return -1;
974}
975
976/*
977 * chn_sync waits until the space in the given channel goes above
978 * a threshold. The threshold is checked against fl or rl respectively.
979 * Assume that the condition can become true, do not check here...
980 */
981int
982chn_sync(pcm_channel *c, int threshold)
983{
984    	u_long s, rdy;
985    	int ret;
986    	snd_dbuf *b = &c->buffer;
987    	snd_dbuf *bs = &c->buffer2nd;
988
989    	for (;;) {
990		s = spltty();
991		chn_checkunderflow(c);
992		while (chn_wrfeed(c) > 0);
993		rdy = (c->direction == PCMDIR_PLAY)? bs->fl : bs->rl;
994		if (rdy <= threshold) {
995	    		ret = tsleep((caddr_t)b, PRIBIO | PCATCH, "pcmsyn", 1);
996	    		splx(s);
997	    		if (ret == ERESTART || ret == EINTR) {
998				DEB(printf("chn_sync: tsleep returns %d\n", ret));
999				return -1;
1000	    		}
1001		} else break;
1002    	}
1003    	splx(s);
1004    	return 0;
1005}
1006
1007int
1008chn_poll(pcm_channel *c, int ev, struct proc *p)
1009{
1010	snd_dbuf *b = &c->buffer;
1011	snd_dbuf *bs = &c->buffer2nd;
1012	u_long s;
1013	int ret;
1014
1015	s = spltty();
1016    	if (!(c->flags & CHN_F_MAPPED)) {
1017		if (c->direction == PCMDIR_PLAY) {
1018			/* Fill up the DMA buffer. */
1019			chn_checkunderflow(c);
1020			while (chn_wrfeed(c) > 0);
1021		} else {
1022			/* Suck up the DMA buffer. */
1023			chn_dmaupdate(c);
1024			while (chn_rdfeed(c) > 0);
1025		}
1026		if (!b->dl)
1027			chn_start(c, 1);
1028	}
1029	ret = 0;
1030	if (chn_polltrigger(c) && chn_pollreset(c))
1031		ret = ev;
1032	else
1033		selrecord(p, &bs->sel);
1034	splx(s);
1035	return ret;
1036}
1037
1038/*
1039 * chn_abort is a non-blocking function which aborts a pending
1040 * DMA transfer and flushes the buffers.
1041 * It returns the number of bytes that have not been transferred.
1042 */
1043int
1044chn_abort(pcm_channel *c)
1045{
1046    	int missing = 0, cnt = 0;
1047    	snd_dbuf *b = &c->buffer;
1048    	snd_dbuf *bs = &c->buffer2nd;
1049
1050	if (!b->dl)
1051		return 0;
1052	c->flags |= CHN_F_ABORTING;
1053	c->flags &= ~CHN_F_TRIGGERED;
1054	cnt = 10;
1055	while (!b->underflow && (cnt-- > 0))
1056		tsleep((caddr_t)b, PRIBIO | PCATCH, "pcmabr", hz / 50);
1057	chn_trigger(c, PCMTRIG_ABORT);
1058	b->dl = 0;
1059	chn_dmaupdate(c);
1060    	missing = bs->rl + b->rl;
1061    	return missing;
1062}
1063
1064/*
1065 * this routine tries to flush the dma transfer. It is called
1066 * on a close. We immediately abort any read DMA
1067 * operation, and then wait for the play buffer to drain.
1068 */
1069
1070int
1071chn_flush(pcm_channel *c)
1072{
1073    	int ret, count, s, resid, resid_p;
1074    	snd_dbuf *b = &c->buffer;
1075    	snd_dbuf *bs = &c->buffer2nd;
1076
1077    	DEB(printf("chn_flush c->flags 0x%08x\n", c->flags));
1078	if (!b->dl)
1079		return 0;
1080
1081    	c->flags |= CHN_F_CLOSING;
1082    	if (c->direction == PCMDIR_REC)
1083		chn_abort(c);
1084    	else {
1085		resid = b->rl + bs->rl;
1086		resid_p = resid;
1087		count = 10;
1088		while ((count > 0) && (resid > 0) && !b->underflow) {
1089			/* still pending output data. */
1090			ret = tsleep((caddr_t)b, PRIBIO | PCATCH, "pcmflu", hz / 10);
1091			if (ret == EINTR || ret == ERESTART) {
1092	    			DEB(printf("chn_flush: tsleep returns %d\n", ret));
1093	    			return ret;
1094			}
1095 			s = spltty();
1096			chn_dmaupdate(c);
1097			splx(s);
1098			DEB(printf("chn_flush: now rl = %d, fl = %d, resid = %d\n", b->rl, b->fl, resid));
1099			resid = b->rl + bs->rl;
1100			if (resid >= resid_p)
1101				count--;
1102			resid_p = resid;
1103   		}
1104		if (count == 0)
1105			DEB(printf("chn_flush: timeout flushing dbuf_out, cnt 0x%x flags 0x%x\n", b->rl, c->flags));
1106    		if (b->dl)
1107			chn_abort(c);
1108	}
1109    	c->flags &= ~CHN_F_CLOSING;
1110    	return 0;
1111}
1112
1113int
1114fmtvalid(u_int32_t fmt, u_int32_t *fmtlist)
1115{
1116	int i;
1117
1118	for (i = 0; fmtlist[i]; i++)
1119		if (fmt == fmtlist[i])
1120			return 1;
1121	return 0;
1122}
1123
1124int
1125chn_reset(pcm_channel *c, u_int32_t fmt)
1126{
1127	int r = 0;
1128
1129	chn_abort(c);
1130	c->flags &= CHN_F_RESET;
1131	if (c->reset)
1132		c->reset(c->devinfo);
1133	r = chn_setblocksize(c, CHN_2NDBUFBLKNUM, CHN_2NDBUFBLKSIZE);
1134	if (r)
1135		return r;
1136	if (fmt) {
1137		c->speed = DSP_DEFAULT_SPEED;
1138		r = chn_setformat(c, fmt);
1139		if (r == 0)
1140			r = chn_setspeed(c, DSP_DEFAULT_SPEED);
1141		if (r == 0)
1142			r = chn_setvolume(c, 100, 100);
1143	}
1144	chn_resetbuf(c);
1145	if (c->resetdone)
1146		c->resetdone(c->devinfo);
1147	/* c->flags |= CHN_F_INIT; */
1148	return 0;
1149}
1150
1151int
1152chn_reinit(pcm_channel *c)
1153{
1154	if ((c->flags & CHN_F_INIT) && CANCHANGE(c)) {
1155		chn_setformat(c, c->format);
1156		chn_setspeed(c, c->speed);
1157		chn_setvolume(c, (c->volume >> 8) & 0xff, c->volume & 0xff);
1158		c->flags &= ~CHN_F_INIT;
1159		return 1;
1160	}
1161	return 0;
1162}
1163
1164int
1165chn_init(pcm_channel *c, void *devinfo, int dir)
1166{
1167	snd_dbuf       *bs = &c->buffer2nd;
1168
1169	/* Initialize the hardware and DMA buffer first. */
1170	c->feeder = malloc(sizeof(*(c->feeder)), M_DEVBUF, M_NOWAIT);
1171	*(c->feeder) = *feeder_getroot();
1172	c->feederdesc = malloc(sizeof(*(c->feeder)), M_DEVBUF, M_NOWAIT);
1173	c->feederdesc->type = FEEDER_ROOT;
1174	c->feederdesc->in = 0;
1175	c->feederdesc->out = 0;
1176	c->feederdesc->flags = 0;
1177	c->feederdesc->idx = 0;
1178	c->feeder->desc = c->feederdesc;
1179	c->feeder->source = NULL;
1180
1181	c->flags = 0;
1182	c->feederflags = 0;
1183	c->buffer.chan = -1;
1184	c->devinfo = c->init(devinfo, &c->buffer, c, dir);
1185	if (c->devinfo == NULL || c->buffer.bufsize == 0)
1186		return 1;
1187	chn_setdir(c, dir);
1188
1189	/* And the secondary buffer. */
1190	bs->buf = NULL;
1191	bs->bufsize = 0;
1192	return 0;
1193}
1194
1195int
1196chn_kill(pcm_channel *c)
1197{
1198	if (c->flags & CHN_F_TRIGGERED)
1199		chn_trigger(c, PCMTRIG_ABORT);
1200	while (chn_removefeeder(c) == 0);
1201	free(c->feeder->desc, M_DEVBUF);
1202	free(c->feeder, M_DEVBUF);
1203	if (c->free)
1204		c->free(c->devinfo);
1205	else
1206		chn_freebuf(&c->buffer);
1207	c->flags |= CHN_F_DEAD;
1208	return 0;
1209}
1210
1211int
1212chn_setdir(pcm_channel *c, int dir)
1213{
1214	int r;
1215
1216	c->direction = dir;
1217	r = c->setdir? c->setdir(c->devinfo, c->direction) : 0;
1218	if (!r && ISA_DMA(&c->buffer))
1219		c->buffer.dir = (dir == PCMDIR_PLAY)? ISADMA_WRITE : ISADMA_READ;
1220	return r;
1221}
1222
1223int
1224chn_setvolume(pcm_channel *c, int left, int right)
1225{
1226	/* could add a feeder for volume changing if channel returns -1 */
1227	if (CANCHANGE(c)) {
1228		c->volume = (left << 8) | right;
1229		return 0;
1230	}
1231	c->volume = (left << 8) | right;
1232	c->flags |= CHN_F_INIT;
1233	return 0;
1234}
1235
1236int
1237chn_setspeed(pcm_channel *c, int speed)
1238{
1239	pcm_feeder *f;
1240	int r, hwspd, delta;
1241
1242	DEB(printf("want speed %d, ", speed));
1243	if (speed <= 0)
1244		return EINVAL;
1245	if (CANCHANGE(c)) {
1246		c->speed = speed;
1247		hwspd = speed;
1248		RANGE(hwspd, chn_getcaps(c)->minspeed, chn_getcaps(c)->maxspeed);
1249		DEB(printf("try speed %d, ", hwspd));
1250		hwspd = c->setspeed(c->devinfo, hwspd);
1251		DEB(printf("got speed %d, ", hwspd));
1252		delta = hwspd - speed;
1253		if (delta < 0)
1254			delta = -delta;
1255		c->feederflags &= ~(1 << FEEDER_RATE);
1256		if (delta > 500)
1257			c->feederflags |= 1 << FEEDER_RATE;
1258		else
1259			speed = hwspd;
1260		r = chn_buildfeeder(c);
1261		DEB(printf("r = %d\n", r));
1262		if (r)
1263			return r;
1264		if (!(c->feederflags & (1 << FEEDER_RATE)))
1265			return 0;
1266		f = chn_findfeeder(c, FEEDER_RATE);
1267		DEB(printf("feedrate = %p\n", f));
1268		if (f == NULL)
1269			return EINVAL;
1270		r = feeder_set(f, FEEDRATE_SRC, speed);
1271		DEB(printf("feeder_set(FEEDRATE_SRC, %d) = %d\n", speed, r));
1272		if (r)
1273			return r;
1274		r = feeder_set(f, FEEDRATE_DST, hwspd);
1275		DEB(printf("feeder_set(FEEDRATE_DST, %d) = %d\n", hwspd, r));
1276		if (r)
1277			return r;
1278		return 0;
1279	}
1280	c->speed = speed;
1281	c->flags |= CHN_F_INIT;
1282	return 0;
1283}
1284
1285int
1286chn_setformat(pcm_channel *c, u_int32_t fmt)
1287{
1288	snd_dbuf *b = &c->buffer;
1289	snd_dbuf *bs = &c->buffer2nd;
1290	int r;
1291
1292	u_int32_t hwfmt;
1293	if (CANCHANGE(c)) {
1294		DEB(printf("want format %d\n", fmt));
1295		c->format = fmt;
1296		c->feederdesc->out = c->format;
1297		hwfmt = c->format;
1298		c->feederflags &= ~(1 << FEEDER_FMT);
1299		if (!fmtvalid(hwfmt, chn_getcaps(c)->fmtlist))
1300			c->feederflags |= 1 << FEEDER_FMT;
1301		r = chn_buildfeeder(c);
1302		if (r)
1303			return r;
1304		hwfmt = c->feeder->desc->out;
1305		b->fmt = hwfmt;
1306		bs->fmt = hwfmt;
1307		chn_resetbuf(c);
1308		c->setformat(c->devinfo, hwfmt);
1309		return chn_setspeed(c, c->speed);
1310	}
1311	c->format = fmt;
1312	c->flags |= CHN_F_INIT;
1313	return 0;
1314}
1315
1316int
1317chn_setblocksize(pcm_channel *c, int blkcnt, int blksz)
1318{
1319	snd_dbuf *b = &c->buffer;
1320	snd_dbuf *bs = &c->buffer2nd;
1321	int s, ss, bufsz;
1322
1323	if (bs->blkcnt == blkcnt && bs->blksz == blksz)
1324		return 0;
1325    	if (c->flags & CHN_F_MAPPED) {
1326		DEB(printf("chn_setblocksize: can't work on mapped channel"));
1327		return EINVAL;
1328	}
1329	c->flags &= ~CHN_F_HAS_SIZE;
1330
1331	ss = 1;
1332	ss <<= (bs->fmt & AFMT_STEREO)? 1 : 0;
1333	ss <<= (bs->fmt & AFMT_16BIT)? 1 : 0;
1334
1335	if (blksz >= 2)
1336		c->flags |= CHN_F_HAS_SIZE;
1337	/* let us specify blksz without setting CHN_F_HAS_SIZE */
1338	if (blksz < 0)
1339		blksz = -blksz;
1340	/* default to blksz = ~0.25s */
1341	if (blksz < 16)
1342		blksz = (ss * c->speed) >> 2;
1343	if (blksz > CHN_2NDBUFMAXSIZE / 2)
1344		blksz = CHN_2NDBUFMAXSIZE / 2;
1345	if (blkcnt < 2)
1346		blkcnt = 2;
1347
1348	if (blkcnt * blksz > CHN_2NDBUFMAXSIZE)
1349		blkcnt = CHN_2NDBUFMAXSIZE / blksz;
1350	bufsz = blkcnt * blksz;
1351
1352	s = spltty();
1353	if (bs->buf != NULL)
1354		free(bs->buf, M_DEVBUF);
1355	bs->buf = malloc(bufsz, M_DEVBUF, M_WAITOK);
1356	if (bs->buf == NULL) {
1357      		splx(s);
1358		DEB(printf("chn_setblocksize: out of memory."));
1359		return ENOSPC;
1360	}
1361	bs->bufsize = bufsz;
1362	bs->rl = bs->rp = bs->fp = 0;
1363	bs->fl = bs->bufsize;
1364	buf_clear(bs, bs->fmt, bs->bufsize);
1365	bs->blkcnt = blkcnt;
1366	bs->blksz = blksz;
1367	RANGE(blksz, 16, b->bufsize / 2);
1368	b->blksz = c->setblocksize(c->devinfo, blksz);
1369	splx(s);
1370
1371	return 0;
1372}
1373
1374int
1375chn_trigger(pcm_channel *c, int go)
1376{
1377	return c->trigger(c->devinfo, go);
1378}
1379
1380int
1381chn_getptr(pcm_channel *c)
1382{
1383	int hwptr;
1384	int a = (1 << c->align) - 1;
1385	snd_dbuf *b = &c->buffer;
1386
1387	hwptr = b->dl? c->getptr(c->devinfo) : 0;
1388	/* don't allow unaligned values in the hwa ptr */
1389	hwptr &= ~a ; /* Apply channel align mask */
1390	hwptr &= DMA_ALIGN_MASK; /* Apply DMA align mask */
1391	return hwptr;
1392}
1393
1394pcmchan_caps *
1395chn_getcaps(pcm_channel *c)
1396{
1397	return c->getcaps(c->devinfo);
1398}
1399
1400u_int32_t
1401chn_getformats(pcm_channel *c)
1402{
1403	u_int32_t *fmtlist, fmts;
1404	int i;
1405
1406	fmtlist = chn_getcaps(c)->fmtlist;
1407	fmts = 0;
1408	for (i = 0; fmtlist[i]; i++)
1409		fmts |= fmtlist[i];
1410
1411	return fmts;
1412}
1413
1414static int
1415chn_buildfeeder(pcm_channel *c)
1416{
1417	pcm_feeder *f;
1418	struct pcm_feederdesc desc;
1419	u_int32_t tmp[2], src, dst, type, flags;
1420
1421	while (chn_removefeeder(c) == 0);
1422	c->align = 0;
1423	flags = c->feederflags;
1424	src = c->feeder->desc->out;
1425	if ((c->flags & CHN_F_MAPPED) && (flags != 0))
1426		return EINVAL;
1427	DEB(printf("not mapped, flags %x, ", flags));
1428	for (type = FEEDER_RATE; type <= FEEDER_LAST; type++) {
1429		if (flags & (1 << type)) {
1430			desc.type = type;
1431			desc.in = 0;
1432			desc.out = 0;
1433			desc.flags = 0;
1434			DEB(printf("find feeder type %d, ", type));
1435			f = feeder_get(&desc);
1436			DEB(printf("got %p\n", f));
1437			if (f == NULL)
1438				return EINVAL;
1439			dst = f->desc->in;
1440			if (src != dst) {
1441 				DEB(printf("build fmtchain from %x to %x: ", src, dst));
1442				tmp[0] = dst;
1443				tmp[1] = 0;
1444				if (chn_fmtchain(c, tmp) == 0)
1445					return EINVAL;
1446 				DEB(printf("ok\n"));
1447			}
1448			if (chn_addfeeder(c, f))
1449				return EINVAL;
1450			src = f->desc->out;
1451			DEB(printf("added feeder %p, output %x\n", f, src));
1452			dst = 0;
1453			flags &= ~(1 << type);
1454		}
1455	}
1456	if (!fmtvalid(src, chn_getcaps(c)->fmtlist)) {
1457		if (chn_fmtchain(c, chn_getcaps(c)->fmtlist) == 0)
1458			return EINVAL;
1459		DEB(printf("built fmtchain from %x to %x\n", src, c->feeder->desc->out));
1460		flags &= ~(1 << FEEDER_FMT);
1461	}
1462	return 0;
1463}
1464