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