Module Name:    src
Committed By:   christos
Date:           Tue Jan 29 00:00:16 UTC 2013

Modified Files:
        src/sys/dev/usb: ehci.c ehcivar.h ohci.c ohcivar.h uhci.c uhcivar.h

Log Message:
use a pool instead of a linked list to avoid synchronization problems.


To generate a diff of this commit:
cvs rdiff -u -r1.203 -r1.204 src/sys/dev/usb/ehci.c
cvs rdiff -u -r1.40 -r1.41 src/sys/dev/usb/ehcivar.h
cvs rdiff -u -r1.231 -r1.232 src/sys/dev/usb/ohci.c
cvs rdiff -u -r1.53 -r1.54 src/sys/dev/usb/ohcivar.h
cvs rdiff -u -r1.252 -r1.253 src/sys/dev/usb/uhci.c
cvs rdiff -u -r1.51 -r1.52 src/sys/dev/usb/uhcivar.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/usb/ehci.c
diff -u src/sys/dev/usb/ehci.c:1.203 src/sys/dev/usb/ehci.c:1.204
--- src/sys/dev/usb/ehci.c:1.203	Tue Jan 22 07:40:42 2013
+++ src/sys/dev/usb/ehci.c	Mon Jan 28 19:00:15 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: ehci.c,v 1.203 2013/01/22 12:40:42 jmcneill Exp $ */
+/*	$NetBSD: ehci.c,v 1.204 2013/01/29 00:00:15 christos Exp $ */
 
 /*
  * Copyright (c) 2004-2012 The NetBSD Foundation, Inc.
@@ -53,7 +53,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.203 2013/01/22 12:40:42 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.204 2013/01/29 00:00:15 christos Exp $");
 
 #include "ohci.h"
 #include "uhci.h"
@@ -353,6 +353,9 @@ ehci_init(ehci_softc_t *sc)
 	cv_init(&sc->sc_softwake_cv, "ehciab");
 	cv_init(&sc->sc_doorbell, "ehcidi");
 
+	sc->sc_xferpool = pool_cache_init(sizeof(struct ehci_xfer), 0, 0, 0,
+	    "ehcixfer", NULL, IPL_USB, NULL, NULL, NULL);
+
 	sc->sc_doorbell_si = softint_establish(SOFTINT_NET | SOFTINT_MPSAFE,
 	    ehci_doorbell, sc);
 	sc->sc_pcd_si = softint_establish(SOFTINT_NET | SOFTINT_MPSAFE,
@@ -1143,7 +1146,6 @@ ehci_childdet(device_t self, device_t ch
 int
 ehci_detach(struct ehci_softc *sc, int flags)
 {
-	usbd_xfer_handle xfer;
 	int rv = 0;
 
 	if (sc->sc_child != NULL)
@@ -1172,10 +1174,7 @@ ehci_detach(struct ehci_softc *sc, int f
 	mutex_destroy(&sc->sc_intr_lock);
 #endif
 
-	while ((xfer = SIMPLEQ_FIRST(&sc->sc_free_xfers)) != NULL) {
-		SIMPLEQ_REMOVE_HEAD(&sc->sc_free_xfers, next);
-		kmem_free(xfer, sizeof(struct ehci_xfer));
-	}
+	pool_cache_destroy(sc->sc_xferpool);
 
 	EOWRITE4(sc, EHCI_CONFIGFLAG, 0);
 
@@ -1369,18 +1368,7 @@ ehci_allocx(struct usbd_bus *bus)
 	struct ehci_softc *sc = bus->hci_private;
 	usbd_xfer_handle 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 = kmem_alloc(sizeof(struct ehci_xfer), KM_SLEEP);
-	}
+	xfer = pool_cache_get(sc->sc_xferpool, PR_NOWAIT);
 	if (xfer != NULL) {
 		memset(xfer, 0, sizeof(struct ehci_xfer));
 #ifdef DIAGNOSTIC
@@ -1406,7 +1394,7 @@ ehci_freex(struct usbd_bus *bus, usbd_xf
 		printf("ehci_freex: !isdone\n");
 	}
 #endif
-	SIMPLEQ_INSERT_HEAD(&sc->sc_free_xfers, xfer, next);
+	pool_cache_put(sc->sc_xferpool, xfer);
 }
 
 Static void

Index: src/sys/dev/usb/ehcivar.h
diff -u src/sys/dev/usb/ehcivar.h:1.40 src/sys/dev/usb/ehcivar.h:1.41
--- src/sys/dev/usb/ehcivar.h:1.40	Sun Jun 10 02:15:53 2012
+++ src/sys/dev/usb/ehcivar.h	Mon Jan 28 19:00:15 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: ehcivar.h,v 1.40 2012/06/10 06:15:53 mrg Exp $ */
+/*	$NetBSD: ehcivar.h,v 1.41 2013/01/29 00:00:15 christos Exp $ */
 
 /*
  * Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -29,6 +29,11 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+#ifndef _EHCIVAR_H_
+#define _EHCIVAR_H_
+
+#include <sys/pool.h>
+
 typedef struct ehci_soft_qtd {
 	ehci_qtd_t qtd;
 	struct ehci_soft_qtd *nextqtd; /* mirrors nextqtd in TD */
@@ -162,7 +167,7 @@ typedef struct ehci_softc {
 	u_int32_t sc_eintrs;
 	ehci_soft_qh_t *sc_async_head;
 
-	SIMPLEQ_HEAD(, usbd_xfer) sc_free_xfers; /* free xfers */
+	pool_cache_t sc_xferpool;	/* free xfer pool */
 
 	struct callout sc_tmo_intrlist;
 
@@ -195,3 +200,5 @@ void		ehci_childdet(device_t, device_t);
 bool		ehci_suspend(device_t, const pmf_qual_t *);
 bool		ehci_resume(device_t, const pmf_qual_t *);
 bool		ehci_shutdown(device_t, int);
+
+#endif /* _EHCIVAR_H_ */

Index: src/sys/dev/usb/ohci.c
diff -u src/sys/dev/usb/ohci.c:1.231 src/sys/dev/usb/ohci.c:1.232
--- src/sys/dev/usb/ohci.c:1.231	Tue Jan 22 07:40:43 2013
+++ src/sys/dev/usb/ohci.c	Mon Jan 28 19:00:15 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: ohci.c,v 1.231 2013/01/22 12:40:43 jmcneill Exp $	*/
+/*	$NetBSD: ohci.c,v 1.232 2013/01/29 00:00:15 christos Exp $	*/
 
 /*
  * Copyright (c) 1998, 2004, 2005, 2012 The NetBSD Foundation, Inc.
@@ -41,7 +41,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ohci.c,v 1.231 2013/01/22 12:40:43 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ohci.c,v 1.232 2013/01/29 00:00:15 christos Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -359,7 +359,6 @@ int
 ohci_detach(struct ohci_softc *sc, int flags)
 {
 	int rv = 0;
-	usbd_xfer_handle xfer;
 
 	if (sc->sc_child != NULL)
 		rv = config_detach(sc->sc_child, flags);
@@ -381,10 +380,7 @@ ohci_detach(struct ohci_softc *sc, int f
 
 	if (sc->sc_hcca != NULL)
 		usb_freemem(&sc->sc_bus, &sc->sc_hccadma);
-	while((xfer = SIMPLEQ_FIRST(&sc->sc_free_xfers)) != NULL) {
-		SIMPLEQ_REMOVE_HEAD(&sc->sc_free_xfers, next);
-		kmem_free(xfer, sizeof(struct ohci_xfer));
-	}
+	pool_cache_destroy(sc->sc_xferpool);
 
 	return (rv);
 }
@@ -672,7 +668,8 @@ ohci_init(ohci_softc_t *sc)
 	for (i = 0; i < OHCI_HASH_SIZE; i++)
 		LIST_INIT(&sc->sc_hash_itds[i]);
 
-	SIMPLEQ_INIT(&sc->sc_free_xfers);
+	sc->sc_xferpool = pool_cache_init(sizeof(struct ohci_xfer), 0, 0, 0,
+	    "ohcixfer", NULL, IPL_USB, NULL, NULL, NULL);
 
 	rev = OREAD4(sc, OHCI_REVISION);
 	aprint_normal("OHCI version %d.%d%s\n",
@@ -951,20 +948,9 @@ ohci_allocx(struct usbd_bus *bus)
 	struct ohci_softc *sc = bus->hci_private;
 	usbd_xfer_handle 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("ohci_allocx: xfer=%p not free, 0x%08x\n", xfer,
-			       xfer->busy_free);
-		}
-#endif
-	} else {
-		xfer = kmem_alloc(sizeof(struct ohci_xfer), KM_SLEEP);
-	}
+	xfer = pool_cache_get(sc->sc_xferpool, PR_NOWAIT);
 	if (xfer != NULL) {
-		memset(xfer, 0, sizeof (struct ohci_xfer));
+		memset(xfer, 0, sizeof(struct ohci_xfer));
 #ifdef DIAGNOSTIC
 		xfer->busy_free = XFER_BUSY;
 #endif
@@ -984,7 +970,7 @@ ohci_freex(struct usbd_bus *bus, usbd_xf
 	}
 	xfer->busy_free = XFER_FREE;
 #endif
-	SIMPLEQ_INSERT_HEAD(&sc->sc_free_xfers, xfer, next);
+	pool_cache_put(sc->sc_xferpool, xfer);
 }
 
 Static void

Index: src/sys/dev/usb/ohcivar.h
diff -u src/sys/dev/usb/ohcivar.h:1.53 src/sys/dev/usb/ohcivar.h:1.54
--- src/sys/dev/usb/ohcivar.h:1.53	Sun Jun 10 02:15:53 2012
+++ src/sys/dev/usb/ohcivar.h	Mon Jan 28 19:00:15 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: ohcivar.h,v 1.53 2012/06/10 06:15:53 mrg Exp $	*/
+/*	$NetBSD: ohcivar.h,v 1.54 2013/01/29 00:00:15 christos Exp $	*/
 
 /*
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -30,6 +30,11 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+#ifndef _OHCIVAR_H_
+#define _OHCIVAR_H_
+
+#include <sys/pool.h>
+
 typedef struct ohci_soft_ed {
 	ohci_ed_t ed;
 	struct ohci_soft_ed *next;
@@ -119,7 +124,7 @@ typedef struct ohci_softc {
 	ohci_soft_td_t *sc_freetds;
 	ohci_soft_itd_t *sc_freeitds;
 
-	SIMPLEQ_HEAD(, usbd_xfer) sc_free_xfers; /* free xfers */
+	pool_cache_t sc_xferpool;	/* free xfer pool */
 
 	usbd_xfer_handle sc_intrxfer;
 
@@ -151,3 +156,5 @@ void		ohci_childdet(device_t, device_t);
 int		ohci_activate(device_t, enum devact);
 bool		ohci_resume(device_t, const pmf_qual_t *);
 bool		ohci_suspend(device_t, const pmf_qual_t *);
+
+#endif /* _OHCIVAR_H_ */

Index: src/sys/dev/usb/uhci.c
diff -u src/sys/dev/usb/uhci.c:1.252 src/sys/dev/usb/uhci.c:1.253
--- src/sys/dev/usb/uhci.c:1.252	Tue Jan 22 07:40:43 2013
+++ src/sys/dev/usb/uhci.c	Mon Jan 28 19:00:15 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: uhci.c,v 1.252 2013/01/22 12:40:43 jmcneill Exp $	*/
+/*	$NetBSD: uhci.c,v 1.253 2013/01/29 00:00:15 christos Exp $	*/
 
 /*
  * Copyright (c) 1998, 2004, 2011, 2012 The NetBSD Foundation, Inc.
@@ -42,7 +42,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uhci.c,v 1.252 2013/01/22 12:40:43 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uhci.c,v 1.253 2013/01/29 00:00:15 christos Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -521,7 +521,8 @@ uhci_init(uhci_softc_t *sc)
 
 	LIST_INIT(&sc->sc_intrhead);
 
-	SIMPLEQ_INIT(&sc->sc_free_xfers);
+	sc->sc_xferpool = pool_cache_init(sizeof(struct uhci_xfer), 0, 0, 0,
+	    "uhcixfer", NULL, IPL_USB, NULL, NULL, NULL);
 
 	callout_init(&sc->sc_poll_handle, CALLOUT_MPSAFE);
 
@@ -569,7 +570,6 @@ uhci_childdet(device_t self, device_t ch
 int
 uhci_detach(struct uhci_softc *sc, int flags)
 {
-	usbd_xfer_handle xfer;
 	int rv = 0;
 
 	if (sc->sc_child != NULL)
@@ -578,14 +578,7 @@ uhci_detach(struct uhci_softc *sc, int f
 	if (rv != 0)
 		return (rv);
 
-	/* 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);
-		kmem_free(xfer, sizeof(struct uhci_xfer));
-	}
+	pool_cache_destroy(sc->sc_xferpool);
 
 	callout_halt(&sc->sc_poll_handle, NULL);
 	callout_destroy(&sc->sc_poll_handle);
@@ -654,21 +647,9 @@ uhci_allocx(struct usbd_bus *bus)
 	struct uhci_softc *sc = bus->hci_private;
 	usbd_xfer_handle 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("uhci_allocx: xfer=%p not free, 0x%08x\n", xfer,
-			       xfer->busy_free);
-		}
-#endif
-	} else {
-		xfer = kmem_alloc(sizeof(struct uhci_xfer), KM_SLEEP);
-	}
+	xfer = pool_cache_get(sc->sc_xferpool, PR_NOWAIT);
 	if (xfer != NULL) {
-		memset(xfer, 0, sizeof (struct uhci_xfer));
-		UXFER(xfer)->iinfo.sc = sc;
+		memset(xfer, 0, sizeof(struct uhci_xfer));
 #ifdef DIAGNOSTIC
 		UXFER(xfer)->iinfo.isdone = 1;
 		xfer->busy_free = XFER_BUSY;
@@ -692,7 +673,7 @@ uhci_freex(struct usbd_bus *bus, usbd_xf
 		printf("uhci_freex: !isdone\n");
 	}
 #endif
-	SIMPLEQ_INSERT_HEAD(&sc->sc_free_xfers, xfer, next);
+	pool_cache_put(sc->sc_xferpool, xfer);
 }
 
 Static void

Index: src/sys/dev/usb/uhcivar.h
diff -u src/sys/dev/usb/uhcivar.h:1.51 src/sys/dev/usb/uhcivar.h:1.52
--- src/sys/dev/usb/uhcivar.h:1.51	Sun Jun 10 02:15:54 2012
+++ src/sys/dev/usb/uhcivar.h	Mon Jan 28 19:00:15 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: uhcivar.h,v 1.51 2012/06/10 06:15:54 mrg Exp $	*/
+/*	$NetBSD: uhcivar.h,v 1.52 2013/01/29 00:00:15 christos Exp $	*/
 
 /*
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -30,6 +30,11 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+#ifndef _UHCIVAR_H_
+#define _UHCIVAR_H_
+
+#include <sys/pool.h>
+
 /*
  * To avoid having 1024 TDs for each isochronous transfer we introduce
  * a virtual frame list.  Every UHCI_VFRAMELIST_COUNT entries in the real
@@ -152,7 +157,7 @@ typedef struct uhci_softc {
 	uhci_soft_td_t *sc_freetds;	/* TD free list */
 	uhci_soft_qh_t *sc_freeqhs;	/* QH free list */
 
-	SIMPLEQ_HEAD(, usbd_xfer) sc_free_xfers; /* free xfers */
+	pool_cache_t sc_xferpool;	/* free xfer pool */
 
 	u_int8_t sc_addr;		/* device address */
 	u_int8_t sc_conf;		/* device configuration */
@@ -187,3 +192,5 @@ void		uhci_childdet(device_t, device_t);
 int		uhci_activate(device_t, enum devact);
 bool		uhci_resume(device_t, const pmf_qual_t *);
 bool		uhci_suspend(device_t, const pmf_qual_t *);
+
+#endif /* _UHCIVAR_H_ */

Reply via email to