diff options
Diffstat (limited to 'sys/dev/sound')
-rw-r--r-- | sys/dev/sound/pci/neomagic-coeff.h | 2 | ||||
-rw-r--r-- | sys/dev/sound/pcm/dsp.c | 75 | ||||
-rw-r--r-- | sys/dev/sound/pcm/mixer.c | 19 | ||||
-rw-r--r-- | sys/dev/sound/pcm/sound.c | 112 | ||||
-rw-r--r-- | sys/dev/sound/pcm/sound.h | 17 | ||||
-rw-r--r-- | sys/dev/sound/pcm/vchan.c | 2 |
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; |