git: a614c07ad452 - main - sound: Embed mixer cdev in snd_mixer

From: Christos Margiolis <christos_at_FreeBSD.org>
Date: Fri, 18 Sep 2026 18:18:38 UTC
The branch main has been updated by christos:

URL: https://cgit.FreeBSD.org/src/commit/?id=a614c07ad4520c072f58aebee54d16d9b72837f5

commit a614c07ad4520c072f58aebee54d16d9b72837f5
Author:     Christos Margiolis <christos@FreeBSD.org>
AuthorDate: 2026-09-18 18:13:32 +0000
Commit:     Christos Margiolis <christos@FreeBSD.org>
CommitDate: 2026-09-18 18:13:32 +0000

    sound: Embed mixer cdev in snd_mixer
    
    The mixer cdev belongs to the mixer, not to the PCM device, so move it
    from snddev_info->mixer_dev into a new snd_mixer->cdev field. snd_mixer
    itself is now included in snddev_info.
    
    Also add a MIXER_REGISTERED() macro similar to PCM_REGISTERED().
    
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 month
    Differential Revision:  https://reviews.freebsd.org/D59071
---
 sys/dev/sound/pci/es137x.c |  2 +-
 sys/dev/sound/pcm/dsp.c    | 16 ++++++++--------
 sys/dev/sound/pcm/mixer.c  | 37 +++++++++++++++++--------------------
 sys/dev/sound/pcm/mixer.h  |  3 +++
 sys/dev/sound/pcm/sound.h  |  1 -
 5 files changed, 29 insertions(+), 30 deletions(-)

diff --git a/sys/dev/sound/pci/es137x.c b/sys/dev/sound/pci/es137x.c
index bafc17f78c98..80d6adff2c75 100644
--- a/sys/dev/sound/pci/es137x.c
+++ b/sys/dev/sound/pci/es137x.c
@@ -1516,7 +1516,7 @@ sysctl_es137x_single_pcm_mixer(SYSCTL_HANDLER_ARGS)
 
 	dev = oidp->oid_arg1;
 	d = device_get_softc(dev);
-	if (!PCM_REGISTERED(d) || d->mixer_dev == NULL || d->mixer == NULL)
+	if (!PCM_REGISTERED(d) || !MIXER_REGISTERED(d->mixer))
 		return (EINVAL);
 	es = d->devinfo;
 	if (es == NULL)
diff --git a/sys/dev/sound/pcm/dsp.c b/sys/dev/sound/pcm/dsp.c
index dfd5779d0dfb..38b23376ce81 100644
--- a/sys/dev/sound/pcm/dsp.c
+++ b/sys/dev/sound/pcm/dsp.c
@@ -735,9 +735,9 @@ dsp_ioctl(struct cdev *i_dev, unsigned long cmd, caddr_t arg, int mode,
 			return (ret);
 		}
 
-		if (d->mixer_dev != NULL) {
+		if (MIXER_REGISTERED(d->mixer)) {
 			PCM_ACQUIRE_QUICK(d);
-			ret = mixer_ioctl_cmd(d->mixer_dev, cmd, arg, -1, td);
+			ret = mixer_ioctl_cmd(d->mixer->cdev, cmd, arg, -1, td);
 			PCM_RELEASE_QUICK(d);
 		} else
 			ret = EBADF;
@@ -1520,9 +1520,9 @@ dsp_ioctl(struct cdev *i_dev, unsigned long cmd, caddr_t arg, int mode,
 			return (ret);
 		}
 
-		if (d->mixer_dev != NULL) {
+		if (MIXER_REGISTERED(d->mixer)) {
 			PCM_ACQUIRE_QUICK(d);
-			ret = mixer_ioctl_cmd(d->mixer_dev, xcmd, arg, -1, td);
+			ret = mixer_ioctl_cmd(d->mixer->cdev, xcmd, arg, -1, td);
 			PCM_RELEASE_QUICK(d);
 		} else
 			ret = ENOTSUP;
@@ -1532,9 +1532,9 @@ dsp_ioctl(struct cdev *i_dev, unsigned long cmd, caddr_t arg, int mode,
 	case SNDCTL_DSP_GET_RECSRC_NAMES:
 	case SNDCTL_DSP_GET_RECSRC:
 	case SNDCTL_DSP_SET_RECSRC:
-		if (d->mixer_dev != NULL) {
+		if (MIXER_REGISTERED(d->mixer)) {
 			PCM_ACQUIRE_QUICK(d);
-			ret = mixer_ioctl_cmd(d->mixer_dev, cmd, arg, -1, td);
+			ret = mixer_ioctl_cmd(d->mixer->cdev, cmd, arg, -1, td);
 			PCM_RELEASE_QUICK(d);
 		} else
 			ret = ENOTSUP;
@@ -2205,7 +2205,7 @@ dsp_oss_audioinfo(struct cdev *i_dev, oss_audioinfo *ai, bool ex)
 	strlcpy(ai->cmd, CHN_COMM_UNKNOWN, sizeof(ai->cmd));
 	ai->card_number = unit;
 	ai->port_number = unit;
-	ai->mixer_dev = (d->mixer_dev != NULL) ? unit : -1;
+	ai->mixer_dev = MIXER_REGISTERED(d->mixer) ? unit : -1;
 	ai->legacy_device = unit;
 	snprintf(ai->devnode, sizeof(ai->devnode), "/dev/dsp%d", unit);
 	ai->enabled = device_is_attached(d->dev) ? 1 : 0;
@@ -2451,7 +2451,7 @@ dsp_oss_engineinfo(struct cdev *i_dev, oss_audioinfo *ai)
 		 * @todo @c port_number - routing information?
 		 */
 		ai->port_number = unit;
-		ai->mixer_dev = (d->mixer_dev != NULL) ? unit : -1;
+		ai->mixer_dev = MIXER_REGISTERED(d->mixer) ? unit : -1;
 		/**
 		 * @note
 		 * @c legacy_device - OSSv4 docs:  "Obsolete."
diff --git a/sys/dev/sound/pcm/mixer.c b/sys/dev/sound/pcm/mixer.c
index 59892b361b5f..87c9c67cc97a 100644
--- a/sys/dev/sound/pcm/mixer.c
+++ b/sys/dev/sound/pcm/mixer.c
@@ -679,13 +679,9 @@ int
 mixer_uninit(device_t dev)
 {
 	int i;
-	struct snddev_info *d;
 	struct snd_mixer *m;
 
-	d = device_get_softc(dev);
-	if (d == NULL)
-		return EBADF;
-	m = d->mixer;
+	m = mixer_get_devt(dev);
 
 	KASSERT(m != NULL, ("NULL snd_mixer"));
 	KASSERT(m->type == MIXER_TYPE_PRIMARY,
@@ -695,9 +691,9 @@ mixer_uninit(device_t dev)
 	 * snd_uaudio(4) in particular can call mixer_uninit() directly if
 	 * attach failed prior to pcm_register(), in which case the cdev will
 	 * not have been created. Do not call destroy_dev() unconditionally.
-	*/
-	if (d->mixer_dev != NULL)
-		destroy_dev(d->mixer_dev);
+	 */
+	if (MIXER_REGISTERED(m))
+		destroy_dev(m->cdev);
 
 	mtx_lock(&m->lock);
 
@@ -715,9 +711,6 @@ mixer_uninit(device_t dev)
 	mtx_destroy(&m->lock);
 	kobj_delete((kobj_t)m, M_DEVBUF);
 
-	d->mixer_dev = NULL;
-	d->mixer = NULL;
-
 	return 0;
 }
 
@@ -765,7 +758,7 @@ mixer_make_dev(device_t dev)
 	devargs.mda_gid = GID_AUDIO;
 	devargs.mda_mode = 0660;
 	devargs.mda_si_drv1 = sc->mixer;
-	err = make_dev_s(&devargs, &sc->mixer_dev, "mixer%d", unit);
+	err = make_dev_s(&devargs, &sc->mixer->cdev, "mixer%d", unit);
 	if (err != 0) {
 		device_printf(dev, "failed to create mixer%d: error %d\n",
 		    unit, err);
@@ -1148,8 +1141,8 @@ mixer_clone(void *arg,
 		bus_topo_lock();
 		d = devclass_get_softc(pcm_devclass, snd_unit);
 		/* See related comment in dsp_clone(). */
-		if (PCM_REGISTERED(d) && d->mixer_dev != NULL) {
-			*dev = d->mixer_dev;
+		if (PCM_REGISTERED(d) && MIXER_REGISTERED(d->mixer)) {
+			*dev = d->mixer->cdev;
 			dev_ref(*dev);
 		}
 		bus_topo_unlock();
@@ -1246,17 +1239,21 @@ mixer_oss_mixerinfo(struct cdev *i_dev, oss_mixerinfo *mi)
 		PCM_UNLOCKASSERT(d);
 		PCM_LOCK(d);
 
-		if (!((d->mixer_dev == i_dev && mi->dev == -1) ||
-		    mi->dev == i)) {
+		if (!MIXER_REGISTERED(d->mixer)) {
+			if (mi->dev == i) {
+				mixer_oss_mixerinfo_unavail(mi, i);
+				PCM_UNLOCK(d);
+				bus_topo_unlock();
+				return (0);
+			}
 			PCM_UNLOCK(d);
 			continue;
 		}
 
-		if (d->mixer == NULL) {
-			mixer_oss_mixerinfo_unavail(mi, i);
+		if (!((d->mixer->cdev == i_dev && mi->dev == -1) ||
+		    mi->dev == i)) {
 			PCM_UNLOCK(d);
-			bus_topo_unlock();
-			return (0);
+			continue;
 		}
 
 		m = d->mixer;
diff --git a/sys/dev/sound/pcm/mixer.h b/sys/dev/sound/pcm/mixer.h
index fef086dec925..47599e7ddcd8 100644
--- a/sys/dev/sound/pcm/mixer.h
+++ b/sys/dev/sound/pcm/mixer.h
@@ -34,6 +34,8 @@
 #ifndef _PCM_MIXER_H_
 #define	_PCM_MIXER_H_
 
+#define MIXER_REGISTERED(x)	((x) != NULL && (x)->cdev != NULL)
+
 #define MIXER_NAMELEN	16
 struct snd_mixer {
 	KOBJ_FIELDS;
@@ -54,6 +56,7 @@ struct snd_mixer {
 	char name[MIXER_NAMELEN];
 	struct mtx lock;
 	int modify_counter;
+	struct cdev *cdev;
 };
 
 struct snd_mixer *mixer_create(device_t dev, kobj_class_t cls, void *devinfo,
diff --git a/sys/dev/sound/pcm/sound.h b/sys/dev/sound/pcm/sound.h
index 5b9a12f948b8..0a63acb16832 100644
--- a/sys/dev/sound/pcm/sound.h
+++ b/sys/dev/sound/pcm/sound.h
@@ -189,7 +189,6 @@ struct snddev_info {
 	device_t dev;
 	char status[SND_STATUSLEN];
 	struct mtx lock;
-	struct cdev *mixer_dev;
 	struct cdev *dsp_dev;
 	struct snd_mixer *mixer;
 	uint32_t pvchanrate, pvchanformat, pvchanmode;