summaryrefslogtreecommitdiffstats
path: root/sys/dev/sound/pcm/channel.c
diff options
context:
space:
mode:
authorcg <cg@FreeBSD.org>2001-06-07 20:06:22 +0000
committercg <cg@FreeBSD.org>2001-06-07 20:06:22 +0000
commit88b6f276b2af09b2d63d82cd4e0535912a9141db (patch)
treeb656cff6fee0e17ae9ae6dba0d20452357cf9e8e /sys/dev/sound/pcm/channel.c
parentd6ce76b54bfd8517c26a090adf004c0728713bda (diff)
downloadFreeBSD-src-88b6f276b2af09b2d63d82cd4e0535912a9141db.zip
FreeBSD-src-88b6f276b2af09b2d63d82cd4e0535912a9141db.tar.gz
lock sound device when adding/removing channels
implement setblocksize for vchans don't panic when doing certain ioctls or aborting on a vchan xmms now works with vchans
Diffstat (limited to 'sys/dev/sound/pcm/channel.c')
-rw-r--r--sys/dev/sound/pcm/channel.c24
1 files changed, 17 insertions, 7 deletions
diff --git a/sys/dev/sound/pcm/channel.c b/sys/dev/sound/pcm/channel.c
index 727c509..72f2852 100644
--- a/sys/dev/sound/pcm/channel.c
+++ b/sys/dev/sound/pcm/channel.c
@@ -156,7 +156,7 @@ chn_wrupdate(struct pcm_channel *c)
CHN_LOCKASSERT(c);
KASSERT(c->direction == PCMDIR_PLAY, ("chn_wrupdate on bad channel"));
- if ((c->flags & CHN_F_MAPPED) || !(c->flags & CHN_F_TRIGGERED))
+ if ((c->flags & (CHN_F_MAPPED | CHN_F_VIRTUAL)) || !(c->flags & CHN_F_TRIGGERED))
return;
chn_dmaupdate(c);
ret = chn_wrfeed(c);
@@ -533,7 +533,8 @@ chn_abort(struct pcm_channel *c)
/* kill the channel */
chn_trigger(c, PCMTRIG_ABORT);
sndbuf_setrun(b, 0);
- chn_dmaupdate(c);
+ if (!(c->flags & CHN_F_VIRTUAL))
+ chn_dmaupdate(c);
missing = sndbuf_getready(bs) + sndbuf_getready(b);
c->flags &= ~CHN_F_ABORTING;
@@ -1056,10 +1057,19 @@ chn_notify(struct pcm_channel *c, u_int32_t flags)
{
struct pcmchan_children *pce;
struct pcm_channel *child;
+ int run;
if (SLIST_EMPTY(&c->children))
return ENODEV;
+ run = (c->flags & CHN_F_TRIGGERED)? 1 : 0;
+ /*
+ * if the hwchan is running, we can't change its rate, format or
+ * blocksize
+ */
+ if (run)
+ flags &= CHN_N_VOLUME | CHN_N_TRIGGER;
+
if (flags & CHN_N_RATE) {
/*
* we could do something here, like scan children and decide on
@@ -1092,21 +1102,21 @@ chn_notify(struct pcm_channel *c, u_int32_t flags)
chn_setblocksize(c, 2, blksz);
}
if (flags & CHN_N_TRIGGER) {
- int run;
+ int nrun;
/*
* scan the children, and figure out if any are running
* if so, we need to be running, otherwise we need to be stopped
* if we aren't in our target sstate, move to it
*/
- run = 0;
+ nrun = 0;
SLIST_FOREACH(pce, &c->children, link) {
child = pce->channel;
if (child->flags & CHN_F_TRIGGERED)
- run = 1;
+ nrun = 1;
}
- if (run && !(c->flags & CHN_F_TRIGGERED))
+ if (nrun && !run)
chn_start(c, 1);
- if (!run && (c->flags & CHN_F_TRIGGERED))
+ if (!nrun && run)
chn_abort(c);
}
return 0;
OpenPOWER on IntegriCloud