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

sys/dev/usb/ohci.c
sys/dev/usb/ohcivar.h
sys/dev/usb/uhci.c
sys/dev/usb/uhcivar.h

index 8571ee6..0709714 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ohci.c,v 1.126 2014/04/29 14:11:23 mpi Exp $ */
+/*     $OpenBSD: ohci.c,v 1.127 2014/04/29 21:51:18 mpi Exp $ */
 /*     $NetBSD: ohci.c,v 1.139 2003/02/22 05:24:16 tsutsui Exp $       */
 /*     $FreeBSD: src/sys/dev/usb/ohci.c,v 1.22 1999/11/17 22:33:40 n_hibma Exp $       */
 
@@ -37,8 +37,9 @@
 #include <sys/malloc.h>
 #include <sys/kernel.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>
@@ -47,7 +48,6 @@
 #include <dev/usb/usbdi.h>
 #include <dev/usb/usbdivar.h>
 #include <dev/usb/usb_mem.h>
-#include <dev/usb/usb_quirks.h>
 
 #include <dev/usb/ohcireg.h>
 #include <dev/usb/ohcivar.h>
@@ -66,10 +66,7 @@ int ohcidebug = 0;
 #define DPRINTFN(n,x)
 #endif
 
-/*
- * The OHCI controller is little endian, so on big endian machines
- * the data stored in memory needs to be swapped.
- */
+struct pool *ohcixfer;
 
 struct ohci_pipe;
 
@@ -728,7 +725,16 @@ ohci_init(struct ohci_softc *sc)
        for (i = 0; i < OHCI_HASH_SIZE; i++)
                LIST_INIT(&sc->sc_hash_itds[i]);
 
-       SIMPLEQ_INIT(&sc->sc_free_xfers);
+       if (ohcixfer == NULL) {
+               ohcixfer = malloc(sizeof(struct pool), M_DEVBUF, M_NOWAIT);
+               if (ohcixfer == NULL) {
+                       printf("%s: unable to allocate pool descriptor\n",
+                           sc->sc_bus.bdev.dv_xname);
+                       return (ENOMEM);
+               }
+               pool_init(ohcixfer, sizeof(struct ohci_xfer), 0, 0, 0,
+                   "ohcixfer", NULL);
+       }
 
        /* XXX determine alignment by R/W */
        /* Allocate the HCCA area. */
@@ -940,44 +946,30 @@ ohci_init(struct ohci_softc *sc)
 struct usbd_xfer *
 ohci_allocx(struct usbd_bus *bus)
 {
-       struct ohci_softc *sc = (struct ohci_softc *)bus;
-       struct usbd_xfer *xfer;
+       struct ohci_xfer *ox;
 
-       xfer = SIMPLEQ_FIRST(&sc->sc_free_xfers);
-       if (xfer != NULL) {
-               SIMPLEQ_REMOVE_HEAD(&sc->sc_free_xfers, next);
+       ox = pool_get(ohcixfer, PR_NOWAIT | PR_ZERO);
 #ifdef DIAGNOSTIC
-               if (xfer->busy_free != XFER_FREE) {
-                       printf("ohci_allocx: xfer=%p not free, 0x%08x\n", xfer,
-                              xfer->busy_free);
-               }
-#endif
-       } else {
-               xfer = malloc(sizeof(struct ohci_xfer), M_USB, M_NOWAIT);
+       if (ox != NULL) {
+               ox->xfer.busy_free = XFER_BUSY;
        }
-       if (xfer != NULL) {
-               memset(xfer, 0, sizeof (struct ohci_xfer));
-#ifdef DIAGNOSTIC
-               xfer->busy_free = XFER_BUSY;
 #endif
-       }
-       return (xfer);
+       return ((struct usbd_xfer *)ox);
 }
 
 void
 ohci_freex(struct usbd_bus *bus, struct usbd_xfer *xfer)
 {
-       struct ohci_softc *sc = (struct ohci_softc *)bus;
+       struct ohci_xfer *ox = (struct ohci_xfer*)xfer;
 
 #ifdef DIAGNOSTIC
        if (xfer->busy_free != XFER_BUSY) {
-               printf("ohci_freex: xfer=%p not busy, 0x%08x\n", xfer,
-                      xfer->busy_free);
+               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(ohcixfer, ox);
 }
 
 #ifdef OHCI_DEBUG
index dde77bb..62505f8 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ohcivar.h,v 1.35 2014/03/25 20:27:37 mpi Exp $ */
+/*     $OpenBSD: ohcivar.h,v 1.36 2014/04/29 21:51:18 mpi Exp $ */
 /*     $NetBSD: ohcivar.h,v 1.32 2003/02/22 05:24:17 tsutsui Exp $     */
 /*     $FreeBSD: src/sys/dev/usb/ohcivar.h,v 1.13 1999/11/17 22:33:41 n_hibma Exp $    */
 
@@ -105,8 +105,6 @@ struct ohci_softc {
        struct ohci_soft_td *sc_freetds;
        struct ohci_soft_itd *sc_freeitds;
 
-       SIMPLEQ_HEAD(, usbd_xfer) sc_free_xfers; /* free xfers */
-
        struct usbd_xfer *sc_intrxfer;
 
        struct ohci_soft_itd *sc_sidone;
index ebbcaf9..49cc9d4 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: uhci.c,v 1.112 2014/04/29 14:11:23 mpi Exp $  */
+/*     $OpenBSD: uhci.c,v 1.113 2014/04/29 21:51:18 mpi Exp $  */
 /*     $NetBSD: uhci.c,v 1.172 2003/02/23 04:19:26 simonb Exp $        */
 /*     $FreeBSD: src/sys/dev/usb/uhci.c,v 1.33 1999/11/17 22:33:41 n_hibma Exp $       */
 
@@ -37,8 +37,9 @@
 #include <sys/kernel.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>
@@ -47,7 +48,6 @@
 #include <dev/usb/usbdi.h>
 #include <dev/usb/usbdivar.h>
 #include <dev/usb/usb_mem.h>
-#include <dev/usb/usb_quirks.h>
 
 #include <dev/usb/uhcireg.h>
 #include <dev/usb/uhcivar.h>
@@ -71,10 +71,7 @@ int uhcinoloop = 0;
 #define DPRINTFN(n,x)
 #endif
 
-/*
- * The UHCI controller is little endian, so on big endian machines
- * the data stored in memory needs to be swapped.
- */
+struct pool *uhcixfer;
 
 struct uhci_pipe {
        struct usbd_pipe pipe;
@@ -376,6 +373,17 @@ uhci_init(struct uhci_softc *sc)
        uhci_globalreset(sc);                   /* reset the controller */
        uhci_reset(sc);
 
+       if (uhcixfer == NULL) {
+               uhcixfer = malloc(sizeof(struct pool), M_DEVBUF, M_NOWAIT);
+               if (uhcixfer == NULL) {
+                       printf("%s: unable to allocate pool descriptor\n",
+                           sc->sc_bus.bdev.dv_xname);
+                       return (ENOMEM);
+               }
+               pool_init(uhcixfer, sizeof(struct uhci_xfer), 0, 0, 0,
+                   "uhcixfer", NULL);
+       }
+
        /* Restore saved SOF. */
        UWRITE1(sc, UHCI_SOF, sc->sc_saved_sof);
 
@@ -474,8 +482,6 @@ uhci_init(struct uhci_softc *sc)
 
        LIST_INIT(&sc->sc_intrhead);
 
-       SIMPLEQ_INIT(&sc->sc_free_xfers);
-
        timeout_set(&sc->sc_poll_handle, NULL, NULL);
 
        /* Set up the bus struct. */
@@ -576,7 +582,6 @@ uhci_activate(struct device *self, int act)
 int
 uhci_detach(struct uhci_softc *sc, int flags)
 {
-       struct usbd_xfer *xfer;
        int rv = 0;
 
        if (sc->sc_child != NULL)
@@ -590,15 +595,6 @@ uhci_detach(struct uhci_softc *sc, int flags)
                sc->sc_intr_xfer = NULL;
        }
 
-       /* Free all xfers associated with this HC. */
-       for (;;) {
-               xfer = SIMPLEQ_FIRST(&sc->sc_free_xfers);
-               if (xfer == NULL)
-                       break;
-               SIMPLEQ_REMOVE_HEAD(&sc->sc_free_xfers, next);
-               free(xfer, M_USB);
-       }
-
        /* XXX free other data structures XXX */
 
        return (rv);
@@ -607,49 +603,35 @@ uhci_detach(struct uhci_softc *sc, int flags)
 struct usbd_xfer *
 uhci_allocx(struct usbd_bus *bus)
 {
-       struct uhci_softc *sc = (struct uhci_softc *)bus;
-       struct usbd_xfer *xfer;
+       struct uhci_xfer *ux;
 
-       xfer = SIMPLEQ_FIRST(&sc->sc_free_xfers);
-       if (xfer != NULL) {
-               SIMPLEQ_REMOVE_HEAD(&sc->sc_free_xfers, next);
+       ux = pool_get(uhcixfer, PR_NOWAIT | PR_ZERO);
 #ifdef DIAGNOSTIC
-               if (xfer->busy_free != XFER_FREE) {
-                       printf("uhci_allocx: xfer=%p not free, 0x%08x\n", xfer,
-                              xfer->busy_free);
-               }
-#endif
-       } else {
-               xfer = malloc(sizeof(struct uhci_xfer), M_USB, M_NOWAIT);
+       if (ux != NULL) {
+               ux->isdone = 1;
+               ux->xfer.busy_free = XFER_BUSY;
        }
-       if (xfer != NULL) {
-               memset(xfer, 0, sizeof (struct uhci_xfer));
-#ifdef DIAGNOSTIC
-               ((struct uhci_xfer *)xfer)->isdone = 1;
-               xfer->busy_free = XFER_BUSY;
 #endif
-       }
-       return (xfer);
+       return ((struct usbd_xfer *)ux);
 }
 
 void
 uhci_freex(struct usbd_bus *bus, struct usbd_xfer *xfer)
 {
-       struct uhci_softc *sc = (struct uhci_softc *)bus;
+       struct uhci_xfer *ux = (struct uhci_xfer*)xfer;
 
 #ifdef DIAGNOSTIC
        if (xfer->busy_free != XFER_BUSY) {
-               printf("uhci_freex: xfer=%p not busy, 0x%08x\n", xfer,
-                      xfer->busy_free);
+               printf("%s: xfer=%p not busy, 0x%08x\n", __func__, xfer,
+                   xfer->busy_free);
                return;
        }
-       xfer->busy_free = XFER_FREE;
-       if (!((struct uhci_xfer *)xfer)->isdone) {
-               printf("uhci_freex: !isdone\n");
+       if (!ux->isdone) {
+               printf("%s: !isdone\n", __func__);
                return;
        }
 #endif
-       SIMPLEQ_INSERT_HEAD(&sc->sc_free_xfers, xfer, next);
+       pool_put(uhcixfer, ux);
 }
 
 #ifdef UHCI_DEBUG
index a078d12..e1b5e3c 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: uhcivar.h,v 1.30 2014/04/27 14:48:10 mpi Exp $ */
+/*     $OpenBSD: uhcivar.h,v 1.31 2014/04/29 21:51:18 mpi Exp $ */
 /*     $NetBSD: uhcivar.h,v 1.36 2002/12/31 00:39:11 augustss Exp $    */
 /*     $FreeBSD: src/sys/dev/usb/uhcivar.h,v 1.14 1999/11/17 22:33:42 n_hibma Exp $    */
 
@@ -138,8 +138,6 @@ struct uhci_softc {
        struct uhci_soft_td *sc_freetds; /* TD free list */
        struct uhci_soft_qh *sc_freeqhs; /* QH free list */
 
-       SIMPLEQ_HEAD(, usbd_xfer) sc_free_xfers; /* free xfers */
-
        u_int8_t sc_conf;               /* device configuration */
 
        u_int8_t sc_saved_sof;