On Wed, 17 Mar 2021 at 07:41:53 +0100, Anton Lindqvist wrote:
> I'm wondering if the umt device is detached more than once since it
> claims multiple report ids. I ran into the same problem while developing
> uhidpp:
> 
>   https://github.com/openbsd/src/blob/master/sys/dev/usb/uhidpp.c#L437-L443
> 
> Also, the output of `show registers` in ddb would be helpful.
> 

Something like this is probably needed (maybe also for 
uhidev_activate):


diff --git sys/dev/usb/uhidev.c sys/dev/usb/uhidev.c
index d777cfb6e45..86231615432 100644
--- sys/dev/usb/uhidev.c
+++ sys/dev/usb/uhidev.c
@@ -403,7 +403,7 @@ int
 uhidev_detach(struct device *self, int flags)
 {
        struct uhidev_softc *sc = (struct uhidev_softc *)self;
-       int i, rv = 0;
+       int i, j, rv = 0;
 
        DPRINTF(("uhidev_detach: sc=%p flags=%d\n", sc, flags));
 
@@ -420,19 +420,19 @@ uhidev_detach(struct device *self, int flags)
        if (sc->sc_repdesc != NULL)
                free(sc->sc_repdesc, M_USBDEV, sc->sc_repdesc_size);
 
-       /*
-        * XXX Check if we have only one children claiming all the Report
-        * IDs, this is a hack since we need a dev -> Report ID mapping
-        * for uhidev_intr().
-        */
-       if (sc->sc_nrepid > 1 && sc->sc_subdevs[0] != NULL &&
-           sc->sc_subdevs[0] == sc->sc_subdevs[1])
-               return (config_detach(&sc->sc_subdevs[0]->sc_dev, flags));
-
        for (i = 0; i < sc->sc_nrepid; i++) {
-               if (sc->sc_subdevs[i] != NULL) {
-                       rv |= config_detach(&sc->sc_subdevs[i]->sc_dev, flags);
-                       sc->sc_subdevs[i] = NULL;
+               if (sc->sc_subdevs[i] == NULL)
+                       continue;
+
+               rv |= config_detach(&sc->sc_subdevs[i]->sc_dev, flags);
+
+               /*
+                * Nullify without detaching any other instances of this device
+                * found on other report ids
+                */
+               for (j = 0; j < sc->sc_nrepid; j++) {
+                       if (sc->sc_subdevs[i] == sc->sc_subdevs[j])
+                               sc->sc_subdevs[j] = NULL;
                }
        }
 

Reply via email to