From feb20a89e8291f86ce68d738606fd459a88a6d9e Mon Sep 17 00:00:00 2001 From: mpi Date: Tue, 29 Apr 2014 12:45:29 +0000 Subject: [PATCH] Get rid of the per-softc freelist of transfer descriptors and use a per-driver pool(9) instead. With inputs from mikeb@ --- sys/dev/usb/ehci.c | 55 +++++++++++++++++++++---------------------- sys/dev/usb/ehcivar.h | 4 +--- sys/dev/usb/xhci.c | 48 ++++++++++++++++++------------------- sys/dev/usb/xhcivar.h | 4 +--- 4 files changed, 53 insertions(+), 58 deletions(-) diff --git a/sys/dev/usb/ehci.c b/sys/dev/usb/ehci.c index 027fec3bdfe..ef8e56473f3 100644 --- a/sys/dev/usb/ehci.c +++ b/sys/dev/usb/ehci.c @@ -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 #include #include -#include #include #include +#include #include #include @@ -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 diff --git a/sys/dev/usb/ehcivar.h b/sys/dev/usb/ehcivar.h index 10d60dd1d8d..4af43570373 100644 --- a/sys/dev/usb/ehcivar.h +++ b/sys/dev/usb/ehcivar.h @@ -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; diff --git a/sys/dev/usb/xhci.c b/sys/dev/usb/xhci.c index 69856b3c4f4..74af7cb4d1a 100644 --- a/sys/dev/usb/xhci.c +++ b/sys/dev/usb/xhci.c @@ -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 #include #include +#include #include +#include #include #include @@ -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 diff --git a/sys/dev/usb/xhcivar.h b/sys/dev/usb/xhcivar.h index 2ac61fb4be0..e9ce1c35a03 100644 --- a/sys/dev/usb/xhcivar.h +++ b/sys/dev/usb/xhcivar.h @@ -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 */ }; -- 2.20.1