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