Do not try to free xfers before aborting the pipes, otherwise a clown
authormpi <mpi@openbsd.org>
Sun, 18 Jan 2015 14:40:05 +0000 (14:40 +0000)
committermpi <mpi@openbsd.org>
Sun, 18 Jan 2015 14:40:05 +0000 (14:40 +0000)
might eat you.

sys/dev/usb/umass.c

index d4155f6..11b2a24 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: umass.c,v 1.67 2014/08/21 14:52:56 mpi Exp $ */
+/*     $OpenBSD: umass.c,v 1.68 2015/01/18 14:40:05 mpi Exp $ */
 /*     $NetBSD: umass.c,v 1.116 2004/06/30 05:53:46 mycroft Exp $      */
 
 /*
@@ -671,13 +671,6 @@ umass_disco(struct umass_softc *sc)
 
        DPRINTF(UDMASS_GEN, ("umass_disco\n"));
 
-       /* Free the xfers. */
-       for (i = 0; i < XFER_NR; i++)
-               if (sc->transfer_xfer[i] != NULL) {
-                       usbd_free_xfer(sc->transfer_xfer[i]);
-                       sc->transfer_xfer[i] = NULL;
-               }
-
        /* Remove all the pipes. */
        for (i = 0 ; i < UMASS_NEP ; i++) {
                if (sc->sc_pipe[i] != NULL) {
@@ -685,6 +678,17 @@ umass_disco(struct umass_softc *sc)
                        sc->sc_pipe[i] = NULL;
                }
        }
+
+       /* Make sure there is no stuck control transfer left. */
+       usbd_abort_pipe(sc->sc_udev->default_pipe);
+
+       /* Free the xfers. */
+       for (i = 0; i < XFER_NR; i++) {
+               if (sc->transfer_xfer[i] != NULL) {
+                       usbd_free_xfer(sc->transfer_xfer[i]);
+                       sc->transfer_xfer[i] = NULL;
+               }
+       }
 }
 
 /*