On Sun, Mar 06, 2022 at 07:34:37PM +0100, Caspar Schutijser wrote:
> Hi,
> 
> I have a problem (described below) that is absent on a kernel that I
> compiled myself. Is there some (USB) audio diff in snapshots that
> could cause this? Otherwise, there may be something wrong with my
> testing.

No related diff(s) in snapshots that I'm aware of.

> The problem starts when I press the volume-up or volume-down button on
> my uaudio(4) headset (once or a couple of times). These are the
> symptoms:
>  * When watching systat -s 1, ehci0 shows 50 interrupts per second
> (that's still normal). When I press one of the physical volume buttons
> on the headset [a couple of times], it jumps to +/- 480 interrupts
> per second.
>  * xterm behaves normally (it processes my keystrokes as usual) but
> providing keyboard or mouse input to Firefox becomes problematic;
> it takes a very long time before they are processed by Firefox.
>  * In the mpv program, pressing the volume-down button on my headset
> causes the volume to go down to 0, as if the button was pressed
> continiously. And the volume goes up to 130 when I press the volume-up
> button. When I press the 'Alt' key, mpv logs the following to the
> console repeatedly:
>     [input] No key binding found for key 'Alt+VOLUME_DOWN'.
> 
> From the last point, it appears that somehow once I press the
> volume-down button, it appears to the computer that the button is
> pressed continiously (which is not the case).
> 
> Those problems (the high number of interrupts, the "key pressing")
> go away immediately if I unplug the USB dongle that connects my
> headset to this machine. And if I plug it back in again,
> the problems stay away until I press the volume buttons again.
> 
> Also, those problems do not appear on a Linux box that I used to test
> (to rule out issues with the headset itself).

Could you try reverting the following diff and report back if the
interrupt storm still happens after pressing the volume keys.
Also, could you extract the raw HID report for your headset using the
following command:

        # usbhidctl -R -f /dev/uhid0

diff --git sys/dev/audio.c sys/dev/audio.c
index 856a88bae98..d5bf6750d48 100644
--- sys/dev/audio.c
+++ sys/dev/audio.c
@@ -1,4 +1,4 @@
-/*     $OpenBSD: audio.c,v 1.195 2022/02/16 06:21:18 anton Exp $       */
+/*     $OpenBSD: audio.c,v 1.196 2022/02/16 06:23:42 anton Exp $       */
 /*
  * Copyright (c) 2015 Alexandre Ratchov <[email protected]>
  *
@@ -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
 
 /*
@@ -2455,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))
@@ -2569,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/usb/uaudio.c sys/dev/usb/uaudio.c
index f7afca68c8c..c37866f061f 100644
--- sys/dev/usb/uaudio.c
+++ sys/dev/usb/uaudio.c
@@ -1,4 +1,4 @@
-/*     $OpenBSD: uaudio.c,v 1.166 2022/02/16 06:21:19 anton Exp $      */
+/*     $OpenBSD: uaudio.c,v 1.167 2022/02/16 06:23:42 anton Exp $      */
 /*
  * Copyright (c) 2018 Alexandre Ratchov <[email protected]>
  *
@@ -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..c37d703ff89 100644
--- sys/dev/usb/ucc.c
+++ sys/dev/usb/ucc.c
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ucc.c,v 1.29 2022/01/09 05:43:00 jsg Exp $    */
+/*     $OpenBSD: ucc.c,v 1.30 2022/02/16 06:23:42 anton Exp $  */
 
 /*
  * Copyright (c) 2021 Anton Lindqvist <[email protected]>
@@ -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..9cbbf7f0368 100644
--- sys/dev/usb/usb_subr.c
+++ sys/dev/usb/usb_subr.c
@@ -1,4 +1,4 @@
-/*     $OpenBSD: usb_subr.c,v 1.157 2022/01/09 05:43:02 jsg Exp $ */
+/*     $OpenBSD: usb_subr.c,v 1.158 2022/02/16 06:23:42 anton Exp $ */
 /*     $NetBSD: usb_subr.c,v 1.103 2003/01/10 11:19:13 augustss Exp $  */
 /*     $FreeBSD: src/sys/dev/usb/usb_subr.c,v 1.18 1999/11/17 22:33:47 n_hibma 
Exp $   */
 
@@ -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..030a6a5cdb6 100644
--- sys/dev/usb/usbdi.h
+++ sys/dev/usb/usbdi.h
@@ -1,4 +1,4 @@
-/*     $OpenBSD: usbdi.h,v 1.71 2021/02/01 09:21:51 mglocker Exp $ */
+/*     $OpenBSD: usbdi.h,v 1.72 2022/02/16 06:23:42 anton Exp $ */
 /*     $NetBSD: usbdi.h,v 1.62 2002/07/11 21:14:35 augustss Exp $      */
 /*     $FreeBSD: src/sys/dev/usb/usbdi.h,v 1.18 1999/11/17 22:33:49 n_hibma 
Exp $      */
 
@@ -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..0fb6ae6feac 100644
--- sys/dev/wscons/wskbd.c
+++ sys/dev/wscons/wskbd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: wskbd.c,v 1.110 2021/12/30 06:55:11 anton Exp $ */
+/* $OpenBSD: wskbd.c,v 1.111 2022/02/16 06:23:42 anton Exp $ */
 /* $NetBSD: wskbd.c,v 1.80 2005/05/04 01:52:16 augustss Exp $ */
 
 /*
@@ -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..557a816c743 100644
--- sys/dev/wscons/wskbdvar.h
+++ sys/dev/wscons/wskbdvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: wskbdvar.h,v 1.3 2017/05/12 09:16:55 mpi Exp $ */
+/* $OpenBSD: wskbdvar.h,v 1.4 2022/02/16 06:23:42 anton Exp $ */
 /* $NetBSD: wskbdvar.h,v 1.8 1999/12/01 23:22:59 augustss Exp $ */
 
 /*
@@ -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