Get rid of the per-softc freelist of transfer descriptors and use a
authormpi <mpi@openbsd.org>
Tue, 29 Apr 2014 12:45:29 +0000 (12:45 +0000)
committermpi <mpi@openbsd.org>
Tue, 29 Apr 2014 12:45:29 +0000 (12:45 +0000)
per-driver pool(9) instead.

With inputs from mikeb@

sys/dev/usb/ehci.c
sys/dev/usb/ehcivar.h
sys/dev/usb/xhci.c
sys/dev/usb/xhcivar.h

index 027fec3..ef8e564 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ehci.c,v 1.147 2014/04/27 14:48:10 mpi Exp $ */
+/*     $OpenBSD: ehci.c,v 1.148 2014/04/29 12:45:29 mpi Exp $ */
 /*     $NetBSD: ehci.c,v 1.66 2004/06/30 03:11:56 mycroft Exp $        */
 
 /*
@@ -46,9 +46,9 @@
 #include <sys/rwlock.h>
 #include <sys/malloc.h>
 #include <sys/device.h>
-#include <sys/selinfo.h>
 #include <sys/queue.h>
 #include <sys/timeout.h>
+#include <sys/pool.h>
 
 #include <machine/bus.h>
 #include <machine/endian.h>
@@ -78,6 +78,8 @@ int ehcidebug = 0;
 #define DPRINTFN(n,x)
 #endif
 
+struct pool *ehcixfer;
+
 struct ehci_pipe {
        struct usbd_pipe pipe;
 
@@ -345,6 +347,17 @@ ehci_init(struct ehci_softc *sc)
        if (err)
                return (err);
 
+       if (ehcixfer == NULL) {
+               ehcixfer = malloc(sizeof(struct pool), M_DEVBUF, M_NOWAIT);
+               if (ehcixfer == NULL) {
+                       printf("%s: unable to allocate pool descriptor\n",
+                           sc->sc_bus.bdev.dv_xname);
+                       return (ENOMEM);
+               }
+               pool_init(ehcixfer, sizeof(struct ehci_xfer), 0, 0, 0,
+                   "ehcixfer", NULL);
+       }
+
        /* frame list size at default, read back what we got and use that */
        switch (EHCI_CMD_FLS(EOREAD4(sc, EHCI_USBCMD))) {
        case 0:
@@ -1180,49 +1193,35 @@ ehci_reset(struct ehci_softc *sc)
 struct usbd_xfer *
 ehci_allocx(struct usbd_bus *bus)
 {
-       struct ehci_softc *sc = (struct ehci_softc *)bus;
-       struct usbd_xfer *xfer;
-
-       xfer = SIMPLEQ_FIRST(&sc->sc_free_xfers);
-       if (xfer != NULL) {
-               SIMPLEQ_REMOVE_HEAD(&sc->sc_free_xfers, next);
-#ifdef DIAGNOSTIC
-               if (xfer->busy_free != XFER_FREE)
-                       printf("ehci_allocx: xfer=%p not free, 0x%08x\n",
-                           xfer, xfer->busy_free);
-#endif
-       } else
-               xfer = malloc(sizeof(struct ehci_xfer), M_USB, M_NOWAIT);
+       struct ehci_xfer *ex;
 
-       if (xfer != NULL) {
-               memset(xfer, 0, sizeof(struct ehci_xfer));
-               ((struct ehci_xfer *)xfer)->ehci_xfer_flags = 0;
+       ex = pool_get(ehcixfer, PR_NOWAIT | PR_ZERO);
 #ifdef DIAGNOSTIC
-               ((struct ehci_xfer *)xfer)->isdone = 1;
-               xfer->busy_free = XFER_BUSY;
-#endif
+       if (ex != NULL) {
+               ex->isdone = 1;
+               ex->xfer.busy_free = XFER_BUSY;
        }
-       return (xfer);
+#endif
+       return ((struct usbd_xfer *)ex);
 }
 
 void
 ehci_freex(struct usbd_bus *bus, struct usbd_xfer *xfer)
 {
-       struct ehci_softc *sc = (struct ehci_softc *)bus;
+       struct ehci_xfer *ex = (struct ehci_xfer*)xfer;
 
 #ifdef DIAGNOSTIC
        if (xfer->busy_free != XFER_BUSY) {
-               printf("ehci_freex: xfer=%p not busy, 0x%08x\n", xfer,
+               printf("%s: xfer=%p not busy, 0x%08x\n", __func__, xfer,
                    xfer->busy_free);
                return;
        }
-       xfer->busy_free = XFER_FREE;
-       if (!((struct ehci_xfer *)xfer)->isdone) {
-               printf("ehci_freex: !isdone\n");
+       if (!ex->isdone) {
+               printf("%s: !isdone\n", __func__);
                return;
        }
 #endif
-       SIMPLEQ_INSERT_HEAD(&sc->sc_free_xfers, xfer, next);
+       pool_put(ehcixfer, ex);
 }
 
 void
index 10d60dd..4af4357 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ehcivar.h,v 1.30 2014/04/27 14:48:10 mpi Exp $ */
+/*     $OpenBSD: ehcivar.h,v 1.31 2014/04/29 12:45:29 mpi Exp $ */
 /*     $NetBSD: ehcivar.h,v 1.19 2005/04/29 15:04:29 augustss Exp $    */
 
 /*
@@ -147,8 +147,6 @@ struct ehci_softc {
        u_int32_t sc_eintrs;
        struct ehci_soft_qh *sc_async_head;
 
-       SIMPLEQ_HEAD(, usbd_xfer) sc_free_xfers; /* free xfers */
-
        struct rwlock sc_doorbell_lock;
 
        struct timeout sc_tmo_intrlist;
index 69856b3..74af7cb 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: xhci.c,v 1.9 2014/04/07 15:34:27 mpi Exp $ */
+/* $OpenBSD: xhci.c,v 1.10 2014/04/29 12:45:29 mpi Exp $ */
 
 /*
  * Copyright (c) 2014 Martin Pieuchot
@@ -21,7 +21,9 @@
 #include <sys/kernel.h>
 #include <sys/malloc.h>
 #include <sys/device.h>
+#include <sys/queue.h>
 #include <sys/timeout.h>
+#include <sys/pool.h>
 
 #include <machine/bus.h>
 #include <machine/endian.h>
@@ -52,6 +54,8 @@ int xhcidebug = 3;
 #define TRBOFF(ring, trb)      ((void *)(trb) - (void *)((ring).trbs))
 #define TRBADDR(ring, trb)     DMAADDR(&(ring).dma, TRBOFF(ring, trb))
 
+struct pool *xhcixfer;
+
 struct xhci_pipe {
        struct usbd_pipe        pipe;
 
@@ -232,6 +236,17 @@ xhci_init(struct xhci_softc *sc)
        if (error)
                return (error);
 
+       if (xhcixfer == NULL) {
+               xhcixfer = malloc(sizeof(struct pool), M_DEVBUF, M_NOWAIT);
+               if (xhcixfer == NULL) {
+                       printf("%s: unable to allocate pool descriptor\n",
+                           DEVNAME(sc));
+                       return (ENOMEM);
+               }
+               pool_init(xhcixfer, sizeof(struct xhci_xfer), 0, 0, 0,
+                   "xhcixfer", NULL);
+       }
+
        hcr = XREAD4(sc, XHCI_HCCPARAMS);
        sc->sc_ctxsize = XHCI_HCC_CSZ(hcr) ? 64 : 32;
        DPRINTF(("%s: %d bytes context\n", DEVNAME(sc), sc->sc_ctxsize));
@@ -1111,44 +1126,29 @@ xhci_pipe_close(struct usbd_pipe *pipe)
 struct usbd_xfer *
 xhci_allocx(struct usbd_bus *bus)
 {
-       struct xhci_softc *sc = (struct xhci_softc *)bus;
-       struct usbd_xfer *xfer;
+       struct xhci_xfer *xx;
 
-       xfer = SIMPLEQ_FIRST(&sc->sc_free_xfers);
-       if (xfer != NULL) {
-               SIMPLEQ_REMOVE_HEAD(&sc->sc_free_xfers, next);
+       xx = pool_get(xhcixfer, PR_NOWAIT | PR_ZERO);
 #ifdef DIAGNOSTIC
-               if (xfer->busy_free != XFER_FREE)
-                       printf("%s: xfer=%p not free, 0x%08x\n", __func__,
-                           xfer, xfer->busy_free);
+       if (xx != NULL)
+               xx->xfer.busy_free = XFER_BUSY;
 #endif
-       } else
-               xfer = malloc(sizeof(struct xhci_xfer), M_USB, M_NOWAIT);
-
-       if (xfer != NULL) {
-               memset(xfer, 0, sizeof(struct xhci_xfer));
-#ifdef DIAGNOSTIC
-               xfer->busy_free = XFER_BUSY;
-#endif
-       }
-       return (xfer);
+       return ((struct usbd_xfer *)xx);
 }
 
 void
 xhci_freex(struct usbd_bus *bus, struct usbd_xfer *xfer)
 {
-       struct xhci_softc *sc = (struct xhci_softc *)bus;
+       struct xhci_xfer *xx = (struct xhci_xfer*)xfer;
 
 #ifdef DIAGNOSTIC
        if (xfer->busy_free != XFER_BUSY) {
-               printf("xhci_freex: xfer=%p not busy, 0x%08x\n", xfer,
+               printf("%s: xfer=%p not busy, 0x%08x\n", __func__, xfer,
                    xfer->busy_free);
                return;
        }
-       xfer->busy_free = XFER_FREE;
 #endif
-
-       SIMPLEQ_INSERT_HEAD(&sc->sc_free_xfers, xfer, next);
+       pool_put(xhcixfer, xx);
 }
 
 int
index 2ac61fb..e9ce1c3 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: xhcivar.h,v 1.3 2014/03/25 20:27:37 mpi Exp $ */
+/* $OpenBSD: xhcivar.h,v 1.4 2014/04/29 12:45:29 mpi Exp $ */
 
 /*
  * Copyright (c) 2014 Martin Pieuchot
@@ -104,8 +104,6 @@ struct xhci_softc {
        struct xhci_trb         *sc_cmd_trb;
        struct xhci_trb          sc_result_trb;
 
-       SIMPLEQ_HEAD(, usbd_xfer) sc_free_xfers; /* free xfers */
-
        char                     sc_vendor[16]; /* Vendor string for root hub */
        int                      sc_id_vendor;  /* Vendor ID for root hub */
 };