buffer.c revision 160439
1139749Simp/*-
2119853Scg * Copyright (c) 1999 Cameron Grant <cg@freebsd.org>
370291Scg * All rights reserved.
470291Scg *
570291Scg * Redistribution and use in source and binary forms, with or without
670291Scg * modification, are permitted provided that the following conditions
770291Scg * are met:
870291Scg * 1. Redistributions of source code must retain the above copyright
970291Scg *    notice, this list of conditions and the following disclaimer.
1070291Scg * 2. Redistributions in binary form must reproduce the above copyright
1170291Scg *    notice, this list of conditions and the following disclaimer in the
1270291Scg *    documentation and/or other materials provided with the distribution.
1370291Scg *
1470291Scg * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1570291Scg * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1670291Scg * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1770291Scg * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1870291Scg * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1970291Scg * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2070291Scg * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2170291Scg * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2270291Scg * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2370291Scg * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2470291Scg * SUCH DAMAGE.
2570291Scg */
2670291Scg
2770291Scg#include <dev/sound/pcm/sound.h>
2870291Scg
2974763Scg#include "feeder_if.h"
3074763Scg
3182180ScgSND_DECLARE_FILE("$FreeBSD: head/sys/dev/sound/pcm/buffer.c 160439 2006-07-17 17:43:06Z netchild $");
3282180Scg
3374763Scgstruct snd_dbuf *
34125136Struckmansndbuf_create(device_t dev, char *drv, char *desc, struct pcm_channel *channel)
3574763Scg{
3674763Scg	struct snd_dbuf *b;
3774763Scg
38111119Simp	b = malloc(sizeof(*b), M_DEVBUF, M_WAITOK | M_ZERO);
3974763Scg	snprintf(b->name, SNDBUF_NAMELEN, "%s:%s", drv, desc);
4089834Scg	b->dev = dev;
41125136Struckman	b->channel = channel;
4289834Scg
4374763Scg	return b;
4474763Scg}
4574763Scg
4674763Scgvoid
4774763Scgsndbuf_destroy(struct snd_dbuf *b)
4874763Scg{
4974763Scg	free(b, M_DEVBUF);
5074763Scg}
5174763Scg
52111183Scognetbus_addr_t
53111183Scognetsndbuf_getbufaddr(struct snd_dbuf *buf)
54111183Scognet{
55111183Scognet	return (buf->buf_addr);
56111183Scognet}
57111183Scognet
5870291Scgstatic void
5970291Scgsndbuf_setmap(void *arg, bus_dma_segment_t *segs, int nseg, int error)
6070291Scg{
6174763Scg	struct snd_dbuf *b = (struct snd_dbuf *)arg;
6270291Scg
6370291Scg	if (bootverbose) {
64136531Syongari		device_printf(b->dev, "sndbuf_setmap %lx, %lx; ",
65136531Syongari		    (u_long)segs[0].ds_addr, (u_long)segs[0].ds_len);
66136531Syongari		printf("%p -> %lx\n", b->buf, (u_long)segs[0].ds_addr);
6770291Scg	}
68136531Syongari	if (error == 0)
69136531Syongari		b->buf_addr = segs[0].ds_addr;
70136531Syongari	else
71136531Syongari		b->buf_addr = 0;
7270291Scg}
7370291Scg
7470291Scg/*
7574763Scg * Allocate memory for DMA buffer. If the device does not use DMA transfers,
7674763Scg * the driver can call malloc(9) and sndbuf_setup() itself.
7770291Scg */
78111183Scognet
7970291Scgint
8074763Scgsndbuf_alloc(struct snd_dbuf *b, bus_dma_tag_t dmatag, unsigned int size)
8170291Scg{
82136531Syongari	int ret;
83136531Syongari
8470291Scg	b->dmatag = dmatag;
8570291Scg	b->maxsize = size;
8670291Scg	b->bufsize = b->maxsize;
87136531Syongari	b->buf_addr = 0;
88136531Syongari	if (bus_dmamem_alloc(b->dmatag, (void **)&b->buf, BUS_DMA_NOWAIT,
89136531Syongari	    &b->dmamap))
90136531Syongari		return (ENOMEM);
91136531Syongari	if (bus_dmamap_load(b->dmatag, b->dmamap, b->buf, b->maxsize,
92136531Syongari	    sndbuf_setmap, b, 0) != 0 || b->buf_addr == 0) {
93136531Syongari		bus_dmamem_free(b->dmatag, b->buf, b->dmamap);
94136531Syongari		b->dmamap = NULL;
95136531Syongari		return (ENOMEM);
96136531Syongari	}
97136531Syongari
98136531Syongari	ret = sndbuf_resize(b, 2, b->maxsize / 2);
99136531Syongari	if (ret != 0)
100136531Syongari		sndbuf_free(b);
101136531Syongari	return (ret);
10270291Scg}
10370291Scg
10470291Scgint
10574763Scgsndbuf_setup(struct snd_dbuf *b, void *buf, unsigned int size)
10670291Scg{
10770291Scg	b->buf = buf;
10870291Scg	b->maxsize = size;
10970291Scg	b->bufsize = b->maxsize;
11070291Scg	return sndbuf_resize(b, 2, b->maxsize / 2);
11170291Scg}
11270291Scg
11370291Scgvoid
11474763Scgsndbuf_free(struct snd_dbuf *b)
11570291Scg{
11674763Scg	if (b->tmpbuf)
11774763Scg		free(b->tmpbuf, M_DEVBUF);
11874763Scg	b->tmpbuf = NULL;
11974763Scg
12074763Scg	if (b->dmamap)
12174797Scg		bus_dmamap_unload(b->dmatag, b->dmamap);
12274763Scg
12374763Scg	if (b->dmamap && b->buf)
12474797Scg		bus_dmamem_free(b->dmatag, b->buf, b->dmamap);
12577265Scg	b->dmamap = NULL;
12677265Scg	b->buf = NULL;
12770291Scg}
12870291Scg
12970291Scgint
13074763Scgsndbuf_resize(struct snd_dbuf *b, unsigned int blkcnt, unsigned int blksz)
13170291Scg{
132125136Struckman	u_int8_t *tmpbuf, *f2;
133125136Struckman
134125136Struckman	chn_lock(b->channel);
13574763Scg	if (b->maxsize == 0)
136125136Struckman		goto out;
13770291Scg	if (blkcnt == 0)
13870291Scg		blkcnt = b->blkcnt;
13970291Scg	if (blksz == 0)
14070291Scg		blksz = b->blksz;
141125136Struckman	if (blkcnt < 2 || blksz < 16 || (blkcnt * blksz > b->maxsize)) {
142125136Struckman		chn_unlock(b->channel);
14370291Scg		return EINVAL;
144125136Struckman	}
14589834Scg	if (blkcnt == b->blkcnt && blksz == b->blksz)
146125136Struckman		goto out;
147125136Struckman
148125136Struckman	chn_unlock(b->channel);
149128730Sgreen	tmpbuf = malloc(blkcnt * blksz, M_DEVBUF, M_NOWAIT);
150125136Struckman	if (tmpbuf == NULL)
151125136Struckman		return ENOMEM;
152125136Struckman	chn_lock(b->channel);
15370291Scg	b->blkcnt = blkcnt;
15470291Scg	b->blksz = blksz;
15570291Scg	b->bufsize = blkcnt * blksz;
156125136Struckman	f2 =  b->tmpbuf;
157113752Sorion	b->tmpbuf = tmpbuf;
15870291Scg	sndbuf_reset(b);
159125136Struckman	chn_unlock(b->channel);
160125136Struckman	free(f2, M_DEVBUF);
16170291Scg	return 0;
162125136Struckmanout:
163125136Struckman	chn_unlock(b->channel);
164125136Struckman	return 0;
16570291Scg}
16670291Scg
16774763Scgint
16874763Scgsndbuf_remalloc(struct snd_dbuf *b, unsigned int blkcnt, unsigned int blksz)
16974763Scg{
170107237Scg        u_int8_t *buf, *tmpbuf, *f1, *f2;
171107237Scg        unsigned int bufsize;
172125136Struckman	int ret;
173107237Scg
17474763Scg	if (blkcnt < 2 || blksz < 16)
17574763Scg		return EINVAL;
17674763Scg
177107237Scg	bufsize = blksz * blkcnt;
17874763Scg
179125136Struckman	chn_unlock(b->channel);
180125136Struckman	buf = malloc(bufsize, M_DEVBUF, M_WAITOK);
181125136Struckman	if (buf == NULL) {
182125136Struckman		ret = ENOMEM;
183125136Struckman		goto out;
184125136Struckman	}
18574763Scg
186125136Struckman	tmpbuf = malloc(bufsize, M_DEVBUF, M_WAITOK);
187107237Scg   	if (tmpbuf == NULL) {
188107237Scg		free(buf, M_DEVBUF);
189125136Struckman		ret = ENOMEM;
190125136Struckman		goto out;
191107237Scg	}
192125136Struckman	chn_lock(b->channel);
19374763Scg
194107237Scg	b->blkcnt = blkcnt;
195107237Scg	b->blksz = blksz;
196107237Scg	b->bufsize = bufsize;
197107237Scg	b->maxsize = bufsize;
198107237Scg	f1 = b->buf;
199107237Scg	f2 = b->tmpbuf;
200107237Scg	b->buf = buf;
201107237Scg	b->tmpbuf = tmpbuf;
202107237Scg
203125136Struckman	sndbuf_reset(b);
204125136Struckman
205125136Struckman	chn_unlock(b->channel);
206107237Scg      	if (f1)
207107237Scg		free(f1, M_DEVBUF);
208107237Scg      	if (f2)
209107237Scg		free(f2, M_DEVBUF);
210107237Scg
211125136Struckman	ret = 0;
212125136Struckmanout:
213125136Struckman	chn_lock(b->channel);
214125136Struckman	return ret;
21574763Scg}
21674763Scg
21770291Scgvoid
21874763Scgsndbuf_clear(struct snd_dbuf *b, unsigned int length)
21970291Scg{
22070291Scg	int i;
22173768Scg	u_char data, *p;
22270291Scg
22370291Scg	if (length == 0)
22470291Scg		return;
22573768Scg	if (length > b->bufsize)
22673768Scg		length = b->bufsize;
22770291Scg
22870291Scg	if (b->fmt & AFMT_SIGNED)
22970291Scg		data = 0x00;
23070291Scg	else
23170291Scg		data = 0x80;
23270291Scg
23374763Scg	i = sndbuf_getfreeptr(b);
23474763Scg	p = sndbuf_getbuf(b);
23573768Scg	while (length > 0) {
23673768Scg		p[i] = data;
23773768Scg		length--;
23873768Scg		i++;
23973768Scg		if (i >= b->bufsize)
24070291Scg			i = 0;
24170291Scg	}
24270291Scg}
24370291Scg
24470291Scgvoid
24577265Scgsndbuf_fillsilence(struct snd_dbuf *b)
24677265Scg{
24777265Scg	int i;
24877265Scg	u_char data, *p;
24977265Scg
25077265Scg	if (b->fmt & AFMT_SIGNED)
25177265Scg		data = 0x00;
25277265Scg	else
25377265Scg		data = 0x80;
25477265Scg
25577265Scg	i = 0;
25677265Scg	p = sndbuf_getbuf(b);
25777265Scg	while (i < b->bufsize)
25877265Scg		p[i++] = data;
25977265Scg	b->rp = 0;
26077265Scg	b->rl = b->bufsize;
26177265Scg}
26277265Scg
26377265Scgvoid
26474763Scgsndbuf_reset(struct snd_dbuf *b)
26570291Scg{
26674763Scg	b->hp = 0;
26774763Scg	b->rp = 0;
26874763Scg	b->rl = 0;
26974763Scg	b->dl = 0;
27074763Scg	b->prev_total = 0;
27174763Scg	b->total = 0;
27274763Scg	b->xrun = 0;
27370291Scg	if (b->buf && b->bufsize > 0)
27470291Scg		sndbuf_clear(b, b->bufsize);
27570291Scg}
27670291Scg
27774763Scgu_int32_t
27874763Scgsndbuf_getfmt(struct snd_dbuf *b)
27974763Scg{
28074763Scg	return b->fmt;
28174763Scg}
28274763Scg
28370291Scgint
28474763Scgsndbuf_setfmt(struct snd_dbuf *b, u_int32_t fmt)
28570291Scg{
28670291Scg	b->fmt = fmt;
28770291Scg	b->bps = 1;
28870291Scg	b->bps <<= (b->fmt & AFMT_STEREO)? 1 : 0;
289148606Snetchild	if (b->fmt & AFMT_16BIT)
290148606Snetchild		b->bps <<= 1;
291148606Snetchild	else if (b->fmt & AFMT_24BIT)
292148606Snetchild		b->bps *= 3;
293148606Snetchild	else if (b->fmt & AFMT_32BIT)
294148606Snetchild		b->bps <<= 2;
29570291Scg	return 0;
29670291Scg}
29770291Scg
29874763Scgunsigned int
29974763Scgsndbuf_getspd(struct snd_dbuf *b)
30070291Scg{
30174763Scg	return b->spd;
30274763Scg}
30374763Scg
30474763Scgvoid
30574763Scgsndbuf_setspd(struct snd_dbuf *b, unsigned int spd)
30674763Scg{
30774763Scg	b->spd = spd;
30874763Scg}
30974763Scg
31074763Scgunsigned int
31174763Scgsndbuf_getalign(struct snd_dbuf *b)
31274763Scg{
31374763Scg	static int align[] = {0, 1, 1, 2, 2, 2, 2, 3};
31474763Scg
31574763Scg	return align[b->bps - 1];
31674763Scg}
31774763Scg
31874763Scgunsigned int
31974763Scgsndbuf_getblkcnt(struct snd_dbuf *b)
32074763Scg{
32174763Scg	return b->blkcnt;
32274763Scg}
32374763Scg
32474763Scgvoid
32574763Scgsndbuf_setblkcnt(struct snd_dbuf *b, unsigned int blkcnt)
32674763Scg{
32774763Scg	b->blkcnt = blkcnt;
32874763Scg}
32974763Scg
33074763Scgunsigned int
33174763Scgsndbuf_getblksz(struct snd_dbuf *b)
33274763Scg{
33374763Scg	return b->blksz;
33474763Scg}
33574763Scg
33674763Scgvoid
33774763Scgsndbuf_setblksz(struct snd_dbuf *b, unsigned int blksz)
33874763Scg{
33974763Scg	b->blksz = blksz;
34074763Scg}
34174763Scg
34274763Scgunsigned int
34374763Scgsndbuf_getbps(struct snd_dbuf *b)
34474763Scg{
34570291Scg	return b->bps;
34670291Scg}
34770291Scg
34870291Scgvoid *
34974763Scgsndbuf_getbuf(struct snd_dbuf *b)
35070291Scg{
35170291Scg	return b->buf;
35270291Scg}
35370291Scg
35474763Scgvoid *
35574763Scgsndbuf_getbufofs(struct snd_dbuf *b, unsigned int ofs)
35670291Scg{
35789771Scg	KASSERT(ofs < b->bufsize, ("%s: ofs invalid %d", __func__, ofs));
35874763Scg
35974763Scg	return b->buf + ofs;
36074763Scg}
36174763Scg
36274763Scgunsigned int
36374763Scgsndbuf_getsize(struct snd_dbuf *b)
36474763Scg{
36570291Scg	return b->bufsize;
36670291Scg}
36770291Scg
36874763Scgunsigned int
36974763Scgsndbuf_getmaxsize(struct snd_dbuf *b)
37070291Scg{
37174763Scg	return b->maxsize;
37274763Scg}
37374763Scg
37474763Scgunsigned int
37574763Scgsndbuf_runsz(struct snd_dbuf *b)
37674763Scg{
37770291Scg	return b->dl;
37870291Scg}
37970291Scg
38074763Scgvoid
38174763Scgsndbuf_setrun(struct snd_dbuf *b, int go)
38274763Scg{
38374763Scg	b->dl = go? b->blksz : 0;
38474763Scg}
38574763Scg
38674763Scgstruct selinfo *
38774763Scgsndbuf_getsel(struct snd_dbuf *b)
38874763Scg{
38974763Scg	return &b->sel;
39074763Scg}
39174763Scg
39274763Scg/************************************************************/
39374763Scgunsigned int
39474763Scgsndbuf_getxrun(struct snd_dbuf *b)
39574763Scg{
39674763Scg	SNDBUF_LOCKASSERT(b);
39774763Scg
39874763Scg	return b->xrun;
39974763Scg}
40074763Scg
40174763Scgvoid
402160439Snetchildsndbuf_setxrun(struct snd_dbuf *b, unsigned int xrun)
40374763Scg{
40474763Scg	SNDBUF_LOCKASSERT(b);
40574763Scg
406160439Snetchild	b->xrun = xrun;
40774763Scg}
40874763Scg
40974763Scgunsigned int
41074763Scgsndbuf_gethwptr(struct snd_dbuf *b)
41174763Scg{
41274763Scg	SNDBUF_LOCKASSERT(b);
41374763Scg
41474763Scg	return b->hp;
41574763Scg}
41674763Scg
41774763Scgvoid
41874763Scgsndbuf_sethwptr(struct snd_dbuf *b, unsigned int ptr)
41974763Scg{
42074763Scg	SNDBUF_LOCKASSERT(b);
42174763Scg
42274763Scg	b->hp = ptr;
42374763Scg}
42474763Scg
42574763Scgunsigned int
42674763Scgsndbuf_getready(struct snd_dbuf *b)
42774763Scg{
42874763Scg	SNDBUF_LOCKASSERT(b);
42987599Sobrien	KASSERT((b->rl >= 0) && (b->rl <= b->bufsize), ("%s: b->rl invalid %d", __func__, b->rl));
43074763Scg
43174763Scg	return b->rl;
43274763Scg}
43374763Scg
43474763Scgunsigned int
43574763Scgsndbuf_getreadyptr(struct snd_dbuf *b)
43674763Scg{
43774763Scg	SNDBUF_LOCKASSERT(b);
43887599Sobrien	KASSERT((b->rp >= 0) && (b->rp <= b->bufsize), ("%s: b->rp invalid %d", __func__, b->rp));
43974763Scg
44074763Scg	return b->rp;
44174763Scg}
44274763Scg
44374763Scgunsigned int
44474763Scgsndbuf_getfree(struct snd_dbuf *b)
44574763Scg{
44674763Scg	SNDBUF_LOCKASSERT(b);
44787599Sobrien	KASSERT((b->rl >= 0) && (b->rl <= b->bufsize), ("%s: b->rl invalid %d", __func__, b->rl));
44874763Scg
44974763Scg	return b->bufsize - b->rl;
45074763Scg}
45174763Scg
45274763Scgunsigned int
45374763Scgsndbuf_getfreeptr(struct snd_dbuf *b)
45474763Scg{
45574763Scg	SNDBUF_LOCKASSERT(b);
45687599Sobrien	KASSERT((b->rp >= 0) && (b->rp <= b->bufsize), ("%s: b->rp invalid %d", __func__, b->rp));
45787599Sobrien	KASSERT((b->rl >= 0) && (b->rl <= b->bufsize), ("%s: b->rl invalid %d", __func__, b->rl));
45874763Scg
45974763Scg	return (b->rp + b->rl) % b->bufsize;
46074763Scg}
46174763Scg
46274763Scgunsigned int
46374763Scgsndbuf_getblocks(struct snd_dbuf *b)
46474763Scg{
46574763Scg	SNDBUF_LOCKASSERT(b);
46674763Scg
46774763Scg	return b->total / b->blksz;
46874763Scg}
46974763Scg
47074763Scgunsigned int
47174763Scgsndbuf_getprevblocks(struct snd_dbuf *b)
47274763Scg{
47374763Scg	SNDBUF_LOCKASSERT(b);
47474763Scg
47574763Scg	return b->prev_total / b->blksz;
47674763Scg}
47774763Scg
47874763Scgunsigned int
47974763Scgsndbuf_gettotal(struct snd_dbuf *b)
48074763Scg{
48174763Scg	SNDBUF_LOCKASSERT(b);
48274763Scg
48374763Scg	return b->total;
48474763Scg}
48574763Scg
48674763Scgvoid
48774763Scgsndbuf_updateprevtotal(struct snd_dbuf *b)
48874763Scg{
48974763Scg	SNDBUF_LOCKASSERT(b);
49074763Scg
49174763Scg	b->prev_total = b->total;
49274763Scg}
49374763Scg
49474763Scg/************************************************************/
49574763Scg
49670291Scgint
49774763Scgsndbuf_acquire(struct snd_dbuf *b, u_int8_t *from, unsigned int count)
49870291Scg{
49974763Scg	int l;
50074763Scg
50187599Sobrien	KASSERT(count <= sndbuf_getfree(b), ("%s: count %d > free %d", __func__, count, sndbuf_getfree(b)));
50287599Sobrien	KASSERT((b->rl >= 0) && (b->rl <= b->bufsize), ("%s: b->rl invalid %d", __func__, b->rl));
50374763Scg	b->total += count;
50474763Scg	if (from != NULL) {
50574763Scg		while (count > 0) {
50674763Scg			l = MIN(count, sndbuf_getsize(b) - sndbuf_getfreeptr(b));
50774763Scg			bcopy(from, sndbuf_getbufofs(b, sndbuf_getfreeptr(b)), l);
50874763Scg			from += l;
50974763Scg			b->rl += l;
51074763Scg			count -= l;
51174763Scg		}
51274763Scg	} else
51374763Scg		b->rl += count;
51487599Sobrien	KASSERT((b->rl >= 0) && (b->rl <= b->bufsize), ("%s: b->rl invalid %d, count %d", __func__, b->rl, count));
51574763Scg
51674763Scg	return 0;
51774763Scg}
51874763Scg
51974763Scgint
52074763Scgsndbuf_dispose(struct snd_dbuf *b, u_int8_t *to, unsigned int count)
52174763Scg{
52274763Scg	int l;
52374763Scg
52487599Sobrien	KASSERT(count <= sndbuf_getready(b), ("%s: count %d > ready %d", __func__, count, sndbuf_getready(b)));
52587599Sobrien	KASSERT((b->rl >= 0) && (b->rl <= b->bufsize), ("%s: b->rl invalid %d", __func__, b->rl));
52674763Scg	if (to != NULL) {
52774763Scg		while (count > 0) {
52874763Scg			l = MIN(count, sndbuf_getsize(b) - sndbuf_getreadyptr(b));
52974763Scg			bcopy(sndbuf_getbufofs(b, sndbuf_getreadyptr(b)), to, l);
53074763Scg			to += l;
53174763Scg			b->rl -= l;
53274763Scg			b->rp = (b->rp + l) % b->bufsize;
53374763Scg			count -= l;
53474763Scg		}
53574763Scg	} else {
53674763Scg		b->rl -= count;
53774763Scg		b->rp = (b->rp + count) % b->bufsize;
53874763Scg	}
53987599Sobrien	KASSERT((b->rl >= 0) && (b->rl <= b->bufsize), ("%s: b->rl invalid %d, count %d", __func__, b->rl, count));
54074763Scg
54174763Scg	return 0;
54274763Scg}
54374763Scg
54474763Scg/* count is number of bytes we want added to destination buffer */
54574763Scgint
54674763Scgsndbuf_feed(struct snd_dbuf *from, struct snd_dbuf *to, struct pcm_channel *channel, struct pcm_feeder *feeder, unsigned int count)
54774763Scg{
54877265Scg	KASSERT(count > 0, ("can't feed 0 bytes"));
54977265Scg
55074763Scg	if (sndbuf_getfree(to) < count)
55174763Scg		return EINVAL;
55274763Scg
55374763Scg	count = FEEDER_FEED(feeder, channel, to->tmpbuf, count, from);
55475317Scg	if (count)
55575317Scg		sndbuf_acquire(to, to->tmpbuf, count);
55674763Scg	/* the root feeder has called sndbuf_dispose(from, , bytes fetched) */
55774763Scg
55874763Scg	return 0;
55974763Scg}
56074763Scg
56174763Scg/************************************************************/
56274763Scg
56374763Scgvoid
56474763Scgsndbuf_dump(struct snd_dbuf *b, char *s, u_int32_t what)
56574763Scg{
56674763Scg	printf("%s: [", s);
56774763Scg	if (what & 0x01)
56874763Scg		printf(" bufsize: %d, maxsize: %d", b->bufsize, b->maxsize);
56974763Scg	if (what & 0x02)
57074763Scg		printf(" dl: %d, rp: %d, rl: %d, hp: %d", b->dl, b->rp, b->rl, b->hp);
57174763Scg	if (what & 0x04)
57274763Scg		printf(" total: %d, prev_total: %d, xrun: %d", b->total, b->prev_total, b->xrun);
57374763Scg   	if (what & 0x08)
57474763Scg		printf(" fmt: 0x%x, spd: %d", b->fmt, b->spd);
57574763Scg	if (what & 0x10)
57674763Scg		printf(" blksz: %d, blkcnt: %d, flags: 0x%x", b->blksz, b->blkcnt, b->flags);
57774763Scg	printf(" ]\n");
57874763Scg}
57974763Scg
58074763Scg/************************************************************/
58174763Scgu_int32_t
58274763Scgsndbuf_getflags(struct snd_dbuf *b)
58374763Scg{
58474763Scg	return b->flags;
58574763Scg}
58674763Scg
58774763Scgvoid
58874763Scgsndbuf_setflags(struct snd_dbuf *b, u_int32_t flags, int on)
58974763Scg{
59074763Scg	b->flags &= ~flags;
59174763Scg	if (on)
59274763Scg		b->flags |= flags;
59374763Scg}
59474763Scg
595