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