summaryrefslogtreecommitdiffstats
path: root/sys/dev/sound/pcm/sound.c
diff options
context:
space:
mode:
authormatk <matk@FreeBSD.org>2004-01-20 03:58:57 +0000
committermatk <matk@FreeBSD.org>2004-01-20 03:58:57 +0000
commitebfd4faca3b4486d6e438fc39dacd968ecf9a8cc (patch)
treeeb0f190890fc8154dc34ccf943d093f9426e4057 /sys/dev/sound/pcm/sound.c
parent1bf3c3e6434fdf234bfa5471a146508c48e6f7f4 (diff)
downloadFreeBSD-src-ebfd4faca3b4486d6e438fc39dacd968ecf9a8cc.zip
FreeBSD-src-ebfd4faca3b4486d6e438fc39dacd968ecf9a8cc.tar.gz
Fix a panic when kldloading a sound driver. Do this by replacing the
link-list of dev_t's with named variables. Remove used code. Approved by: tanimura (mentor)
Diffstat (limited to 'sys/dev/sound/pcm/sound.c')
-rw-r--r--sys/dev/sound/pcm/sound.c144
1 files changed, 48 insertions, 96 deletions
diff --git a/sys/dev/sound/pcm/sound.c b/sys/dev/sound/pcm/sound.c
index 652fb7a..3ba4636 100644
--- a/sys/dev/sound/pcm/sound.c
+++ b/sys/dev/sound/pcm/sound.c
@@ -27,6 +27,7 @@
#include <dev/sound/pcm/sound.h>
#include <dev/sound/pcm/vchan.h>
+#include <dev/sound/pcm/dsp.h>
#include <sys/sysctl.h>
#include "feeder_if.h"
@@ -413,11 +414,20 @@ pcm_chn_destroy(struct pcm_channel *ch)
}
int
-pcm_chn_add(struct snddev_info *d, struct pcm_channel *ch, int mkdev)
+pcm_chn_add(struct snddev_info *d, struct pcm_channel *ch)
{
struct snddev_channel *sce, *tmp, *after;
- int unit = device_get_unit(d->dev);
- int x = -1;
+ int device = device_get_unit(d->dev);
+
+ /*
+ * Note it's confusing nomenclature.
+ * dev_t
+ * device -> pcm_device
+ * unit -> pcm_channel
+ * channel -> snddev_channel
+ * device_t
+ * unit -> pcm_device
+ */
sce = malloc(sizeof(*sce), M_DEVBUF, M_WAITOK | M_ZERO);
if (!sce) {
@@ -426,6 +436,7 @@ pcm_chn_add(struct snddev_info *d, struct pcm_channel *ch, int mkdev)
snd_mtxlock(d->lock);
sce->channel = ch;
+ sce->chan_num= d->devcount++;
if (SLIST_EMPTY(&d->channels)) {
SLIST_INSERT_HEAD(&d->channels, sce, link);
} else {
@@ -435,24 +446,35 @@ pcm_chn_add(struct snddev_info *d, struct pcm_channel *ch, int mkdev)
}
SLIST_INSERT_AFTER(after, sce, link);
}
- if (mkdev)
- x = d->devcount++;
snd_mtxunlock(d->lock);
-
- if (mkdev) {
- dsp_register(unit, x);
- if (ch->direction == PCMDIR_REC)
- dsp_registerrec(unit, ch->num);
- }
+ sce->dsp_devt= make_dev(&dsp_cdevsw,
+ PCMMKMINOR(device, SND_DEV_DSP, sce->chan_num),
+ UID_ROOT, GID_WHEEL, 0666, "dsp%d.%d",
+ device, sce->chan_num);
+
+ sce->dspW_devt= make_dev(&dsp_cdevsw,
+ PCMMKMINOR(device, SND_DEV_DSP16, sce->chan_num),
+ UID_ROOT, GID_WHEEL, 0666, "dspW%d.%d",
+ device, sce->chan_num);
+
+ sce->audio_devt= make_dev(&dsp_cdevsw,
+ PCMMKMINOR(device, SND_DEV_AUDIO, sce->chan_num),
+ UID_ROOT, GID_WHEEL, 0666, "audio%d.%d",
+ device, sce->chan_num);
+
+ if (ch->direction == PCMDIR_REC)
+ sce->dspr_devt = make_dev(&dsp_cdevsw,
+ PCMMKMINOR(device, SND_DEV_DSPREC,
+ sce->chan_num), UID_ROOT, GID_WHEEL,
+ 0666, "dspr%d.%d", device, sce->chan_num);
return 0;
}
int
-pcm_chn_remove(struct snddev_info *d, struct pcm_channel *ch, int rmdev)
+pcm_chn_remove(struct snddev_info *d, struct pcm_channel *ch)
{
struct snddev_channel *sce;
- int unit = device_get_unit(d->dev);
#if 0
int ourlock;
@@ -474,11 +496,6 @@ pcm_chn_remove(struct snddev_info *d, struct pcm_channel *ch, int rmdev)
return EINVAL;
gotit:
SLIST_REMOVE(&d->channels, sce, snddev_channel, link);
- if (rmdev) {
- dsp_unregister(unit, --d->devcount);
- if (ch->direction == PCMDIR_REC)
- dsp_unregisterrec(unit, ch->num);
- }
if (ch->direction == PCMDIR_REC)
d->reccount--;
@@ -509,7 +526,7 @@ pcm_addchan(device_t dev, int dir, kobj_class_t cls, void *devinfo)
return ENODEV;
}
- err = pcm_chn_add(d, ch, 1);
+ err = pcm_chn_add(d, ch);
if (err) {
device_printf(d->dev, "pcm_chn_add(%s) failed, err=%d\n", ch->name, err);
snd_mtxunlock(d->lock);
@@ -541,7 +558,7 @@ pcm_killchan(device_t dev)
sce = SLIST_FIRST(&d->channels);
ch = sce->channel;
- error = pcm_chn_remove(d, sce->channel, SLIST_EMPTY(&ch->children));
+ error = pcm_chn_remove(d, sce->channel);
if (error)
return (error);
return (pcm_chn_destroy(ch));
@@ -685,6 +702,8 @@ pcm_unregister(device_t dev)
snd_mtxunlock(d->lock);
return EBUSY;
}
+
+
SLIST_FOREACH(sce, &d->channels, link) {
ch = sce->channel;
if (ch->refcount > 0) {
@@ -693,6 +712,15 @@ pcm_unregister(device_t dev)
return EBUSY;
}
}
+
+ SLIST_FOREACH(sce, &d->channels, link) {
+ destroy_dev(sce->dsp_devt);
+ destroy_dev(sce->dspW_devt);
+ destroy_dev(sce->audio_devt);
+ if (sce->dspr_devt)
+ destroy_dev(sce->dspr_devt);
+ }
+
if (mixer_uninit(dev)) {
device_printf(dev, "unregister: mixer busy\n");
snd_mtxunlock(d->lock);
@@ -715,82 +743,6 @@ pcm_unregister(device_t dev)
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
OpenPOWER on IntegriCloud