summaryrefslogtreecommitdiff
path: root/sys/dev/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/sound')
-rw-r--r--sys/dev/sound/pci/neomagic-coeff.h2
-rw-r--r--sys/dev/sound/pcm/dsp.c75
-rw-r--r--sys/dev/sound/pcm/mixer.c19
-rw-r--r--sys/dev/sound/pcm/sound.c112
-rw-r--r--sys/dev/sound/pcm/sound.h17
-rw-r--r--sys/dev/sound/pcm/vchan.c2
6 files changed, 171 insertions, 56 deletions
diff --git a/sys/dev/sound/pci/neomagic-coeff.h b/sys/dev/sound/pci/neomagic-coeff.h
index 345598c148c8a..f6cdecfd2f02e 100644
--- a/sys/dev/sound/pci/neomagic-coeff.h
+++ b/sys/dev/sound/pci/neomagic-coeff.h
@@ -30,7 +30,7 @@
#define NM_TOTAL_COEFF_COUNT 0x3158
-static char coefficients[NM_TOTAL_COEFF_COUNT * 4] = {
+static u_char coefficients[NM_TOTAL_COEFF_COUNT * 4] = {
0xFF, 0xFF, 0x2F, 0x00, 0x4B, 0xFF, 0xA5, 0x01, 0xEF, 0xFC, 0x21,
0x05, 0x87, 0xF7, 0x62, 0x11, 0xE9, 0x45, 0x5E, 0xF9, 0xB5, 0x01,
0xDE, 0xFF, 0xA4, 0xFF, 0x60, 0x00, 0xCA, 0xFF, 0x0D, 0x00, 0xFD,
diff --git a/sys/dev/sound/pcm/dsp.c b/sys/dev/sound/pcm/dsp.c
index 9fde9750448f0..c6ab830cf4060 100644
--- a/sys/dev/sound/pcm/dsp.c
+++ b/sys/dev/sound/pcm/dsp.c
@@ -455,15 +455,11 @@ dsp_ioctl(dev_t i_dev, u_long cmd, caddr_t arg, int mode, struct thread *td)
* on dsp devices.
*/
- if (IOCGROUP(cmd) == 'M') {
- dev_t pdev;
-
- pdev = makedev(SND_CDEV_MAJOR, PCMMKMINOR(PCMUNIT(i_dev), SND_DEV_CTL, 0));
- return mixer_ioctl(pdev, cmd, arg, mode, td);
- }
+ d = dsp_get_info(i_dev);
+ if (IOCGROUP(cmd) == 'M')
+ return mixer_ioctl(d->mixer_dev, cmd, arg, mode, td);
s = spltty();
- d = dsp_get_info(i_dev);
getchns(i_dev, &rdch, &wrch, 0);
kill = 0;
@@ -580,7 +576,7 @@ dsp_ioctl(dev_t i_dev, u_long cmd, caddr_t arg, int mode, struct thread *td)
(wrch? chn_getformats(wrch) : 0xffffffff);
if (rdch && wrch)
p->formats |= (dsp_get_flags(i_dev) & SD_F_SIMPLEX)? 0 : AFMT_FULLDUPLEX;
- pdev = makedev(SND_CDEV_MAJOR, PCMMKMINOR(PCMUNIT(i_dev), SND_DEV_CTL, 0));
+ pdev = d->mixer_dev;
p->mixers = 1; /* default: one mixer */
p->inputs = pdev->si_drv1? mix_getdevs(pdev->si_drv1) : 0;
p->left = p->right = 100;
@@ -1051,12 +1047,26 @@ dsp_mmap(dev_t i_dev, vm_offset_t offset, vm_paddr_t *paddr, int nprot)
int
dsp_register(int unit, int channel)
{
- make_dev(&dsp_cdevsw, PCMMKMINOR(unit, SND_DEV_DSP, channel),
+ dev_t dt;
+ int r;
+
+ dt = make_dev(&dsp_cdevsw, PCMMKMINOR(unit, SND_DEV_DSP, channel),
UID_ROOT, GID_WHEEL, 0666, "dsp%d.%d", unit, channel);
- make_dev(&dsp_cdevsw, PCMMKMINOR(unit, SND_DEV_DSP16, channel),
+ r = pcm_regdevt(dt, unit, SND_DEV_DSP, channel);
+ if (r)
+ return r;
+
+ dt = make_dev(&dsp_cdevsw, PCMMKMINOR(unit, SND_DEV_DSP16, channel),
UID_ROOT, GID_WHEEL, 0666, "dspW%d.%d", unit, channel);
- make_dev(&dsp_cdevsw, PCMMKMINOR(unit, SND_DEV_AUDIO, channel),
+ r = pcm_regdevt(dt, unit, SND_DEV_DSP16, channel);
+ if (r)
+ return r;
+
+ dt = make_dev(&dsp_cdevsw, PCMMKMINOR(unit, SND_DEV_AUDIO, channel),
UID_ROOT, GID_WHEEL, 0666, "audio%d.%d", unit, channel);
+ r = pcm_regdevt(dt, unit, SND_DEV_AUDIO, channel);
+ if (r)
+ return r;
return 0;
}
@@ -1064,23 +1074,46 @@ dsp_register(int unit, int channel)
int
dsp_registerrec(int unit, int channel)
{
- make_dev(&dsp_cdevsw, PCMMKMINOR(unit, SND_DEV_DSPREC, channel),
+ dev_t dt;
+ int r;
+
+ dt = make_dev(&dsp_cdevsw, PCMMKMINOR(unit, SND_DEV_DSPREC, channel),
UID_ROOT, GID_WHEEL, 0666, "dspr%d.%d", unit, channel);
- return 0;
+ r = pcm_regdevt(dt, unit, SND_DEV_DSPREC, channel);
+
+ return r;
}
int
dsp_unregister(int unit, int channel)
{
dev_t pdev;
+ int r;
- pdev = makedev(SND_CDEV_MAJOR, PCMMKMINOR(unit, SND_DEV_DSP, channel));
+ pdev = pcm_getdevt(unit, SND_DEV_DSP, channel);
+ if (pdev == NULL)
+ return ENOENT;
destroy_dev(pdev);
- pdev = makedev(SND_CDEV_MAJOR, PCMMKMINOR(unit, SND_DEV_DSP16, channel));
+ r = pcm_unregdevt(unit, SND_DEV_DSP, channel);
+ if (r)
+ return r;
+
+ pdev = pcm_getdevt(unit, SND_DEV_DSP16, channel);
+ if (pdev == NULL)
+ return ENOENT;
destroy_dev(pdev);
- pdev = makedev(SND_CDEV_MAJOR, PCMMKMINOR(unit, SND_DEV_AUDIO, channel));
+ r = pcm_unregdevt(unit, SND_DEV_DSP16, channel);
+ if (r)
+ return r;
+
+ pdev = pcm_getdevt(unit, SND_DEV_AUDIO, channel);
+ if (pdev == NULL)
+ return ENOENT;
destroy_dev(pdev);
+ r = pcm_unregdevt(unit, SND_DEV_AUDIO, channel);
+ if (r)
+ return r;
return 0;
}
@@ -1089,11 +1122,15 @@ int
dsp_unregisterrec(int unit, int channel)
{
dev_t pdev;
+ int r;
- pdev = makedev(SND_CDEV_MAJOR, PCMMKMINOR(unit, SND_DEV_DSPREC, channel));
+ pdev = pcm_getdevt(unit, SND_DEV_DSPREC, channel);
+ if (pdev == NULL)
+ return ENOENT;
destroy_dev(pdev);
+ r = pcm_unregdevt(unit, SND_DEV_DSPREC, channel);
- return 0;
+ return r;
}
#ifdef USING_DEVFS
@@ -1126,7 +1163,7 @@ dsp_clone(void *arg, char *name, int namelen, dev_t *dev)
cont = 1;
for (i = 0; cont; i++) {
- pdev = makedev(SND_CDEV_MAJOR, PCMMKMINOR(unit, devtype, i));
+ pdev = pcm_getdevt(unit, devtype, i);
if (pdev->si_flags & SI_NAMED) {
if ((pdev->si_drv1 == NULL) && (pdev->si_drv2 == NULL)) {
*dev = pdev;
diff --git a/sys/dev/sound/pcm/mixer.c b/sys/dev/sound/pcm/mixer.c
index 1c89bb99ccd9b..61d6c09003f64 100644
--- a/sys/dev/sound/pcm/mixer.c
+++ b/sys/dev/sound/pcm/mixer.c
@@ -87,13 +87,11 @@ static eventhandler_tag mixer_ehtag;
static dev_t
mixer_get_devt(device_t dev)
{
- dev_t pdev;
- int unit;
+ struct snddev_info *snddev;
- unit = device_get_unit(dev);
- pdev = makedev(SND_CDEV_MAJOR, PCMMKMINOR(unit, SND_DEV_CTL, 0));
+ snddev = device_get_softc(dev);
- return pdev;
+ return snddev->mixer_dev;
}
#ifdef SND_DYNSYSCTL
@@ -187,6 +185,7 @@ mix_getdevinfo(struct snd_mixer *m)
int
mixer_init(device_t dev, kobj_class_t cls, void *devinfo)
{
+ struct snddev_info *snddev;
struct snd_mixer *m;
u_int16_t v;
dev_t pdev;
@@ -213,6 +212,8 @@ mixer_init(device_t dev, kobj_class_t cls, void *devinfo)
pdev = make_dev(&mixer_cdevsw, PCMMKMINOR(unit, SND_DEV_CTL, 0),
UID_ROOT, GID_WHEEL, 0666, "mixer%d", unit);
pdev->si_drv1 = m;
+ snddev = device_get_softc(dev);
+ snddev->mixer_dev = pdev;
return 0;
@@ -478,14 +479,14 @@ mixer_ioctl(dev_t i_dev, u_long cmd, caddr_t arg, int mode, struct thread *td)
static void
mixer_clone(void *arg, char *name, int namelen, dev_t *dev)
{
- dev_t pdev;
+ struct snddev_info *sd;
if (*dev != NODEV)
return;
if (strcmp(name, "mixer") == 0) {
- pdev = makedev(SND_CDEV_MAJOR, PCMMKMINOR(snd_unit, SND_DEV_CTL, 0));
- if (pdev->si_flags & SI_NAMED)
- *dev = pdev;
+ sd = devclass_get_softc(pcm_devclass, snd_unit);
+ if (sd != NULL)
+ *dev = sd->mixer_dev;
}
}
diff --git a/sys/dev/sound/pcm/sound.c b/sys/dev/sound/pcm/sound.c
index ecf8b8dac7d81..652fb7a592e63 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))
diff --git a/sys/dev/sound/pcm/sound.h b/sys/dev/sound/pcm/sound.h
index 7b7f5f0f512e5..f89f1bfeeb53c 100644
--- a/sys/dev/sound/pcm/sound.h
+++ b/sys/dev/sound/pcm/sound.h
@@ -234,6 +234,10 @@ u_int32_t pcm_getflags(device_t dev);
void pcm_setflags(device_t dev, u_int32_t val);
void *pcm_getdevinfo(device_t dev);
+int pcm_regdevt(dev_t dev, unsigned unit, unsigned type, unsigned channel);
+dev_t pcm_getdevt(unsigned unit, unsigned type, unsigned channel);
+int pcm_unregdevt(unsigned unit, unsigned type, unsigned channel);
+
int snd_setup_intr(device_t dev, struct resource *res, int flags,
driver_intr_t hand, void *param, void **cookiep);
@@ -276,16 +280,24 @@ int sndstat_busy(void);
/*
* this is rather kludgey- we need to duplicate these struct def'ns from sound.c
* so that the macro versions of pcm_{,un}lock can dereference them.
+ * we also have to do this now makedev() has gone away.
*/
-#ifdef PCM_DEBUG_MTX
struct snddev_channel {
SLIST_ENTRY(snddev_channel) link;
struct pcm_channel *channel;
};
+struct snddev_devt {
+ SLIST_ENTRY(snddev_devt) link;
+ dev_t dev;
+ unsigned channel;
+ unsigned type;
+};
+
struct snddev_info {
SLIST_HEAD(, snddev_channel) channels;
+ SLIST_HEAD(, snddev_devt) devs;
struct pcm_channel *fakechan;
unsigned devcount, playcount, reccount, vchancount;
unsigned flags;
@@ -297,8 +309,11 @@ struct snddev_info {
struct sysctl_ctx_list sysctl_tree;
struct sysctl_oid *sysctl_tree_top;
struct mtx *lock;
+ dev_t mixer_dev;
+
};
+#ifdef PCM_DEBUG_MTX
#define pcm_lock(d) mtx_lock(((struct snddev_info *)(d))->lock)
#define pcm_unlock(d) mtx_unlock(((struct snddev_info *)(d))->lock)
#else
diff --git a/sys/dev/sound/pcm/vchan.c b/sys/dev/sound/pcm/vchan.c
index 484dbf3e43d96..4a70a82d7c0ff 100644
--- a/sys/dev/sound/pcm/vchan.c
+++ b/sys/dev/sound/pcm/vchan.c
@@ -312,7 +312,7 @@ gotch:
if (last)
parent->flags &= ~CHN_F_BUSY;
- /* remove us from our grantparent's channel list */
+ /* remove us from our grandparent's channel list */
err = pcm_chn_remove(d, c, !last);
if (err)
return err;