On Sun, Aug 30, 2015 at 12:32:24PM +0200, Martin Pieuchot stated:
> That's good but the original design of allocating an xfer for every
> usbd_transfer(9) call does not make much sense.  
> 
> You could allocate two xfers (one for read and one for write) at the
> same time the pipes are opened and free them when they're closed.
> 
> You could even allocate the DMA buffer with usb_alloc_buffer() and pass
> the USBD_NO_COPY flag to usbd_transfer(9) to avoid a supplementary copy.

Thanks for the feedback, Martin. I've been running with your first
suggestion for a bit with no issues. I wonder though if the xfer can't
just be shared for rx and tx? I also NULLed out the pipes on failure
since it looks like otherwise they'd be re-closed on detach. I'll look
into the usbd_alloc_buffer() idea.


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       30 Aug 2015 12:49:12 -0000
@@ -49,7 +49,8 @@ struct uow_softc {
        struct usbd_pipe        *sc_ph_obulk;
        struct usbd_pipe        *sc_ph_intr;
        u_int8_t                 sc_regs[DS2490_NREGS];
-       struct usbd_xfer        *sc_xfer;
+       struct usbd_xfer        *sc_xfer_in;
+       struct usbd_xfer        *sc_xfer_out;
        u_int8_t                 sc_fifo[DS2490_DATAFIFOSIZE];
 };
 
@@ -186,14 +187,17 @@ uow_attach(struct device *parent, struct
                goto fail;
        }
 
-#if 0
-       /* Allocate xfer for bulk transfers */
-       if ((sc->sc_xfer = usbd_alloc_xfer(sc->sc_udev)) == NULL) {
-               printf("%s: failed to alloc bulk xfer\n",
+       /* Allocate xfers for bulk transfers */
+       if ((sc->sc_xfer_in = usbd_alloc_xfer(sc->sc_udev)) == NULL) {
+               printf("%s: failed to alloc bulk-in xfer\n",
+                   sc->sc_dev.dv_xname);
+               goto fail;
+       }
+       if ((sc->sc_xfer_out = usbd_alloc_xfer(sc->sc_udev)) == NULL) {
+               printf("%s: failed to alloc bulk-out xfer\n",
                    sc->sc_dev.dv_xname);
                goto fail;
        }
-#endif
 
        memset(sc->sc_fifo, 0xff, sizeof(sc->sc_fifo));
 
@@ -220,14 +224,26 @@ uow_attach(struct device *parent, struct
        return;
 
 fail:
-       if (sc->sc_ph_ibulk != NULL)
+       if (sc->sc_ph_ibulk != NULL) {
                usbd_close_pipe(sc->sc_ph_ibulk);
-       if (sc->sc_ph_obulk != NULL)
+               sc->sc_ph_ibulk = NULL;
+       }
+       if (sc->sc_ph_obulk != NULL) {
                usbd_close_pipe(sc->sc_ph_obulk);
-       if (sc->sc_ph_intr != NULL)
+               sc->sc_ph_obulk = NULL;
+       }
+       if (sc->sc_ph_intr != NULL) {
                usbd_close_pipe(sc->sc_ph_intr);
-       if (sc->sc_xfer != NULL)
-               usbd_free_xfer(sc->sc_xfer);
+               sc->sc_ph_intr = NULL;
+       }
+       if (sc->sc_xfer_in != NULL) {
+               usbd_free_xfer(sc->sc_xfer_in);
+               sc->sc_xfer_in = NULL;
+       }
+       if (sc->sc_xfer_out != NULL) {
+               usbd_free_xfer(sc->sc_xfer_out);
+               sc->sc_xfer_out = NULL;
+       }
 }
 
 int
@@ -251,8 +267,10 @@ uow_detach(struct device *self, int flag
                usbd_close_pipe(sc->sc_ph_intr);
        }
 
-       if (sc->sc_xfer != NULL)
-               usbd_free_xfer(sc->sc_xfer);
+       if (sc->sc_xfer_in != NULL)
+               usbd_free_xfer(sc->sc_xfer_in);
+       if (sc->sc_xfer_out != NULL)
+               usbd_free_xfer(sc->sc_xfer_out);
 
        if (sc->sc_ow_dev != NULL)
                rv = config_detach(sc->sc_ow_dev, flags);
@@ -457,14 +475,9 @@ uow_read(struct uow_softc *sc, void *buf
                return (-1);
        }
 
-       if ((sc->sc_xfer = usbd_alloc_xfer(sc->sc_udev)) == NULL) {
-               printf("%s: failed to alloc xfer\n", sc->sc_dev.dv_xname);
-               return (-1);
-       }
-       usbd_setup_xfer(sc->sc_xfer, sc->sc_ph_ibulk, sc, buf, len,
+       usbd_setup_xfer(sc->sc_xfer_in, 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);
+       error = usbd_transfer(sc->sc_xfer_in);
        if (error != 0) {
                printf("%s: read failed, len %d: %s\n",
                    sc->sc_dev.dv_xname, len, usbd_errstr(error));
@@ -472,7 +485,7 @@ uow_read(struct uow_softc *sc, void *buf
                return (-1);
        }
 
-       usbd_get_xfer_status(sc->sc_xfer, NULL, NULL, &count, &error);
+       usbd_get_xfer_status(sc->sc_xfer_in, NULL, NULL, &count, &error);
        return (count);
 }
 
@@ -488,14 +501,9 @@ uow_write(struct uow_softc *sc, const vo
                return (1);
        }
 
-       if ((sc->sc_xfer = usbd_alloc_xfer(sc->sc_udev)) == NULL) {
-               printf("%s: failed to alloc xfer\n", sc->sc_dev.dv_xname);
-               return (-1);
-       }
-       usbd_setup_xfer(sc->sc_xfer, sc->sc_ph_obulk, sc, (void *)buf, len,
-           USBD_SYNCHRONOUS, UOW_TIMEOUT, NULL);
-       error = usbd_transfer(sc->sc_xfer);
-       usbd_free_xfer(sc->sc_xfer);
+       usbd_setup_xfer(sc->sc_xfer_out, sc->sc_ph_obulk, sc, (void *)buf,
+           len, USBD_SYNCHRONOUS, UOW_TIMEOUT, NULL);
+       error = usbd_transfer(sc->sc_xfer_out);
        if (error != 0) {
                printf("%s: write failed, len %d: %s\n",
                    sc->sc_dev.dv_xname, len, usbd_errstr(error));

Reply via email to