summaryrefslogtreecommitdiff
path: root/sys/dev/usb
diff options
context:
space:
mode:
authorMartin Pieuchot <mpi@cvs.openbsd.org>2014-04-29 21:51:19 +0000
committerMartin Pieuchot <mpi@cvs.openbsd.org>2014-04-29 21:51:19 +0000
commit0d2e8e984854d5dc22e8eebb7a60f4f535635057 (patch)
tree296b326aa38b749d82a265b765b03da70a77d154 /sys/dev/usb
parentddfb5c6b24575556b8446031bc155a5ecfec13ce (diff)
Get rid of the per-softc freelist of transfer descriptors and use a
per-driver pool(9) instead.
Diffstat (limited to 'sys/dev/usb')
-rw-r--r--sys/dev/usb/ohci.c54
-rw-r--r--sys/dev/usb/ohcivar.h4
-rw-r--r--sys/dev/usb/uhci.c72
-rw-r--r--sys/dev/usb/uhcivar.h4
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 <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
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 <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
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;