From 5dacfd1dba27dc2420866c40f1c21c4e4856f0fa Mon Sep 17 00:00:00 2001 From: mpi Date: Tue, 29 Apr 2014 21:51:18 +0000 Subject: [PATCH] Get rid of the per-softc freelist of transfer descriptors and use a per-driver pool(9) instead. --- sys/dev/usb/ohci.c | 54 ++++++++++++++------------------ sys/dev/usb/ohcivar.h | 4 +-- sys/dev/usb/uhci.c | 72 ++++++++++++++++--------------------------- sys/dev/usb/uhcivar.h | 4 +-- 4 files changed, 52 insertions(+), 82 deletions(-) diff --git a/sys/dev/usb/ohci.c b/sys/dev/usb/ohci.c index 8571ee60c6d..07097148663 100644 --- a/sys/dev/usb/ohci.c +++ b/sys/dev/usb/ohci.c @@ -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 #include #include -#include #include +#include +#include #include #include @@ -47,7 +48,6 @@ #include #include #include -#include #include #include @@ -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 diff --git a/sys/dev/usb/ohcivar.h b/sys/dev/usb/ohcivar.h index dde77bb5efc..62505f8dd99 100644 --- a/sys/dev/usb/ohcivar.h +++ b/sys/dev/usb/ohcivar.h @@ -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; diff --git a/sys/dev/usb/uhci.c b/sys/dev/usb/uhci.c index ebbcaf9ab5d..49cc9d46081 100644 --- a/sys/dev/usb/uhci.c +++ b/sys/dev/usb/uhci.c @@ -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 #include #include -#include #include +#include +#include #include #include @@ -47,7 +48,6 @@ #include #include #include -#include #include #include @@ -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 diff --git a/sys/dev/usb/uhcivar.h b/sys/dev/usb/uhcivar.h index a078d127ff6..e1b5e3cfae0 100644 --- a/sys/dev/usb/uhcivar.h +++ b/sys/dev/usb/uhcivar.h @@ -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; -- 2.20.1