Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/jmcneill-usbmp]: src/sys/dev/usb convert splusb() calls to using a new u...
details: https://anonhg.NetBSD.org/src/rev/85ed87585898
branches: jmcneill-usbmp
changeset: 771795:85ed87585898
user: mrg <mrg%NetBSD.org@localhost>
date: Mon Feb 20 03:25:33 2012 +0000
description:
convert splusb() calls to using a new usb_blk_lock.
diffstat:
sys/dev/usb/usb_mem.c | 46 ++++++++++++++++++++++++++++++----------------
1 files changed, 30 insertions(+), 16 deletions(-)
diffs (177 lines):
diff -r 1d0285167c96 -r 85ed87585898 sys/dev/usb/usb_mem.c
--- a/sys/dev/usb/usb_mem.c Mon Feb 20 03:23:26 2012 +0000
+++ b/sys/dev/usb/usb_mem.c Mon Feb 20 03:25:33 2012 +0000
@@ -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 @@
#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 @@
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 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 @@
}
#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 @@
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 @@
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 @@
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 @@
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 @@
#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 @@
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 @@
#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));
}
Home |
Main Index |
Thread Index |
Old Index