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 ?
> diff --git sys/dev/audio.c sys/dev/audio.c
> index 64696025a50..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
>
> /*
> @@ -2455,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))
> @@ -2569,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/usb/uaudio.c sys/dev/usb/uaudio.c
> index 0a19d512a5c..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, NULL, &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..fc5808bfeb1 100644
> --- sys/dev/usb/usb_subr.c
> +++ sys/dev/usb/usb_subr.c
> @@ -839,6 +839,7 @@ usbd_status
> usbd_probe_and_attach(struct device *parent, struct usbd_device *dev, int
> port,
> int addr)
> {
> + static char *cookie = 0;
> struct usb_attach_arg uaa;
> usb_device_descriptor_t *dd = &dev->ddesc;
> int i, confi, nifaces;
> @@ -860,6 +861,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/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
>