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().
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..f2b40637771 100644
--- sys/dev/audio.c
+++ sys/dev/audio.c
@@ -28,6 +28,7 @@
#include <sys/audioio.h>
#include <dev/audio_if.h>
#include <dev/mulaw.h>
+#include <dev/wscons/wskbdvar.h> /* struct wskbd_audio */
#include "audio.h"
#include "wskbd.h"
@@ -96,6 +97,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 +115,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 +1240,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 +1472,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 +2458,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 +2568,55 @@ wskbd_set_mixermute(long mute, long out)
return 0;
}
+int
+wskbd_set_mixervolume_sc(struct wskbd_audio *audio, long dir, long out)
+{
+ if (audio->dev != NULL) {
+ if ((audio->dev->dv_flags & DVF_ACTIVE) == 0) {
+ /* Audio device gone, fallback to audio0. */
+ device_unref(audio->dev);
+ audio->dev = NULL;
+ audio->unit = 0;
+ }
+ } else if (audio->cookie != NULL) {
+ void *cookie;
+ int i;
+
+ cookie = audio->cookie;
+ audio->cookie = NULL;
+ 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;
+ }
+
+ audio->dev = (struct device *)sc;
+ audio->unit = i;
+ break;
+ }
+ }
+
+ return wskbd_set_mixervolume_unit(audio->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..e0a73830a2d 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
+ struct wskbd_audio sc_audio;
+#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_sc(struct wskbd_audio *, 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_audio.cookie = ap->audiocookie;
+#endif
+
sc->id->t_sc = sc;
sc->sc_accessops = ap->accessops;
@@ -608,6 +616,11 @@ wskbd_detach(struct device *self, int flags)
}
#endif
+#if NAUDIO > 0
+ if (sc->sc_audio.dev != NULL)
+ device_unref(sc->sc_audio.dev);
+#endif
+
if (sc->sc_isconsole) {
KASSERT(wskbd_console_device == sc);
wskbd_cndetach();
@@ -1766,13 +1779,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_sc(&sc->sc_audio, 0, 1);
return (0);
case KS_AudioLower:
- wskbd_set_mixervolume(-1, 1);
+ wskbd_set_mixervolume_sc(&sc->sc_audio, -1, 1);
return (0);
case KS_AudioRaise:
- wskbd_set_mixervolume(1, 1);
+ wskbd_set_mixervolume_sc(&sc->sc_audio, 1, 1);
return (0);
#endif
default:
diff --git sys/dev/wscons/wskbdvar.h sys/dev/wscons/wskbdvar.h
index 91bca39e30f..ce0d88d6350 100644
--- sys/dev/wscons/wskbdvar.h
+++ sys/dev/wscons/wskbdvar.h
@@ -61,6 +61,15 @@ struct wskbd_consops {
void (*debugger)(void *);
};
+/*
+ * Audio device associated with keyboard.
+ */
+struct wskbd_audio {
+ void *cookie;
+ struct device *dev;
+ int unit;
+};
+
/*
* Attachment information provided by wskbddev devices when attaching
* wskbd units.
@@ -71,6 +80,8 @@ struct wskbddev_attach_args {
const struct wskbd_accessops *accessops; /* access ops */
void *accesscookie; /* access cookie */
+
+ void *audiocookie;
};
#define WSKBDDEVCF_CONSOLE 0