channel.c revision 65209
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 65209 2000-08-29 16:32:26Z 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 u_int32_t chn_start(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;
311
312	/* The DMA buffer may have some space. */
313	while (chn_wrfeed(c) > 0);
314
315	/* ensure we always have a whole number of samples */
316	wacc = 0;
317	while (buf->uio_resid > 0 && bs->fl > 0) {
318		/*
319		 * The size of the data to move here does not have to be
320		 * aligned. We take care of it upon moving the data to a
321		 * DMA buffer.
322		 */
323		l = min(bs->fl, bs->bufsize - bs->fp);
324		/* Move the samples, update the markers and pointers. */
325		w = c->feeder->feed(c->feeder, c, bs->buf + bs->fp, l, buf);
326		if (w == 0)
327			panic("no feed");
328		bs->rl += w;
329		bs->fl -= w;
330		bs->fp = (bs->fp + w) % bs->bufsize;
331		/* Accumulate the total bytes of the moved samples. */
332		wacc += w;
333
334		/* If any pcm data gets moved, push it to the DMA buffer. */
335		if (w > 0)
336			while (chn_wrfeed(c) > 0);
337	}
338
339	return wacc;
340}
341
342/*
343 * Write interrupt routine. Can be called from other places (e.g.
344 * to start a paused transfer), but with interrupts disabled.
345 */
346static void
347chn_wrintr(pcm_channel *c)
348{
349    	snd_dbuf *b = &c->buffer;
350
351    	if (b->underflow && !(c->flags & CHN_F_MAPPED)) {
352/*		printf("underflow return\n");
353*/		return; /* nothing new happened */
354	}
355	if (b->dl)
356		chn_dmadone(c);
357
358    	/*
359	 * start another dma operation only if have ready data in the buffer,
360	 * there is no pending abort, have a full-duplex device, or have a
361	 * half duplex device and there is no pending op on the other side.
362	 *
363	 * Force transfers to be aligned to a boundary of 4, which is
364	 * needed when doing stereo and 16-bit.
365	 */
366
367	/* Check underflow and update the pointers. */
368	chn_checkunderflow(c);
369
370	/*
371	 * Fill up the DMA buffer, followed by waking up the top half.
372	 * If some of the pcm data in uio are still left, the top half
373	 * goes to sleep by itself.
374	 */
375	if (c->flags & CHN_F_MAPPED)
376		chn_wrfeed(c);
377	else {
378		while (chn_wrfeed(c) > 0);
379		buf_clear(b, b->fmt, b->fl);
380	}
381	chn_dmawakeup(c);
382    	if (c->flags & CHN_F_TRIGGERED) {
383		chn_dmaupdate(c);
384		/*
385	 	 * check if we need to reprogram the DMA on the sound card.
386	 	 * This happens if the size has changed from zero
387	 	 */
388		if (b->dl == 0) {
389			/* Start DMA operation */
390	    		b->dl = b->blksz; /* record new transfer size */
391	    		chn_trigger(c, PCMTRIG_START);
392		}
393 		/*
394 		 * Emulate writing by DMA, i.e. transfer the pcm data from
395 		 * the emulated-DMA buffer to the device itself.
396 		 */
397 		chn_trigger(c, PCMTRIG_EMLDMAWR);
398		if (b->rl < b->dl) {
399			DEB(printf("near underflow (%d < %d), %d\n", b->rl, b->dl, b->fl));
400			/*
401			 * we are near to underflow condition, so to prevent
402			 * audio 'clicks' clear next b->fl bytes
403			 */
404			buf_clear(b, b->fmt, b->fl);
405			if (b->rl < DMA_ALIGN_THRESHOLD)
406				b->underflow = 1;
407		}
408    	} else {
409		/* cannot start a new dma transfer */
410		DEB(printf("underflow, flags 0x%08x rp %d rl %d\n", c->flags, b->rp, b->rl));
411		if (b->dl) { /* DMA was active */
412			b->underflow = 1; /* set underflow flag */
413			buf_clear(b, b->fmt, b->bufsize);
414		}
415    	}
416}
417
418/*
419 * user write routine
420 *
421 * advance the boundary between READY and FREE, fill the space with
422 * uiomove(), and possibly start DMA. Do the above until the transfer
423 * is complete.
424 *
425 * To minimize latency in case a pending DMA transfer is about to end,
426 * we do the transfer in pieces of increasing sizes, extending the
427 * READY area at every checkpoint. In the (necessary) assumption that
428 * memory bandwidth is larger than the rate at which the dma consumes
429 * data, we reduce the latency to something proportional to the length
430 * of the first piece, while keeping the overhead low and being able
431 * to feed the DMA with large blocks.
432 */
433
434int
435chn_write(pcm_channel *c, struct uio *buf)
436{
437	int 		ret = 0, timeout, res, newsize, count;
438	long		s;
439	snd_dbuf       *b = &c->buffer;
440	snd_dbuf       *bs = &c->buffer2nd;
441
442	if (c->flags & CHN_F_WRITING) {
443		/* This shouldn't happen and is actually silly
444		 * - will never wake up, just timeout; why not sleep on b?
445		 */
446	       	tsleep(&s, PZERO, "pcmwrW", hz);
447		return EBUSY;
448	}
449	c->flags |= CHN_F_WRITING;
450	c->flags &= ~CHN_F_ABORTING;
451	s = spltty();
452
453	/*
454	 * XXX Certain applications attempt to write larger size
455	 * of pcm data than c->blocksize2nd without blocking,
456	 * resulting partial write. Expand the block size so that
457	 * the write operation avoids blocking.
458	 */
459	if ((c->flags & CHN_F_NBIO) && buf->uio_resid > bs->blksz) {
460		DEB(printf("pcm warning: broken app, nbio and tried to write %d bytes with fragsz %d\n",
461			buf->uio_resid, bs->blksz));
462		newsize = 16;
463		while (newsize < min(buf->uio_resid, CHN_2NDBUFMAXSIZE / 2))
464			newsize <<= 1;
465		chn_setblocksize(c, bs->blkcnt, newsize);
466		DEB(printf("pcm warning: frags reset to %d x %d\n", bs->blkcnt, bs->blksz));
467	}
468
469	/*
470	 * Fill up the secondary and DMA buffer.
471	 * chn_wrfeed*() takes care of the alignment.
472	 */
473
474	/* Check for underflow before writing into the buffers. */
475	chn_checkunderflow(c);
476  	while (chn_wrfeed2nd(c, buf) > 0);
477   	if ((c->flags & CHN_F_NBIO) && (buf->uio_resid > 0))
478		ret = EAGAIN;
479
480	/* Start playing if not yet. */
481	if (!b->dl)
482		chn_start(c);
483
484	if (ret == 0) {
485		count = hz;
486		/* Wait until all samples are played in blocking mode. */
487   		while ((buf->uio_resid > 0) && (count > 0)) {
488			/* Check for underflow before writing into the buffers. */
489			chn_checkunderflow(c);
490			/* Fill up the buffers with new pcm data. */
491			res = buf->uio_resid;
492  			while (chn_wrfeed2nd(c, buf) > 0);
493			if (buf->uio_resid < res)
494				count = hz;
495			else
496				count--;
497
498			/* Have we finished to feed the secondary buffer? */
499			if (buf->uio_resid == 0)
500				break;
501
502			/* Wait for new free space to write new pcm samples. */
503			/* splx(s); */
504			timeout = 1; /*(buf->uio_resid >= b->dl)? hz / 20 : 1; */
505   			ret = tsleep(b, PRIBIO | PCATCH, "pcmwr", timeout);
506   			/* s = spltty(); */
507 			/* if (ret == EINTR) chn_abort(c); */
508 			if (ret == EINTR || ret == ERESTART)
509				break;
510 		}
511		if (count == 0) {
512			c->flags |= CHN_F_DEAD;
513			device_printf(c->parent->dev, "play interrupt timeout, channel dead\n");
514		}
515	} else
516		ret = 0;
517	c->flags &= ~CHN_F_WRITING;
518   	splx(s);
519	return ret;
520}
521
522/*
523 * SOUND INPUT
524 *
525
526The input part is similar to the output one, with a circular buffer
527split in two regions, and boundaries advancing because of read() calls
528[r] or dma operation [d].  At initialization, as for the write
529routine, READY is empty, and FREE takes all the space.
530
531      0          rp,rl        fp,fl    bufsize
532      |__________>____________>________|
533	  FREE   r   READY    d  FREE
534
535Operation is as follows: upon user read (dsp_read_body()) a DMA read
536is started if not already active (marked by b->dl > 0),
537then as soon as data are available in the READY region they are
538transferred to the user buffer, thus advancing the boundary between FREE
539and READY. Upon interrupts, caused by a completion of a DMA transfer,
540the READY region is extended and possibly a new transfer is started.
541
542When necessary, dsp_rd_dmaupdate() is called to advance fp (and update
543rl,fl accordingly). Upon user reads, rp is advanced and rl,fl are
544updated accordingly.
545
546The rules to choose the size of the new DMA area are similar to
547the other case, with a preferred constant transfer size equal to
548rec_blocksize, and fallback to smaller sizes if no space is available.
549
550 */
551
552static int
553chn_rddump(pcm_channel *c, int cnt)
554{
555    	snd_dbuf *b = &c->buffer;
556	int maxover, ss;
557
558	ss = 1;
559	ss <<= (b->fmt & AFMT_STEREO)? 1 : 0;
560	ss <<= (b->fmt & AFMT_16BIT)? 1 : 0;
561	maxover = c->speed * ss;
562
563	b->overrun += cnt;
564	if (b->overrun > maxover) {
565		device_printf(c->parent->dev, "record overrun, dumping %d bytes\n",
566			b->overrun);
567		b->overrun = 0;
568	}
569	b->rl -= cnt;
570	b->fl += cnt;
571	b->rp = (b->rp + cnt) % b->bufsize;
572	return cnt;
573}
574
575/*
576 * Feed new data from the read buffer. Can be called in the bottom half.
577 * Hence must be called at spltty.
578 */
579int
580chn_rdfeed(pcm_channel *c)
581{
582    	snd_dbuf *b = &c->buffer;
583    	snd_dbuf *bs = &c->buffer2nd;
584	int l, lacc;
585
586	/*
587	printf("b: [rl: %d, rp %d, fl %d, fp %d]; bs: [rl: %d, rp %d, fl %d, fp %d]\n",
588		b->rl, b->rp, b->fl, b->fp, bs->rl, bs->rp, bs->fl, bs->fp);
589	 */
590	/* ensure we always have a whole number of samples */
591	lacc = 0;
592	while (bs->fl >= DMA_ALIGN_THRESHOLD && b->rl >= DMA_ALIGN_THRESHOLD) {
593		l = min(min(bs->fl, bs->bufsize - bs->fp), min(b->rl, b->bufsize - b->rp)) & DMA_ALIGN_MASK;
594		/* Move the samples, update the markers and pointers. */
595		bcopy(b->buf + b->rp, bs->buf + bs->fp, l);
596		bs->fl -= l;
597		bs->rl += l;
598		bs->fp = (bs->fp + l) % bs->bufsize;
599		b->rl -= l;
600		b->fl += l;
601		b->rp = (b->rp + l) % b->bufsize;
602		/* Accumulate the total bytes of the moved samples. */
603		lacc += l;
604		/* A feed from the DMA buffer is equivalent to an interrupt. */
605		bs->int_count++;
606		if (bs->sel.si_pid && chn_polltrigger(c))
607			selwakeup(&bs->sel);
608	}
609
610	return lacc;
611}
612
613/* Feeds new data from the secondary read buffer. */
614static int
615chn_rdfeed2nd(pcm_channel *c, struct uio *buf)
616{
617    	snd_dbuf *bs = &c->buffer2nd;
618	int l, w, wacc;
619
620	/* ensure we always have a whole number of samples */
621	wacc = 0;
622	while ((buf->uio_resid > 0) && (bs->rl > 0)) {
623		/* The DMA buffer may have pcm data. */
624		/* while (chn_rdfeed(c) > 0); */
625		/*
626		 * The size of the data to move here does not have to be
627		 * aligned. We take care of it upon moving the data to a
628		 * DMA buffer.
629		 */
630		l = min(bs->rl, bs->bufsize - bs->rp);
631		/* Move the samples, update the markers and pointers. */
632		w = c->feeder->feed(c->feeder, c, bs->buf + bs->rp, l, buf);
633		if (w == 0)
634			panic("no feed");
635		bs->fl += w;
636		bs->rl -= w;
637		bs->rp = (bs->rp + w) % bs->bufsize;
638		/* Clear the new space in the secondary buffer. */
639		buf_clear(bs, bs->fmt, l);
640		/* Accumulate the total bytes of the moved samples. */
641		bs->total += w;
642		wacc += w;
643	}
644
645	return wacc;
646}
647
648/* read interrupt routine. Must be called with interrupts blocked. */
649static void
650chn_rdintr(pcm_channel *c)
651{
652    	snd_dbuf *b = &c->buffer;
653
654    	if (b->dl) chn_dmadone(c);
655
656    	DEB(printf("rdintr: start dl %d, rp:rl %d:%d, fp:fl %d:%d\n",
657		b->dl, b->rp, b->rl, b->fp, b->fl));
658
659	/* Update the pointers. */
660	chn_dmaupdate(c);
661
662	/*
663	 * Suck up the DMA buffer, followed by waking up the top half.
664	 * If some of the pcm data in the secondary buffer are still left,
665	 * the top half goes to sleep by itself.
666	 */
667	while(chn_rdfeed(c) > 0);
668	chn_dmawakeup(c);
669
670	if (b->fl < b->dl) {
671		DEB(printf("near overflow (%d < %d), %d\n", b->fl, b->dl, b->rl));
672		chn_rddump(c, b->blksz - b->fl);
673	}
674
675	if (c->flags & CHN_F_TRIGGERED) {
676		/*
677	 	 * check if we need to reprogram the DMA on the sound card.
678	 	 * This happens if the size has changed from zero
679	 	 */
680		if (b->dl == 0) {
681			/* Start DMA operation */
682	    		b->dl = b->blksz; /* record new transfer size */
683	    		chn_trigger(c, PCMTRIG_START);
684		}
685 		/*
686 		 * Emulate writing by DMA, i.e. transfer the pcm data from
687 		 * the emulated-DMA buffer to the device itself.
688 		 */
689 		chn_trigger(c, PCMTRIG_EMLDMARD);
690    	} else {
691		if (b->dl) { /* was active */
692	    		b->dl = 0;
693	    		chn_trigger(c, PCMTRIG_STOP);
694	    		chn_dmaupdate(c);
695		}
696    	}
697}
698
699/*
700 * body of user-read routine
701 *
702 * Start DMA if not active; wait for READY not empty.
703 * Transfer data from READY region using uiomove(), advance boundary
704 * between FREE and READY. Repeat until transfer is complete.
705 *
706 * To avoid excessive latency in freeing up space for the DMA
707 * engine, transfers are done in blocks of increasing size, so that
708 * the latency is proportional to the size of the smallest block, but
709 * we have a low overhead and are able to feed the dma engine with
710 * large blocks.
711 *
712 * NOTE: in the current version, read will not return more than
713 * blocksize bytes at once (unless more are already available), to
714 * avoid that requests using very large buffers block for too long.
715 */
716
717int
718chn_read(pcm_channel *c, struct uio *buf)
719{
720	int		ret = 0, timeout, limit, res, count;
721	long		s;
722	snd_dbuf       *b = &c->buffer;
723	snd_dbuf       *bs = &c->buffer2nd;
724
725	if (c->flags & CHN_F_READING) {
726		/* This shouldn't happen and is actually silly */
727		tsleep(&s, PZERO, "pcmrdR", hz);
728		return (EBUSY);
729	}
730
731  	s = spltty();
732
733	/* Store the initial size in the uio. */
734	res = buf->uio_resid;
735
736	c->flags |= CHN_F_READING;
737	c->flags &= ~CHN_F_ABORTING;
738
739	/* suck up the DMA and secondary buffers. */
740 	while (chn_rdfeed2nd(c, buf) > 0);
741
742	if (buf->uio_resid == 0)
743		goto skip;
744
745	limit = res - b->blksz;
746	if (limit < 0)
747		limit = 0;
748
749	/* Start capturing if not yet. */
750  	if ((!bs->rl || !b->rl) && !b->dl)
751		chn_start(c);
752
753  	if (!(c->flags & CHN_F_NBIO)) {
754		count = hz;
755  		/* Wait until all samples are captured. */
756  		while ((buf->uio_resid > 0) && (count > 0)) {
757			/* Suck up the DMA and secondary buffers. */
758			chn_dmaupdate(c);
759			res = buf->uio_resid;
760			while (chn_rdfeed(c) > 0);
761 			while (chn_rdfeed2nd(c, buf) > 0);
762			if (buf->uio_resid < res)
763				count = hz;
764			else
765				count--;
766
767			/* Have we finished to feed the uio? */
768			if (buf->uio_resid == 0)
769				break;
770
771			/* Wait for new pcm samples. */
772			/* splx(s); */
773			timeout = (buf->uio_resid - limit >= b->dl)? hz / 20 : 1;
774  			ret = tsleep(b, PRIBIO | PCATCH, "pcmrd", 1);
775  			/* s = spltty(); */
776			/* if (ret == EINTR) chn_abort(c); */
777			if (ret == EINTR || ret == ERESTART)
778				break;
779		}
780		if (count == 0) {
781			c->flags |= CHN_F_DEAD;
782			device_printf(c->parent->dev, "record interrupt timeout, channel dead\n");
783		}
784	} else {
785		/* If no pcm data was read on nonblocking, return EAGAIN. */
786		if (buf->uio_resid == res)
787			ret = EAGAIN;
788	}
789
790skip:
791	c->flags &= ~CHN_F_READING;
792  	splx(s);
793	return ret;
794}
795
796void
797chn_intr(pcm_channel *c)
798{
799	if (c->flags & CHN_F_INIT)
800		chn_reinit(c);
801	if (c->direction == PCMDIR_PLAY)
802		chn_wrintr(c);
803	else
804		chn_rdintr(c);
805}
806
807u_int32_t
808chn_start(pcm_channel *c)
809{
810	u_int32_t r, s;
811	snd_dbuf *b = &c->buffer;
812
813	r = 0;
814	s = spltty();
815    	if (b->dl == 0 && !(c->flags & (CHN_F_MAPPED | CHN_F_NOTRIGGER))) {
816		if (c->direction == PCMDIR_PLAY) {
817			/* Fill up the DMA buffer. */
818			while (chn_wrfeed(c) > 0);
819			if (b->rl >= b->blksz)
820				r = CHN_F_TRIGGERED;
821		} else {
822			/* Suck up the DMA buffer. */
823			while (chn_rdfeed(c) > 0);
824			if (b->fl >= b->blksz)
825				r = CHN_F_TRIGGERED;
826		}
827		c->flags |= r;
828		chn_intr(c);
829	}
830	splx(s);
831	return r;
832}
833
834static void
835chn_dma_setmap(void *arg, bus_dma_segment_t *segs, int nseg, int error)
836{
837	snd_dbuf *b = (snd_dbuf *)arg;
838
839	if (bootverbose) {
840		printf("pcm: setmap %lx, %lx; ", (unsigned long)segs->ds_addr,
841		       (unsigned long)segs->ds_len);
842		printf("%p -> %lx\n", b->buf, (unsigned long)vtophys(b->buf));
843	}
844}
845
846/*
847 * Allocate memory for DMA buffer. If the device do not perform DMA transfer,
848 * the drvier can call malloc(9) by its own.
849 */
850int
851chn_allocbuf(snd_dbuf *b, bus_dma_tag_t parent_dmat)
852{
853	if (bus_dmamem_alloc(parent_dmat, (void **)&b->buf,
854			     BUS_DMA_NOWAIT, &b->dmamap)) return -1;
855	if (bus_dmamap_load(parent_dmat, b->dmamap, b->buf,
856			    b->bufsize, chn_dma_setmap, b, 0)) return -1;
857	return 0;
858}
859
860static void
861buf_clear(snd_dbuf *b, u_int32_t fmt, int length)
862{
863	int i;
864	u_int16_t data, *p;
865
866	if (length == 0)
867		return;
868
869	if (fmt & AFMT_SIGNED)
870		data = 0x00;
871	else
872		data = 0x80;
873
874	if (fmt & AFMT_16BIT)
875		data <<= 8;
876	else
877		data |= data << 8;
878
879	if (fmt & AFMT_BIGENDIAN)
880		data = ((data >> 8) & 0x00ff) | ((data << 8) & 0xff00);
881
882	i = b->fp;
883	p = (u_int16_t *)(b->buf + b->fp);
884	while (length > 1) {
885		*p++ = data;
886		length -= 2;
887		i += 2;
888		if (i >= b->bufsize) {
889			p = (u_int16_t *)b->buf;
890			i = 0;
891		}
892	}
893	if (length == 1)
894		*(b->buf + i) = data & 0xff;
895}
896
897void
898chn_resetbuf(pcm_channel *c)
899{
900	snd_dbuf *b = &c->buffer;
901	snd_dbuf *bs = &c->buffer2nd;
902
903	c->blocks = 0;
904	b->rp = b->fp = 0;
905	b->dl = b->rl = 0;
906	b->fl = b->bufsize;
907	b->prev_total = b->total = 0;
908	b->prev_int_count = b->int_count = 0;
909	b->underflow = 0;
910	if (b->buf && b->bufsize > 0)
911		buf_clear(b, b->fmt, b->bufsize);
912
913	bs->rp = bs->fp = 0;
914	bs->dl = bs->rl = 0;
915	bs->fl = bs->bufsize;
916	bs->prev_total = bs->total = 0;
917	bs->prev_int_count = bs->int_count = 0;
918	bs->underflow = 0;
919	if (bs->buf && bs->bufsize > 0)
920		buf_clear(bs, bs->fmt, bs->bufsize);
921}
922
923void
924buf_isadma(snd_dbuf *b, int go)
925{
926	if (ISA_DMA(b)) {
927		switch (go) {
928		case PCMTRIG_START:
929			DEB(printf("buf 0x%p ISA DMA started\n", b));
930			isa_dmastart(b->dir | ISADMA_RAW, b->buf,
931					b->bufsize, b->chan);
932			break;
933		case PCMTRIG_STOP:
934		case PCMTRIG_ABORT:
935			DEB(printf("buf 0x%p ISA DMA stopped\n", b));
936			isa_dmastop(b->chan);
937			isa_dmadone(b->dir | ISADMA_RAW, b->buf, b->bufsize,
938				    b->chan);
939			break;
940		}
941    	} else KASSERT(1, ("buf_isadma called on invalid channel"));
942}
943
944int
945buf_isadmaptr(snd_dbuf *b)
946{
947	if (ISA_DMA(b)) {
948		int i = b->dl? isa_dmastatus(b->chan) : b->bufsize;
949		if (i < 0)
950			i = 0;
951		return b->bufsize - i;
952    	} else KASSERT(1, ("buf_isadmaptr called on invalid channel"));
953	return -1;
954}
955
956/*
957 * chn_sync waits until the space in the given channel goes above
958 * a threshold. The threshold is checked against fl or rl respectively.
959 * Assume that the condition can become true, do not check here...
960 */
961int
962chn_sync(pcm_channel *c, int threshold)
963{
964    	u_long s, rdy;
965    	int ret;
966    	snd_dbuf *b = &c->buffer;
967    	snd_dbuf *bs = &c->buffer2nd;
968
969    	for (;;) {
970		s = spltty();
971		chn_checkunderflow(c);
972		while (chn_wrfeed(c) > 0);
973		rdy = (c->direction == PCMDIR_PLAY)? bs->fl : bs->rl;
974		if (rdy <= threshold) {
975	    		ret = tsleep((caddr_t)b, PRIBIO | PCATCH, "pcmsyn", 1);
976	    		splx(s);
977	    		if (ret == ERESTART || ret == EINTR) {
978				DEB(printf("chn_sync: tsleep returns %d\n", ret));
979				return -1;
980	    		}
981		} else break;
982    	}
983    	splx(s);
984    	return 0;
985}
986
987int
988chn_poll(pcm_channel *c, int ev, struct proc *p)
989{
990	snd_dbuf *b = &c->buffer;
991	snd_dbuf *bs = &c->buffer2nd;
992	u_long s;
993	int ret;
994
995	s = spltty();
996    	if (!(c->flags & CHN_F_MAPPED)) {
997		if (c->direction == PCMDIR_PLAY) {
998			/* Fill up the DMA buffer. */
999			chn_checkunderflow(c);
1000			while (chn_wrfeed(c) > 0);
1001		} else {
1002			/* Suck up the DMA buffer. */
1003			chn_dmaupdate(c);
1004			while (chn_rdfeed(c) > 0);
1005		}
1006		if (!b->dl)
1007			chn_start(c);
1008	}
1009	ret = 0;
1010	if (chn_polltrigger(c) && chn_pollreset(c))
1011		ret = ev;
1012	else
1013		selrecord(p, &bs->sel);
1014	splx(s);
1015	return ret;
1016}
1017
1018/*
1019 * chn_abort is a non-blocking function which aborts a pending
1020 * DMA transfer and flushes the buffers.
1021 * It returns the number of bytes that have not been transferred.
1022 */
1023int
1024chn_abort(pcm_channel *c)
1025{
1026    	int missing = 0, cnt = 0;
1027    	snd_dbuf *b = &c->buffer;
1028    	snd_dbuf *bs = &c->buffer2nd;
1029
1030	if (!b->dl)
1031		return 0;
1032	c->flags |= CHN_F_ABORTING;
1033	c->flags &= ~CHN_F_TRIGGERED;
1034	cnt = 10;
1035	while (!b->underflow && (cnt-- > 0))
1036		tsleep((caddr_t)b, PRIBIO | PCATCH, "pcmabr", hz / 50);
1037	chn_trigger(c, PCMTRIG_ABORT);
1038	b->dl = 0;
1039	chn_dmaupdate(c);
1040    	missing = bs->rl + b->rl;
1041    	return missing;
1042}
1043
1044/*
1045 * this routine tries to flush the dma transfer. It is called
1046 * on a close. We immediately abort any read DMA
1047 * operation, and then wait for the play buffer to drain.
1048 */
1049
1050int
1051chn_flush(pcm_channel *c)
1052{
1053    	int ret, count, s, resid, resid_p;
1054    	snd_dbuf *b = &c->buffer;
1055    	snd_dbuf *bs = &c->buffer2nd;
1056
1057    	DEB(printf("chn_flush c->flags 0x%08x\n", c->flags));
1058    	c->flags |= CHN_F_CLOSING;
1059    	if (c->direction == PCMDIR_REC)
1060		chn_abort(c);
1061    	else if (b->dl) {
1062		resid_p = resid = b->rl + bs->rl;
1063		count = 10;
1064		while ((count > 0) && (resid > 0) && !b->underflow) {
1065			/* still pending output data. */
1066			ret = tsleep((caddr_t)b, PRIBIO | PCATCH, "pcmflu", hz / 10);
1067			if (ret == EINTR || ret == ERESTART) {
1068	    			DEB(printf("chn_flush: tsleep returns %d\n", ret));
1069	    			return ret;
1070			}
1071 			s = spltty();
1072			chn_dmaupdate(c);
1073			splx(s);
1074			DEB(printf("chn_flush: now rl = %d, fl = %d\n", b->rl, b->fl));
1075			resid = b->rl + bs->rl;
1076			if (resid >= resid_p)
1077				count--;
1078			resid_p = resid;
1079   		}
1080		if (count == 0)
1081			DEB(printf("chn_flush: timeout flushing dbuf_out, cnt 0x%x flags 0x%x\n", b->rl, c->flags));
1082    		if (c->direction == PCMDIR_PLAY && b->dl)
1083			chn_abort(c);
1084	}
1085    	c->flags &= ~CHN_F_CLOSING;
1086    	return 0;
1087}
1088
1089int
1090chn_reset(pcm_channel *c, u_int32_t fmt)
1091{
1092	int r = 0;
1093
1094	chn_abort(c);
1095	c->flags &= CHN_F_RESET;
1096	r = chn_setblocksize(c, CHN_2NDBUFBLKNUM, CHN_2NDBUFBLKSIZE);
1097	if (r)
1098		return r;
1099	if (fmt) {
1100		r = chn_setformat(c, fmt);
1101		if (r == 0)
1102			r = chn_setspeed(c, DSP_DEFAULT_SPEED);
1103		if (r == 0)
1104			r = chn_setvolume(c, 100, 100);
1105	}
1106	chn_resetbuf(c);
1107	/* c->flags |= CHN_F_INIT; */
1108	return 0;
1109}
1110
1111int
1112chn_reinit(pcm_channel *c)
1113{
1114	if ((c->flags & CHN_F_INIT) && CANCHANGE(c)) {
1115		chn_setformat(c, c->format);
1116		chn_setspeed(c, c->speed);
1117		chn_setvolume(c, (c->volume >> 8) & 0xff, c->volume & 0xff);
1118		c->flags &= ~CHN_F_INIT;
1119		return 1;
1120	}
1121	return 0;
1122}
1123
1124int
1125chn_init(pcm_channel *c, void *devinfo, int dir)
1126{
1127	snd_dbuf       *bs = &c->buffer2nd;
1128
1129	/* Initialize the hardware and DMA buffer first. */
1130	c->feeder = malloc(sizeof(*(c->feeder)), M_DEVBUF, M_NOWAIT);
1131	*(c->feeder) = *feeder_getroot();
1132	c->feederdesc = malloc(sizeof(*(c->feeder)), M_DEVBUF, M_NOWAIT);
1133	c->feederdesc->type = FEEDER_ROOT;
1134	c->feederdesc->in = 0;
1135	c->feederdesc->out = 0;
1136	c->feederdesc->flags = 0;
1137	c->feederdesc->idx = 0;
1138	c->feeder->desc = c->feederdesc;
1139	c->feeder->source = NULL;
1140
1141	c->flags = 0;
1142	c->buffer.chan = -1;
1143	c->devinfo = c->init(devinfo, &c->buffer, c, dir);
1144	if (c->devinfo == NULL || c->buffer.bufsize == 0)
1145		return 1;
1146	chn_setdir(c, dir);
1147
1148	/* And the secondary buffer. */
1149	bs->buf = NULL;
1150	bs->bufsize = 0;
1151	return 0;
1152}
1153
1154int
1155chn_setdir(pcm_channel *c, int dir)
1156{
1157	int r;
1158
1159	c->direction = dir;
1160	r = c->setdir(c->devinfo, c->direction);
1161	if (!r && ISA_DMA(&c->buffer))
1162		c->buffer.dir = (dir == PCMDIR_PLAY)? ISADMA_WRITE : ISADMA_READ;
1163	return r;
1164}
1165
1166int
1167chn_setvolume(pcm_channel *c, int left, int right)
1168{
1169	/* could add a feeder for volume changing if channel returns -1 */
1170	if (CANCHANGE(c)) {
1171		c->volume = (left << 8) | right;
1172		return 0;
1173	}
1174	c->volume = (left << 8) | right;
1175	c->flags |= CHN_F_INIT;
1176	return 0;
1177}
1178
1179int
1180chn_setspeed(pcm_channel *c, int speed)
1181{
1182	if (speed <= 0)
1183		return EINVAL;
1184	/* could add a feeder for rate conversion */
1185	if (CANCHANGE(c)) {
1186		c->speed = c->setspeed(c->devinfo, speed);
1187		return 0;
1188	}
1189	c->speed = speed;
1190	c->flags |= CHN_F_INIT;
1191	return 0;
1192}
1193
1194int
1195fmtvalid(u_int32_t fmt, u_int32_t *fmtlist)
1196{
1197	int i;
1198
1199	for (i = 0; fmtlist[i]; i++)
1200		if (fmt == fmtlist[i])
1201			return 1;
1202
1203	return 0;
1204}
1205
1206int
1207chn_setformat(pcm_channel *c, u_int32_t fmt)
1208{
1209	snd_dbuf *b = &c->buffer;
1210	snd_dbuf *bs = &c->buffer2nd;
1211
1212	u_int32_t hwfmt;
1213	if (CANCHANGE(c)) {
1214		while (chn_removefeeder(c) == 0);
1215		c->format = fmt;
1216		c->feederdesc->out = c->format;
1217		hwfmt = c->format;
1218		if (!fmtvalid(hwfmt, chn_getcaps(c)->fmtlist)) {
1219			if (c->flags & CHN_F_MAPPED)
1220				return EINVAL;
1221			hwfmt = chn_feedchain(c, chn_getcaps(c)->fmtlist);
1222			if (hwfmt == 0)
1223				return EINVAL;
1224		}
1225		b->fmt = hwfmt;
1226		bs->fmt = hwfmt;
1227		chn_resetbuf(c);
1228		c->setformat(c->devinfo, hwfmt);
1229		return 0;
1230	}
1231	c->format = fmt;
1232	c->flags |= CHN_F_INIT;
1233	return 0;
1234}
1235
1236int
1237chn_setblocksize(pcm_channel *c, int blkcnt, int blksz)
1238{
1239	snd_dbuf *b = &c->buffer;
1240	snd_dbuf *bs = &c->buffer2nd;
1241	int s, ss, bufsz;
1242
1243	if (bs->blkcnt == blkcnt && bs->blksz == blksz)
1244		return 0;
1245    	if (c->flags & CHN_F_MAPPED) {
1246		DEB(printf("chn_setblocksize: can't work on mapped channel"));
1247		return EINVAL;
1248	}
1249	c->flags &= ~CHN_F_HAS_SIZE;
1250
1251	ss = 1;
1252	ss <<= (bs->fmt & AFMT_STEREO)? 1 : 0;
1253	ss <<= (bs->fmt & AFMT_16BIT)? 1 : 0;
1254
1255	if (blksz >= 2)
1256		c->flags |= CHN_F_HAS_SIZE;
1257	/* let us specify blksz without setting CHN_F_HAS_SIZE */
1258	if (blksz < 0)
1259		blksz = -blksz;
1260	/* default to blksz = ~0.25s */
1261	if (blksz < 16)
1262		blksz = (ss * c->speed) >> 2;
1263	if (blksz > CHN_2NDBUFMAXSIZE / 2)
1264		blksz = CHN_2NDBUFMAXSIZE / 2;
1265	if (blkcnt < 2)
1266		blkcnt = 2;
1267
1268	if (blkcnt * blksz > CHN_2NDBUFMAXSIZE)
1269		blkcnt = CHN_2NDBUFMAXSIZE / blksz;
1270	bufsz = blkcnt * blksz;
1271
1272	s = spltty();
1273	if (bs->buf != NULL)
1274		free(bs->buf, M_DEVBUF);
1275	bs->buf = malloc(bufsz, M_DEVBUF, M_WAITOK);
1276	if (bs->buf == NULL) {
1277      		splx(s);
1278		DEB(printf("chn_setblocksize: out of memory."));
1279		return ENOSPC;
1280	}
1281	bs->bufsize = bufsz;
1282	bs->rl = bs->rp = bs->fp = 0;
1283	bs->fl = bs->bufsize;
1284	buf_clear(bs, bs->fmt, bs->bufsize);
1285	bs->blkcnt = blkcnt;
1286	bs->blksz = blksz;
1287	RANGE(blksz, 16, b->bufsize / 2);
1288	b->blksz = c->setblocksize(c->devinfo, blksz);
1289	splx(s);
1290
1291	return 0;
1292}
1293
1294int
1295chn_trigger(pcm_channel *c, int go)
1296{
1297	return c->trigger(c->devinfo, go);
1298}
1299
1300int
1301chn_getptr(pcm_channel *c)
1302{
1303	int hwptr;
1304	int a = (1 << c->align) - 1;
1305	snd_dbuf *b = &c->buffer;
1306
1307	hwptr = b->dl? c->getptr(c->devinfo) : 0;
1308	/* don't allow unaligned values in the hwa ptr */
1309	hwptr &= ~a ; /* Apply channel align mask */
1310	hwptr &= DMA_ALIGN_MASK; /* Apply DMA align mask */
1311	return hwptr;
1312}
1313
1314pcmchan_caps *
1315chn_getcaps(pcm_channel *c)
1316{
1317	return c->getcaps(c->devinfo);
1318}
1319
1320u_int32_t
1321chn_getformats(pcm_channel *c)
1322{
1323	u_int32_t *fmtlist, fmts;
1324	int i;
1325
1326	fmtlist = chn_getcaps(c)->fmtlist;
1327	fmts = 0;
1328	for (i = 0; fmtlist[i]; i++)
1329		fmts |= fmtlist[i];
1330
1331	return fmts;
1332}
1333
1334
1335