From 694d02aab2058ebbae5e44eb00c3af2fa6482988 Mon Sep 17 00:00:00 2001 From: Taylor R Campbell Date: Tue, 7 Apr 2020 02:50:26 +0000 Subject: [PATCH] Fix uhidev detach. - Omit needless sc_dying. - Omit needless uhidev_activate. - Use config_detach_children. - Don't free anything or take any other destructive actions until after config_detach_children has succeeded. - Move rnd_detach_source into uhidev_childdet where it belongs. --- sys/dev/usb/uhidev.c | 45 +++++++++++--------------------------------- sys/dev/usb/uhidev.h | 1 - 2 files changed, 11 insertions(+), 35 deletions(-) diff --git a/sys/dev/usb/uhidev.c b/sys/dev/usb/uhidev.c index e29616c01f79..8f4679f53f48 100644 --- a/sys/dev/usb/uhidev.c +++ b/sys/dev/usb/uhidev.c @@ -89,10 +89,9 @@ static int uhidev_match(device_t, cfdata_t, void *); static void uhidev_attach(device_t, device_t, void *); static void uhidev_childdet(device_t, device_t); static int uhidev_detach(device_t, int); -static int uhidev_activate(device_t, enum devact); CFATTACH_DECL2_NEW(uhidev, sizeof(struct uhidev_softc), uhidev_match, - uhidev_attach, uhidev_detach, uhidev_activate, NULL, uhidev_childdet); + uhidev_attach, uhidev_detach, NULL, NULL, uhidev_childdet); static int uhidev_match(device_t parent, cfdata_t match, void *aux) @@ -173,7 +172,6 @@ uhidev_attach(device_t parent, device_t self, void *aux) if (ed == NULL) { aprint_error_dev(self, "could not read endpoint descriptor\n"); - sc->sc_dying = 1; return; } @@ -204,7 +202,6 @@ uhidev_attach(device_t parent, device_t self, void *aux) */ if (sc->sc_iep_addr == -1) { aprint_error_dev(self, "no input interrupt endpoint\n"); - sc->sc_dying = 1; return; } @@ -265,7 +262,6 @@ uhidev_attach(device_t parent, device_t self, void *aux) } if (err) { aprint_error_dev(self, "no report descriptor\n"); - sc->sc_dying = 1; return; } @@ -413,25 +409,12 @@ uhidevprint(void *aux, const char *pnp) return UNCONF; } -static int -uhidev_activate(device_t self, enum devact act) -{ - struct uhidev_softc *sc = device_private(self); - - switch (act) { - case DVACT_DEACTIVATE: - sc->sc_dying = 1; - return 0; - default: - return EOPNOTSUPP; - } -} - static void uhidev_childdet(device_t self, device_t child) { int i; struct uhidev_softc *sc = device_private(self); + struct uhidev *csc = device_private(child); for (i = 0; i < sc->sc_nrepid; i++) { if (sc->sc_subdevs[i] == child) @@ -439,39 +422,33 @@ uhidev_childdet(device_t self, device_t child) } KASSERT(i < sc->sc_nrepid); sc->sc_subdevs[i] = NULL; + rnd_detach_source(&csc->rnd_source); } static int uhidev_detach(device_t self, int flags) { struct uhidev_softc *sc = device_private(self); - int i, rv; - struct uhidev *csc; + int error; DPRINTF(("uhidev_detach: sc=%p flags=%d\n", sc, flags)); - sc->sc_dying = 1; if (sc->sc_ipipe != NULL) usbd_abort_pipe(sc->sc_ipipe); - if (sc->sc_repdesc != NULL) - kmem_free(sc->sc_repdesc, sc->sc_repdesc_size); - - rv = 0; - for (i = 0; i < sc->sc_nrepid; i++) { - if (sc->sc_subdevs[i] != NULL) { - csc = device_private(sc->sc_subdevs[i]); - rnd_detach_source(&csc->rnd_source); - rv |= config_detach(sc->sc_subdevs[i], flags); - } - } + error = config_detach_children(self, flags); + if (error) + return error; usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev); + if (sc->sc_repdesc != NULL) + kmem_free(sc->sc_repdesc, sc->sc_repdesc_size); + pmf_device_deregister(self); mutex_destroy(&sc->sc_lock); - return rv; + return 0; } void diff --git a/sys/dev/usb/uhidev.h b/sys/dev/usb/uhidev.h index 66f5b5930da5..789b327d97f5 100644 --- a/sys/dev/usb/uhidev.h +++ b/sys/dev/usb/uhidev.h @@ -54,7 +54,6 @@ struct uhidev_softc { device_t *sc_subdevs; int sc_refcnt; - u_char sc_dying; kmutex_t sc_lock; /* protects writes to sc_state */