On Wed, Feb 09, 2022 at 09:13:58AM +0100, Alexandre Ratchov wrote:
> On Tue, Feb 08, 2022 at 06:59:39PM +0100, Anton Lindqvist wrote:
> > On Tue, Feb 08, 2022 at 07:32:38AM +0100, Alexandre Ratchov wrote:
> > > On Mon, Feb 07, 2022 at 06:55:21PM +0100, Anton Lindqvist wrote:
> > > > On Mon, Feb 07, 2022 at 11:21:43AM +0100, Alexandre Ratchov wrote:
> > > > > On Sun, Feb 06, 2022 at 08:40:35AM +0100, Anton Lindqvist wrote:
> > > > > > 
> > > > > > Polished diff. I'm omitting a necessary refactoring commit making
> > > > > > audio_attach_mi() accept a new cookie argument.
> > > > > > 
> > > > > 
> > > > > I'm not sure to understand the need for the wskbd_audio structure.
> > > > > Couldn't we just store the cookie in audio and wskbd softc structures,
> > > > > then pass it in the wskbd_set_mixervolume_sc() calls ?
> > > > 
> > > > Due to the device caching the data must be stored in either the audio or
> > > > wskbd softc and I don't want to expose the softc structures so I ended
> > > > up introducing wskbd_audio. Dropping the caching would probably make it
> > > > possible to only pass down the cookie to wskbd_set_mixervolume_sc() and
> > > > always do the audio device lookup.
> > > > 
> > > > Is anyone in favor of this approach? I achieves the expected behavior in
> > > > my opinion.
> > > 
> > > IMHO, handling the volume keys this way won't work in the general
> > > case. But for the short term we've no other options, have we?
> > > 
> > > AFAICS, you're fixing a concrete use-case by tweaking what already
> > > exists, this won't make things more broken than they already are. I'm
> > > OK with it.
> > 
> > Here's the complete diff including adding a cookie argument to
> > audio_attach_mi().
> 
> Is the caching necessary? device_lookup() seems cheap and there are at
> most two devices in most cases. Keeping the code minimal especially on
> rare and non-performace-critical code-paths would be nice.
> 
> If you choose to drop the caching, this would allow to just add a a
> new "cookie" argument to wskbd_set_mixervolume(), similarly to what
> you did for audio_attach_mi()

Sure, I ended up adding a new function after all since the
wskbd_set_mixervolume() prototype is not present in any header at this
point.

diff --git sys/arch/hppa/gsc/harmony.c sys/arch/hppa/gsc/harmony.c
index 033a3d2c356..d5748fac4b1 100644
--- sys/arch/hppa/gsc/harmony.c
+++ sys/arch/hppa/gsc/harmony.c
@@ -249,7 +249,7 @@ harmony_attach(parent, self, aux)
        if ((rev & CS4215_REV_VER) >= CS4215_REV_VER_E)
                sc->sc_hasulinear8 = 1;
 
-       audio_attach_mi(&harmony_sa_hw_if, sc, &sc->sc_dv);
+       audio_attach_mi(&harmony_sa_hw_if, sc, NULL, &sc->sc_dv);
 
        timeout_set(&sc->sc_acc_tmo, harmony_acc_tmo, sc);
        sc->sc_acc_num = 0xa5a5a5a5;
diff --git sys/arch/luna88k/cbus/nec86.c sys/arch/luna88k/cbus/nec86.c
index b6516cc4888..dc4e2069ddd 100644
--- sys/arch/luna88k/cbus/nec86.c
+++ sys/arch/luna88k/cbus/nec86.c
@@ -237,7 +237,7 @@ nec86_attachsubr(struct nec86_softc *sc)
 
        if (sc->sc_attached == 0) {
                printf(": %s\n", boardname[ysc->model]);
-               audio_attach_mi(&nec86_hw_if, ysc, &ysc->sc_dev);
+               audio_attach_mi(&nec86_hw_if, ysc, NULL, &ysc->sc_dev);
                sc->sc_attached = 1;
        }
 }
diff --git sys/arch/macppc/dev/aoa.c sys/arch/macppc/dev/aoa.c
index a2ca8e10a95..638da4b1669 100644
--- sys/arch/macppc/dev/aoa.c
+++ sys/arch/macppc/dev/aoa.c
@@ -134,7 +134,7 @@ aoa_defer(struct device *dev)
 {
        struct aoa_softc *sc = (struct aoa_softc *)dev;
 
-       audio_attach_mi(&aoa_hw_if, sc, &sc->sc_dev);
+       audio_attach_mi(&aoa_hw_if, sc, NULL, &sc->sc_dev);
        deq_reset(sc);
 }
 
diff --git sys/arch/macppc/dev/awacs.c sys/arch/macppc/dev/awacs.c
index 8ea7d4869a0..adcafcf79fb 100644
--- sys/arch/macppc/dev/awacs.c
+++ sys/arch/macppc/dev/awacs.c
@@ -340,7 +340,7 @@ awacs_attach(struct device *parent, struct device *self, 
void *aux)
        awacs_halt_input(sc);
        printf("\n");
 
-       audio_attach_mi(&awacs_hw_if, sc, &sc->sc_dev);
+       audio_attach_mi(&awacs_hw_if, sc, NULL, &sc->sc_dev);
 }
 
 u_int
diff --git sys/arch/macppc/dev/daca.c sys/arch/macppc/dev/daca.c
index 070b839c99a..91b078dd254 100644
--- sys/arch/macppc/dev/daca.c
+++ sys/arch/macppc/dev/daca.c
@@ -154,7 +154,7 @@ daca_defer(struct device *dev)
 
        /* XXX If i2c has failed to attach, what should we do? */
 
-       audio_attach_mi(&daca_hw_if, sc, &sc->sc_dev);
+       audio_attach_mi(&daca_hw_if, sc, NULL, &sc->sc_dev);
 
        daca_init(sc);
 }
diff --git sys/arch/macppc/dev/onyx.c sys/arch/macppc/dev/onyx.c
index c279258f091..9252d1c7376 100644
--- sys/arch/macppc/dev/onyx.c
+++ sys/arch/macppc/dev/onyx.c
@@ -165,7 +165,7 @@ onyx_defer(struct device *dev)
 
        /* XXX If i2c has failed to attach, what should we do? */
 
-       audio_attach_mi(&onyx_hw_if, sc, &sc->sc_dev);
+       audio_attach_mi(&onyx_hw_if, sc, NULL, &sc->sc_dev);
 
        deq_reset(sc);
        onyx_set_volume(sc, 192, 192);
diff --git sys/arch/macppc/dev/snapper.c sys/arch/macppc/dev/snapper.c
index 3fbf58aec0f..13784f6d207 100644
--- sys/arch/macppc/dev/snapper.c
+++ sys/arch/macppc/dev/snapper.c
@@ -486,7 +486,7 @@ snapper_defer(struct device *dev)
 
        /* XXX If i2c has failed to attach, what should we do? */
 
-       audio_attach_mi(&snapper_hw_if, sc, &sc->sc_dev);
+       audio_attach_mi(&snapper_hw_if, sc, NULL, &sc->sc_dev);
 
        /* kiic_setmode(sc->sc_i2c, I2C_STDSUBMODE); */
        snapper_init(sc);
diff --git sys/arch/macppc/dev/tumbler.c sys/arch/macppc/dev/tumbler.c
index 6c522a10585..4e2b1fc321a 100644
--- sys/arch/macppc/dev/tumbler.c
+++ sys/arch/macppc/dev/tumbler.c
@@ -299,7 +299,7 @@ tumbler_defer(struct device *dev)
 
        /* XXX If i2c has failed to attach, what should we do? */
 
-       audio_attach_mi(&tumbler_hw_if, sc, &sc->sc_dev);
+       audio_attach_mi(&tumbler_hw_if, sc, NULL, &sc->sc_dev);
 
        tumbler_init(sc);
 }
diff --git sys/arch/sparc64/dev/ce4231.c sys/arch/sparc64/dev/ce4231.c
index 5e97b0fb228..970d759ba3e 100644
--- sys/arch/sparc64/dev/ce4231.c
+++ sys/arch/sparc64/dev/ce4231.c
@@ -268,7 +268,7 @@ ce4231_attach(struct device *parent, struct device *self, 
void *aux)
 
        printf(": nvaddrs %d\n", ea->ea_nvaddrs);
 
-       audio_attach_mi(&ce4231_sa_hw_if, sc, &sc->sc_dev);
+       audio_attach_mi(&ce4231_sa_hw_if, sc, NULL, &sc->sc_dev);
 
        /* Enable mode 2. */
        ce4231_write(sc, SP_MISC_INFO, ce4231_read(sc, SP_MISC_INFO) | MODE2);
diff --git sys/dev/audio.c sys/dev/audio.c
index ec52ee6ef01..2344b48a4b4 100644
--- sys/dev/audio.c
+++ sys/dev/audio.c
@@ -96,6 +96,8 @@ struct wskbd_vol
 #define WSKBD_MUTE_DISABLE     2
 #define WSKBD_MUTE_ENABLE      3
 };
+
+int wskbd_set_mixervolume_unit(int, long, long);
 #endif
 
 /*
@@ -112,6 +114,7 @@ struct mixer_ev {
 struct audio_softc {
        struct device dev;
        struct audio_hw_if *ops;        /* driver funcs */
+       void *cookie;                   /* wskbd cookie */
        void *arg;                      /* first arg to driver funcs */
        int mode;                       /* bitmask of AUMODE_* */
        int quiesce;                    /* device suspended */
@@ -1236,6 +1239,7 @@ audio_attach(struct device *parent, struct device *self, 
void *aux)
        }
 #endif
        sc->ops = ops;
+       sc->cookie = sa->cookie;
        sc->arg = arg;
 
 #if NWSKBD > 0
@@ -1467,13 +1471,14 @@ audio_submatch(struct device *parent, void *match, void 
*aux)
 }
 
 struct device *
-audio_attach_mi(struct audio_hw_if *ops, void *arg, struct device *dev)
+audio_attach_mi(struct audio_hw_if *ops, void *arg, void *cookie, struct 
device *dev)
 {
        struct audio_attach_args aa;
 
        aa.type = AUDIODEV_TYPE_AUDIO;
        aa.hwif = ops;
        aa.hdl = arg;
+       aa.cookie = cookie;
 
        /*
         * attach this driver to the caller (hardware driver), this
@@ -2452,10 +2457,6 @@ wskbd_mixer_init(struct audio_softc *sc)
        };
        int i;
 
-       if (sc->dev.dv_unit != 0) {
-               DPRINTF("%s: not configuring wskbd keys\n", DEVNAME(sc));
-               return;
-       }
        for (i = 0; i < sizeof(spkr_names) / sizeof(spkr_names[0]); i++) {
                if (wskbd_initvol(sc, &sc->spkr,
                        spkr_names[i].cn, spkr_names[i].dn))
@@ -2566,13 +2567,48 @@ wskbd_set_mixermute(long mute, long out)
        return 0;
 }
 
+/*
+ * Adjust the volume of the audio device associated with the given cookie.
+ * Otherwise, fallback to audio0.
+ */
+int
+wskbd_set_mixervolume_dev(void *cookie, long dir, long out)
+{
+       int unit = 0;
+       int i;
+
+       for (i = 0; i < audio_cd.cd_ndevs; i++) {
+               struct audio_softc *sc;
+
+               sc = (struct audio_softc *)device_lookup(&audio_cd, i);
+               if (sc == NULL)
+                       continue;
+               if (sc->cookie != cookie) {
+                       device_unref(&sc->dev);
+                       continue;
+               }
+
+               device_unref(&sc->dev);
+               unit = i;
+               break;
+       }
+
+       return wskbd_set_mixervolume_unit(unit, dir, out);
+}
+
 int
 wskbd_set_mixervolume(long dir, long out)
+{
+       return wskbd_set_mixervolume_unit(0, dir, out);
+}
+
+int
+wskbd_set_mixervolume_unit(int unit, long dir, long out)
 {
        struct audio_softc *sc;
        struct wskbd_vol *vol;
 
-       sc = (struct audio_softc *)device_lookup(&audio_cd, 0);
+       sc = (struct audio_softc *)device_lookup(&audio_cd, unit);
        if (sc == NULL)
                return ENODEV;
        vol = out ? &sc->spkr : &sc->mic;
diff --git sys/dev/audio_if.h sys/dev/audio_if.h
index 8b96211bced..d9d026521e3 100644
--- sys/dev/audio_if.h
+++ sys/dev/audio_if.h
@@ -143,6 +143,7 @@ struct audio_attach_args {
        int     type;
        void    *hwif;          /* either audio_hw_if * or midi_hw_if * */
        void    *hdl;
+       void    *cookie;
 };
 #define        AUDIODEV_TYPE_AUDIO     0
 #define        AUDIODEV_TYPE_MIDI      1
@@ -151,7 +152,7 @@ struct audio_attach_args {
 #define AUDIODEV_TYPE_RADIO    4
 
 /* Attach the MI driver(s) to the MD driver. */
-struct device *audio_attach_mi(struct audio_hw_if *, void *, struct device *);
+struct device *audio_attach_mi(struct audio_hw_if *, void *, void *, struct 
device *);
 int           audioprint(void *, const char *);
 int           audio_blksz_bytes(int,
                   struct audio_params *, struct audio_params *, int);
diff --git sys/dev/fdt/graphaudio.c sys/dev/fdt/graphaudio.c
index bf2889306bf..4cdd22de07d 100644
--- sys/dev/fdt/graphaudio.c
+++ sys/dev/fdt/graphaudio.c
@@ -186,7 +186,7 @@ graphaudio_attach_deferred(struct device *self)
 
        graphaudio_set_format(sc, fmt, pol, clk);
 
-       audio_attach_mi(&graphaudio_hw_if, sc, &sc->sc_dev);
+       audio_attach_mi(&graphaudio_hw_if, sc, NULL, &sc->sc_dev);
 }
 
 void
diff --git sys/dev/fdt/simpleaudio.c sys/dev/fdt/simpleaudio.c
index 055f2e78e10..2b8153c7267 100644
--- sys/dev/fdt/simpleaudio.c
+++ sys/dev/fdt/simpleaudio.c
@@ -206,7 +206,7 @@ simpleaudio_attach_deferred(struct device *self)
 
        simpleaudio_set_format(sc, fmt, pol, clk);
 
-       audio_attach_mi(&simpleaudio_hw_if, sc, &sc->sc_dev);
+       audio_attach_mi(&simpleaudio_hw_if, sc, NULL, &sc->sc_dev);
 }
 
 void
diff --git sys/dev/ic/arcofi.c sys/dev/ic/arcofi.c
index 9c34840db1a..8cd20b904d2 100644
--- sys/dev/ic/arcofi.c
+++ sys/dev/ic/arcofi.c
@@ -1125,7 +1125,7 @@ arcofi_attach(struct arcofi_softc *sc, const char 
*version)
        arcofi_write(sc, ARCOFI_FIFO_IR, 0);
        arcofi_write(sc, ARCOFI_CSR, CSR_INTR_ENABLE);
 
-       audio_attach_mi(&arcofi_hw_if, sc, &sc->sc_dev);
+       audio_attach_mi(&arcofi_hw_if, sc, NULL, &sc->sc_dev);
        return;
 
 error:
diff --git sys/dev/isa/ess.c sys/dev/isa/ess.c
index 221bfb46b0f..35f74932cfc 100644
--- sys/dev/isa/ess.c
+++ sys/dev/isa/ess.c
@@ -975,9 +975,9 @@ essattach(struct ess_softc *sc)
        sc->spkr_state = SPKR_OFF;
 
        if (ESS_USE_AUDIO1(sc->sc_model))
-               audio_attach_mi(&ess_1788_hw_if, sc, &sc->sc_dev);
+               audio_attach_mi(&ess_1788_hw_if, sc, NULL, &sc->sc_dev);
        else
-               audio_attach_mi(&ess_1888_hw_if, sc, &sc->sc_dev);
+               audio_attach_mi(&ess_1888_hw_if, sc, NULL, &sc->sc_dev);
 
        arg.type = AUDIODEV_TYPE_OPL;
        arg.hwif = 0;
diff --git sys/dev/isa/gus.c sys/dev/isa/gus.c
index 32dc84502d7..2959e081762 100644
--- sys/dev/isa/gus.c
+++ sys/dev/isa/gus.c
@@ -3398,7 +3398,7 @@ gus_subattach(struct gus_softc *sc, struct 
isa_attach_args *ia)
         */
 
        audio_attach_mi(&gus_hw_if, HAS_CODEC(sc) ? (void *)&sc->sc_codec :
-           (void *)sc, &sc->sc_dev);
+           (void *)sc, NULL, &sc->sc_dev);
 }
 
 /*
diff --git sys/dev/isa/pas.c sys/dev/isa/pas.c
index fd3363d0ec8..52e7ca516ba 100644
--- sys/dev/isa/pas.c
+++ sys/dev/isa/pas.c
@@ -398,5 +398,5 @@ pasattach(struct device *parent, struct device *self, void 
*aux)
        
        sbdsp_attach(&sc->sc_sbdsp);
 
-       audio_attach_mi(&pas_hw_if, &sc->sc_sbdsp, &sc->sc_sbdsp.sc_dev);
+       audio_attach_mi(&pas_hw_if, &sc->sc_sbdsp, NULL, &sc->sc_sbdsp.sc_dev);
 }
diff --git sys/dev/isa/sb.c sys/dev/isa/sb.c
index 9458d043c4e..3bd1d041211 100644
--- sys/dev/isa/sb.c
+++ sys/dev/isa/sb.c
@@ -264,7 +264,7 @@ sbattach(struct sbdsp_softc *sc)
        midi_attach_mi(mhw, sc, &sc->sc_dev);
 #endif
 
-       audio_attach_mi(&sb_hw_if, sc, &sc->sc_dev);
+       audio_attach_mi(&sb_hw_if, sc, NULL, &sc->sc_dev);
 
        arg.type = AUDIODEV_TYPE_OPL;
        arg.hwif = 0;
diff --git sys/dev/pci/auacer.c sys/dev/pci/auacer.c
index c42f78e0abb..20baabc2397 100644
--- sys/dev/pci/auacer.c
+++ sys/dev/pci/auacer.c
@@ -274,7 +274,7 @@ auacer_attach(struct device *parent, struct device *self, 
void *aux)
        if (ac97_attach(&sc->host_if) != 0)
                return;
 
-       audio_attach_mi(&auacer_hw_if, sc, &sc->sc_dev);
+       audio_attach_mi(&auacer_hw_if, sc, NULL, &sc->sc_dev);
 
        auacer_reset(sc);
 }
diff --git sys/dev/pci/auglx.c sys/dev/pci/auglx.c
index 84bbf238a5b..bd0c50aa2cc 100644
--- sys/dev/pci/auglx.c
+++ sys/dev/pci/auglx.c
@@ -334,7 +334,7 @@ auglx_attach(struct device *parent, struct device *self, 
void *aux)
                bus_space_unmap(sc->sc_iot, sc->sc_ioh, bar_size);
                return;
        }
-       audio_attach_mi(&auglx_hw_if, sc, &sc->sc_dev);
+       audio_attach_mi(&auglx_hw_if, sc, NULL, &sc->sc_dev);
 }
 
 /* Functions to communicate with the AC97 Codec via the ACC */
diff --git sys/dev/pci/auich.c sys/dev/pci/auich.c
index ab1403a6c73..918b57098db 100644
--- sys/dev/pci/auich.c
+++ sys/dev/pci/auich.c
@@ -512,7 +512,7 @@ auich_attach(struct device *parent, struct device *self, 
void *aux)
                goto fail_disestablish_intr;
        sc->codec_if->vtbl->unlock(sc->codec_if);
 
-       audio_attach_mi(&auich_hw_if, sc, &sc->sc_dev);
+       audio_attach_mi(&auich_hw_if, sc, NULL, &sc->sc_dev);
 
        /* Watch for power changes */
        sc->suspend = DVACT_RESUME;
diff --git sys/dev/pci/auixp.c sys/dev/pci/auixp.c
index 578572e1a91..71dca689d12 100644
--- sys/dev/pci/auixp.c
+++ sys/dev/pci/auixp.c
@@ -1035,7 +1035,7 @@ auixp_post_config(struct device *self)
                return;
        }
 
-       audio_attach_mi(&auixp_hw_if, &sc->sc_codec, &sc->sc_dev);
+       audio_attach_mi(&auixp_hw_if, &sc->sc_codec, NULL, &sc->sc_dev);
 
        if (sc->has_spdif)
                sc->has_spdif = 0;
diff --git sys/dev/pci/autri.c sys/dev/pci/autri.c
index 7f85a254b81..57e38754a85 100644
--- sys/dev/pci/autri.c
+++ sys/dev/pci/autri.c
@@ -574,7 +574,7 @@ autri_attach(struct device *parent, struct device *self, 
void *aux)
        ctl.dev = autri_get_portnum_by_name(sc,AudioCoutputs,AudioNmaster,NULL);
        autri_mixer_set_port(sc, &ctl);
 
-       audio_attach_mi(&autri_hw_if, sc, &sc->sc_dev);
+       audio_attach_mi(&autri_hw_if, sc, NULL, &sc->sc_dev);
 
 #if NMIDI > 0
        midi_attach_mi(&autri_midi_hw_if, sc, &sc->sc_dev);
diff --git sys/dev/pci/auvia.c sys/dev/pci/auvia.c
index 8ca4e924543..9fec1acff44 100644
--- sys/dev/pci/auvia.c
+++ sys/dev/pci/auvia.c
@@ -346,7 +346,7 @@ auvia_attach(struct device *parent, struct device *self, 
void *aux)
            AudioCoutputs, AudioNmaster, NULL);
        auvia_set_port(sc, &ctl);
 
-       audio_attach_mi(&auvia_hw_if, sc, &sc->sc_dev);
+       audio_attach_mi(&auvia_hw_if, sc, NULL, &sc->sc_dev);
        sc->codec_if->vtbl->unlock(sc->codec_if);
 }
 
diff --git sys/dev/pci/azalia.c sys/dev/pci/azalia.c
index 83fa8d1d7f0..f5195374942 100644
--- sys/dev/pci/azalia.c
+++ sys/dev/pci/azalia.c
@@ -588,7 +588,7 @@ azalia_pci_attach(struct device *parent, struct device 
*self, void *aux)
        if (azalia_init_streams(sc))
                goto err_exit;
 
-       audio_attach_mi(&azalia_hw_if, sc, &sc->dev);
+       audio_attach_mi(&azalia_hw_if, sc, NULL, &sc->dev);
 
        return;
 
diff --git sys/dev/pci/cmpci.c sys/dev/pci/cmpci.c
index 40ebb9bad7d..b83489223bc 100644
--- sys/dev/pci/cmpci.c
+++ sys/dev/pci/cmpci.c
@@ -392,7 +392,7 @@ cmpci_attach(struct device *parent, struct device *self, 
void *aux)
 
        sc->sc_dmat = pa->pa_dmat;
 
-       audio_attach_mi(&cmpci_hw_if, sc, &sc->sc_dev);
+       audio_attach_mi(&cmpci_hw_if, sc, NULL, &sc->sc_dev);
 
        /* attach OPL device */
        aa.type = AUDIODEV_TYPE_OPL;
diff --git sys/dev/pci/cs4280.c sys/dev/pci/cs4280.c
index f24d6d75dda..bac42d932e9 100644
--- sys/dev/pci/cs4280.c
+++ sys/dev/pci/cs4280.c
@@ -548,7 +548,7 @@ cs4280_attachhook(struct device *self)
                                             AudioNcd, AudioNmute);
        cs4280_mixer_set_port(sc, &ctl);
 
-       audio_attach_mi(&cs4280_hw_if, sc, &sc->sc_dev);
+       audio_attach_mi(&cs4280_hw_if, sc, NULL, &sc->sc_dev);
 
 #if NMIDI > 0
        midi_attach_mi(&cs4280_midi_hw_if, sc, &sc->sc_dev);
diff --git sys/dev/pci/cs4281.c sys/dev/pci/cs4281.c
index ac2ae6bccf4..818d7e708fb 100644
--- sys/dev/pci/cs4281.c
+++ sys/dev/pci/cs4281.c
@@ -327,7 +327,7 @@ cs4281_attach(struct device *parent, struct device *self, 
void *aux)
                printf("%s: ac97_attach failed\n", sc->sc_dev.dv_xname);
                return;
        }
-       audio_attach_mi(&cs4281_hw_if, sc, &sc->sc_dev);
+       audio_attach_mi(&cs4281_hw_if, sc, NULL, &sc->sc_dev);
 
 #if NMIDI > 0
        midi_attach_mi(&cs4281_midi_hw_if, sc, &sc->sc_dev);
diff --git sys/dev/pci/eap.c sys/dev/pci/eap.c
index 18662619337..d99b39df8f6 100644
--- sys/dev/pci/eap.c
+++ sys/dev/pci/eap.c
@@ -588,7 +588,7 @@ eap_attach(struct device *parent, struct device *self, void 
*aux)
                eap_hw_if = &eap1371_hw_if;
        }
 
-       audio_attach_mi(eap_hw_if, sc, &sc->sc_dev);
+       audio_attach_mi(eap_hw_if, sc, NULL, &sc->sc_dev);
 #if NMIDI > 0
        sc->sc_mididev = midi_attach_mi(&eap_midi_hw_if, sc, &sc->sc_dev);
 #endif
diff --git sys/dev/pci/emuxki.c sys/dev/pci/emuxki.c
index 35ae40dda02..daf338c9317 100644
--- sys/dev/pci/emuxki.c
+++ sys/dev/pci/emuxki.c
@@ -474,7 +474,7 @@ emuxki_attach(struct device *parent, struct device *self, 
void *aux)
        if (emuxki_scinit(sc, 0) ||
            /* APS has no ac97 XXX */
            (sc->sc_flags & EMUXKI_APS || emuxki_ac97_init(sc)) ||
-           (sc->sc_audev = audio_attach_mi(&emuxki_hw_if, sc, self)) == NULL) {
+           (sc->sc_audev = audio_attach_mi(&emuxki_hw_if, sc, NULL, self)) == 
NULL) {
                emuxki_pci_shutdown(sc);
                return;
        }
diff --git sys/dev/pci/envy.c sys/dev/pci/envy.c
index c43bbf43ece..5b0b9a1516a 100644
--- sys/dev/pci/envy.c
+++ sys/dev/pci/envy.c
@@ -1761,7 +1761,7 @@ envyattach(struct device *parent, struct device *self, 
void *aux)
        printf("%s: %s, %u inputs, %u outputs\n", DEVNAME(sc),
            sc->card->name, sc->card->nich, sc->card->noch);
        envy_reset(sc);
-       sc->audio = audio_attach_mi(&envy_hw_if, sc, &sc->dev);
+       sc->audio = audio_attach_mi(&envy_hw_if, sc, NULL, &sc->dev);
 #if NMIDI > 0
        if (sc->card->nmidi > 0 && (!sc->isht ||
                sc->eeprom[ENVY_EEPROM_CONF] & ENVY_CONF_MIDI)) {
diff --git sys/dev/pci/esa.c sys/dev/pci/esa.c
index 286db17038b..79f12f056d5 100644
--- sys/dev/pci/esa.c
+++ sys/dev/pci/esa.c
@@ -1048,7 +1048,7 @@ esa_attach(struct device *parent, struct device *self, 
void *aux)
                sc->voice[i].parent = (struct device *)sc;
                sc->voice[i].index = i;
                sc->sc_audiodev[i] =
-                   audio_attach_mi(&esa_hw_if, &sc->voice[i], &sc->sc_dev);
+                   audio_attach_mi(&esa_hw_if, &sc->voice[i], NULL, 
&sc->sc_dev);
        }
 }
 
diff --git sys/dev/pci/eso.c sys/dev/pci/eso.c
index 3df0f89b01b..0cef207475a 100644
--- sys/dev/pci/eso.c
+++ sys/dev/pci/eso.c
@@ -289,7 +289,7 @@ eso_attach(struct device *parent, struct device *self, void 
*aux)
                config_defer((struct device *)sc, eso_defer);
        }
        
-       audio_attach_mi(&eso_hw_if, sc, &sc->sc_dev);
+       audio_attach_mi(&eso_hw_if, sc, NULL, &sc->sc_dev);
 
        aa.type = AUDIODEV_TYPE_OPL;
        aa.hwif = NULL;
diff --git sys/dev/pci/fms.c sys/dev/pci/fms.c
index b07694ff71a..593f36aa34a 100644
--- sys/dev/pci/fms.c
+++ sys/dev/pci/fms.c
@@ -256,7 +256,7 @@ fms_attach(struct device *parent, struct device *self, void 
*aux)
                fms_set_port(sc, &ctl);
        }
 
-       audio_attach_mi(&fms_hw_if, sc, &sc->sc_dev);
+       audio_attach_mi(&fms_hw_if, sc, NULL, &sc->sc_dev);
 
        aa.type = AUDIODEV_TYPE_OPL;
        aa.hwif = NULL;
diff --git sys/dev/pci/maestro.c sys/dev/pci/maestro.c
index f3523120203..b44a650b1ec 100644
--- sys/dev/pci/maestro.c
+++ sys/dev/pci/maestro.c
@@ -727,7 +727,7 @@ maestro_attach(struct device *parent, struct device *self, 
void *aux)
        sc->record.mode = 0;
 
        /* Attach audio */
-       audio_attach_mi(&maestro_hw_if, sc, &sc->dev);
+       audio_attach_mi(&maestro_hw_if, sc, NULL, &sc->dev);
        return;
 
  bad:
diff --git sys/dev/pci/neo.c sys/dev/pci/neo.c
index 3548c09f2da..2149e922df4 100644
--- sys/dev/pci/neo.c
+++ sys/dev/pci/neo.c
@@ -597,7 +597,7 @@ neo_attach(struct device *parent, struct device *self, void 
*aux)
        if ((error = ac97_attach(&sc->host_if)) != 0)
                return;
 
-       audio_attach_mi(&neo_hw_if, sc, &sc->dev);
+       audio_attach_mi(&neo_hw_if, sc, NULL, &sc->dev);
 
        return;
 }
diff --git sys/dev/pci/sv.c sys/dev/pci/sv.c
index 40e38941a0a..0142a63761b 100644
--- sys/dev/pci/sv.c
+++ sys/dev/pci/sv.c
@@ -357,7 +357,7 @@ sv_attach(struct device *parent, struct device *self, void 
*aux)
 
   sv_init_mixer(sc);
 
-  audio_attach_mi(&sv_hw_if, sc, &sc->sc_dev);
+  audio_attach_mi(&sv_hw_if, sc, NULL, &sc->sc_dev);
 }
 
 #ifdef AUDIO_DEBUG
diff --git sys/dev/pci/yds.c sys/dev/pci/yds.c
index 010665375d7..6e34749d336 100644
--- sys/dev/pci/yds.c
+++ sys/dev/pci/yds.c
@@ -785,7 +785,7 @@ yds_attachhook(struct device *self)
                sc->sc_codec[0].codec_if, AudioCoutputs, AudioNmaster, NULL);
        yds_mixer_set_port(sc, &ctl);
 
-       audio_attach_mi(&yds_hw_if, sc, &sc->sc_dev);
+       audio_attach_mi(&yds_hw_if, sc, NULL, &sc->sc_dev);
 
        /* Watch for power changes */
        sc->suspend = DVACT_RESUME;
diff --git sys/dev/sbus/cs4231.c sys/dev/sbus/cs4231.c
index 959b9bee704..91d3956d1f6 100644
--- sys/dev/sbus/cs4231.c
+++ sys/dev/sbus/cs4231.c
@@ -243,7 +243,7 @@ cs4231_attach(struct device *parent, struct device *self, 
void *aux)
 
        printf("\n");
 
-       audio_attach_mi(&cs4231_sa_hw_if, sc, &sc->sc_dev);
+       audio_attach_mi(&cs4231_sa_hw_if, sc, NULL, &sc->sc_dev);
 
        /* Default to speaker, unmuted, reasonable volume */
        sc->sc_out_port = CSPORT_SPEAKER;
diff --git sys/dev/tc/bba.c sys/dev/tc/bba.c
index 41c7b43a8ce..097df1cd201 100644
--- sys/dev/tc/bba.c
+++ sys/dev/tc/bba.c
@@ -229,7 +229,7 @@ bba_attach(struct device *parent, struct device *self, void 
*aux)
        ioasic_intr_establish(parent, ia->iada_cookie, IPL_AUDIO,
            bba_intr, sc, self->dv_xname);
 
-       audio_attach_mi(&bba_hw_if, sc, self);
+       audio_attach_mi(&bba_hw_if, sc, NULL, self);
 }
 
 void
diff --git sys/dev/usb/uaudio.c sys/dev/usb/uaudio.c
index 025892ddf04..d86019311e0 100644
--- sys/dev/usb/uaudio.c
+++ sys/dev/usb/uaudio.c
@@ -3841,7 +3841,7 @@ uaudio_attach(struct device *parent, struct device *self, 
void *aux)
        /* print a nice uaudio attach line */
        uaudio_print(sc);
 
-       audio_attach_mi(&uaudio_hw_if, sc, &sc->dev);
+       audio_attach_mi(&uaudio_hw_if, sc, arg->cookie, &sc->dev);
 }
 
 int
diff --git sys/dev/usb/ucc.c sys/dev/usb/ucc.c
index f23f32990bb..705a31b327b 100644
--- sys/dev/usb/ucc.c
+++ sys/dev/usb/ucc.c
@@ -104,7 +104,7 @@ void        ucc_attach(struct device *, struct device *, 
void *);
 int    ucc_detach(struct device *, int);
 void   ucc_intr(struct uhidev *, void *, u_int);
 
-void   ucc_attach_wskbd(struct ucc_softc *);
+void   ucc_attach_wskbd(struct ucc_softc *, void *);
 int    ucc_enable(void *, int);
 void   ucc_set_leds(void *, int);
 int    ucc_ioctl(void *, u_long, caddr_t, int, struct proc *);
@@ -680,7 +680,7 @@ ucc_attach(struct device *parent, struct device *self, void 
*aux)
 
        /* Cannot load an empty map. */
        if (sc->sc_maplen > 0)
-               ucc_attach_wskbd(sc);
+               ucc_attach_wskbd(sc, uha->uaa->cookie);
 }
 
 int
@@ -772,7 +772,7 @@ unknown:
 }
 
 void
-ucc_attach_wskbd(struct ucc_softc *sc)
+ucc_attach_wskbd(struct ucc_softc *sc, void *cookie)
 {
        static const struct wskbd_accessops accessops = {
                .enable         = ucc_enable,
@@ -784,6 +784,7 @@ ucc_attach_wskbd(struct ucc_softc *sc)
                .keymap         = &sc->sc_keymap,
                .accessops      = &accessops,
                .accesscookie   = sc,
+               .audiocookie    = cookie,
        };
 
        sc->sc_keydesc[0].name = KB_US;
diff --git sys/dev/usb/usb_subr.c sys/dev/usb/usb_subr.c
index 7d8480f0f01..f5cd81dcf2d 100644
--- sys/dev/usb/usb_subr.c
+++ sys/dev/usb/usb_subr.c
@@ -839,6 +839,11 @@ usbd_status
 usbd_probe_and_attach(struct device *parent, struct usbd_device *dev, int port,
     int addr)
 {
+       /*
+        * Used to correlate audio and wskbd devices as this is the common point
+        * of attachment between the two.
+        */
+       static char *cookie = 0;
        struct usb_attach_arg uaa;
        usb_device_descriptor_t *dd = &dev->ddesc;
        int i, confi, nifaces;
@@ -860,6 +865,7 @@ usbd_probe_and_attach(struct device *parent, struct 
usbd_device *dev, int port,
        uaa.vendor = UGETW(dd->idVendor);
        uaa.product = UGETW(dd->idProduct);
        uaa.release = UGETW(dd->bcdDevice);
+       uaa.cookie = ++cookie;
 
        /* First try with device specific drivers. */
        DPRINTF(("usbd_probe_and_attach trying device specific drivers\n"));
diff --git sys/dev/usb/usbdi.h sys/dev/usb/usbdi.h
index 05209bcb809..15404ffe9bd 100644
--- sys/dev/usb/usbdi.h
+++ sys/dev/usb/usbdi.h
@@ -227,6 +227,7 @@ struct usb_attach_arg {
        int                     usegeneric;
        struct usbd_interface   **ifaces;/* all interfaces */
        int                     nifaces; /* number of interfaces */
+       void                    *cookie;
 };
 
 /* Match codes. */
diff --git sys/dev/usb/utvfu.c sys/dev/usb/utvfu.c
index 6f99460f1db..59b1508a3e0 100644
--- sys/dev/usb/utvfu.c
+++ sys/dev/usb/utvfu.c
@@ -958,7 +958,7 @@ utvfu_attach(struct device *parent, struct device *self, 
void *aux)
 
        rw_init(&sc->sc_audio.rwlock, "audiorwl");
 
-       sc->sc_audiodev = audio_attach_mi(&utvfu_au_hw_if, sc, &sc->sc_dev);
+       sc->sc_audiodev = audio_attach_mi(&utvfu_au_hw_if, sc, NULL, 
&sc->sc_dev);
        sc->sc_videodev = video_attach_mi(&utvfu_vid_hw_if, sc, &sc->sc_dev);
 }
 
diff --git sys/dev/wscons/wskbd.c sys/dev/wscons/wskbd.c
index 5693a5b614e..d0e062ecbfb 100644
--- sys/dev/wscons/wskbd.c
+++ sys/dev/wscons/wskbd.c
@@ -169,6 +169,10 @@ struct wskbd_softc {
 
        int     sc_refcnt;
        u_char  sc_dying;               /* device is being detached */
+
+#if NAUDIO > 0
+       void    *sc_audiocookie;
+#endif
 };
 
 #define MOD_SHIFT_L            (1 << 0)
@@ -307,7 +311,7 @@ static struct wskbd_internal wskbd_console_data;
 void   wskbd_update_layout(struct wskbd_internal *, kbd_t);
 
 #if NAUDIO > 0
-extern int wskbd_set_mixervolume(long, long);
+extern int wskbd_set_mixervolume_dev(void *, long, long);
 #endif
 
 void
@@ -395,6 +399,10 @@ wskbd_attach(struct device *parent, struct device *self, 
void *aux)
        timeout_set(&sc->sc_repeat_ch, wskbd_repeat, sc);
 #endif
 
+#if NAUDIO > 0
+       sc->sc_audiocookie = ap->audiocookie;
+#endif
+
        sc->id->t_sc = sc;
 
        sc->sc_accessops = ap->accessops;
@@ -1766,13 +1774,13 @@ wskbd_translate(struct wskbd_internal *id, u_int type, 
int value)
                switch (ksym) {
 #if NAUDIO > 0
                case KS_AudioMute:
-                       wskbd_set_mixervolume(0, 1);
+                       wskbd_set_mixervolume_dev(sc->sc_audiocookie, 0, 1);
                        return (0);
                case KS_AudioLower:
-                       wskbd_set_mixervolume(-1, 1);
+                       wskbd_set_mixervolume_dev(sc->sc_audiocookie, -1, 1);
                        return (0);
                case KS_AudioRaise:
-                       wskbd_set_mixervolume(1, 1);
+                       wskbd_set_mixervolume_dev(sc->sc_audiocookie, 1, 1);
                        return (0);
 #endif
                default:
diff --git sys/dev/wscons/wskbdvar.h sys/dev/wscons/wskbdvar.h
index 91bca39e30f..30f3b8b7560 100644
--- sys/dev/wscons/wskbdvar.h
+++ sys/dev/wscons/wskbdvar.h
@@ -71,6 +71,8 @@ struct wskbddev_attach_args {
 
        const struct wskbd_accessops *accessops;        /* access ops */
        void    *accesscookie;                          /* access cookie */
+
+       void    *audiocookie;
 };
 
 #define        WSKBDDEVCF_CONSOLE      0

Reply via email to