summaryrefslogtreecommitdiffstats
path: root/sys/dev/sound/pcm/vchan.c
diff options
context:
space:
mode:
authorcg <cg@FreeBSD.org>2001-06-27 19:59:45 +0000
committercg <cg@FreeBSD.org>2001-06-27 19:59:45 +0000
commite47dc3a01ad0ecf8ea64deb1584aa18b93b5e335 (patch)
treec9bac9f9f4b0ae142d512a208a6f4e48252f6053 /sys/dev/sound/pcm/vchan.c
parentb60e83c2e101de07dfdea7984cf365a8684ac1ee (diff)
downloadFreeBSD-src-e47dc3a01ad0ecf8ea64deb1584aa18b93b5e335.zip
FreeBSD-src-e47dc3a01ad0ecf8ea64deb1584aa18b93b5e335.tar.gz
don't flag the playback hardchan as busy on devices with only one of them.
if a device has vchans already but they are all busy, allocate another one at open() time, up to a maximum of hw.snd.maxvchans. when creating/destroying vchans, don't make/remove a devnode for the first/last one as it replaces a hardchan.
Diffstat (limited to 'sys/dev/sound/pcm/vchan.c')
-rw-r--r--sys/dev/sound/pcm/vchan.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/sys/dev/sound/pcm/vchan.c b/sys/dev/sound/pcm/vchan.c
index 25e48c1..7a8d41d 100644
--- a/sys/dev/sound/pcm/vchan.c
+++ b/sys/dev/sound/pcm/vchan.c
@@ -263,7 +263,7 @@ vchan_create(struct pcm_channel *parent)
CHN_UNLOCK(parent);
/* add us to our grandparent's channel list */
- err = pcm_chn_add(d, child);
+ err = pcm_chn_add(d, child, !first);
if (err) {
pcm_chn_destroy(child);
free(pce, M_DEVBUF);
@@ -288,12 +288,7 @@ vchan_destroy(struct pcm_channel *c)
struct pcm_channel *parent = c->parentchannel;
struct snddev_info *d = parent->parentsnddev;
struct pcmchan_children *pce;
- int err;
-
- /* remove us from our grantparent's channel list */
- err = pcm_chn_remove(d, c);
- if (err)
- return err;
+ int err, last;
CHN_LOCK(parent);
if (!(parent->flags & CHN_F_BUSY)) {
@@ -316,8 +311,15 @@ gotch:
SLIST_REMOVE(&parent->children, pce, pcmchan_children, link);
free(pce, M_DEVBUF);
- if (SLIST_EMPTY(&parent->children))
+ last = SLIST_EMPTY(&parent->children);
+ if (last)
parent->flags &= ~CHN_F_BUSY;
+
+ /* remove us from our grantparent's channel list */
+ err = pcm_chn_remove(d, c, !last);
+ if (err)
+ return err;
+
CHN_UNLOCK(parent);
/* destroy ourselves */
err = pcm_chn_destroy(c);
OpenPOWER on IntegriCloud