summaryrefslogtreecommitdiffstats
path: root/sys/dev/sound/pcm/sound.c
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>2004-01-17 10:37:11 +0000
committerphk <phk@FreeBSD.org>2004-01-17 10:37:11 +0000
commit756ba78a920fb35b9c7d4d2bbdc0422e55f17673 (patch)
tree25148bfa1e9a15eb76a843b1a772991f476fbe79 /sys/dev/sound/pcm/sound.c
parent0bdb9e022017015ce285eea59bf776562406559b (diff)
downloadFreeBSD-src-756ba78a920fb35b9c7d4d2bbdc0422e55f17673.zip
FreeBSD-src-756ba78a920fb35b9c7d4d2bbdc0422e55f17673.tar.gz
As previously announced: discontinue use of makedev() call in soundcode.
This takes us a lot closer to refcounting dev_t. This patch originally by cg@ with a few minor changes by me. It is largely untested, but has been HEADSUP'ed twice, so presumably people have not found any issues with it. Submitted by: cg@
Diffstat (limited to 'sys/dev/sound/pcm/sound.c')
-rw-r--r--sys/dev/sound/pcm/sound.c112
1 files changed, 87 insertions, 25 deletions
diff --git a/sys/dev/sound/pcm/sound.c b/sys/dev/sound/pcm/sound.c
index ecf8b8d..652fb7a 100644
--- a/sys/dev/sound/pcm/sound.c
+++ b/sys/dev/sound/pcm/sound.c
@@ -33,28 +33,6 @@
SND_DECLARE_FILE("$FreeBSD$");
-#ifndef PCM_DEBUG_MTX
-struct snddev_channel {
- SLIST_ENTRY(snddev_channel) link;
- struct pcm_channel *channel;
-};
-
-struct snddev_info {
- SLIST_HEAD(, snddev_channel) channels;
- struct pcm_channel *fakechan;
- unsigned devcount, playcount, reccount, vchancount;
- unsigned flags;
- int inprog;
- unsigned int bufsz;
- void *devinfo;
- device_t dev;
- char status[SND_STATUSLEN];
- struct sysctl_ctx_list sysctl_tree;
- struct sysctl_oid *sysctl_tree_top;
- struct mtx *lock;
-};
-#endif
-
devclass_t pcm_devclass;
int pcm_veto_load = 1;
@@ -475,6 +453,7 @@ pcm_chn_remove(struct snddev_info *d, struct pcm_channel *ch, int rmdev)
{
struct snddev_channel *sce;
int unit = device_get_unit(d->dev);
+#if 0
int ourlock;
ourlock = 0;
@@ -482,13 +461,16 @@ pcm_chn_remove(struct snddev_info *d, struct pcm_channel *ch, int rmdev)
snd_mtxlock(d->lock);
ourlock = 1;
}
+#endif
SLIST_FOREACH(sce, &d->channels, link) {
if (sce->channel == ch)
goto gotit;
}
+#if 0
if (ourlock)
snd_mtxunlock(d->lock);
+#endif
return EINVAL;
gotit:
SLIST_REMOVE(&d->channels, sce, snddev_channel, link);
@@ -505,8 +487,10 @@ gotit:
else
d->playcount--;
+#if 0
if (ourlock)
snd_mtxunlock(d->lock);
+#endif
free(sce, M_DEVBUF);
return 0;
@@ -554,9 +538,7 @@ pcm_killchan(device_t dev)
struct pcm_channel *ch;
int error = 0;
- snd_mtxlock(d->lock);
sce = SLIST_FIRST(&d->channels);
- snd_mtxunlock(d->lock);
ch = sce->channel;
error = pcm_chn_remove(d, sce->channel, SLIST_EMPTY(&ch->children));
@@ -652,6 +634,9 @@ pcm_register(device_t dev, void *devinfo, int numplay, int numrec)
d->vchancount = 0;
d->inprog = 0;
+ SLIST_INIT(&d->channels);
+ SLIST_INIT(&d->channels);
+
if (((numplay == 0) || (numrec == 0)) && (numplay != numrec))
d->flags |= SD_F_SIMPLEX;
@@ -725,10 +710,87 @@ pcm_unregister(device_t dev)
fkchan_kill(d->fakechan);
sndstat_unregister(dev);
+ snd_mtxunlock(d->lock);
snd_mtxfree(d->lock);
return 0;
}
+int
+pcm_regdevt(dev_t dev, unsigned unit, unsigned type, unsigned channel)
+{
+ struct snddev_info *d;
+ struct snddev_devt *dt;
+
+ d = devclass_get_softc(pcm_devclass, unit);
+ KASSERT((d != NULL), ("bad d"));
+ KASSERT((dev != NULL), ("bad dev"));
+
+ dt = malloc(sizeof(*dt), M_DEVBUF, M_ZERO | M_WAITOK);
+ if (dt == NULL)
+ return ENOMEM;
+ dt->dev = dev;
+ dt->type = type;
+ dt->channel = channel;
+
+ snd_mtxlock(d->lock);
+ SLIST_INSERT_HEAD(&d->devs, dt, link);
+ snd_mtxunlock(d->lock);
+
+ return 0;
+}
+
+dev_t
+pcm_getdevt(unsigned unit, unsigned type, unsigned channel)
+{
+ struct snddev_info *d;
+ struct snddev_devt *dt;
+
+ d = devclass_get_softc(pcm_devclass, unit);
+ KASSERT((d != NULL), ("bad d"));
+
+#if 0
+ snd_mtxlock(d->lock);
+#endif
+ SLIST_FOREACH(dt, &d->devs, link) {
+ if ((dt->type == type) && (dt->channel == channel))
+ return dt->dev;
+ }
+#if 0
+ snd_mtxunlock(d->lock);
+#endif
+
+ return NULL;
+}
+
+int
+pcm_unregdevt(unsigned unit, unsigned type, unsigned channel)
+{
+ struct snddev_info *d;
+ struct snddev_devt *dt;
+
+ d = devclass_get_softc(pcm_devclass, unit);
+ KASSERT((d != NULL), ("bad d"));
+
+#if 0
+ snd_mtxlock(d->lock);
+#endif
+ SLIST_FOREACH(dt, &d->devs, link) {
+ if ((dt->type == type) && (dt->channel == channel)) {
+ SLIST_REMOVE(&d->devs, dt, snddev_devt, link);
+ free(dt, M_DEVBUF);
+#if 0
+ snd_mtxunlock(d->lock);
+#endif
+ return 0;
+ }
+ }
+#if 0
+ snd_mtxunlock(d->lock);
+#endif
+
+ return ENOENT;
+}
+
/************************************************************************/
static int
@@ -778,7 +840,7 @@ sndstat_prepare_pcm(struct sbuf *s, device_t dev, int verbose)
c = sce->channel;
sbuf_printf(s, "\n\t");
- /* it would be bettet to indent child channels */
+ /* it would be better to indent child channels */
sbuf_printf(s, "%s[%s]: ", c->parentchannel? c->parentchannel->name : "", c->name);
sbuf_printf(s, "spd %d", c->speed);
if (c->speed != sndbuf_getspd(c->bufhard))
OpenPOWER on IntegriCloud