aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/sound/pcm
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/sound/pcm')
-rw-r--r--sys/dev/sound/pcm/buffer.c199
-rw-r--r--sys/dev/sound/pcm/buffer.h38
-rw-r--r--sys/dev/sound/pcm/channel.c152
-rw-r--r--sys/dev/sound/pcm/channel.h1
-rw-r--r--sys/dev/sound/pcm/dsp.c311
-rw-r--r--sys/dev/sound/pcm/feeder.c135
-rw-r--r--sys/dev/sound/pcm/feeder.h37
-rw-r--r--sys/dev/sound/pcm/feeder_chain.c30
-rw-r--r--sys/dev/sound/pcm/feeder_eq.c7
-rw-r--r--sys/dev/sound/pcm/feeder_format.c7
-rw-r--r--sys/dev/sound/pcm/feeder_matrix.c9
-rw-r--r--sys/dev/sound/pcm/feeder_mixer.c21
-rw-r--r--sys/dev/sound/pcm/feeder_rate.c7
-rw-r--r--sys/dev/sound/pcm/feeder_volume.c9
-rw-r--r--sys/dev/sound/pcm/mixer.c53
-rw-r--r--sys/dev/sound/pcm/mixer.h4
-rw-r--r--sys/dev/sound/pcm/sndstat.c79
-rw-r--r--sys/dev/sound/pcm/sound.h110
-rw-r--r--sys/dev/sound/pcm/vchan.c4
-rw-r--r--sys/dev/sound/pcm/vchan.h4
20 files changed, 450 insertions, 767 deletions
diff --git a/sys/dev/sound/pcm/buffer.c b/sys/dev/sound/pcm/buffer.c
index de535ec2dcba..eb2cbe667bf3 100644
--- a/sys/dev/sound/pcm/buffer.c
+++ b/sys/dev/sound/pcm/buffer.c
@@ -5,6 +5,10 @@
* Portions Copyright (c) Ryan Beasley <ryan.beasley@gmail.com> - GSoC 2006
* Copyright (c) 1999 Cameron Grant <cg@FreeBSD.org>
* All rights reserved.
+ * Copyright (c) 2025 The FreeBSD Foundation
+ *
+ * Portions of this software were developed by Christos Margiolis
+ * <christos@FreeBSD.org> under sponsorship from the FreeBSD Foundation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -41,13 +45,12 @@
#include "snd_fxdiv_gen.h"
struct snd_dbuf *
-sndbuf_create(device_t dev, char *drv, char *desc, struct pcm_channel *channel)
+sndbuf_create(struct pcm_channel *channel, const char *desc)
{
struct snd_dbuf *b;
b = malloc(sizeof(*b), M_DEVBUF, M_WAITOK | M_ZERO);
- snprintf(b->name, SNDBUF_NAMELEN, "%s:%s", drv, desc);
- b->dev = dev;
+ snprintf(b->name, SNDBUF_NAMELEN, "%s:%s", channel->name, desc);
b->channel = channel;
return b;
@@ -60,19 +63,13 @@ sndbuf_destroy(struct snd_dbuf *b)
free(b, M_DEVBUF);
}
-bus_addr_t
-sndbuf_getbufaddr(struct snd_dbuf *buf)
-{
- return (buf->buf_addr);
-}
-
static void
sndbuf_setmap(void *arg, bus_dma_segment_t *segs, int nseg, int error)
{
struct snd_dbuf *b = (struct snd_dbuf *)arg;
if (snd_verbose > 3) {
- device_printf(b->dev, "sndbuf_setmap %lx, %lx; ",
+ printf("sndbuf_setmap %lx, %lx; ",
(u_long)segs[0].ds_addr, (u_long)segs[0].ds_len);
printf("%p -> %lx\n", b->buf, (u_long)segs[0].ds_addr);
}
@@ -147,7 +144,7 @@ sndbuf_free(struct snd_dbuf *b)
} else
free(b->buf, M_DEVBUF);
}
- seldrain(sndbuf_getsel(b));
+ seldrain(&b->sel);
b->tmpbuf = NULL;
b->shadbuf = NULL;
@@ -277,16 +274,10 @@ sndbuf_clear(struct snd_dbuf *b, unsigned int length)
length = b->bufsize;
data = sndbuf_zerodata(b->fmt);
-
i = sndbuf_getfreeptr(b);
- p = sndbuf_getbuf(b);
- while (length > 0) {
- p[i] = data;
- length--;
- i++;
- if (i >= b->bufsize)
- i = 0;
- }
+ p = b->buf;
+ for (; length > 0; length--, i++)
+ p[i % b->bufsize] = data;
}
/**
@@ -298,7 +289,7 @@ void
sndbuf_fillsilence(struct snd_dbuf *b)
{
if (b->bufsize > 0)
- memset(sndbuf_getbuf(b), sndbuf_zerodata(b->fmt), b->bufsize);
+ memset(b->buf, sndbuf_zerodata(b->fmt), b->bufsize);
b->rp = 0;
b->rl = b->bufsize;
}
@@ -307,7 +298,7 @@ void
sndbuf_fillsilence_rl(struct snd_dbuf *b, u_int rl)
{
if (b->bufsize > 0)
- memset(sndbuf_getbuf(b), sndbuf_zerodata(b->fmt), b->bufsize);
+ memset(b->buf, sndbuf_zerodata(b->fmt), b->bufsize);
b->rp = 0;
b->rl = min(b->bufsize, rl);
}
@@ -344,12 +335,6 @@ sndbuf_reset(struct snd_dbuf *b)
sndbuf_clearshadow(b);
}
-u_int32_t
-sndbuf_getfmt(struct snd_dbuf *b)
-{
- return b->fmt;
-}
-
int
sndbuf_setfmt(struct snd_dbuf *b, u_int32_t fmt)
{
@@ -359,60 +344,12 @@ sndbuf_setfmt(struct snd_dbuf *b, u_int32_t fmt)
return 0;
}
-unsigned int
-sndbuf_getspd(struct snd_dbuf *b)
-{
- return b->spd;
-}
-
void
sndbuf_setspd(struct snd_dbuf *b, unsigned int spd)
{
b->spd = spd;
}
-unsigned int
-sndbuf_getalign(struct snd_dbuf *b)
-{
- return (b->align);
-}
-
-unsigned int
-sndbuf_getblkcnt(struct snd_dbuf *b)
-{
- return b->blkcnt;
-}
-
-void
-sndbuf_setblkcnt(struct snd_dbuf *b, unsigned int blkcnt)
-{
- b->blkcnt = blkcnt;
-}
-
-unsigned int
-sndbuf_getblksz(struct snd_dbuf *b)
-{
- return b->blksz;
-}
-
-void
-sndbuf_setblksz(struct snd_dbuf *b, unsigned int blksz)
-{
- b->blksz = blksz;
-}
-
-unsigned int
-sndbuf_getbps(struct snd_dbuf *b)
-{
- return b->bps;
-}
-
-void *
-sndbuf_getbuf(struct snd_dbuf *b)
-{
- return b->buf;
-}
-
void *
sndbuf_getbufofs(struct snd_dbuf *b, unsigned int ofs)
{
@@ -422,24 +359,6 @@ sndbuf_getbufofs(struct snd_dbuf *b, unsigned int ofs)
}
unsigned int
-sndbuf_getsize(struct snd_dbuf *b)
-{
- return b->bufsize;
-}
-
-unsigned int
-sndbuf_getmaxsize(struct snd_dbuf *b)
-{
- return b->maxsize;
-}
-
-unsigned int
-sndbuf_getallocsize(struct snd_dbuf *b)
-{
- return b->allocsize;
-}
-
-unsigned int
sndbuf_runsz(struct snd_dbuf *b)
{
return b->dl;
@@ -451,19 +370,6 @@ sndbuf_setrun(struct snd_dbuf *b, int go)
b->dl = go? b->blksz : 0;
}
-struct selinfo *
-sndbuf_getsel(struct snd_dbuf *b)
-{
- return &b->sel;
-}
-
-/************************************************************/
-unsigned int
-sndbuf_getxrun(struct snd_dbuf *b)
-{
- return b->xrun;
-}
-
void
sndbuf_setxrun(struct snd_dbuf *b, unsigned int xrun)
{
@@ -471,18 +377,6 @@ sndbuf_setxrun(struct snd_dbuf *b, unsigned int xrun)
}
unsigned int
-sndbuf_gethwptr(struct snd_dbuf *b)
-{
- return b->hp;
-}
-
-void
-sndbuf_sethwptr(struct snd_dbuf *b, unsigned int ptr)
-{
- b->hp = ptr;
-}
-
-unsigned int
sndbuf_getready(struct snd_dbuf *b)
{
KASSERT((b->rl >= 0) && (b->rl <= b->bufsize), ("%s: b->rl invalid %d", __func__, b->rl));
@@ -521,38 +415,13 @@ sndbuf_getblocks(struct snd_dbuf *b)
return b->total / b->blksz;
}
-u_int64_t
-sndbuf_getprevblocks(struct snd_dbuf *b)
-{
- return b->prev_total / b->blksz;
-}
-
-u_int64_t
-sndbuf_gettotal(struct snd_dbuf *b)
-{
- return b->total;
-}
-
-u_int64_t
-sndbuf_getprevtotal(struct snd_dbuf *b)
-{
- return b->prev_total;
-}
-
-void
-sndbuf_updateprevtotal(struct snd_dbuf *b)
-{
- b->prev_total = b->total;
-}
-
unsigned int
sndbuf_xbytes(unsigned int v, struct snd_dbuf *from, struct snd_dbuf *to)
{
if (from == NULL || to == NULL || v == 0)
return 0;
- return snd_xbytes(v, sndbuf_getalign(from) * sndbuf_getspd(from),
- sndbuf_getalign(to) * sndbuf_getspd(to));
+ return snd_xbytes(v, from->align * from->spd, to->align * to->spd);
}
u_int8_t
@@ -592,7 +461,7 @@ sndbuf_acquire(struct snd_dbuf *b, u_int8_t *from, unsigned int count)
b->total += count;
if (from != NULL) {
while (count > 0) {
- l = min(count, sndbuf_getsize(b) - sndbuf_getfreeptr(b));
+ l = min(count, b->bufsize - sndbuf_getfreeptr(b));
bcopy(from, sndbuf_getbufofs(b, sndbuf_getfreeptr(b)), l);
from += l;
b->rl += l;
@@ -628,7 +497,7 @@ sndbuf_dispose(struct snd_dbuf *b, u_int8_t *to, unsigned int count)
KASSERT((b->rl >= 0) && (b->rl <= b->bufsize), ("%s: b->rl invalid %d", __func__, b->rl));
if (to != NULL) {
while (count > 0) {
- l = min(count, sndbuf_getsize(b) - sndbuf_getreadyptr(b));
+ l = min(count, b->bufsize - sndbuf_getreadyptr(b));
bcopy(sndbuf_getbufofs(b, sndbuf_getreadyptr(b)), to, l);
to += l;
b->rl -= l;
@@ -673,7 +542,7 @@ sndbuf_feed(struct snd_dbuf *from, struct snd_dbuf *to, struct pcm_channel *chan
if (sndbuf_getfree(to) < count)
return (EINVAL);
- maxfeed = SND_FXROUND(SND_FXDIV_MAX, sndbuf_getalign(to));
+ maxfeed = SND_FXROUND(SND_FXDIV_MAX, to->align);
do {
cnt = FEEDER_FEED(feeder, channel, to->tmpbuf,
@@ -695,40 +564,6 @@ sndbuf_feed(struct snd_dbuf *from, struct snd_dbuf *to, struct pcm_channel *chan
return (0);
}
-/************************************************************/
-
-void
-sndbuf_dump(struct snd_dbuf *b, char *s, u_int32_t what)
-{
- printf("%s: [", s);
- if (what & 0x01)
- printf(" bufsize: %d, maxsize: %d", b->bufsize, b->maxsize);
- if (what & 0x02)
- printf(" dl: %d, rp: %d, rl: %d, hp: %d", b->dl, b->rp, b->rl, b->hp);
- if (what & 0x04)
- printf(" total: %ju, prev_total: %ju, xrun: %d", (uintmax_t)b->total, (uintmax_t)b->prev_total, b->xrun);
- if (what & 0x08)
- printf(" fmt: 0x%x, spd: %d", b->fmt, b->spd);
- if (what & 0x10)
- printf(" blksz: %d, blkcnt: %d, flags: 0x%x", b->blksz, b->blkcnt, b->flags);
- printf(" ]\n");
-}
-
-/************************************************************/
-u_int32_t
-sndbuf_getflags(struct snd_dbuf *b)
-{
- return b->flags;
-}
-
-void
-sndbuf_setflags(struct snd_dbuf *b, u_int32_t flags, int on)
-{
- b->flags &= ~flags;
- if (on)
- b->flags |= flags;
-}
-
/**
* @brief Clear the shadow buffer by filling with samples equal to zero.
*
diff --git a/sys/dev/sound/pcm/buffer.h b/sys/dev/sound/pcm/buffer.h
index ddf4083ec19f..371ba2dd94ce 100644
--- a/sys/dev/sound/pcm/buffer.h
+++ b/sys/dev/sound/pcm/buffer.h
@@ -3,6 +3,10 @@
*
* Copyright (c) 1999 Cameron Grant <cg@freebsd.org>
* All rights reserved.
+ * Copyright (c) 2025 The FreeBSD Foundation
+ *
+ * Portions of this software were developed by Christos Margiolis
+ * <christos@FreeBSD.org> under sponsorship from the FreeBSD Foundation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -26,12 +30,11 @@
* SUCH DAMAGE.
*/
-#define SNDBUF_F_MANAGED 0x00000008
+#define SNDBUF_F_MANAGED 0x00000001
#define SNDBUF_NAMELEN 48
struct snd_dbuf {
- device_t dev;
u_int8_t *buf, *tmpbuf;
u_int8_t *shadbuf; /**< shadow buffer used w/ S_D_SILENCE/SKIP */
volatile int sl; /**< shadbuf ready length in # of bytes */
@@ -41,7 +44,7 @@ struct snd_dbuf {
volatile int rl; /* length of ready area */
volatile int hp;
volatile u_int64_t total, prev_total;
- int dmachan, dir; /* dma channel */
+ int dmachan; /* dma channel */
u_int32_t fmt, spd, bps, align;
unsigned int blksz, blkcnt;
int xrun;
@@ -55,11 +58,9 @@ struct snd_dbuf {
char name[SNDBUF_NAMELEN];
};
-struct snd_dbuf *sndbuf_create(device_t dev, char *drv, char *desc, struct pcm_channel *channel);
+struct snd_dbuf *sndbuf_create(struct pcm_channel *channel, const char *desc);
void sndbuf_destroy(struct snd_dbuf *b);
-void sndbuf_dump(struct snd_dbuf *b, char *s, u_int32_t what);
-
int sndbuf_alloc(struct snd_dbuf *b, bus_dma_tag_t dmatag, int dmaflags, unsigned int size);
int sndbuf_setup(struct snd_dbuf *b, void *buf, unsigned int size);
void sndbuf_free(struct snd_dbuf *b);
@@ -72,51 +73,26 @@ void sndbuf_fillsilence_rl(struct snd_dbuf *b, u_int rl);
void sndbuf_softreset(struct snd_dbuf *b);
void sndbuf_clearshadow(struct snd_dbuf *b);
-u_int32_t sndbuf_getfmt(struct snd_dbuf *b);
int sndbuf_setfmt(struct snd_dbuf *b, u_int32_t fmt);
-unsigned int sndbuf_getspd(struct snd_dbuf *b);
void sndbuf_setspd(struct snd_dbuf *b, unsigned int spd);
-unsigned int sndbuf_getbps(struct snd_dbuf *b);
-bus_addr_t sndbuf_getbufaddr(struct snd_dbuf *buf);
-
-void *sndbuf_getbuf(struct snd_dbuf *b);
void *sndbuf_getbufofs(struct snd_dbuf *b, unsigned int ofs);
-unsigned int sndbuf_getsize(struct snd_dbuf *b);
-unsigned int sndbuf_getmaxsize(struct snd_dbuf *b);
-unsigned int sndbuf_getallocsize(struct snd_dbuf *b);
-unsigned int sndbuf_getalign(struct snd_dbuf *b);
-unsigned int sndbuf_getblkcnt(struct snd_dbuf *b);
-void sndbuf_setblkcnt(struct snd_dbuf *b, unsigned int blkcnt);
-unsigned int sndbuf_getblksz(struct snd_dbuf *b);
-void sndbuf_setblksz(struct snd_dbuf *b, unsigned int blksz);
unsigned int sndbuf_runsz(struct snd_dbuf *b);
void sndbuf_setrun(struct snd_dbuf *b, int go);
-struct selinfo *sndbuf_getsel(struct snd_dbuf *b);
-unsigned int sndbuf_getxrun(struct snd_dbuf *b);
void sndbuf_setxrun(struct snd_dbuf *b, unsigned int xrun);
-unsigned int sndbuf_gethwptr(struct snd_dbuf *b);
-void sndbuf_sethwptr(struct snd_dbuf *b, unsigned int ptr);
unsigned int sndbuf_getfree(struct snd_dbuf *b);
unsigned int sndbuf_getfreeptr(struct snd_dbuf *b);
unsigned int sndbuf_getready(struct snd_dbuf *b);
unsigned int sndbuf_getreadyptr(struct snd_dbuf *b);
u_int64_t sndbuf_getblocks(struct snd_dbuf *b);
-u_int64_t sndbuf_getprevblocks(struct snd_dbuf *b);
-u_int64_t sndbuf_gettotal(struct snd_dbuf *b);
-u_int64_t sndbuf_getprevtotal(struct snd_dbuf *b);
unsigned int sndbuf_xbytes(unsigned int v, struct snd_dbuf *from, struct snd_dbuf *to);
u_int8_t sndbuf_zerodata(u_int32_t fmt);
-void sndbuf_updateprevtotal(struct snd_dbuf *b);
int sndbuf_acquire(struct snd_dbuf *b, u_int8_t *from, unsigned int count);
int sndbuf_dispose(struct snd_dbuf *b, u_int8_t *to, unsigned int count);
int sndbuf_feed(struct snd_dbuf *from, struct snd_dbuf *to, struct pcm_channel *channel, struct pcm_feeder *feeder, unsigned int count);
-u_int32_t sndbuf_getflags(struct snd_dbuf *b);
-void sndbuf_setflags(struct snd_dbuf *b, u_int32_t flags, int on);
-
#ifdef OSSV4_EXPERIMENT
void sndbuf_getpeaks(struct snd_dbuf *b, int *lp, int *rp);
#endif
diff --git a/sys/dev/sound/pcm/channel.c b/sys/dev/sound/pcm/channel.c
index 4d13f20a5262..f29a819ce0ae 100644
--- a/sys/dev/sound/pcm/channel.c
+++ b/sys/dev/sound/pcm/channel.c
@@ -271,7 +271,7 @@ chn_lockdestroy(struct pcm_channel *c)
* @retval 1 = ready for I/O
* @retval 0 = not ready for I/O
*/
-static int
+int
chn_polltrigger(struct pcm_channel *c)
{
struct snd_dbuf *bs = c->bufsoft;
@@ -280,10 +280,10 @@ chn_polltrigger(struct pcm_channel *c)
CHN_LOCKASSERT(c);
if (c->flags & CHN_F_MMAP) {
- if (sndbuf_getprevtotal(bs) < c->lw)
+ if (bs->prev_total < c->lw)
delta = c->lw;
else
- delta = sndbuf_gettotal(bs) - sndbuf_getprevtotal(bs);
+ delta = bs->total - bs->prev_total;
} else {
if (c->direction == PCMDIR_PLAY)
delta = sndbuf_getfree(bs);
@@ -299,7 +299,7 @@ chn_pollreset(struct pcm_channel *c)
{
CHN_LOCKASSERT(c);
- sndbuf_updateprevtotal(c->bufsoft);
+ c->bufsoft->prev_total = c->bufsoft->total;
}
static void
@@ -313,8 +313,9 @@ chn_wakeup(struct pcm_channel *c)
bs = c->bufsoft;
if (CHN_EMPTY(c, children.busy)) {
- if (SEL_WAITING(sndbuf_getsel(bs)) && chn_polltrigger(c))
- selwakeuppri(sndbuf_getsel(bs), PRIBIO);
+ KNOTE_LOCKED(&bs->sel.si_note, 0);
+ if (SEL_WAITING(&bs->sel) && chn_polltrigger(c))
+ selwakeuppri(&bs->sel, PRIBIO);
CHN_BROADCAST(&c->intr_cv);
} else {
CHN_FOREACH(ch, c, children.busy) {
@@ -353,22 +354,22 @@ chn_dmaupdate(struct pcm_channel *c)
struct snd_dbuf *b = c->bufhard;
unsigned int delta, old, hwptr, amt;
- KASSERT(sndbuf_getsize(b) > 0, ("bufsize == 0"));
+ KASSERT(b->bufsize > 0, ("bufsize == 0"));
CHN_LOCKASSERT(c);
- old = sndbuf_gethwptr(b);
+ old = b->hp;
hwptr = chn_getptr(c);
- delta = (sndbuf_getsize(b) + hwptr - old) % sndbuf_getsize(b);
- sndbuf_sethwptr(b, hwptr);
+ delta = (b->bufsize + hwptr - old) % b->bufsize;
+ b->hp = hwptr;
if (c->direction == PCMDIR_PLAY) {
amt = min(delta, sndbuf_getready(b));
- amt -= amt % sndbuf_getalign(b);
+ amt -= amt % b->align;
if (amt > 0)
sndbuf_dispose(b, NULL, amt);
} else {
amt = min(delta, sndbuf_getfree(b));
- amt -= amt % sndbuf_getalign(b);
+ amt -= amt % b->align;
if (amt > 0)
sndbuf_acquire(b, NULL, amt);
}
@@ -396,8 +397,7 @@ chn_wrfeed(struct pcm_channel *c)
sndbuf_acquire(bs, NULL, sndbuf_getfree(bs));
wasfree = sndbuf_getfree(b);
- want = min(sndbuf_getsize(b),
- imax(0, sndbuf_xbytes(sndbuf_getsize(bs), bs, b) -
+ want = min(b->bufsize, imax(0, sndbuf_xbytes(bs->bufsize, bs, b) -
sndbuf_getready(b)));
amt = min(wasfree, want);
if (amt > 0)
@@ -455,7 +455,7 @@ chn_write(struct pcm_channel *c, struct uio *buf)
*/
while (ret == 0 && sz > 0) {
p = sndbuf_getfreeptr(bs);
- t = min(sz, sndbuf_getsize(bs) - p);
+ t = min(sz, bs->bufsize - p);
off = sndbuf_getbufofs(bs, p);
CHN_UNLOCK(c);
ret = uiomove(off, t, buf);
@@ -577,7 +577,7 @@ chn_read(struct pcm_channel *c, struct uio *buf)
*/
while (ret == 0 && sz > 0) {
p = sndbuf_getreadyptr(bs);
- t = min(sz, sndbuf_getsize(bs) - p);
+ t = min(sz, bs->bufsize - p);
off = sndbuf_getbufofs(bs, p);
CHN_UNLOCK(c);
ret = uiomove(off, t, buf);
@@ -663,7 +663,7 @@ chn_start(struct pcm_channel *c, int force)
pb = CHN_BUF_PARENT(c, b);
i = sndbuf_xbytes(sndbuf_getready(bs), bs, pb);
- j = sndbuf_getalign(pb);
+ j = pb->align;
}
}
if (snd_verbose > 3 && CHN_EMPTY(c, children))
@@ -686,7 +686,7 @@ chn_start(struct pcm_channel *c, int force)
if (c->parentchannel == NULL) {
if (c->direction == PCMDIR_PLAY)
sndbuf_fillsilence_rl(b,
- sndbuf_xbytes(sndbuf_getsize(bs), bs, b));
+ sndbuf_xbytes(bs->bufsize, bs, b));
if (snd_verbose > 3)
device_printf(c->dev,
"%s(): %s starting! (%s/%s) "
@@ -699,8 +699,8 @@ chn_start(struct pcm_channel *c, int force)
"running",
sndbuf_getready(b),
force, i, j, c->timeout,
- (sndbuf_getsize(b) * 1000) /
- (sndbuf_getalign(b) * sndbuf_getspd(b)));
+ (b->bufsize * 1000) /
+ (b->align * b->spd));
}
err = chn_trigger(c, PCMTRIG_START);
}
@@ -759,7 +759,7 @@ chn_sync(struct pcm_channel *c, int threshold)
syncdelay = chn_syncdelay;
if (syncdelay < 0 && (threshold > 0 || sndbuf_getready(bs) > 0))
- minflush += sndbuf_xbytes(sndbuf_getsize(b), b, bs);
+ minflush += sndbuf_xbytes(b->bufsize, b, bs);
/*
* Append (0-1000) millisecond trailing buffer (if needed)
@@ -767,10 +767,10 @@ chn_sync(struct pcm_channel *c, int threshold)
* to avoid audible truncation.
*/
if (syncdelay > 0)
- minflush += (sndbuf_getalign(bs) * sndbuf_getspd(bs) *
+ minflush += (bs->align * bs->spd *
((syncdelay > 1000) ? 1000 : syncdelay)) / 1000;
- minflush -= minflush % sndbuf_getalign(bs);
+ minflush -= minflush % bs->align;
if (minflush > 0) {
threshold = min(minflush, sndbuf_getfree(bs));
@@ -781,14 +781,14 @@ chn_sync(struct pcm_channel *c, int threshold)
resid = sndbuf_getready(bs);
residp = resid;
- blksz = sndbuf_getblksz(b);
+ blksz = b->blksz;
if (blksz < 1) {
device_printf(c->dev,
"%s(): WARNING: blksz < 1 ! maxsize=%d [%d/%d/%d]\n",
- __func__, sndbuf_getmaxsize(b), sndbuf_getsize(b),
- sndbuf_getblksz(b), sndbuf_getblkcnt(b));
- if (sndbuf_getblkcnt(b) > 0)
- blksz = sndbuf_getsize(b) / sndbuf_getblkcnt(b);
+ __func__, b->maxsize, b->bufsize,
+ b->blksz, b->blkcnt);
+ if (b->blkcnt > 0)
+ blksz = b->bufsize / b->blkcnt;
if (blksz < 1)
blksz = 1;
}
@@ -874,7 +874,7 @@ chn_poll(struct pcm_channel *c, int ev, struct thread *td)
chn_pollreset(c);
ret = ev;
} else
- selrecord(td, sndbuf_getsel(bs));
+ selrecord(td, &bs->sel);
return (ret);
}
@@ -1257,7 +1257,7 @@ chn_init(struct snddev_info *d, struct pcm_channel *parent, kobj_class_t cls,
chn_vpc_reset(c, SND_VOL_C_PCM, 1);
CHN_UNLOCK(c);
- fc = feeder_getclass(NULL);
+ fc = feeder_getclass(FEEDER_ROOT);
if (fc == NULL) {
device_printf(d->dev, "%s(): failed to get feeder class\n",
__func__);
@@ -1268,8 +1268,8 @@ chn_init(struct snddev_info *d, struct pcm_channel *parent, kobj_class_t cls,
goto fail;
}
- b = sndbuf_create(c->dev, c->name, "primary", c);
- bs = sndbuf_create(c->dev, c->name, "secondary", c);
+ b = sndbuf_create(c, "primary");
+ bs = sndbuf_create(c, "secondary");
if (b == NULL || bs == NULL) {
device_printf(d->dev, "%s(): failed to create %s buffer\n",
__func__, b == NULL ? "hardware" : "software");
@@ -1277,6 +1277,7 @@ chn_init(struct snddev_info *d, struct pcm_channel *parent, kobj_class_t cls,
}
c->bufhard = b;
c->bufsoft = bs;
+ knlist_init_mtx(&bs->sel.si_note, c->lock);
c->devinfo = CHANNEL_INIT(c->methods, devinfo, b, c, direction);
if (c->devinfo == NULL) {
@@ -1284,7 +1285,7 @@ chn_init(struct snddev_info *d, struct pcm_channel *parent, kobj_class_t cls,
goto fail;
}
- if ((sndbuf_getsize(b) == 0) && ((c->flags & CHN_F_VIRTUAL) == 0)) {
+ if (b->bufsize == 0 && ((c->flags & CHN_F_VIRTUAL) == 0)) {
device_printf(d->dev, "%s(): hardware buffer's size is 0\n",
__func__);
goto fail;
@@ -1302,7 +1303,7 @@ chn_init(struct snddev_info *d, struct pcm_channel *parent, kobj_class_t cls,
* seems to only come into existence in sndbuf_resize().
*/
if (c->direction == PCMDIR_PLAY) {
- bs->sl = sndbuf_getmaxsize(bs);
+ bs->sl = bs->maxsize;
bs->shadbuf = malloc(bs->sl, M_DEVBUF, M_WAITOK);
}
@@ -1319,8 +1320,8 @@ chn_init(struct snddev_info *d, struct pcm_channel *parent, kobj_class_t cls,
if ((c->flags & CHN_F_VIRTUAL) == 0) {
CHN_INSERT_SORT_ASCEND(d, c, channels.pcm.primary);
/* Initialize the *vchanrate/vchanformat parameters. */
- *vchanrate = sndbuf_getspd(c->bufsoft);
- *vchanformat = sndbuf_getfmt(c->bufsoft);
+ *vchanrate = c->bufsoft->spd;
+ *vchanformat = c->bufsoft->fmt;
}
return (c);
@@ -1371,10 +1372,13 @@ chn_kill(struct pcm_channel *c)
}
free_unr(chn_getunr(d, c->type), c->unit);
feeder_remove(c);
- if (c->devinfo && CHANNEL_FREE(c->methods, c->devinfo))
- sndbuf_free(b);
- if (bs)
+ if (c->devinfo)
+ CHANNEL_FREE(c->methods, c->devinfo);
+ if (bs) {
+ knlist_clear(&bs->sel.si_note, 0);
+ knlist_destroy(&bs->sel.si_note);
sndbuf_destroy(bs);
+ }
if (b)
sndbuf_destroy(b);
CHN_LOCK(c);
@@ -1895,20 +1899,20 @@ chn_resizebuf(struct pcm_channel *c, int latency,
b = c->bufhard;
if (!(blksz == 0 || blkcnt == -1) &&
- (blksz < 16 || blksz < sndbuf_getalign(bs) || blkcnt < 2 ||
+ (blksz < 16 || blksz < bs->align || blkcnt < 2 ||
(blksz * blkcnt) > CHN_2NDBUFMAXSIZE))
return EINVAL;
- chn_calclatency(c->direction, latency, sndbuf_getalign(bs),
- sndbuf_getalign(bs) * sndbuf_getspd(bs), CHN_2NDBUFMAXSIZE,
+ chn_calclatency(c->direction, latency, bs->align,
+ bs->align * bs->spd, CHN_2NDBUFMAXSIZE,
&sblksz, &sblkcnt);
if (blksz == 0 || blkcnt == -1) {
if (blkcnt == -1)
c->flags &= ~CHN_F_HAS_SIZE;
if (c->flags & CHN_F_HAS_SIZE) {
- blksz = sndbuf_getblksz(bs);
- blkcnt = sndbuf_getblkcnt(bs);
+ blksz = bs->blksz;
+ blkcnt = bs->blkcnt;
}
} else
c->flags |= CHN_F_HAS_SIZE;
@@ -1921,7 +1925,7 @@ chn_resizebuf(struct pcm_channel *c, int latency,
* defeat the purpose of having custom control. The least
* we can do is round it to the nearest ^2 and align it.
*/
- sblksz = round_blksz(blksz, sndbuf_getalign(bs));
+ sblksz = round_blksz(blksz, bs->align);
sblkcnt = round_pow2(blkcnt);
}
@@ -1934,49 +1938,46 @@ chn_resizebuf(struct pcm_channel *c, int latency,
CHN_LOCK(c);
if (c->direction == PCMDIR_PLAY) {
limit = (pb != NULL) ?
- sndbuf_xbytes(sndbuf_getsize(pb), pb, bs) : 0;
+ sndbuf_xbytes(pb->bufsize, pb, bs) : 0;
} else {
limit = (pb != NULL) ?
- sndbuf_xbytes(sndbuf_getblksz(pb), pb, bs) * 2 : 0;
+ sndbuf_xbytes(pb->blksz, pb, bs) * 2 : 0;
}
} else {
hblkcnt = 2;
if (c->flags & CHN_F_HAS_SIZE) {
hblksz = round_blksz(sndbuf_xbytes(sblksz, bs, b),
- sndbuf_getalign(b));
- hblkcnt = round_pow2(sndbuf_getblkcnt(bs));
+ b->align);
+ hblkcnt = round_pow2(bs->blkcnt);
} else
chn_calclatency(c->direction, latency,
- sndbuf_getalign(b),
- sndbuf_getalign(b) * sndbuf_getspd(b),
+ b->align, b->align * b->spd,
CHN_2NDBUFMAXSIZE, &hblksz, &hblkcnt);
- if ((hblksz << 1) > sndbuf_getmaxsize(b))
- hblksz = round_blksz(sndbuf_getmaxsize(b) >> 1,
- sndbuf_getalign(b));
+ if ((hblksz << 1) > b->maxsize)
+ hblksz = round_blksz(b->maxsize >> 1, b->align);
- while ((hblksz * hblkcnt) > sndbuf_getmaxsize(b)) {
+ while ((hblksz * hblkcnt) > b->maxsize) {
if (hblkcnt < 4)
hblksz >>= 1;
else
hblkcnt >>= 1;
}
- hblksz -= hblksz % sndbuf_getalign(b);
+ hblksz -= hblksz % b->align;
CHN_UNLOCK(c);
if (chn_usefrags == 0 ||
CHANNEL_SETFRAGMENTS(c->methods, c->devinfo,
hblksz, hblkcnt) != 0)
- sndbuf_setblksz(b, CHANNEL_SETBLOCKSIZE(c->methods,
- c->devinfo, hblksz));
+ b->blksz = CHANNEL_SETBLOCKSIZE(c->methods,
+ c->devinfo, hblksz);
CHN_LOCK(c);
if (!CHN_EMPTY(c, children)) {
nsblksz = round_blksz(
- sndbuf_xbytes(sndbuf_getblksz(b), b, bs),
- sndbuf_getalign(bs));
- nsblkcnt = sndbuf_getblkcnt(b);
+ sndbuf_xbytes(b->blksz, b, bs), bs->align);
+ nsblkcnt = b->blkcnt;
if (c->direction == PCMDIR_PLAY) {
do {
nsblkcnt--;
@@ -1988,7 +1989,7 @@ chn_resizebuf(struct pcm_channel *c, int latency,
sblkcnt = nsblkcnt;
limit = 0;
} else
- limit = sndbuf_xbytes(sndbuf_getblksz(b), b, bs) * 2;
+ limit = sndbuf_xbytes(b->blksz, b, bs) * 2;
}
if (limit > CHN_2NDBUFMAXSIZE)
@@ -2004,10 +2005,10 @@ chn_resizebuf(struct pcm_channel *c, int latency,
sblkcnt >>= 1;
}
- sblksz -= sblksz % sndbuf_getalign(bs);
+ sblksz -= sblksz % bs->align;
- if (sndbuf_getblkcnt(bs) != sblkcnt || sndbuf_getblksz(bs) != sblksz ||
- sndbuf_getsize(bs) != (sblkcnt * sblksz)) {
+ if (bs->blkcnt != sblkcnt || bs->blksz != sblksz ||
+ bs->bufsize != (sblkcnt * sblksz)) {
ret = sndbuf_remalloc(bs, sblkcnt, sblksz);
if (ret != 0) {
device_printf(c->dev, "%s(): Failed: %d %d\n",
@@ -2019,8 +2020,8 @@ chn_resizebuf(struct pcm_channel *c, int latency,
/*
* Interrupt timeout
*/
- c->timeout = ((u_int64_t)hz * sndbuf_getsize(bs)) /
- ((u_int64_t)sndbuf_getspd(bs) * sndbuf_getalign(bs));
+ c->timeout = ((u_int64_t)hz * bs->bufsize) /
+ ((u_int64_t)bs->spd * bs->align);
if (c->parentchannel != NULL)
c->timeout = min(c->timeout, c->parentchannel->timeout);
if (c->timeout < 1)
@@ -2030,7 +2031,7 @@ chn_resizebuf(struct pcm_channel *c, int latency,
* OSSv4 docs: "By default OSS will set the low water level equal
* to the fragment size which is optimal in most cases."
*/
- c->lw = sndbuf_getblksz(bs);
+ c->lw = bs->blksz;
chn_resetbuf(c);
if (snd_verbose > 3)
@@ -2039,10 +2040,10 @@ chn_resizebuf(struct pcm_channel *c, int latency,
__func__, CHN_DIRSTR(c),
(c->flags & CHN_F_VIRTUAL) ? "virtual" : "hardware",
c->timeout,
- sndbuf_getsize(b), sndbuf_getblksz(b),
- sndbuf_getblkcnt(b),
- sndbuf_getsize(bs), sndbuf_getblksz(bs),
- sndbuf_getblkcnt(bs), limit);
+ b->bufsize, b->blksz,
+ b->blkcnt,
+ bs->bufsize, bs->blksz,
+ bs->blkcnt, limit);
return 0;
}
@@ -2085,7 +2086,7 @@ chn_setparam(struct pcm_channel *c, uint32_t format, uint32_t speed)
sndbuf_setspd(c->bufhard, CHANNEL_SETSPEED(c->methods, c->devinfo,
hwspeed));
- hwspeed = sndbuf_getspd(c->bufhard);
+ hwspeed = c->bufhard->spd;
delta = (hwspeed > speed) ? (hwspeed - speed) : (speed - hwspeed);
@@ -2095,8 +2096,7 @@ chn_setparam(struct pcm_channel *c, uint32_t format, uint32_t speed)
ret = feeder_chain(c);
if (ret == 0)
- ret = CHANNEL_SETFORMAT(c->methods, c->devinfo,
- sndbuf_getfmt(c->bufhard));
+ ret = CHANNEL_SETFORMAT(c->methods, c->devinfo, c->bufhard->fmt);
if (ret == 0)
ret = chn_resizebuf(c, -2, 0, 0);
@@ -2339,7 +2339,7 @@ chn_getptr(struct pcm_channel *c)
CHN_LOCKASSERT(c);
hwptr = (CHN_STARTED(c)) ? CHANNEL_GETPTR(c->methods, c->devinfo) : 0;
- return (hwptr - (hwptr % sndbuf_getalign(c->bufhard)));
+ return (hwptr - (hwptr % c->bufhard->align));
}
struct pcmchan_caps *
diff --git a/sys/dev/sound/pcm/channel.h b/sys/dev/sound/pcm/channel.h
index 9ad21d219001..15180bc8f0b6 100644
--- a/sys/dev/sound/pcm/channel.h
+++ b/sys/dev/sound/pcm/channel.h
@@ -261,6 +261,7 @@ int chn_read(struct pcm_channel *c, struct uio *buf);
u_int32_t chn_start(struct pcm_channel *c, int force);
int chn_sync(struct pcm_channel *c, int threshold);
int chn_flush(struct pcm_channel *c);
+int chn_polltrigger(struct pcm_channel *c);
int chn_poll(struct pcm_channel *c, int ev, struct thread *td);
char *chn_mkname(char *buf, size_t len, struct pcm_channel *c);
diff --git a/sys/dev/sound/pcm/dsp.c b/sys/dev/sound/pcm/dsp.c
index da38f52021ae..1ae090f252c2 100644
--- a/sys/dev/sound/pcm/dsp.c
+++ b/sys/dev/sound/pcm/dsp.c
@@ -72,8 +72,6 @@ SYSCTL_INT(_hw_snd, OID_AUTO, basename_clone, CTLFLAG_RWTUN,
#define DSP_F_READ(x) ((x) & FREAD)
#define DSP_F_WRITE(x) ((x) & FWRITE)
-#define OLDPCM_IOCTL
-
static d_open_t dsp_open;
static d_read_t dsp_read;
static d_write_t dsp_write;
@@ -81,17 +79,19 @@ static d_ioctl_t dsp_ioctl;
static d_poll_t dsp_poll;
static d_mmap_t dsp_mmap;
static d_mmap_single_t dsp_mmap_single;
+static d_kqfilter_t dsp_kqfilter;
struct cdevsw dsp_cdevsw = {
- .d_version = D_VERSION,
- .d_open = dsp_open,
- .d_read = dsp_read,
- .d_write = dsp_write,
- .d_ioctl = dsp_ioctl,
- .d_poll = dsp_poll,
- .d_mmap = dsp_mmap,
- .d_mmap_single = dsp_mmap_single,
- .d_name = "dsp",
+ .d_version = D_VERSION,
+ .d_open = dsp_open,
+ .d_read = dsp_read,
+ .d_write = dsp_write,
+ .d_ioctl = dsp_ioctl,
+ .d_poll = dsp_poll,
+ .d_kqfilter = dsp_kqfilter,
+ .d_mmap = dsp_mmap,
+ .d_mmap_single = dsp_mmap_single,
+ .d_name = "dsp",
};
static eventhandler_tag dsp_ehtag = NULL;
@@ -462,15 +462,11 @@ static __inline int
dsp_io_ops(struct dsp_cdevpriv *priv, struct uio *buf)
{
struct snddev_info *d;
- struct pcm_channel **ch;
+ struct pcm_channel *ch;
int (*chn_io)(struct pcm_channel *, struct uio *);
int prio, ret;
pid_t runpid;
- KASSERT(buf != NULL &&
- (buf->uio_rw == UIO_READ || buf->uio_rw == UIO_WRITE),
- ("%s(): io train wreck!", __func__));
-
d = priv->sc;
if (!DSP_REGISTERED(d))
return (EBADF);
@@ -480,38 +476,35 @@ dsp_io_ops(struct dsp_cdevpriv *priv, struct uio *buf)
switch (buf->uio_rw) {
case UIO_READ:
prio = FREAD;
- ch = &priv->rdch;
+ ch = priv->rdch;
chn_io = chn_read;
break;
case UIO_WRITE:
prio = FWRITE;
- ch = &priv->wrch;
+ ch = priv->wrch;
chn_io = chn_write;
break;
- default:
- panic("invalid/corrupted uio direction: %d", buf->uio_rw);
- break;
}
runpid = buf->uio_td->td_proc->p_pid;
dsp_lock_chans(priv, prio);
- if (*ch == NULL || !((*ch)->flags & CHN_F_BUSY)) {
+ if (ch == NULL || !(ch->flags & CHN_F_BUSY)) {
if (priv->rdch != NULL || priv->wrch != NULL)
dsp_unlock_chans(priv, prio);
PCM_GIANT_EXIT(d);
return (EBADF);
}
- if (((*ch)->flags & (CHN_F_MMAP | CHN_F_DEAD)) ||
- (((*ch)->flags & CHN_F_RUNNING) && (*ch)->pid != runpid)) {
+ if (ch->flags & (CHN_F_MMAP | CHN_F_DEAD) ||
+ (ch->flags & CHN_F_RUNNING && ch->pid != runpid)) {
dsp_unlock_chans(priv, prio);
PCM_GIANT_EXIT(d);
return (EINVAL);
- } else if (!((*ch)->flags & CHN_F_RUNNING)) {
- (*ch)->flags |= CHN_F_RUNNING;
- (*ch)->pid = runpid;
+ } else if (!(ch->flags & CHN_F_RUNNING)) {
+ ch->flags |= CHN_F_RUNNING;
+ ch->pid = runpid;
}
/*
@@ -519,11 +512,11 @@ dsp_io_ops(struct dsp_cdevpriv *priv, struct uio *buf)
* from/to userland, so up the "in progress" counter to make sure
* someone else doesn't come along and muss up the buffer.
*/
- ++(*ch)->inprog;
- ret = chn_io(*ch, buf);
- --(*ch)->inprog;
+ ch->inprog++;
+ ret = chn_io(ch, buf);
+ ch->inprog--;
- CHN_BROADCAST(&(*ch)->cv);
+ CHN_BROADCAST(&ch->cv);
dsp_unlock_chans(priv, prio);
@@ -671,6 +664,43 @@ dsp_ioctl_channel(struct dsp_cdevpriv *priv, struct pcm_channel *ch,
return (0);
}
+#ifdef COMPAT_FREEBSD32
+typedef struct _snd_chan_param32 {
+ uint32_t play_rate;
+ uint32_t rec_rate;
+ uint32_t play_format;
+ uint32_t rec_format;
+} snd_chan_param32;
+#define AIOGFMT32 _IOC_NEWTYPE(AIOGFMT, snd_chan_param32)
+#define AIOSFMT32 _IOC_NEWTYPE(AIOSFMT, snd_chan_param32)
+
+typedef struct _snd_capabilities32 {
+ uint32_t rate_min, rate_max;
+ uint32_t formats;
+ uint32_t bufsize;
+ uint32_t mixers;
+ uint32_t inputs;
+ uint16_t left, right;
+} snd_capabilities32;
+#define AIOGCAP32 _IOC_NEWTYPE(AIOGCAP, snd_capabilities32)
+
+typedef struct audio_errinfo32
+{
+ int32_t play_underruns;
+ int32_t rec_overruns;
+ uint32_t play_ptradjust;
+ uint32_t rec_ptradjust;
+ int32_t play_errorcount;
+ int32_t rec_errorcount;
+ int32_t play_lasterror;
+ int32_t rec_lasterror;
+ int32_t play_errorparm;
+ int32_t rec_errorparm;
+ int32_t filler[16];
+} audio_errinfo32;
+#define SNDCTL_DSP_GETERROR32 _IOC_NEWTYPE(SNDCTL_DSP_GETERROR, audio_errinfo32)
+#endif
+
static int
dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode,
struct thread *td)
@@ -769,10 +799,6 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode,
}
switch(cmd) {
-#ifdef OLDPCM_IOCTL
- /*
- * we start with the new ioctl interface.
- */
case AIONWRITE: /* how many bytes can write ? */
if (wrch) {
CHN_LOCK(wrch);
@@ -798,13 +824,13 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode,
if (wrch) {
CHN_LOCK(wrch);
chn_setblocksize(wrch, 2, p->play_size);
- p->play_size = sndbuf_getblksz(wrch->bufsoft);
+ p->play_size = wrch->bufsoft->blksz;
CHN_UNLOCK(wrch);
}
if (rdch) {
CHN_LOCK(rdch);
chn_setblocksize(rdch, 2, p->rec_size);
- p->rec_size = sndbuf_getblksz(rdch->bufsoft);
+ p->rec_size = rdch->bufsoft->blksz;
CHN_UNLOCK(rdch);
}
PCM_RELEASE_QUICK(d);
@@ -816,12 +842,12 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode,
if (wrch) {
CHN_LOCK(wrch);
- p->play_size = sndbuf_getblksz(wrch->bufsoft);
+ p->play_size = wrch->bufsoft->blksz;
CHN_UNLOCK(wrch);
}
if (rdch) {
CHN_LOCK(rdch);
- p->rec_size = sndbuf_getblksz(rdch->bufsoft);
+ p->rec_size = rdch->bufsoft->blksz;
CHN_UNLOCK(rdch);
}
}
@@ -829,9 +855,25 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode,
case AIOSFMT:
case AIOGFMT:
+#ifdef COMPAT_FREEBSD32
+ case AIOSFMT32:
+ case AIOGFMT32:
+#endif
{
snd_chan_param *p = (snd_chan_param *)arg;
+#ifdef COMPAT_FREEBSD32
+ snd_chan_param32 *p32 = (snd_chan_param32 *)arg;
+ snd_chan_param param;
+
+ if (cmd == AIOSFMT32) {
+ p = &param;
+ p->play_rate = p32->play_rate;
+ p->rec_rate = p32->rec_rate;
+ p->play_format = p32->play_format;
+ p->rec_format = p32->rec_format;
+ }
+#endif
if (cmd == AIOSFMT &&
((p->play_format != 0 && p->play_rate == 0) ||
(p->rec_format != 0 && p->rec_rate == 0))) {
@@ -872,15 +914,41 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode,
p->rec_format = 0;
}
PCM_RELEASE_QUICK(d);
+#ifdef COMPAT_FREEBSD32
+ if (cmd == AIOSFMT32 || cmd == AIOGFMT32) {
+ p32->play_rate = p->play_rate;
+ p32->rec_rate = p->rec_rate;
+ p32->play_format = p->play_format;
+ p32->rec_format = p->rec_format;
+ }
+#endif
}
break;
case AIOGCAP: /* get capabilities */
+#ifdef COMPAT_FREEBSD32
+ case AIOGCAP32:
+#endif
{
snd_capabilities *p = (snd_capabilities *)arg;
struct pcmchan_caps *pcaps = NULL, *rcaps = NULL;
struct cdev *pdev;
-
+#ifdef COMPAT_FREEBSD32
+ snd_capabilities32 *p32 = (snd_capabilities32 *)arg;
+ snd_capabilities capabilities;
+
+ if (cmd == AIOGCAP32) {
+ p = &capabilities;
+ p->rate_min = p32->rate_min;
+ p->rate_max = p32->rate_max;
+ p->formats = p32->formats;
+ p->bufsize = p32->bufsize;
+ p->mixers = p32->mixers;
+ p->inputs = p32->inputs;
+ p->left = p32->left;
+ p->right = p32->right;
+ }
+#endif
PCM_LOCK(d);
if (rdch) {
CHN_LOCK(rdch);
@@ -894,8 +962,8 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode,
pcaps? pcaps->minspeed : 0);
p->rate_max = min(rcaps? rcaps->maxspeed : 1000000,
pcaps? pcaps->maxspeed : 1000000);
- p->bufsize = min(rdch? sndbuf_getsize(rdch->bufsoft) : 1000000,
- wrch? sndbuf_getsize(wrch->bufsoft) : 1000000);
+ p->bufsize = min(rdch? rdch->bufsoft->bufsize : 1000000,
+ wrch? wrch->bufsoft->bufsize : 1000000);
/* XXX bad on sb16 */
p->formats = (rdch? chn_getformats(rdch) : 0xffffffff) &
(wrch? chn_getformats(wrch) : 0xffffffff);
@@ -913,6 +981,18 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode,
if (rdch)
CHN_UNLOCK(rdch);
PCM_UNLOCK(d);
+#ifdef COMPAT_FREEBSD32
+ if (cmd == AIOGCAP32) {
+ p32->rate_min = p->rate_min;
+ p32->rate_max = p->rate_max;
+ p32->formats = p->formats;
+ p32->bufsize = p->bufsize;
+ p32->mixers = p->mixers;
+ p32->inputs = p->inputs;
+ p32->left = p->left;
+ p32->right = p->right;
+ }
+#endif
}
break;
@@ -935,10 +1015,6 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode,
printf("AIOSYNC chan 0x%03lx pos %lu unimplemented\n",
((snd_sync_parm *)arg)->chan, ((snd_sync_parm *)arg)->pos);
break;
-#endif
- /*
- * here follow the standard ioctls (filio.h etc.)
- */
case FIONREAD: /* get # bytes to read */
if (rdch) {
CHN_LOCK(rdch);
@@ -977,16 +1053,11 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode,
}
break;
- /*
- * Finally, here is the linux-compatible ioctl interface
- */
-#define THE_REAL_SNDCTL_DSP_GETBLKSIZE _IOWR('P', 4, int)
- case THE_REAL_SNDCTL_DSP_GETBLKSIZE:
case SNDCTL_DSP_GETBLKSIZE:
chn = wrch ? wrch : rdch;
if (chn) {
CHN_LOCK(chn);
- *arg_i = sndbuf_getblksz(chn->bufsoft);
+ *arg_i = chn->bufsoft->blksz;
CHN_UNLOCK(chn);
} else {
*arg_i = 0;
@@ -1224,8 +1295,8 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode,
if (rdch) {
CHN_LOCK(rdch);
ret = chn_setblocksize(rdch, maxfrags, fragsz);
- r_maxfrags = sndbuf_getblkcnt(rdch->bufsoft);
- r_fragsz = sndbuf_getblksz(rdch->bufsoft);
+ r_maxfrags = rdch->bufsoft->blkcnt;
+ r_fragsz = rdch->bufsoft->blksz;
CHN_UNLOCK(rdch);
} else {
r_maxfrags = maxfrags;
@@ -1234,8 +1305,8 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode,
if (wrch && ret == 0) {
CHN_LOCK(wrch);
ret = chn_setblocksize(wrch, maxfrags, fragsz);
- maxfrags = sndbuf_getblkcnt(wrch->bufsoft);
- fragsz = sndbuf_getblksz(wrch->bufsoft);
+ maxfrags = wrch->bufsoft->blkcnt;
+ fragsz = wrch->bufsoft->blksz;
CHN_UNLOCK(wrch);
} else { /* use whatever came from the read channel */
maxfrags = r_maxfrags;
@@ -1261,9 +1332,9 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode,
CHN_LOCK(rdch);
a->bytes = sndbuf_getready(bs);
- a->fragments = a->bytes / sndbuf_getblksz(bs);
- a->fragstotal = sndbuf_getblkcnt(bs);
- a->fragsize = sndbuf_getblksz(bs);
+ a->fragments = a->bytes / bs->blksz;
+ a->fragstotal = bs->blkcnt;
+ a->fragsize = bs->blksz;
CHN_UNLOCK(rdch);
} else
ret = EINVAL;
@@ -1279,9 +1350,9 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode,
CHN_LOCK(wrch);
a->bytes = sndbuf_getfree(bs);
- a->fragments = a->bytes / sndbuf_getblksz(bs);
- a->fragstotal = sndbuf_getblkcnt(bs);
- a->fragsize = sndbuf_getblksz(bs);
+ a->fragments = a->bytes / bs->blksz;
+ a->fragstotal = bs->blkcnt;
+ a->fragsize = bs->blksz;
CHN_UNLOCK(wrch);
} else
ret = EINVAL;
@@ -1295,7 +1366,7 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode,
struct snd_dbuf *bs = rdch->bufsoft;
CHN_LOCK(rdch);
- a->bytes = sndbuf_gettotal(bs);
+ a->bytes = bs->total;
a->blocks = sndbuf_getblocks(bs) - rdch->blocks;
a->ptr = sndbuf_getfreeptr(bs);
rdch->blocks = sndbuf_getblocks(bs);
@@ -1312,7 +1383,7 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode,
struct snd_dbuf *bs = wrch->bufsoft;
CHN_LOCK(wrch);
- a->bytes = sndbuf_gettotal(bs);
+ a->bytes = bs->total;
a->blocks = sndbuf_getblocks(bs) - wrch->blocks;
a->ptr = sndbuf_getreadyptr(bs);
wrch->blocks = sndbuf_getblocks(bs);
@@ -1599,8 +1670,8 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode,
CHN_LOCK(chn);
bs = chn->bufsoft;
- oc->samples = sndbuf_gettotal(bs) / sndbuf_getalign(bs);
- oc->fifo_samples = sndbuf_getready(bs) / sndbuf_getalign(bs);
+ oc->samples = bs->total / bs->align;
+ oc->fifo_samples = sndbuf_getready(bs) / bs->align;
CHN_UNLOCK(chn);
}
break;
@@ -1635,6 +1706,9 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode,
break;
case SNDCTL_DSP_GETERROR:
+#ifdef COMPAT_FREEBSD32
+ case SNDCTL_DSP_GETERROR32:
+#endif
/*
* OSSv4 docs: "All errors and counters will automatically be
* cleared to zeroes after the call so each call will return only
@@ -1644,6 +1718,14 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode,
*/
{
audio_errinfo *ei = (audio_errinfo *)arg;
+#ifdef COMPAT_FREEBSD32
+ audio_errinfo errinfo;
+ audio_errinfo32 *ei32 = (audio_errinfo32 *)arg;
+
+ if (cmd == SNDCTL_DSP_GETERROR32) {
+ ei = &errinfo;
+ }
+#endif
bzero((void *)ei, sizeof(*ei));
@@ -1659,6 +1741,21 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode,
rdch->xruns = 0;
CHN_UNLOCK(rdch);
}
+#ifdef COMPAT_FREEBSD32
+ if (cmd == SNDCTL_DSP_GETERROR32) {
+ bzero((void *)ei32, sizeof(*ei32));
+ ei32->play_underruns = ei->play_underruns;
+ ei32->rec_overruns = ei->rec_overruns;
+ ei32->play_ptradjust = ei->play_ptradjust;
+ ei32->rec_ptradjust = ei->rec_ptradjust;
+ ei32->play_errorcount = ei->play_errorcount;
+ ei32->rec_errorcount = ei->rec_errorcount;
+ ei32->play_lasterror = ei->play_lasterror;
+ ei32->rec_lasterror = ei->rec_lasterror;
+ ei32->play_errorparm = ei->play_errorparm;
+ ei32->rec_errorparm = ei->rec_errorparm;
+ }
+#endif
}
break;
@@ -1875,7 +1972,7 @@ dsp_mmap_single(struct cdev *i_dev, vm_ooffset_t *offset,
c = ((nprot & PROT_WRITE) != 0) ? wrch : rdch;
if (c == NULL || (c->flags & CHN_F_MMAP_INVALID) ||
- (*offset + size) > sndbuf_getallocsize(c->bufsoft) ||
+ (*offset + size) > c->bufsoft->allocsize ||
(wrch != NULL && (wrch->flags & CHN_F_MMAP_INVALID)) ||
(rdch != NULL && (rdch->flags & CHN_F_MMAP_INVALID))) {
dsp_unlock_chans(priv, FREAD | FWRITE);
@@ -2845,6 +2942,86 @@ dsp_oss_getchannelmask(struct pcm_channel *wrch, struct pcm_channel *rdch,
return (ret);
}
+static void
+dsp_kqdetach(struct knote *kn)
+{
+ struct pcm_channel *ch = kn->kn_hook;
+
+ if (ch == NULL)
+ return;
+ CHN_LOCK(ch);
+ knlist_remove(&ch->bufsoft->sel.si_note, kn, 1);
+ CHN_UNLOCK(ch);
+}
+
+static int
+dsp_kqevent(struct knote *kn, long hint)
+{
+ struct pcm_channel *ch = kn->kn_hook;
+
+ CHN_LOCKASSERT(ch);
+ if (ch->flags & CHN_F_DEAD) {
+ kn->kn_flags |= EV_EOF;
+ return (1);
+ }
+ kn->kn_data = 0;
+ if (chn_polltrigger(ch)) {
+ if (kn->kn_filter == EVFILT_READ)
+ kn->kn_data = sndbuf_getready(ch->bufsoft);
+ else
+ kn->kn_data = sndbuf_getfree(ch->bufsoft);
+ }
+
+ return (kn->kn_data > 0);
+}
+
+static const struct filterops dsp_filtops = {
+ .f_isfd = 1,
+ .f_detach = dsp_kqdetach,
+ .f_event = dsp_kqevent,
+};
+
+static int
+dsp_kqfilter(struct cdev *dev, struct knote *kn)
+{
+ struct dsp_cdevpriv *priv;
+ struct snddev_info *d;
+ struct pcm_channel *ch;
+ int err = 0;
+
+ if ((err = devfs_get_cdevpriv((void **)&priv)) != 0)
+ return (err);
+
+ d = priv->sc;
+ if (!DSP_REGISTERED(d))
+ return (EBADF);
+ PCM_GIANT_ENTER(d);
+ switch (kn->kn_filter) {
+ case EVFILT_READ:
+ ch = priv->rdch;
+ break;
+ case EVFILT_WRITE:
+ ch = priv->wrch;
+ break;
+ default:
+ kn->kn_hook = NULL;
+ err = EINVAL;
+ ch = NULL;
+ break;
+ }
+ if (ch != NULL) {
+ kn->kn_fop = &dsp_filtops;
+ CHN_LOCK(ch);
+ knlist_add(&ch->bufsoft->sel.si_note, kn, 1);
+ CHN_UNLOCK(ch);
+ kn->kn_hook = ch;
+ } else
+ err = EINVAL;
+ PCM_GIANT_LEAVE(d);
+
+ return (err);
+}
+
#ifdef OSSV4_EXPERIMENT
/**
* @brief Retrieve an audio device's label
diff --git a/sys/dev/sound/pcm/feeder.c b/sys/dev/sound/pcm/feeder.c
index af3ada441e48..fa4e4e16a133 100644
--- a/sys/dev/sound/pcm/feeder.c
+++ b/sys/dev/sound/pcm/feeder.c
@@ -36,94 +36,25 @@
#endif
#include <dev/sound/pcm/sound.h>
-#include <dev/sound/pcm/vchan.h>
#include "feeder_if.h"
static MALLOC_DEFINE(M_FEEDER, "feeder", "pcm feeder");
-#define MAXFEEDERS 256
-
-struct feedertab_entry {
- SLIST_ENTRY(feedertab_entry) link;
- struct feeder_class *feederclass;
- struct pcm_feederdesc *desc;
-
- int idx;
-};
-static SLIST_HEAD(, feedertab_entry) feedertab;
-static int feedercnt = 0;
-
-/*****************************************************************************/
-
-static void
-feeder_register_root(void *p)
-{
- struct feeder_class *fc = p;
- struct feedertab_entry *fte;
-
- MPASS(feedercnt == 0);
- KASSERT(fc->desc == NULL, ("first feeder not root: %s", fc->name));
-
- SLIST_INIT(&feedertab);
- fte = malloc(sizeof(*fte), M_FEEDER, M_WAITOK | M_ZERO);
- fte->feederclass = fc;
- fte->desc = NULL;
- fte->idx = feedercnt;
- SLIST_INSERT_HEAD(&feedertab, fte, link);
- feedercnt++;
-}
+static SLIST_HEAD(, feeder_class) feedertab = SLIST_HEAD_INITIALIZER(feedertab);
void
feeder_register(void *p)
{
struct feeder_class *fc = p;
- struct feedertab_entry *fte;
- int i;
- KASSERT(fc->desc != NULL, ("feeder '%s' has no descriptor", fc->name));
-
- /*
- * beyond this point failure is non-fatal but may result in some
- * translations being unavailable
- */
- i = 0;
- while ((feedercnt < MAXFEEDERS) && (fc->desc[i].type > 0)) {
- fte = malloc(sizeof(*fte), M_FEEDER, M_WAITOK | M_ZERO);
- fte->feederclass = fc;
- fte->desc = &fc->desc[i];
- fte->idx = feedercnt;
- fte->desc->idx = feedercnt;
- SLIST_INSERT_HEAD(&feedertab, fte, link);
- i++;
- }
- feedercnt++;
- if (feedercnt >= MAXFEEDERS) {
- printf("MAXFEEDERS (%d >= %d) exceeded\n",
- feedercnt, MAXFEEDERS);
- }
+ SLIST_INSERT_HEAD(&feedertab, fc, link);
}
static void
-feeder_unregisterall(void *p)
+feeder_unregisterall(void *p __unused)
{
- struct feedertab_entry *fte, *next;
-
- next = SLIST_FIRST(&feedertab);
- while (next != NULL) {
- fte = next;
- next = SLIST_NEXT(fte, link);
- free(fte, M_FEEDER);
- }
-}
-
-static int
-cmpdesc(struct pcm_feederdesc *n, struct pcm_feederdesc *m)
-{
- return ((n->type == m->type) &&
- ((n->in == 0) || (n->in == m->in)) &&
- ((n->out == 0) || (n->out == m->out)) &&
- (n->flags == m->flags));
+ SLIST_INIT(&feedertab);
}
static void
@@ -143,21 +74,10 @@ feeder_create(struct feeder_class *fc, struct pcm_feederdesc *desc)
if (f == NULL)
return NULL;
- f->data = fc->data;
- f->source = NULL;
- f->parent = NULL;
f->class = fc;
f->desc = &(f->desc_static);
-
- if (desc) {
+ if (desc != NULL)
*(f->desc) = *desc;
- } else {
- f->desc->type = FEEDER_ROOT;
- f->desc->in = 0;
- f->desc->out = 0;
- f->desc->flags = 0;
- f->desc->idx = 0;
- }
err = FEEDER_INIT(f);
if (err) {
@@ -171,17 +91,15 @@ feeder_create(struct feeder_class *fc, struct pcm_feederdesc *desc)
}
struct feeder_class *
-feeder_getclass(struct pcm_feederdesc *desc)
+feeder_getclass(u_int32_t type)
{
- struct feedertab_entry *fte;
+ struct feeder_class *fc;
- SLIST_FOREACH(fte, &feedertab, link) {
- if ((desc == NULL) && (fte->desc == NULL))
- return fte->feederclass;
- if ((fte->desc != NULL) && (desc != NULL) && cmpdesc(desc, fte->desc))
- return fte->feederclass;
+ SLIST_FOREACH(fc, &feedertab, link) {
+ if (fc->type == type)
+ return (fc);
}
- return NULL;
+ return (NULL);
}
int
@@ -221,7 +139,7 @@ feeder_find(struct pcm_channel *c, u_int32_t type)
f = c->feeder;
while (f != NULL) {
- if (f->desc->type == type)
+ if (f->class->type == type)
return f;
f = f->source;
}
@@ -386,22 +304,6 @@ snd_fmtbest(u_int32_t fmt, u_int32_t *fmts)
return best2;
}
-void
-feeder_printchain(struct pcm_feeder *head)
-{
- struct pcm_feeder *f;
-
- printf("feeder chain (head @%p)\n", head);
- f = head;
- while (f != NULL) {
- printf("%s/%d @ %p\n", f->class->name, f->desc->idx, f);
- f = f->source;
- }
- printf("[end]\n\n");
-}
-
-/*****************************************************************************/
-
static int
feed_root(struct pcm_feeder *feeder, struct pcm_channel *ch, u_int8_t *buffer, u_int32_t count, void *source)
{
@@ -433,9 +335,7 @@ feed_root(struct pcm_feeder *feeder, struct pcm_channel *ch, u_int8_t *buffer, u
offset, count, l, ch->feedcount);
if (ch->feedcount == 1) {
- memset(buffer,
- sndbuf_zerodata(sndbuf_getfmt(src)),
- offset);
+ memset(buffer, sndbuf_zerodata(src->fmt), offset);
if (l > 0)
sndbuf_dispose(src, buffer + offset, l);
else
@@ -443,9 +343,7 @@ feed_root(struct pcm_feeder *feeder, struct pcm_channel *ch, u_int8_t *buffer, u
} else {
if (l > 0)
sndbuf_dispose(src, buffer, l);
- memset(buffer + l,
- sndbuf_zerodata(sndbuf_getfmt(src)),
- offset);
+ memset(buffer + l, sndbuf_zerodata(src->fmt), offset);
if (!(ch->flags & CHN_F_CLOSING))
ch->xruns++;
}
@@ -463,13 +361,12 @@ static struct feeder_class feeder_root_class = {
.name = "feeder_root",
.methods = feeder_root_methods,
.size = sizeof(struct pcm_feeder),
- .desc = NULL,
- .data = NULL,
+ .type = FEEDER_ROOT,
};
/*
* Register the root feeder first so that pcm_addchan() and subsequent
* functions can use it.
*/
-SYSINIT(feeder_root, SI_SUB_DRIVERS, SI_ORDER_FIRST, feeder_register_root,
+SYSINIT(feeder_root, SI_SUB_DRIVERS, SI_ORDER_FIRST, feeder_register,
&feeder_root_class);
SYSUNINIT(feeder_root, SI_SUB_DRIVERS, SI_ORDER_FIRST, feeder_unregisterall, NULL);
diff --git a/sys/dev/sound/pcm/feeder.h b/sys/dev/sound/pcm/feeder.h
index 60b8280e59ef..f1c96d86fda0 100644
--- a/sys/dev/sound/pcm/feeder.h
+++ b/sys/dev/sound/pcm/feeder.h
@@ -27,17 +27,25 @@
* SUCH DAMAGE.
*/
+enum feeder_type {
+ FEEDER_ROOT,
+ FEEDER_FORMAT,
+ FEEDER_MIXER,
+ FEEDER_RATE,
+ FEEDER_EQ,
+ FEEDER_VOLUME,
+ FEEDER_MATRIX,
+ FEEDER_LAST,
+};
+
struct pcm_feederdesc {
- u_int32_t type;
u_int32_t in, out;
- u_int32_t flags;
- int idx;
};
struct feeder_class {
KOBJ_CLASS_FIELDS;
- struct pcm_feederdesc *desc;
- void *data;
+ enum feeder_type type;
+ SLIST_ENTRY(feeder_class) link;
};
struct pcm_feeder {
@@ -51,7 +59,7 @@ struct pcm_feeder {
};
void feeder_register(void *p);
-struct feeder_class *feeder_getclass(struct pcm_feederdesc *desc);
+struct feeder_class *feeder_getclass(u_int32_t type);
u_int32_t snd_fmtscore(u_int32_t fmt);
u_int32_t snd_fmtbestbit(u_int32_t fmt, u_int32_t *fmts);
@@ -62,31 +70,18 @@ int feeder_add(struct pcm_channel *c, struct feeder_class *fc,
struct pcm_feederdesc *desc);
void feeder_remove(struct pcm_channel *c);
struct pcm_feeder *feeder_find(struct pcm_channel *c, u_int32_t type);
-void feeder_printchain(struct pcm_feeder *head);
int feeder_chain(struct pcm_channel *);
-#define FEEDER_DECLARE(feeder, pdata) \
+#define FEEDER_DECLARE(feeder, ctype) \
static struct feeder_class feeder ## _class = { \
.name = #feeder, \
.methods = feeder ## _methods, \
.size = sizeof(struct pcm_feeder), \
- .desc = feeder ## _desc, \
- .data = pdata, \
+ .type = ctype, \
}; \
SYSINIT(feeder, SI_SUB_DRIVERS, SI_ORDER_ANY, feeder_register, \
&feeder ## _class)
-enum {
- FEEDER_ROOT,
- FEEDER_FORMAT,
- FEEDER_MIXER,
- FEEDER_RATE,
- FEEDER_EQ,
- FEEDER_VOLUME,
- FEEDER_MATRIX,
- FEEDER_LAST,
-};
-
/* feeder_format */
enum {
FEEDFORMAT_CHANNELS
diff --git a/sys/dev/sound/pcm/feeder_chain.c b/sys/dev/sound/pcm/feeder_chain.c
index 56de32441de7..32dd4ca14faf 100644
--- a/sys/dev/sound/pcm/feeder_chain.c
+++ b/sys/dev/sound/pcm/feeder_chain.c
@@ -144,12 +144,10 @@ feeder_build_format(struct pcm_channel *c, struct feeder_chain_desc *cdesc)
int ret;
desc = &(cdesc->desc);
- desc->type = FEEDER_FORMAT;
desc->in = 0;
desc->out = 0;
- desc->flags = 0;
- fc = feeder_getclass(desc);
+ fc = feeder_getclass(FEEDER_FORMAT);
if (fc == NULL) {
device_printf(c->dev,
"%s(): can't find feeder_format\n", __func__);
@@ -217,12 +215,10 @@ feeder_build_rate(struct pcm_channel *c, struct feeder_chain_desc *cdesc)
return (ret);
desc = &(cdesc->desc);
- desc->type = FEEDER_RATE;
desc->in = 0;
desc->out = 0;
- desc->flags = 0;
- fc = feeder_getclass(desc);
+ fc = feeder_getclass(FEEDER_RATE);
if (fc == NULL) {
device_printf(c->dev,
"%s(): can't find feeder_rate\n", __func__);
@@ -295,12 +291,10 @@ feeder_build_matrix(struct pcm_channel *c, struct feeder_chain_desc *cdesc)
return (ret);
desc = &(cdesc->desc);
- desc->type = FEEDER_MATRIX;
desc->in = 0;
desc->out = 0;
- desc->flags = 0;
- fc = feeder_getclass(desc);
+ fc = feeder_getclass(FEEDER_MATRIX);
if (fc == NULL) {
device_printf(c->dev,
"%s(): can't find feeder_matrix\n", __func__);
@@ -352,12 +346,10 @@ feeder_build_volume(struct pcm_channel *c, struct feeder_chain_desc *cdesc)
return (ret);
desc = &(cdesc->desc);
- desc->type = FEEDER_VOLUME;
desc->in = 0;
desc->out = 0;
- desc->flags = 0;
- fc = feeder_getclass(desc);
+ fc = feeder_getclass(FEEDER_VOLUME);
if (fc == NULL) {
device_printf(c->dev,
"%s(): can't find feeder_volume\n", __func__);
@@ -420,12 +412,10 @@ feeder_build_eq(struct pcm_channel *c, struct feeder_chain_desc *cdesc)
return (ret);
desc = &(cdesc->desc);
- desc->type = FEEDER_EQ;
desc->in = 0;
desc->out = 0;
- desc->flags = 0;
- fc = feeder_getclass(desc);
+ fc = feeder_getclass(FEEDER_EQ);
if (fc == NULL) {
device_printf(c->dev,
"%s(): can't find feeder_eq\n", __func__);
@@ -467,7 +457,7 @@ feeder_build_root(struct pcm_channel *c, struct feeder_chain_desc *cdesc)
struct feeder_class *fc;
int ret;
- fc = feeder_getclass(NULL);
+ fc = feeder_getclass(FEEDER_ROOT);
if (fc == NULL) {
device_printf(c->dev,
"%s(): can't find feeder_root\n", __func__);
@@ -500,12 +490,10 @@ feeder_build_mixer(struct pcm_channel *c, struct feeder_chain_desc *cdesc)
int ret;
desc = &(cdesc->desc);
- desc->type = FEEDER_MIXER;
desc->in = 0;
desc->out = 0;
- desc->flags = 0;
- fc = feeder_getclass(desc);
+ fc = feeder_getclass(FEEDER_MIXER);
if (fc == NULL) {
device_printf(c->dev,
"%s(): can't find feeder_mixer\n", __func__);
@@ -695,11 +683,11 @@ feeder_chain(struct pcm_channel *c)
cdesc.origin.rate = c->speed;
cdesc.target.afmt = hwfmt;
cdesc.target.matrix = hwmatrix;
- cdesc.target.rate = sndbuf_getspd(c->bufhard);
+ cdesc.target.rate = c->bufhard->spd;
} else {
cdesc.origin.afmt = hwfmt;
cdesc.origin.matrix = hwmatrix;
- cdesc.origin.rate = sndbuf_getspd(c->bufhard);
+ cdesc.origin.rate = c->bufhard->spd;
cdesc.target.afmt = softfmt;
cdesc.target.matrix = softmatrix;
cdesc.target.rate = c->speed;
diff --git a/sys/dev/sound/pcm/feeder_eq.c b/sys/dev/sound/pcm/feeder_eq.c
index 23e27b922486..3838328fb0bb 100644
--- a/sys/dev/sound/pcm/feeder_eq.c
+++ b/sys/dev/sound/pcm/feeder_eq.c
@@ -419,11 +419,6 @@ feed_eq_feed(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
return (dst - b);
}
-static struct pcm_feederdesc feeder_eq_desc[] = {
- { FEEDER_EQ, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0 }
-};
-
static kobj_method_t feeder_eq_methods[] = {
KOBJMETHOD(feeder_init, feed_eq_init),
KOBJMETHOD(feeder_free, feed_eq_free),
@@ -432,7 +427,7 @@ static kobj_method_t feeder_eq_methods[] = {
KOBJMETHOD_END
};
-FEEDER_DECLARE(feeder_eq, NULL);
+FEEDER_DECLARE(feeder_eq, FEEDER_EQ);
static int32_t
feed_eq_scan_preamp_arg(const char *s)
diff --git a/sys/dev/sound/pcm/feeder_format.c b/sys/dev/sound/pcm/feeder_format.c
index 0feac43374b8..d2c4d7618ab4 100644
--- a/sys/dev/sound/pcm/feeder_format.c
+++ b/sys/dev/sound/pcm/feeder_format.c
@@ -172,11 +172,6 @@ feed_format_feed(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
return (dst - b);
}
-static struct pcm_feederdesc feeder_format_desc[] = {
- { FEEDER_FORMAT, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0 }
-};
-
static kobj_method_t feeder_format_methods[] = {
KOBJMETHOD(feeder_init, feed_format_init),
KOBJMETHOD(feeder_free, feed_format_free),
@@ -185,4 +180,4 @@ static kobj_method_t feeder_format_methods[] = {
KOBJMETHOD_END
};
-FEEDER_DECLARE(feeder_format, NULL);
+FEEDER_DECLARE(feeder_format, FEEDER_FORMAT);
diff --git a/sys/dev/sound/pcm/feeder_matrix.c b/sys/dev/sound/pcm/feeder_matrix.c
index 43258a311d82..2c7a3e04690d 100644
--- a/sys/dev/sound/pcm/feeder_matrix.c
+++ b/sys/dev/sound/pcm/feeder_matrix.c
@@ -398,11 +398,6 @@ feed_matrix_feed(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
return (dst - b);
}
-static struct pcm_feederdesc feeder_matrix_desc[] = {
- { FEEDER_MATRIX, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0 }
-};
-
static kobj_method_t feeder_matrix_methods[] = {
KOBJMETHOD(feeder_init, feed_matrix_init),
KOBJMETHOD(feeder_free, feed_matrix_free),
@@ -410,7 +405,7 @@ static kobj_method_t feeder_matrix_methods[] = {
KOBJMETHOD_END
};
-FEEDER_DECLARE(feeder_matrix, NULL);
+FEEDER_DECLARE(feeder_matrix, FEEDER_MATRIX);
/* External */
int
@@ -418,7 +413,7 @@ feeder_matrix_setup(struct pcm_feeder *f, struct pcmchan_matrix *m_in,
struct pcmchan_matrix *m_out)
{
- if (f == NULL || f->desc == NULL || f->desc->type != FEEDER_MATRIX ||
+ if (f == NULL || f->desc == NULL || f->class->type != FEEDER_MATRIX ||
f->data == NULL)
return (EINVAL);
diff --git a/sys/dev/sound/pcm/feeder_mixer.c b/sys/dev/sound/pcm/feeder_mixer.c
index b6b81ad9a51c..10de42ba727a 100644
--- a/sys/dev/sound/pcm/feeder_mixer.c
+++ b/sys/dev/sound/pcm/feeder_mixer.c
@@ -145,8 +145,8 @@ feed_mixer_rec(struct pcm_channel *c)
b = c->bufsoft;
b->rp = 0;
b->rl = 0;
- cnt = sndbuf_getsize(b);
- maxfeed = SND_FXROUND(SND_FXDIV_MAX, sndbuf_getalign(b));
+ cnt = b->bufsize;
+ maxfeed = SND_FXROUND(SND_FXDIV_MAX, b->align);
do {
cnt = FEEDER_FEED(c->feeder->source, c, b->tmpbuf,
@@ -158,7 +158,7 @@ feed_mixer_rec(struct pcm_channel *c)
} while (cnt != 0);
/* Not enough data */
- if (b->rl < sndbuf_getalign(b)) {
+ if (b->rl < b->align) {
b->rl = 0;
return (0);
}
@@ -187,11 +187,11 @@ feed_mixer_rec(struct pcm_channel *c)
if (ch->flags & CHN_F_MMAP)
sndbuf_dispose(bs, NULL, sndbuf_getready(bs));
cnt = sndbuf_getfree(bs);
- if (cnt < sndbuf_getalign(bs)) {
+ if (cnt < bs->align) {
CHN_UNLOCK(ch);
continue;
}
- maxfeed = SND_FXROUND(SND_FXDIV_MAX, sndbuf_getalign(bs));
+ maxfeed = SND_FXROUND(SND_FXDIV_MAX, bs->align);
do {
cnt = FEEDER_FEED(ch->feeder, ch, bs->tmpbuf,
min(cnt, maxfeed), b);
@@ -244,7 +244,7 @@ feed_mixer_feed(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
if (c->direction == PCMDIR_REC)
return (feed_mixer_rec(c));
- sz = sndbuf_getsize(src);
+ sz = src->bufsize;
if (sz < count)
count = sz;
@@ -260,7 +260,7 @@ feed_mixer_feed(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
* list of children and calling mixer function to mix count bytes from
* each into our destination buffer, b.
*/
- tmp = sndbuf_getbuf(src);
+ tmp = src->buf;
rcnt = 0;
mcnt = 0;
passthrough = 0; /* 'passthrough' / 'exclusive' marker */
@@ -358,11 +358,6 @@ feed_mixer_feed(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
return (rcnt);
}
-static struct pcm_feederdesc feeder_mixer_desc[] = {
- { FEEDER_MIXER, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0 }
-};
-
static kobj_method_t feeder_mixer_methods[] = {
KOBJMETHOD(feeder_init, feed_mixer_init),
KOBJMETHOD(feeder_free, feed_mixer_free),
@@ -371,4 +366,4 @@ static kobj_method_t feeder_mixer_methods[] = {
KOBJMETHOD_END
};
-FEEDER_DECLARE(feeder_mixer, NULL);
+FEEDER_DECLARE(feeder_mixer, FEEDER_MIXER);
diff --git a/sys/dev/sound/pcm/feeder_rate.c b/sys/dev/sound/pcm/feeder_rate.c
index 9c29142b9d6b..c2c232a97177 100644
--- a/sys/dev/sound/pcm/feeder_rate.c
+++ b/sys/dev/sound/pcm/feeder_rate.c
@@ -1705,11 +1705,6 @@ z_resampler_feed(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
return (count - left);
}
-static struct pcm_feederdesc feeder_rate_desc[] = {
- { FEEDER_RATE, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0 },
-};
-
static kobj_method_t feeder_rate_methods[] = {
KOBJMETHOD(feeder_init, z_resampler_init),
KOBJMETHOD(feeder_free, z_resampler_free),
@@ -1719,4 +1714,4 @@ static kobj_method_t feeder_rate_methods[] = {
KOBJMETHOD_END
};
-FEEDER_DECLARE(feeder_rate, NULL);
+FEEDER_DECLARE(feeder_rate, FEEDER_RATE);
diff --git a/sys/dev/sound/pcm/feeder_volume.c b/sys/dev/sound/pcm/feeder_volume.c
index ddcbf29804f3..101cc7ba003b 100644
--- a/sys/dev/sound/pcm/feeder_volume.c
+++ b/sys/dev/sound/pcm/feeder_volume.c
@@ -306,11 +306,6 @@ feed_volume_feed(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
return (dst - b);
}
-static struct pcm_feederdesc feeder_volume_desc[] = {
- { FEEDER_VOLUME, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0 }
-};
-
static kobj_method_t feeder_volume_methods[] = {
KOBJMETHOD(feeder_init, feed_volume_init),
KOBJMETHOD(feeder_free, feed_volume_free),
@@ -319,7 +314,7 @@ static kobj_method_t feeder_volume_methods[] = {
KOBJMETHOD_END
};
-FEEDER_DECLARE(feeder_volume, NULL);
+FEEDER_DECLARE(feeder_volume, FEEDER_VOLUME);
/* Extern */
@@ -337,7 +332,7 @@ feeder_volume_apply_matrix(struct pcm_feeder *f, struct pcmchan_matrix *m)
struct feed_volume_info *info;
uint32_t i;
- if (f == NULL || f->desc == NULL || f->desc->type != FEEDER_VOLUME ||
+ if (f == NULL || f->desc == NULL || f->class->type != FEEDER_VOLUME ||
f->data == NULL || m == NULL || m->channels < SND_CHN_MIN ||
m->channels > SND_CHN_MAX)
return (EINVAL);
diff --git a/sys/dev/sound/pcm/mixer.c b/sys/dev/sound/pcm/mixer.c
index f281dff36248..adbde195c34c 100644
--- a/sys/dev/sound/pcm/mixer.c
+++ b/sys/dev/sound/pcm/mixer.c
@@ -65,11 +65,6 @@ struct snd_mixer {
char name[MIXER_NAMELEN];
struct mtx *lock;
oss_mixer_enuminfo enuminfo;
- /**
- * Counter is incremented when applications change any of this
- * mixer's controls. A change in value indicates that persistent
- * mixer applications should update their displays.
- */
int modify_counter;
};
@@ -609,14 +604,6 @@ mix_getparent(struct snd_mixer *m, u_int32_t dev)
}
u_int32_t
-mix_getchild(struct snd_mixer *m, u_int32_t dev)
-{
- if (m == NULL || dev >= SOUND_MIXER_NRDEVICES)
- return 0;
- return m->child[dev];
-}
-
-u_int32_t
mix_getdevs(struct snd_mixer *m)
{
return m->devs;
@@ -1024,14 +1011,6 @@ mix_getrecsrc(struct snd_mixer *m)
return (ret);
}
-int
-mix_get_type(struct snd_mixer *m)
-{
- KASSERT(m != NULL, ("NULL snd_mixer"));
-
- return (m->type);
-}
-
device_t
mix_get_dev(struct snd_mixer *m)
{
@@ -1490,6 +1469,11 @@ mixer_oss_mixerinfo(struct cdev *i_dev, oss_mixerinfo *mi)
mi->dev = i;
snprintf(mi->id, sizeof(mi->id), "mixer%d", i);
strlcpy(mi->name, m->name, sizeof(mi->name));
+ /**
+ * Counter is incremented when applications change any of this
+ * mixer's controls. A change in value indicates that
+ * persistent mixer applications should update their displays.
+ */
mi->modify_counter = m->modify_counter;
mi->card_number = i;
/*
@@ -1573,30 +1557,3 @@ mixer_get_lock(struct snd_mixer *m)
}
return (m->lock);
}
-
-int
-mix_get_locked(struct snd_mixer *m, u_int dev, int *pleft, int *pright)
-{
- int level;
-
- level = mixer_get(m, dev);
- if (level < 0) {
- *pright = *pleft = -1;
- return (-1);
- }
-
- *pleft = level & 0xFF;
- *pright = (level >> 8) & 0xFF;
-
- return (0);
-}
-
-int
-mix_set_locked(struct snd_mixer *m, u_int dev, int left, int right)
-{
- int level;
-
- level = (left & 0xFF) | ((right & 0xFF) << 8);
-
- return (mixer_set(m, dev, m->mutedevs, level));
-}
diff --git a/sys/dev/sound/pcm/mixer.h b/sys/dev/sound/pcm/mixer.h
index 7139a766b392..c47247ab570d 100644
--- a/sys/dev/sound/pcm/mixer.h
+++ b/sys/dev/sound/pcm/mixer.h
@@ -47,13 +47,10 @@ void mixer_hwvol_step(device_t dev, int left_step, int right_step);
int mixer_busy(struct snd_mixer *m);
-int mix_get_locked(struct snd_mixer *m, u_int dev, int *pleft, int *pright);
-int mix_set_locked(struct snd_mixer *m, u_int dev, int left, int right);
int mix_set(struct snd_mixer *m, u_int dev, u_int left, u_int right);
int mix_get(struct snd_mixer *m, u_int dev);
int mix_setrecsrc(struct snd_mixer *m, u_int32_t src);
u_int32_t mix_getrecsrc(struct snd_mixer *m);
-int mix_get_type(struct snd_mixer *m);
device_t mix_get_dev(struct snd_mixer *m);
void mix_setdevs(struct snd_mixer *m, u_int32_t v);
@@ -65,7 +62,6 @@ u_int32_t mix_getmutedevs(struct snd_mixer *m);
void mix_setparentchild(struct snd_mixer *m, u_int32_t parent, u_int32_t childs);
void mix_setrealdev(struct snd_mixer *m, u_int32_t dev, u_int32_t realdev);
u_int32_t mix_getparent(struct snd_mixer *m, u_int32_t dev);
-u_int32_t mix_getchild(struct snd_mixer *m, u_int32_t dev);
void *mix_getdevinfo(struct snd_mixer *m);
struct mtx *mixer_get_lock(struct snd_mixer *m);
diff --git a/sys/dev/sound/pcm/sndstat.c b/sys/dev/sound/pcm/sndstat.c
index 51d0fb3bb686..a7c53ac85eb8 100644
--- a/sys/dev/sound/pcm/sndstat.c
+++ b/sys/dev/sound/pcm/sndstat.c
@@ -491,29 +491,29 @@ sndstat_build_sound4_nvlist(struct snddev_info *d, nvlist_t **dip)
nvlist_add_number(cdi, SNDST_DSPS_SOUND4_CHAN_RIGHTVOL,
CHN_GETVOLUME(c, SND_VOL_C_PCM, SND_CHN_T_FR));
nvlist_add_number(cdi, SNDST_DSPS_SOUND4_CHAN_HWBUF_FORMAT,
- sndbuf_getfmt(c->bufhard));
+ c->bufhard->fmt);
nvlist_add_number(cdi, SNDST_DSPS_SOUND4_CHAN_HWBUF_RATE,
- sndbuf_getspd(c->bufhard));
+ c->bufhard->spd);
nvlist_add_number(cdi, SNDST_DSPS_SOUND4_CHAN_HWBUF_SIZE,
- sndbuf_getsize(c->bufhard));
+ c->bufhard->bufsize);
nvlist_add_number(cdi, SNDST_DSPS_SOUND4_CHAN_HWBUF_BLKSZ,
- sndbuf_getblksz(c->bufhard));
+ c->bufhard->blksz);
nvlist_add_number(cdi, SNDST_DSPS_SOUND4_CHAN_HWBUF_BLKCNT,
- sndbuf_getblkcnt(c->bufhard));
+ c->bufhard->blkcnt);
nvlist_add_number(cdi, SNDST_DSPS_SOUND4_CHAN_HWBUF_FREE,
sndbuf_getfree(c->bufhard));
nvlist_add_number(cdi, SNDST_DSPS_SOUND4_CHAN_HWBUF_READY,
sndbuf_getready(c->bufhard));
nvlist_add_number(cdi, SNDST_DSPS_SOUND4_CHAN_SWBUF_FORMAT,
- sndbuf_getfmt(c->bufsoft));
+ c->bufsoft->fmt);
nvlist_add_number(cdi, SNDST_DSPS_SOUND4_CHAN_SWBUF_RATE,
- sndbuf_getspd(c->bufsoft));
+ c->bufsoft->spd);
nvlist_add_number(cdi, SNDST_DSPS_SOUND4_CHAN_SWBUF_SIZE,
- sndbuf_getsize(c->bufsoft));
+ c->bufsoft->bufsize);
nvlist_add_number(cdi, SNDST_DSPS_SOUND4_CHAN_SWBUF_BLKSZ,
- sndbuf_getblksz(c->bufsoft));
+ c->bufsoft->blksz);
nvlist_add_number(cdi, SNDST_DSPS_SOUND4_CHAN_SWBUF_BLKCNT,
- sndbuf_getblkcnt(c->bufsoft));
+ c->bufsoft->blkcnt);
nvlist_add_number(cdi, SNDST_DSPS_SOUND4_CHAN_SWBUF_FREE,
sndbuf_getfree(c->bufsoft));
nvlist_add_number(cdi, SNDST_DSPS_SOUND4_CHAN_SWBUF_READY,
@@ -524,7 +524,8 @@ sndstat_build_sound4_nvlist(struct snddev_info *d, nvlist_t **dip)
c->parentchannel->name : "userland");
} else {
sbuf_printf(&sb, "[%s", (c->direction == PCMDIR_REC) ?
- "hardware" : "userland");
+ "hardware" :
+ ((d->flags & SD_F_PVCHANS) ? "vchans" : "userland"));
}
sbuf_printf(&sb, " -> ");
f = c->feeder;
@@ -532,12 +533,12 @@ sndstat_build_sound4_nvlist(struct snddev_info *d, nvlist_t **dip)
f = f->source;
while (f != NULL) {
sbuf_printf(&sb, "%s", f->class->name);
- if (f->desc->type == FEEDER_FORMAT) {
+ if (f->class->type == FEEDER_FORMAT) {
snd_afmt2str(f->desc->in, buf, sizeof(buf));
sbuf_printf(&sb, "(%s -> ", buf);
snd_afmt2str(f->desc->out, buf, sizeof(buf));
sbuf_printf(&sb, "%s)", buf);
- } else if (f->desc->type == FEEDER_MATRIX) {
+ } else if (f->class->type == FEEDER_MATRIX) {
sbuf_printf(&sb, "(%d.%dch -> %d.%dch)",
AFMT_CHANNEL(f->desc->in) -
AFMT_EXTCHANNEL(f->desc->in),
@@ -545,7 +546,7 @@ sndstat_build_sound4_nvlist(struct snddev_info *d, nvlist_t **dip)
AFMT_CHANNEL(f->desc->out) -
AFMT_EXTCHANNEL(f->desc->out),
AFMT_EXTCHANNEL(f->desc->out));
- } else if (f->desc->type == FEEDER_RATE) {
+ } else if (f->class->type == FEEDER_RATE) {
sbuf_printf(&sb, "(%d -> %d)",
FEEDER_GET(f, FEEDRATE_SRC),
FEEDER_GET(f, FEEDRATE_DST));
@@ -561,7 +562,8 @@ sndstat_build_sound4_nvlist(struct snddev_info *d, nvlist_t **dip)
"userland" : c->parentchannel->name);
} else {
sbuf_printf(&sb, "%s]", (c->direction == PCMDIR_REC) ?
- "userland" : "hardware");
+ ((d->flags & SD_F_RVCHANS) ? "vchans" : "userland") :
+ "hardware");
}
CHN_UNLOCK(c);
@@ -1265,14 +1267,11 @@ sndstat_prepare_pcm(struct sbuf *s, device_t dev, int verbose)
(c->parentchannel != NULL) ?
c->parentchannel->name : "", c->name);
sbuf_printf(s, "spd %d", c->speed);
- if (c->speed != sndbuf_getspd(c->bufhard)) {
- sbuf_printf(s, "/%d",
- sndbuf_getspd(c->bufhard));
- }
+ if (c->speed != c->bufhard->spd)
+ sbuf_printf(s, "/%d", c->bufhard->spd);
sbuf_printf(s, ", fmt 0x%08x", c->format);
- if (c->format != sndbuf_getfmt(c->bufhard)) {
- sbuf_printf(s, "/0x%08x",
- sndbuf_getfmt(c->bufhard));
+ if (c->format != c->bufhard->fmt) {
+ sbuf_printf(s, "/0x%08x", c->bufhard->fmt);
}
sbuf_printf(s, ", flags 0x%08x, 0x%08x",
c->flags, c->feederflags);
@@ -1291,24 +1290,24 @@ sndstat_prepare_pcm(struct sbuf *s, device_t dev, int verbose)
c->xruns, c->feedcount,
sndbuf_getfree(c->bufhard),
sndbuf_getfree(c->bufsoft),
- sndbuf_getsize(c->bufhard),
- sndbuf_getblksz(c->bufhard),
- sndbuf_getblkcnt(c->bufhard),
- sndbuf_getsize(c->bufsoft),
- sndbuf_getblksz(c->bufsoft),
- sndbuf_getblkcnt(c->bufsoft));
+ c->bufhard->bufsize,
+ c->bufhard->blksz,
+ c->bufhard->blkcnt,
+ c->bufsoft->bufsize,
+ c->bufsoft->blksz,
+ c->bufsoft->blkcnt);
} else {
sbuf_printf(s,
"underruns %d, feed %u, ready %d "
"\n\t\t[b:%d/%d/%d|bs:%d/%d/%d]",
c->xruns, c->feedcount,
sndbuf_getready(c->bufsoft),
- sndbuf_getsize(c->bufhard),
- sndbuf_getblksz(c->bufhard),
- sndbuf_getblkcnt(c->bufhard),
- sndbuf_getsize(c->bufsoft),
- sndbuf_getblksz(c->bufsoft),
- sndbuf_getblkcnt(c->bufsoft));
+ c->bufhard->bufsize,
+ c->bufhard->blksz,
+ c->bufhard->blkcnt,
+ c->bufsoft->bufsize,
+ c->bufsoft->blksz,
+ c->bufsoft->blkcnt);
}
sbuf_printf(s, "\n\t");
@@ -1320,7 +1319,8 @@ sndstat_prepare_pcm(struct sbuf *s, device_t dev, int verbose)
c->parentchannel->name : "userland");
} else {
sbuf_printf(s, "\t{%s}", (c->direction == PCMDIR_REC) ?
- "hardware" : "userland");
+ "hardware" :
+ ((d->flags & SD_F_PVCHANS) ? "vchans" : "userland"));
}
sbuf_printf(s, " -> ");
f = c->feeder;
@@ -1328,10 +1328,10 @@ sndstat_prepare_pcm(struct sbuf *s, device_t dev, int verbose)
f = f->source;
while (f != NULL) {
sbuf_printf(s, "%s", f->class->name);
- if (f->desc->type == FEEDER_FORMAT) {
+ if (f->class->type == FEEDER_FORMAT) {
sbuf_printf(s, "(0x%08x -> 0x%08x)",
f->desc->in, f->desc->out);
- } else if (f->desc->type == FEEDER_MATRIX) {
+ } else if (f->class->type == FEEDER_MATRIX) {
sbuf_printf(s, "(%d.%d -> %d.%d)",
AFMT_CHANNEL(f->desc->in) -
AFMT_EXTCHANNEL(f->desc->in),
@@ -1339,7 +1339,7 @@ sndstat_prepare_pcm(struct sbuf *s, device_t dev, int verbose)
AFMT_CHANNEL(f->desc->out) -
AFMT_EXTCHANNEL(f->desc->out),
AFMT_EXTCHANNEL(f->desc->out));
- } else if (f->desc->type == FEEDER_RATE) {
+ } else if (f->class->type == FEEDER_RATE) {
sbuf_printf(s,
"(0x%08x q:%d %d -> %d)",
f->desc->out,
@@ -1358,7 +1358,8 @@ sndstat_prepare_pcm(struct sbuf *s, device_t dev, int verbose)
"userland" : c->parentchannel->name);
} else {
sbuf_printf(s, "{%s}", (c->direction == PCMDIR_REC) ?
- "userland" : "hardware");
+ ((d->flags & SD_F_RVCHANS) ? "vchans" : "userland") :
+ "hardware");
}
CHN_UNLOCK(c);
diff --git a/sys/dev/sound/pcm/sound.h b/sys/dev/sound/pcm/sound.h
index 6bd435d0ea25..8542a96ccb14 100644
--- a/sys/dev/sound/pcm/sound.h
+++ b/sys/dev/sound/pcm/sound.h
@@ -76,10 +76,6 @@
#include <sys/mutex.h>
#include <sys/condvar.h>
-#ifndef KOBJMETHOD_END
-#define KOBJMETHOD_END { NULL, NULL }
-#endif
-
struct pcm_channel;
struct pcm_feeder;
struct snd_dbuf;
@@ -148,8 +144,6 @@ struct snd_mixer;
#define RANGE(var, low, high) (var) = \
(((var)<(low))? (low) : ((var)>(high))? (high) : (var))
-#define DSP_DEFAULT_SPEED 8000
-
extern int snd_unit;
extern int snd_verbose;
extern devclass_t pcm_devclass;
@@ -186,7 +180,6 @@ int sndstat_unregister(device_t dev);
enum {
SCF_PCM,
SCF_MIDI,
- SCF_SYNTH,
};
/*
@@ -258,108 +251,6 @@ int sound_oss_card_info(oss_card_info *);
* For PCM_[WAIT | ACQUIRE | RELEASE], be sure to surround these
* with PCM_LOCK/UNLOCK() sequence, or I'll come to gnaw upon you!
*/
-#ifdef SND_DIAGNOSTIC
-#define PCM_WAIT(x) do { \
- if (!PCM_LOCKOWNED(x)) \
- panic("%s(%d): [PCM WAIT] Mutex not owned!", \
- __func__, __LINE__); \
- while ((x)->flags & SD_F_BUSY) { \
- if (snd_verbose > 3) \
- device_printf((x)->dev, \
- "%s(%d): [PCM WAIT] calling cv_wait().\n", \
- __func__, __LINE__); \
- cv_wait(&(x)->cv, (x)->lock); \
- } \
-} while (0)
-
-#define PCM_ACQUIRE(x) do { \
- if (!PCM_LOCKOWNED(x)) \
- panic("%s(%d): [PCM ACQUIRE] Mutex not owned!", \
- __func__, __LINE__); \
- if ((x)->flags & SD_F_BUSY) \
- panic("%s(%d): [PCM ACQUIRE] " \
- "Trying to acquire BUSY cv!", __func__, __LINE__); \
- (x)->flags |= SD_F_BUSY; \
-} while (0)
-
-#define PCM_RELEASE(x) do { \
- if (!PCM_LOCKOWNED(x)) \
- panic("%s(%d): [PCM RELEASE] Mutex not owned!", \
- __func__, __LINE__); \
- if ((x)->flags & SD_F_BUSY) { \
- (x)->flags &= ~SD_F_BUSY; \
- cv_broadcast(&(x)->cv); \
- } else \
- panic("%s(%d): [PCM RELEASE] Releasing non-BUSY cv!", \
- __func__, __LINE__); \
-} while (0)
-
-/* Quick version, for shorter path. */
-#define PCM_ACQUIRE_QUICK(x) do { \
- if (PCM_LOCKOWNED(x)) \
- panic("%s(%d): [PCM ACQUIRE QUICK] Mutex owned!", \
- __func__, __LINE__); \
- PCM_LOCK(x); \
- PCM_WAIT(x); \
- PCM_ACQUIRE(x); \
- PCM_UNLOCK(x); \
-} while (0)
-
-#define PCM_RELEASE_QUICK(x) do { \
- if (PCM_LOCKOWNED(x)) \
- panic("%s(%d): [PCM RELEASE QUICK] Mutex owned!", \
- __func__, __LINE__); \
- PCM_LOCK(x); \
- PCM_RELEASE(x); \
- PCM_UNLOCK(x); \
-} while (0)
-
-#define PCM_BUSYASSERT(x) do { \
- if (!((x) != NULL && ((x)->flags & SD_F_BUSY))) \
- panic("%s(%d): [PCM BUSYASSERT] " \
- "Failed, snddev_info=%p", __func__, __LINE__, x); \
-} while (0)
-
-#define PCM_GIANT_ENTER(x) do { \
- int _pcm_giant = 0; \
- if (PCM_LOCKOWNED(x)) \
- panic("%s(%d): [GIANT ENTER] PCM lock owned!", \
- __func__, __LINE__); \
- if (mtx_owned(&Giant) != 0 && snd_verbose > 3) \
- device_printf((x)->dev, \
- "%s(%d): [GIANT ENTER] Giant owned!\n", \
- __func__, __LINE__); \
- if (!((x)->flags & SD_F_MPSAFE) && mtx_owned(&Giant) == 0) \
- do { \
- mtx_lock(&Giant); \
- _pcm_giant = 1; \
- } while (0)
-
-#define PCM_GIANT_EXIT(x) do { \
- if (PCM_LOCKOWNED(x)) \
- panic("%s(%d): [GIANT EXIT] PCM lock owned!", \
- __func__, __LINE__); \
- if (!(_pcm_giant == 0 || _pcm_giant == 1)) \
- panic("%s(%d): [GIANT EXIT] _pcm_giant screwed!", \
- __func__, __LINE__); \
- if ((x)->flags & SD_F_MPSAFE) { \
- if (_pcm_giant == 1) \
- panic("%s(%d): [GIANT EXIT] MPSAFE Giant?", \
- __func__, __LINE__); \
- if (mtx_owned(&Giant) != 0 && snd_verbose > 3) \
- device_printf((x)->dev, \
- "%s(%d): [GIANT EXIT] Giant owned!\n", \
- __func__, __LINE__); \
- } \
- if (_pcm_giant != 0) { \
- if (mtx_owned(&Giant) == 0) \
- panic("%s(%d): [GIANT EXIT] Giant not owned!", \
- __func__, __LINE__); \
- _pcm_giant = 0; \
- mtx_unlock(&Giant); \
- } \
-} while (0)
-#else /* !SND_DIAGNOSTIC */
#define PCM_WAIT(x) do { \
PCM_LOCKASSERT(x); \
while ((x)->flags & SD_F_BUSY) \
@@ -429,7 +320,6 @@ int sound_oss_card_info(oss_card_info *);
mtx_unlock(&Giant); \
} \
} while (0)
-#endif /* SND_DIAGNOSTIC */
#define PCM_GIANT_LEAVE(x) \
PCM_GIANT_EXIT(x); \
diff --git a/sys/dev/sound/pcm/vchan.c b/sys/dev/sound/pcm/vchan.c
index 31a4f7db8d70..b31e28d51453 100644
--- a/sys/dev/sound/pcm/vchan.c
+++ b/sys/dev/sound/pcm/vchan.c
@@ -492,7 +492,7 @@ sysctl_dev_pcm_vchanrate(SYSCTL_HANDLER_ARGS)
}
}
}
- *vchanrate = sndbuf_getspd(c->bufsoft);
+ *vchanrate = c->bufsoft->spd;
CHN_UNLOCK(c);
}
@@ -591,7 +591,7 @@ sysctl_dev_pcm_vchanformat(SYSCTL_HANDLER_ARGS)
}
}
}
- *vchanformat = sndbuf_getfmt(c->bufsoft);
+ *vchanformat = c->bufsoft->fmt;
CHN_UNLOCK(c);
}
diff --git a/sys/dev/sound/pcm/vchan.h b/sys/dev/sound/pcm/vchan.h
index 8c1de9496ef3..65b0218781fb 100644
--- a/sys/dev/sound/pcm/vchan.h
+++ b/sys/dev/sound/pcm/vchan.h
@@ -48,8 +48,8 @@ int vchan_sync(struct pcm_channel *);
#define VCHAN_SYNC_REQUIRED(c) \
(((c)->flags & CHN_F_VIRTUAL) && (((c)->flags & CHN_F_DIRTY) || \
- sndbuf_getfmt((c)->bufhard) != (c)->parentchannel->format || \
- sndbuf_getspd((c)->bufhard) != (c)->parentchannel->speed))
+ (c)->bufhard->fmt != (c)->parentchannel->format || \
+ (c)->bufhard->spd != (c)->parentchannel->speed))
void vchan_initsys(device_t);