fixes panic on attach/detach due to free list corruption, also use
after usbd_free_xfer(), tested on i386

~~~

Index: uow.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/uow.c,v
retrieving revision 1.33
diff -u -p -s -r1.33 uow.c
--- uow.c       15 Apr 2013 09:23:02 -0000      1.33
+++ uow.c       29 Aug 2015 20:06:02 -0000
@@ -226,8 +226,10 @@ fail:
                usbd_close_pipe(sc->sc_ph_obulk);
        if (sc->sc_ph_intr != NULL)
                usbd_close_pipe(sc->sc_ph_intr);
-       if (sc->sc_xfer != NULL)
+       if (sc->sc_xfer != NULL) {
                usbd_free_xfer(sc->sc_xfer);
+               sc->sc_xfer = NULL;
+       }
 }
 
 int
@@ -251,8 +253,10 @@ uow_detach(struct device *self, int flag
                usbd_close_pipe(sc->sc_ph_intr);
        }
 
-       if (sc->sc_xfer != NULL)
+       if (sc->sc_xfer != NULL) {
                usbd_free_xfer(sc->sc_xfer);
+               sc->sc_xfer = NULL;
+       }
 
        if (sc->sc_ow_dev != NULL)
                rv = config_detach(sc->sc_ow_dev, flags);
@@ -464,15 +468,18 @@ uow_read(struct uow_softc *sc, void *buf
        usbd_setup_xfer(sc->sc_xfer, sc->sc_ph_ibulk, sc, buf, len,
            USBD_SHORT_XFER_OK | USBD_SYNCHRONOUS, UOW_TIMEOUT, NULL);
        error = usbd_transfer(sc->sc_xfer);
-       usbd_free_xfer(sc->sc_xfer);
        if (error != 0) {
                printf("%s: read failed, len %d: %s\n",
                    sc->sc_dev.dv_xname, len, usbd_errstr(error));
                uow_reset(sc);
+               usbd_free_xfer(sc->sc_xfer);
+               sc->sc_xfer = NULL;
                return (-1);
        }
 
        usbd_get_xfer_status(sc->sc_xfer, NULL, NULL, &count, &error);
+       usbd_free_xfer(sc->sc_xfer);
+       sc->sc_xfer = NULL;
        return (count);
 }
 
@@ -496,6 +503,7 @@ uow_write(struct uow_softc *sc, const vo
            USBD_SYNCHRONOUS, UOW_TIMEOUT, NULL);
        error = usbd_transfer(sc->sc_xfer);
        usbd_free_xfer(sc->sc_xfer);
+       sc->sc_xfer = NULL;
        if (error != 0) {
                printf("%s: write failed, len %d: %s\n",
                    sc->sc_dev.dv_xname, len, usbd_errstr(error));

Reply via email to