git: 13fcc9caaf96 - main - sound: Standardize mixer_init() call order

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

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

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

    sound: Standardize mixer_init() call order
    
    Device drivers call mixer_init() in a non-standard order - some before
    pcm_init(), and some after pcm_register(). However, both approaches are
    potentially risky, and logically weak, since pcm_register() is supposed
    to be the function that finalizes sound(4) attach.
    
    Standardize the call ordering by moving all mixer_init() calls after
    pcm_init(). This is also necessary for a follow-up patch, which expects
    pcm_init() to have run first and initialized the PCM lock.
    
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 month
    Differential Revision:  https://reviews.freebsd.org/D59069
---
 sys/arm/allwinner/a10_codec.c            |  4 ++--
 sys/arm/broadcom/bcm2835/bcm2835_audio.c |  4 ++--
 sys/arm/freescale/imx/imx6_ssi.c         |  3 ++-
 sys/arm/freescale/vybrid/vf_sai.c        |  4 ++--
 sys/dev/sound/dummy.c                    |  2 +-
 sys/dev/sound/fdt/audio_soc.c            |  9 +++++----
 sys/dev/sound/macio/aoa.c                |  6 +++++-
 sys/dev/sound/macio/aoa.h                |  2 +-
 sys/dev/sound/macio/davbus.c             | 19 +++++++++++--------
 sys/dev/sound/macio/i2s.c                | 12 ++++++++----
 sys/dev/sound/pci/als4000.c              |  4 ++--
 sys/dev/sound/pci/atiixp.c               |  4 ++--
 sys/dev/sound/pci/cmi.c                  |  4 ++--
 sys/dev/sound/pci/cs4281.c               |  4 ++--
 sys/dev/sound/pci/csapcm.c               |  2 +-
 sys/dev/sound/pci/emu10k1.c              |  2 +-
 sys/dev/sound/pci/emu10kx-pcm.c          |  2 +-
 sys/dev/sound/pci/envy24.c               |  3 ++-
 sys/dev/sound/pci/envy24ht.c             |  3 ++-
 sys/dev/sound/pci/es137x.c               |  2 +-
 sys/dev/sound/pci/fm801.c                |  2 +-
 sys/dev/sound/pci/hda/hdaa.c             | 12 ++++++------
 sys/dev/sound/pci/hdsp-pcm.c             |  4 ++--
 sys/dev/sound/pci/hdspe-pcm.c            |  4 ++--
 sys/dev/sound/pci/ich.c                  |  4 ++--
 sys/dev/sound/pci/maestro3.c             |  2 +-
 sys/dev/sound/pci/neomagic.c             |  2 +-
 sys/dev/sound/pci/solo.c                 |  3 ++-
 sys/dev/sound/pci/t4dwave.c              |  2 +-
 sys/dev/sound/pci/via8233.c              |  2 +-
 sys/dev/sound/pci/via82c686.c            |  2 +-
 sys/dev/sound/pci/vibes.c                |  3 ++-
 sys/dev/sound/usb/uaudio.c               | 15 ++++++++-------
 33 files changed, 85 insertions(+), 67 deletions(-)

diff --git a/sys/arm/allwinner/a10_codec.c b/sys/arm/allwinner/a10_codec.c
index d3920eddc1f1..01f514af2e9a 100644
--- a/sys/arm/allwinner/a10_codec.c
+++ b/sys/arm/allwinner/a10_codec.c
@@ -1150,6 +1150,8 @@ a10codec_attach(device_t dev)
 	val |= DAC_DPC_EN_DA;
 	CODEC_WRITE(sc, AC_DAC_DPC(sc), val);
 
+	pcm_init(dev, sc);
+
 	if (mixer_init(dev, sc->cfg->mixer_class, sc)) {
 		device_printf(dev, "mixer_init failed\n");
 		goto fail;
@@ -1165,8 +1167,6 @@ a10codec_attach(device_t dev)
 
 	pcm_setflags(dev, pcm_getflags(dev) | SD_F_MPSAFE);
 
-	pcm_init(dev, sc);
-
 	pcm_addchan(dev, PCMDIR_PLAY, &a10codec_chan_class, sc);
 	pcm_addchan(dev, PCMDIR_REC, &a10codec_chan_class, sc);
 
diff --git a/sys/arm/broadcom/bcm2835/bcm2835_audio.c b/sys/arm/broadcom/bcm2835/bcm2835_audio.c
index 556edce502f0..da6a00c3e3a1 100644
--- a/sys/arm/broadcom/bcm2835/bcm2835_audio.c
+++ b/sys/arm/broadcom/bcm2835/bcm2835_audio.c
@@ -1037,13 +1037,13 @@ bcm2835_audio_delayed_init(void *xsc)
 	sc->dest = DEST_AUTO;
 	sc->verbose_trace = 0;
 
+	pcm_init(sc->dev, sc);
+
     	if (mixer_init(sc->dev, &bcmmixer_class, sc)) {
 		device_printf(sc->dev, "mixer_init failed\n");
 		goto no;
 	}
 
-	pcm_init(sc->dev, sc);
-
 	pcm_addchan(sc->dev, PCMDIR_PLAY, &bcmchan_class, sc);
     	snprintf(status, SND_STATUSLEN, "at VCHIQ");
 	if (pcm_register(sc->dev, status)) {
diff --git a/sys/arm/freescale/imx/imx6_ssi.c b/sys/arm/freescale/imx/imx6_ssi.c
index f4ef955761b4..738c2cc09a55 100644
--- a/sys/arm/freescale/imx/imx6_ssi.c
+++ b/sys/arm/freescale/imx/imx6_ssi.c
@@ -808,6 +808,8 @@ ssi_attach(device_t dev)
 
 	pcm_init(dev, scp);
 
+	mixer_init(dev, &ssimixer_class, scp);
+
 	scp->chnum = 0;
 	pcm_addchan(dev, PCMDIR_PLAY, &ssichan_class, scp);
 	scp->chnum++;
@@ -819,7 +821,6 @@ ssi_attach(device_t dev)
 		return (ENXIO);
 	}
 
-	mixer_init(dev, &ssimixer_class, scp);
 	setup_ssi(sc);
 
 	imx_ccm_ssi_configure(dev);
diff --git a/sys/arm/freescale/vybrid/vf_sai.c b/sys/arm/freescale/vybrid/vf_sai.c
index d3a3ab93fe80..17a3d4fc799b 100644
--- a/sys/arm/freescale/vybrid/vf_sai.c
+++ b/sys/arm/freescale/vybrid/vf_sai.c
@@ -760,6 +760,8 @@ sai_attach(device_t dev)
 
 	pcm_init(dev, scp);
 
+	mixer_init(dev, &saimixer_class, scp);
+
 	scp->chnum = 0;
 	pcm_addchan(dev, PCMDIR_PLAY, &saichan_class, scp);
 	scp->chnum++;
@@ -771,8 +773,6 @@ sai_attach(device_t dev)
 		return (ENXIO);
 	}
 
-	mixer_init(dev, &saimixer_class, scp);
-
 	setup_dma(scp);
 	setup_sai(sc);
 
diff --git a/sys/dev/sound/dummy.c b/sys/dev/sound/dummy.c
index 5791347c59df..7b456884040e 100644
--- a/sys/dev/sound/dummy.c
+++ b/sys/dev/sound/dummy.c
@@ -376,6 +376,7 @@ dummy_attach(device_t dev)
 
 	pcm_setflags(dev, pcm_getflags(dev) | SD_F_MPSAFE);
 	pcm_init(dev, sc);
+	mixer_init(dev, &dummy_mixer_class, sc);
 	for (i = 0; i < DUMMY_NPCHAN; i++)
 		pcm_addchan(dev, PCMDIR_PLAY, &dummy_chan_class, sc);
 	for (i = 0; i < DUMMY_NRCHAN; i++)
@@ -385,7 +386,6 @@ dummy_attach(device_t dev)
 	    device_get_nameunit(device_get_parent(dev)));
 	if (pcm_register(dev, status))
 		return (ENXIO);
-	mixer_init(dev, &dummy_mixer_class, sc);
 
 	/*
 	 * Create an alias so that tests do not need to guess which one is the
diff --git a/sys/dev/sound/fdt/audio_soc.c b/sys/dev/sound/fdt/audio_soc.c
index 33269dc302fa..9cd913004c0e 100644
--- a/sys/dev/sound/fdt/audio_soc.c
+++ b/sys/dev/sound/fdt/audio_soc.c
@@ -398,6 +398,11 @@ audio_soc_init(void *arg)
 
 	pcm_init(sc->dev, sc);
 
+	AUDIO_DAI_SETUP_MIXER(sc->codec_dev, sc->dev);
+	SLIST_FOREACH(aux_node, &sc->aux_devs, link) {
+		AUDIO_DAI_SETUP_MIXER(aux_node->dev, sc->dev);
+	}
+
 	sc->play_channel.sc = sc;
 	sc->rec_channel.sc = sc;
 
@@ -410,10 +415,6 @@ audio_soc_init(void *arg)
 	}
 
 	AUDIO_DAI_SETUP_INTR(sc->cpu_dev, audio_soc_intr, sc);
-	AUDIO_DAI_SETUP_MIXER(sc->codec_dev, sc->dev);
-	SLIST_FOREACH(aux_node, &sc->aux_devs, link) {
-		AUDIO_DAI_SETUP_MIXER(aux_node->dev, sc->dev);
-	}
 }
 
 static int
diff --git a/sys/dev/sound/macio/aoa.c b/sys/dev/sound/macio/aoa.c
index ff8f17224384..db22dcc4a2d8 100644
--- a/sys/dev/sound/macio/aoa.c
+++ b/sys/dev/sound/macio/aoa.c
@@ -362,7 +362,7 @@ static kobj_method_t aoa_chan_methods[] = {
 CHANNEL_DECLARE(aoa_chan);
 
 int
-aoa_attach(void *xsc)
+aoa_attach(void *xsc, kobj_class_t mixer_class, void *mixer_devinfo)
 {
 	char status[SND_STATUSLEN];
 	struct aoa_softc *sc;
@@ -374,6 +374,10 @@ aoa_attach(void *xsc)
 
 	pcm_init(self, sc);
 
+	/* Install the codec's mixer, if we have one. */
+	if (mixer_class != NULL)
+		mixer_init(self, mixer_class, mixer_devinfo);
+
 	err = pcm_getbuffersize(self, AOA_BUFFER_SIZE, AOA_BUFFER_SIZE,
 	    AOA_BUFFER_SIZE);
 	DPRINTF(("pcm_getbuffersize returned %d\n", err));
diff --git a/sys/dev/sound/macio/aoa.h b/sys/dev/sound/macio/aoa.h
index 511fe345d74a..b14fad3b6500 100644
--- a/sys/dev/sound/macio/aoa.h
+++ b/sys/dev/sound/macio/aoa.h
@@ -41,6 +41,6 @@ struct aoa_softc {
 };
 
 void	aoa_interrupt(void *);
-int	aoa_attach(void *xsc);
+int	aoa_attach(void *xsc, kobj_class_t mixer_class, void *mixer_devinfo);
 
 #endif /* SOUND_AOA_H */
diff --git a/sys/dev/sound/macio/davbus.c b/sys/dev/sound/macio/davbus.c
index de15806e6d5c..10cf85cf98e0 100644
--- a/sys/dev/sound/macio/davbus.c
+++ b/sys/dev/sound/macio/davbus.c
@@ -495,6 +495,7 @@ davbus_attach(device_t self)
 	struct davbus_softc 	*sc;
 	struct resource 	*dbdma_irq, *cintr;
 	void 			*cookie;
+	kobj_class_t		 mixer_class;
 	char			 compat[64];
 	int 			 rid, oirq, err;
 
@@ -557,16 +558,18 @@ davbus_attach(device_t self)
         bus_write_4(sc->reg, DAVBUS_SOUND_CTRL, DAVBUS_INPUT_SUBFRAME0 | 
 	    DAVBUS_OUTPUT_SUBFRAME0 | DAVBUS_RATE_44100 | DAVBUS_INTR_PORTCHG);
 
-	/* Attach DBDMA engine and PCM layer */
-	err = aoa_attach(sc);
-	if (err)
-		return (err);
-
-	/* Install codec module */
+	/* Pick the codec module */
 	if (strcmp(compat, "screamer") == 0)
-		mixer_init(self, &screamer_mixer_class, sc);
+		mixer_class = &screamer_mixer_class;
 	else if (strcmp(compat, "burgundy") == 0)
-		mixer_init(self, &burgundy_mixer_class, sc);
+		mixer_class = &burgundy_mixer_class;
+	else
+		mixer_class = NULL;
+
+	/* Attach DBDMA engine, codec mixer and PCM layer */
+	err = aoa_attach(sc, mixer_class, sc);
+	if (err)
+		return (err);
 
 	return (0);
 }
diff --git a/sys/dev/sound/macio/i2s.c b/sys/dev/sound/macio/i2s.c
index 327fbe5fc0bd..711484fd0132 100644
--- a/sys/dev/sound/macio/i2s.c
+++ b/sys/dev/sound/macio/i2s.c
@@ -249,7 +249,7 @@ i2s_attach(device_t self)
 	if (config_intrhook_establish(i2s_delayed_attach) != 0)
 		return (ENOMEM);
 
-	return (aoa_attach(sc));
+	return (0);
 }
 
 /*****************************************************************************
@@ -737,9 +737,13 @@ i2s_postattach(void *xsc)
 	/* Reset the codec. */
 	i2s_audio_hw_reset(sc);
 
-	/* If we have a codec, initialize it. */
-	if (i2s_mixer)
-		mixer_init(self, i2s_mixer_class, i2s_mixer);
+	/*
+	 * Attach the DBDMA engine and the PCM layer, along with the codec's
+	 * mixer, if we have one. This is deferred until now because the codec
+	 * only becomes available once the I2C controller has attached.
+	 */
+	if (aoa_attach(sc, i2s_mixer_class, i2s_mixer) != 0)
+		device_printf(self, "could not attach PCM layer\n");
 
 	/* Read initial port status. */
 	i2s_cint(sc);
diff --git a/sys/dev/sound/pci/als4000.c b/sys/dev/sound/pci/als4000.c
index 0613f3ec2b97..b5aefa333d86 100644
--- a/sys/dev/sound/pci/als4000.c
+++ b/sys/dev/sound/pci/als4000.c
@@ -832,13 +832,13 @@ als_pci_attach(device_t dev)
 		goto bad_attach;
 	}
 
+	pcm_init(dev, sc);
+
 	if (mixer_init(dev, &als_mixer_class, sc)) {
 		device_printf(dev, "failed to initialize mixer\n");
 		goto bad_attach;
 	}
 
-	pcm_init(dev, sc);
-
 	pcm_addchan(dev, PCMDIR_PLAY, &alspchan_class, sc);
 	pcm_addchan(dev, PCMDIR_REC,  &alsrchan_class, sc);
 
diff --git a/sys/dev/sound/pci/atiixp.c b/sys/dev/sound/pci/atiixp.c
index 39ef2f375328..631205b273ab 100644
--- a/sys/dev/sound/pci/atiixp.c
+++ b/sys/dev/sound/pci/atiixp.c
@@ -1080,10 +1080,10 @@ atiixp_chip_post_init(void *arg)
 		break;
 	}
 
-	mixer_init(sc->dev, ac97_getmixerclass(), sc->codec);
-
 	pcm_init(sc->dev, sc);
 
+	mixer_init(sc->dev, ac97_getmixerclass(), sc->codec);
+
 	for (i = 0; i < ATI_IXP_NPCHAN; i++)
 		pcm_addchan(sc->dev, PCMDIR_PLAY, &atiixp_chan_class, sc);
 	for (i = 0; i < ATI_IXP_NRCHAN; i++)
diff --git a/sys/dev/sound/pci/cmi.c b/sys/dev/sound/pci/cmi.c
index 58ab961b74e1..e53b46467f0b 100644
--- a/sys/dev/sound/pci/cmi.c
+++ b/sys/dev/sound/pci/cmi.c
@@ -980,11 +980,11 @@ cmi_attach(device_t dev)
 	if (cmi_init(sc))
 		goto bad;
 
+	pcm_init(dev, sc);
+
 	if (mixer_init(dev, &cmi_mixer_class, sc))
 		goto bad;
 
-	pcm_init(dev, sc);
-
 	cmi_initsys(sc);
 
 	pcm_addchan(dev, PCMDIR_PLAY, &cmichan_class, sc);
diff --git a/sys/dev/sound/pci/cs4281.c b/sys/dev/sound/pci/cs4281.c
index ef5183331331..a30467566b36 100644
--- a/sys/dev/sound/pci/cs4281.c
+++ b/sys/dev/sound/pci/cs4281.c
@@ -837,10 +837,10 @@ cs4281_pci_attach(device_t dev)
     if (codec == NULL)
         goto bad;
 
-    mixer_init(dev, ac97_getmixerclass(), codec);
-
     pcm_init(dev, sc);
 
+    mixer_init(dev, ac97_getmixerclass(), codec);
+
     pcm_addchan(dev, PCMDIR_PLAY, &cs4281chan_class, sc);
     pcm_addchan(dev, PCMDIR_REC, &cs4281chan_class, sc);
 
diff --git a/sys/dev/sound/pci/csapcm.c b/sys/dev/sound/pci/csapcm.c
index 8fd18a2a4361..a40c4a083787 100644
--- a/sys/dev/sound/pci/csapcm.c
+++ b/sys/dev/sound/pci/csapcm.c
@@ -809,6 +809,7 @@ pcmcsa_attach(device_t dev)
 	}
 	if (csa->card->inv_eapd)
 		ac97_setflags(codec, AC97_F_EAPD_INV);
+	pcm_init(dev, csa);
 	if (mixer_init(dev, ac97_getmixerclass(), codec) == -1) {
 		ac97_destroy(codec);
 		csa_releaseres(csa, dev);
@@ -829,7 +830,6 @@ pcmcsa_attach(device_t dev)
 	csa_writemem(resp, BA1_CIE, (csa_readmem(resp, BA1_CIE) & ~0x0000003f) | 0x00000001);
 	csa_active(csa, -1);
 
-	pcm_init(dev, csa);
 	pcm_addchan(dev, PCMDIR_REC, &csachan_class, csa);
 	pcm_addchan(dev, PCMDIR_PLAY, &csachan_class, csa);
 	if (pcm_register(dev, status)) {
diff --git a/sys/dev/sound/pci/emu10k1.c b/sys/dev/sound/pci/emu10k1.c
index d3afa8d4fe43..5120ec2411a1 100644
--- a/sys/dev/sound/pci/emu10k1.c
+++ b/sys/dev/sound/pci/emu10k1.c
@@ -2114,6 +2114,7 @@ emu_pci_attach(device_t dev)
 	codec = AC97_CREATE(dev, sc, emu_ac97);
 	if (codec == NULL) goto bad;
 	gotmic = (ac97_getcaps(codec) & AC97_CAP_MICCHANNEL) ? 1 : 0;
+	pcm_init(dev, sc);
 	if (mixer_init(dev, ac97_getmixerclass(), codec) == -1) goto bad;
 
 	emu_midiattach(sc);
@@ -2131,7 +2132,6 @@ emu_pci_attach(device_t dev)
 	    rman_get_start(sc->reg), rman_get_start(sc->irq),
 	    device_get_nameunit(device_get_parent(dev)));
 
-	pcm_init(dev, sc);
 	for (i = 0; i < sc->nchans; i++)
 		pcm_addchan(dev, PCMDIR_PLAY, &emupchan_class, sc);
 	for (i = 0; i < (gotmic ? 3 : 2); i++)
diff --git a/sys/dev/sound/pci/emu10kx-pcm.c b/sys/dev/sound/pci/emu10kx-pcm.c
index 0a15b8ba3448..55b1b4d8cc1c 100644
--- a/sys/dev/sound/pci/emu10kx-pcm.c
+++ b/sys/dev/sound/pci/emu10kx-pcm.c
@@ -1393,6 +1393,7 @@ emu_pcm_attach(device_t dev)
 	sc->emu10k1_volcache[1][1] = 75;
 	BUS_READ_IVAR(device_get_parent(dev), dev, EMU_VAR_ROUTE, &route);
 	sc->route = route;
+	pcm_init(dev, sc);
 	switch (route) {
 	case RT_FRONT:
 		sc->rt.amounts_left[0] = 0xff;
@@ -1474,7 +1475,6 @@ emu_pcm_attach(device_t dev)
 	pcm_setflags(dev, pcm_getflags(dev) | SD_F_MPSAFE);
 
 	/* XXX we should better get number of available channels from parent */
-	pcm_init(dev, sc);
 	sc->pnum = 0;
 	if (route != RT_MCHRECORD)
 		pcm_addchan(dev, PCMDIR_PLAY, &emupchan_class, sc);
diff --git a/sys/dev/sound/pci/envy24.c b/sys/dev/sound/pci/envy24.c
index df9c680b9414..533c8aeddeb3 100644
--- a/sys/dev/sound/pci/envy24.c
+++ b/sys/dev/sound/pci/envy24.c
@@ -2570,11 +2570,12 @@ envy24_pci_attach(device_t dev)
 		goto bad;
 	}
 
+	pcm_init(dev, sc);
+
 	/* set multi track mixer */
 	mixer_init(dev, &envy24mixer_class, sc);
 
 	/* set channel information */
-	pcm_init(dev, sc);
 	sc->chnum = 0;
 	for (i = 0; i < 5; i++) {
 		pcm_addchan(dev, PCMDIR_PLAY, &envy24chan_class, sc);
diff --git a/sys/dev/sound/pci/envy24ht.c b/sys/dev/sound/pci/envy24ht.c
index 19a4ee39eacd..34052ee869db 100644
--- a/sys/dev/sound/pci/envy24ht.c
+++ b/sys/dev/sound/pci/envy24ht.c
@@ -2474,11 +2474,12 @@ envy24ht_pci_attach(device_t dev)
 		goto bad;
 	}
 
+	pcm_init(dev, sc);
+
 	/* set multi track mixer */
 	mixer_init(dev, &envy24htmixer_class, sc);
 
 	/* set channel information */
-	pcm_init(dev, sc);
 	sc->chnum = 0;
 	/* for (i = 0; i < 5; i++) { */
 		pcm_addchan(dev, PCMDIR_PLAY, &envy24htchan_class, sc);
diff --git a/sys/dev/sound/pci/es137x.c b/sys/dev/sound/pci/es137x.c
index ab8a6db74640..f67bb41e4542 100644
--- a/sys/dev/sound/pci/es137x.c
+++ b/sys/dev/sound/pci/es137x.c
@@ -1798,6 +1798,7 @@ es_pci_attach(device_t dev)
 	es->escfg = ES_SET_NUMREC(es->escfg, 1);
 
 	devid = pci_get_devid(dev);
+	pcm_init(dev, es);
 	switch (devid) {
 	case ES1371_PCI_ID:
 	case ES1371_PCI_ID2:
@@ -1858,7 +1859,6 @@ es_pci_attach(device_t dev)
 	    rman_get_start(es->reg), rman_get_start(es->irq),
 	    device_get_nameunit(device_get_parent(dev)));
 
-	pcm_init(dev, es);
 	for (i = 0; i < numplay; i++)
 		pcm_addchan(dev, PCMDIR_PLAY, ct, es);
 	pcm_addchan(dev, PCMDIR_REC, ct, es);
diff --git a/sys/dev/sound/pci/fm801.c b/sys/dev/sound/pci/fm801.c
index 69c74ad91303..65e1987abc6a 100644
--- a/sys/dev/sound/pci/fm801.c
+++ b/sys/dev/sound/pci/fm801.c
@@ -613,6 +613,7 @@ fm801_pci_attach(device_t dev)
 	codec = AC97_CREATE(dev, fm801, fm801_ac97);
 	if (codec == NULL) goto oops;
 
+	pcm_init(dev, fm801);
 	if (mixer_init(dev, ac97_getmixerclass(), codec) == -1) goto oops;
 
 	fm801->irqid = 0;
@@ -642,7 +643,6 @@ fm801_pci_attach(device_t dev)
 		device_get_nameunit(device_get_parent(dev)));
 
 #define FM801_MAXPLAYCH	1
-	pcm_init(dev, fm801);
 	pcm_addchan(dev, PCMDIR_PLAY, &fm801ch_class, fm801);
 	pcm_addchan(dev, PCMDIR_REC, &fm801ch_class, fm801);
 	if (pcm_register(dev, status))
diff --git a/sys/dev/sound/pci/hda/hdaa.c b/sys/dev/sound/pci/hda/hdaa.c
index 44cca506751f..c11ce3c0bf6a 100644
--- a/sys/dev/sound/pci/hda/hdaa.c
+++ b/sys/dev/sound/pci/hda/hdaa.c
@@ -7114,12 +7114,6 @@ hdaa_pcm_attach(device_t dev)
 	 */
 	pcm_setflags(dev, pcm_getflags(dev) | SD_F_MPSAFE);
 
-	HDA_BOOTHVERBOSE(
-		device_printf(dev, "OSS mixer initialization...\n");
-	);
-	if (mixer_init(dev, &hdaa_audio_ctl_ossmixer_class, pdevinfo) != 0)
-		device_printf(dev, "Can't register mixer\n");
-
 	HDA_BOOTHVERBOSE(
 		device_printf(dev, "Registering PCM channels...\n");
 	);
@@ -7127,6 +7121,12 @@ hdaa_pcm_attach(device_t dev)
 
 	pdevinfo->registered++;
 
+	HDA_BOOTHVERBOSE(
+		device_printf(dev, "OSS mixer initialization...\n");
+	);
+	if (mixer_init(dev, &hdaa_audio_ctl_ossmixer_class, pdevinfo) != 0)
+		device_printf(dev, "Can't register mixer\n");
+
 	d = device_get_softc(dev);
 	if (pdevinfo->playas >= 0) {
 		as = &devinfo->as[pdevinfo->playas];
diff --git a/sys/dev/sound/pci/hdsp-pcm.c b/sys/dev/sound/pci/hdsp-pcm.c
index 7f4f7dc76557..46bdc1f6ea7e 100644
--- a/sys/dev/sound/pci/hdsp-pcm.c
+++ b/sys/dev/sound/pci/hdsp-pcm.c
@@ -1070,6 +1070,8 @@ hdsp_pcm_attach(device_t dev)
 
 	pcm_init(dev, scp);
 
+	mixer_init(dev, &hdspmixer_class, scp);
+
 	play = (hdsp_channel_play_ports(scp->hc)) ? 1 : 0;
 	rec = (hdsp_channel_rec_ports(scp->hc)) ? 1 : 0;
 
@@ -1094,8 +1096,6 @@ hdsp_pcm_attach(device_t dev)
 		return (ENXIO);
 	}
 
-	mixer_init(dev, &hdspmixer_class, scp);
-
 	/* Register the PCM child for interrupt dispatch. */
 	mtx_lock(&sc->lock);
 	for (i = 0; i < HDSP_MAX_PCMDEV; i++) {
diff --git a/sys/dev/sound/pci/hdspe-pcm.c b/sys/dev/sound/pci/hdspe-pcm.c
index a814c80127b1..ffd3a2cee1dc 100644
--- a/sys/dev/sound/pci/hdspe-pcm.c
+++ b/sys/dev/sound/pci/hdspe-pcm.c
@@ -1064,6 +1064,8 @@ hdspe_pcm_attach(device_t dev)
 
 	pcm_init(dev, scp);
 
+	mixer_init(dev, &hdspemixer_class, scp);
+
 	play = (hdspe_channel_play_ports(scp->hc)) ? 1 : 0;
 	rec = (hdspe_channel_rec_ports(scp->hc)) ? 1 : 0;
 
@@ -1088,8 +1090,6 @@ hdspe_pcm_attach(device_t dev)
 		return (ENXIO);
 	}
 
-	mixer_init(dev, &hdspemixer_class, scp);
-
 	/* Register the PCM child for interrupt dispatch. */
 	mtx_lock(&sc->lock);
 	for (i = 0; i < HDSPE_MAX_PCMDEV; i++) {
diff --git a/sys/dev/sound/pci/ich.c b/sys/dev/sound/pci/ich.c
index 1295e7eb5bc1..7cb0983b17ef 100644
--- a/sys/dev/sound/pci/ich.c
+++ b/sys/dev/sound/pci/ich.c
@@ -1029,6 +1029,8 @@ ich_pci_attach(device_t dev)
 		break;
 	}
 
+	pcm_init(dev, sc);
+
 	mixer_init(dev, ac97_getmixerclass(), sc->codec);
 
 	/* check and set VRA function */
@@ -1067,8 +1069,6 @@ ich_pci_attach(device_t dev)
 	    ich_setmap, sc, 0))
 		goto bad;
 
-	pcm_init(dev, sc);
-
 	pcm_addchan(dev, PCMDIR_PLAY, &ichchan_class, sc);		/* play */
 	pcm_addchan(dev, PCMDIR_REC, &ichchan_class, sc);		/* record */
 	if (sc->hasmic)
diff --git a/sys/dev/sound/pci/maestro3.c b/sys/dev/sound/pci/maestro3.c
index 5bf420c86c95..4f101ccdbfe6 100644
--- a/sys/dev/sound/pci/maestro3.c
+++ b/sys/dev/sound/pci/maestro3.c
@@ -1416,6 +1416,7 @@ m3_pci_attach(device_t dev)
 		device_printf(dev, "ac97_create error\n");
 		goto bad;
 	}
+	pcm_init(dev, sc);
 	if (mixer_init(dev, ac97_getmixerclass(), codec)) {
 		device_printf(dev, "mixer_init error\n");
 		goto bad;
@@ -1423,7 +1424,6 @@ m3_pci_attach(device_t dev)
 
 	m3_enable_ints(sc);
 
-	pcm_init(dev, sc);
 	for (i=0 ; i<dacn ; i++) {
 		if (pcm_addchan(dev, PCMDIR_PLAY, &m3_pch_class, sc)) {
 			device_printf(dev, "pcm_addchan (play) error\n");
diff --git a/sys/dev/sound/pci/neomagic.c b/sys/dev/sound/pci/neomagic.c
index 0e0af654b734..2813c7de57b3 100644
--- a/sys/dev/sound/pci/neomagic.c
+++ b/sys/dev/sound/pci/neomagic.c
@@ -692,6 +692,7 @@ nm_pci_attach(device_t dev)
 
 	codec = AC97_CREATE(dev, sc, nm_ac97);
 	if (codec == NULL) goto bad;
+	pcm_init(dev, sc);
 	if (mixer_init(dev, ac97_getmixerclass(), codec) == -1) goto bad;
 
 	sc->irqid = 0;
@@ -707,7 +708,6 @@ nm_pci_attach(device_t dev)
 		 rman_get_start(sc->irq),
 		 device_get_nameunit(device_get_parent(dev)));
 
-	pcm_init(dev, sc);
 	pcm_addchan(dev, PCMDIR_REC, &nmchan_class, sc);
 	pcm_addchan(dev, PCMDIR_PLAY, &nmchan_class, sc);
 	if (pcm_register(dev, status))
diff --git a/sys/dev/sound/pci/solo.c b/sys/dev/sound/pci/solo.c
index 21054973d9a2..71da677167bf 100644
--- a/sys/dev/sound/pci/solo.c
+++ b/sys/dev/sound/pci/solo.c
@@ -1017,6 +1017,8 @@ ess_attach(device_t dev)
 	if (sc->newspeed)
 		ess_setmixer(sc, 0x71, 0x2a);
 
+	pcm_init(dev, sc);
+
     	if (mixer_init(dev, &solomixer_class, sc))
 		goto no;
 
@@ -1025,7 +1027,6 @@ ess_attach(device_t dev)
 		rman_get_start(sc->irq),
 		device_get_nameunit(device_get_parent(dev)));
 
-	pcm_init(dev, sc);
       	pcm_addchan(dev, PCMDIR_REC, &esschan_class, sc);
 	pcm_addchan(dev, PCMDIR_PLAY, &esschan_class, sc);
 	if (pcm_register(dev, status))
diff --git a/sys/dev/sound/pci/t4dwave.c b/sys/dev/sound/pci/t4dwave.c
index d4650cfa07e2..83416976f603 100644
--- a/sys/dev/sound/pci/t4dwave.c
+++ b/sys/dev/sound/pci/t4dwave.c
@@ -874,6 +874,7 @@ tr_pci_attach(device_t dev)
 
 	codec = AC97_CREATE(dev, tr, tr_ac97);
 	if (codec == NULL) goto bad;
+	pcm_init(dev, tr);
 	if (mixer_init(dev, ac97_getmixerclass(), codec) == -1) goto bad;
 
 	tr->irqid = 0;
@@ -922,7 +923,6 @@ tr_pci_attach(device_t dev)
 		 rman_get_start(tr->reg), rman_get_start(tr->irq),
 		 device_get_nameunit(device_get_parent(dev)));
 
-	pcm_init(dev, tr);
 	pcm_addchan(dev, PCMDIR_REC, &trrchan_class, tr);
 	for (i = 0; i < dacn; i++)
 		pcm_addchan(dev, PCMDIR_PLAY, &trpchan_class, tr);
diff --git a/sys/dev/sound/pci/via8233.c b/sys/dev/sound/pci/via8233.c
index 90e966b864e3..69ffc6a9e3be 100644
--- a/sys/dev/sound/pci/via8233.c
+++ b/sys/dev/sound/pci/via8233.c
@@ -1331,6 +1331,7 @@ via_attach(device_t dev)
 	if (!via->codec)
 		goto bad;
 
+	pcm_init(dev, via);
 	mixer_init(dev, ac97_getmixerclass(), via->codec);
 
 	via->codec_caps = ac97_getextcaps(via->codec);
@@ -1350,7 +1351,6 @@ via_attach(device_t dev)
 	    device_get_nameunit(device_get_parent(dev)));
 
 	/* Register */
-	pcm_init(dev, via);
 	for (i = 0; i < via_dxs_chnum; i++)
 	      pcm_addchan(dev, PCMDIR_PLAY, &via8233dxs_class, via);
 	for (i = 0; i < via_sgd_chnum; i++)
diff --git a/sys/dev/sound/pci/via82c686.c b/sys/dev/sound/pci/via82c686.c
index 85356cc64145..b9fc1f9953fd 100644
--- a/sys/dev/sound/pci/via82c686.c
+++ b/sys/dev/sound/pci/via82c686.c
@@ -535,6 +535,7 @@ via_attach(device_t dev)
 	if (!via->codec)
 		goto bad;
 
+	pcm_init(dev, via);
 	if (mixer_init(dev, ac97_getmixerclass(), via->codec))
 		goto bad;
 
@@ -585,7 +586,6 @@ via_attach(device_t dev)
 		 device_get_nameunit(device_get_parent(dev)));
 
 	/* Register */
-	pcm_init(dev, via);
 	pcm_addchan(dev, PCMDIR_PLAY, &viachan_class, via);
 	pcm_addchan(dev, PCMDIR_REC, &viachan_class, via);
 	if (pcm_register(dev, status))
diff --git a/sys/dev/sound/pci/vibes.c b/sys/dev/sound/pci/vibes.c
index 08ba83a54d2a..445b8295085a 100644
--- a/sys/dev/sound/pci/vibes.c
+++ b/sys/dev/sound/pci/vibes.c
@@ -785,6 +785,8 @@ sv_attach(device_t dev) {
 	sv_power(sc, 0);
 	sv_init(sc);
 
+	pcm_init(dev, sc);
+
 	if (mixer_init(dev, &sv_mixer_class, sc) != 0) {
 		device_printf(dev, "sv_attach: Mixer failed to initialize\n");
 		goto fail;
@@ -867,7 +869,6 @@ sv_attach(device_t dev) {
 	if (bootverbose)
 		printf("Sonicvibes: revision %d.\n", sc->rev);
 
-	pcm_init(dev, sc);
         pcm_addchan(dev, PCMDIR_PLAY, &svpchan_class, sc);
         pcm_addchan(dev, PCMDIR_REC,  &svrchan_class, sc);
 
diff --git a/sys/dev/sound/usb/uaudio.c b/sys/dev/sound/usb/uaudio.c
index 491827c87f84..4e1d7c4c89d5 100644
--- a/sys/dev/sound/usb/uaudio.c
+++ b/sys/dev/sound/usb/uaudio.c
@@ -1204,13 +1204,6 @@ uaudio_attach_sub(device_t dev, kobj_class_t mixer_class, kobj_class_t chan_clas
 		DPRINTF("device needs bitperfect by default\n");
 		uaudio_pcm_setflags(dev, SD_F_BITPERFECT);
 	}
-	if (mixer_init(dev, mixer_class, sc))
-		goto detach;
-	mix_set(sc->sc_child[i].mixer_dev, SOUND_MIXER_MONITOR,
-	    UAUDIO_DEFAULT_MONITOR, UAUDIO_DEFAULT_MONITOR);
-	sc->sc_child[i].mixer_init = 1;
-
-	mixer_hwvol_init(dev);
 
 	device_set_descf(dev, "%s %s",
 	    usb_get_manufacturer(sc->sc_udev),
@@ -1223,6 +1216,14 @@ uaudio_attach_sub(device_t dev, kobj_class_t mixer_class, kobj_class_t chan_clas
 
 	uaudio_pcm_setflags(dev, SD_F_MPSAFE);
 
+	if (mixer_init(dev, mixer_class, sc))
+		goto detach;
+	mix_set(sc->sc_child[i].mixer_dev, SOUND_MIXER_MONITOR,
+	    UAUDIO_DEFAULT_MONITOR, UAUDIO_DEFAULT_MONITOR);
+	sc->sc_child[i].mixer_init = 1;
+
+	mixer_hwvol_init(dev);
+
 	if (sc->sc_play_chan[i].num_alt > 0) {
 		sc->sc_play_chan[i].priv_sc = sc;
 		pcm_addchan(dev, PCMDIR_PLAY, chan_class,