Module Name:    src
Committed By:   mrg
Date:           Mon Feb 20 03:25:33 UTC 2012

Modified Files:
        src/sys/dev/usb [jmcneill-usbmp]: usb_mem.c

Log Message:
convert splusb() calls to using a new usb_blk_lock.


To generate a diff of this commit:
cvs rdiff -u -r1.50.6.1 -r1.50.6.2 src/sys/dev/usb/usb_mem.c

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/usb_mem.c
diff -u src/sys/dev/usb/usb_mem.c:1.50.6.1 src/sys/dev/usb/usb_mem.c:1.50.6.2
--- src/sys/dev/usb/usb_mem.c:1.50.6.1	Sat Feb 18 07:35:11 2012
+++ src/sys/dev/usb/usb_mem.c	Mon Feb 20 03:25:33 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: usb_mem.c,v 1.50.6.1 2012/02/18 07:35:11 mrg Exp $	*/
+/*	$NetBSD: usb_mem.c,v 1.50.6.2 2012/02/20 03:25:33 mrg Exp $	*/
 
 /*
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -38,7 +38,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: usb_mem.c,v 1.50.6.1 2012/02/18 07:35:11 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: usb_mem.c,v 1.50.6.2 2012/02/20 03:25:33 mrg Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -52,6 +52,7 @@ __KERNEL_RCSID(0, "$NetBSD: usb_mem.c,v 
 #include <sys/device.h>		/* for usbdivar.h */
 #include <sys/bus.h>
 #include <sys/cpu.h>
+#include <sys/once.h>
 
 #ifdef __NetBSD__
 #include <sys/extent.h>
@@ -93,6 +94,8 @@ Static void		usb_block_freemem(usb_dma_b
 LIST_HEAD(usb_dma_block_qh, usb_dma_block);
 Static struct usb_dma_block_qh usb_blk_freelist =
 	LIST_HEAD_INITIALIZER(usb_blk_freelist);
+kmutex_t usb_blk_lock;
+
 #ifdef DEBUG
 Static struct usb_dma_block_qh usb_blk_fraglist =
 	LIST_HEAD_INITIALIZER(usb_blk_fraglist);
@@ -104,13 +107,22 @@ Static u_int usb_blk_nfree = 0;
 Static LIST_HEAD(, usb_frag_dma) usb_frag_freelist =
 	LIST_HEAD_INITIALIZER(usb_frag_freelist);
 
+Static int usb_mem_init(void);
+
+Static int
+usb_mem_init(void)
+{
+
+	mutex_init(&usb_blk_lock, MUTEX_DEFAULT, IPL_NONE);
+	return 0;
+}
+
 Static usbd_status
 usb_block_allocmem(bus_dma_tag_t tag, size_t size, size_t align,
 		   usb_dma_block_t **dmap)
 {
 	usb_dma_block_t *b;
 	int error;
-	int s;
 
 	DPRINTFN(5, ("usb_block_allocmem: size=%zu align=%zu\n", size, align));
 
@@ -121,20 +133,19 @@ usb_block_allocmem(bus_dma_tag_t tag, si
 	}
 #endif
 
-	s = splusb();
+	KASSERT(mutex_owned(&usb_blk_lock));
+
 	/* First check the free list. */
 	LIST_FOREACH(b, &usb_blk_freelist, next) {
 		if (b->tag == tag && b->size >= size && b->align >= align) {
 			LIST_REMOVE(b, next);
 			usb_blk_nfree--;
-			splx(s);
 			*dmap = b;
 			DPRINTFN(6,("usb_block_allocmem: free list size=%zu\n",
 			    b->size));
 			return (USBD_NORMAL_COMPLETION);
 		}
 	}
-	splx(s);
 
 #ifdef DIAGNOSTIC
 	if (cpu_intr_p()) {
@@ -228,16 +239,15 @@ usb_valid_block_p(usb_dma_block_t *b, st
 Static void
 usb_block_freemem(usb_dma_block_t *b)
 {
-	int s;
+
+	KASSERT(mutex_owned(&usb_blk_lock));
 
 	DPRINTFN(6, ("usb_block_freemem: size=%zu\n", b->size));
-	s = splusb();
 #ifdef DEBUG
 	LIST_REMOVE(b, next);
 #endif
 	LIST_INSERT_HEAD(&usb_blk_freelist, b, next);
 	usb_blk_nfree++;
-	splx(s);
 }
 
 usbd_status
@@ -248,12 +258,15 @@ usb_allocmem(usbd_bus_handle bus, size_t
 	struct usb_frag_dma *f;
 	usb_dma_block_t *b;
 	int i;
-	int s;
+	static ONCE_DECL(init_control);
+
+	RUN_ONCE(&init_control, usb_mem_init);
 
 	/* If the request is large then just use a full block. */
 	if (size > USB_MEM_SMALL || align > USB_MEM_SMALL) {
 		DPRINTFN(1, ("usb_allocmem: large alloc %d\n", (int)size));
 		size = (size + USB_MEM_BLOCK - 1) & ~(USB_MEM_BLOCK - 1);
+		mutex_enter(&usb_blk_lock);
 		err = usb_block_allocmem(tag, size, align, &p->block);
 		if (!err) {
 #ifdef DEBUG
@@ -262,10 +275,11 @@ usb_allocmem(usbd_bus_handle bus, size_t
 			p->block->flags = USB_DMA_FULLBLOCK;
 			p->offs = 0;
 		}
+		mutex_exit(&usb_blk_lock);
 		return (err);
 	}
 
-	s = splusb();
+	mutex_enter(&usb_blk_lock);
 	/* Check for free fragments. */
 	LIST_FOREACH(f, &usb_frag_freelist, next) {
 		KDASSERTMSG(usb_valid_block_p(f->block, &usb_blk_fraglist),
@@ -278,7 +292,7 @@ usb_allocmem(usbd_bus_handle bus, size_t
 		DPRINTFN(1, ("usb_allocmem: adding fragments\n"));
 		err = usb_block_allocmem(tag, USB_MEM_BLOCK, USB_MEM_SMALL,&b);
 		if (err) {
-			splx(s);
+			mutex_exit(&usb_blk_lock);
 			return (err);
 		}
 #ifdef DEBUG
@@ -303,7 +317,7 @@ usb_allocmem(usbd_bus_handle bus, size_t
 #endif
 	p->block->flags &= ~USB_DMA_RESERVE;
 	LIST_REMOVE(f, next);
-	splx(s);
+	mutex_exit(&usb_blk_lock);
 	DPRINTFN(5, ("usb_allocmem: use frag=%p size=%d\n", f, (int)size));
 	return (USBD_NORMAL_COMPLETION);
 }
@@ -312,14 +326,15 @@ void
 usb_freemem(usbd_bus_handle bus, usb_dma_t *p)
 {
 	struct usb_frag_dma *f;
-	int s;
 
+	mutex_enter(&usb_blk_lock);
 	if (p->block->flags & USB_DMA_FULLBLOCK) {
 		KDASSERTMSG(usb_valid_block_p(p->block, &usb_blk_fulllist),
 		    "%s: dma %p: invalid block pointer %p",
 		     __func__, p, p->block);
 		DPRINTFN(1, ("usb_freemem: large free\n"));
 		usb_block_freemem(p->block);
+		mutex_exit(&usb_blk_lock);
 		return;
 	}
 	KDASSERTMSG(usb_valid_block_p(p->block, &usb_blk_fraglist),
@@ -335,9 +350,8 @@ usb_freemem(usbd_bus_handle bus, usb_dma
 #ifdef USB_FRAG_DMA_WORKAROUND
 	f->offs -= USB_MEM_SMALL;
 #endif
-	s = splusb();
 	LIST_INSERT_HEAD(&usb_frag_freelist, f, next);
-	splx(s);
+	mutex_exit(&usb_blk_lock);
 	DPRINTFN(5, ("usb_freemem: frag=%p\n", f));
 }
 

Reply via email to