busdma: Add PROTECTED bus_dma_tag_create() flag.
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Mon, 27 Dec 2010 08:24:03 +0000 (16:24 +0800)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Sat, 8 Jan 2011 15:15:01 +0000 (23:15 +0800)
PROTECTED
  All of the functions called with the dma_tag are already protected by
  the caller, so busdma code need not to protect the internal data
  structures.  Panic, if the "defered dmamap load callback" is going to
  happen.

When used along with PRIVBZONE, ALLOCALL and ALLOCNOW, it could greatly
reduce the work load of fixing all of the drivers that mal-use busdma
functions.

sys/platform/pc32/i386/busdma_machdep.c
sys/platform/pc64/x86_64/busdma_machdep.c
sys/sys/bus_dma.h

index 354d708..3a24893 100644 (file)
@@ -216,6 +216,9 @@ static __inline
 bus_dma_segment_t *
 bus_dma_tag_lock(bus_dma_tag_t tag, bus_dma_segment_t *cache)
 {
+       if (tag->flags & BUS_DMA_PROTECTED)
+               return(tag->segments);
+
        if (tag->nsegments <= BUS_DMA_CACHE_SEGMENTS)
                return(cache);
 #ifdef SMP
@@ -229,6 +232,9 @@ void
 bus_dma_tag_unlock(bus_dma_tag_t tag)
 {
 #ifdef SMP
+       if (tag->flags & BUS_DMA_PROTECTED)
+               return;
+
        if (tag->nsegments > BUS_DMA_CACHE_SEGMENTS)
                spin_unlock(&tag->spin);
 #endif
@@ -835,6 +841,10 @@ bus_dmamap_load(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf,
                KKASSERT((dmat->flags &
                          (BUS_DMA_PRIVBZONE | BUS_DMA_ALLOCALL)) !=
                         (BUS_DMA_PRIVBZONE | BUS_DMA_ALLOCALL));
+
+               if (dmat->flags & BUS_DMA_PROTECTED)
+                       panic("protected dmamap callback will be defered\n");
+
                bus_dma_tag_unlock(dmat);
                return error;
        }
index fe62403..ed3e6aa 100644 (file)
@@ -216,6 +216,9 @@ static __inline
 bus_dma_segment_t *
 bus_dma_tag_lock(bus_dma_tag_t tag, bus_dma_segment_t *cache)
 {
+       if (tag->flags & BUS_DMA_PROTECTED)
+               return(tag->segments);
+
        if (tag->nsegments <= BUS_DMA_CACHE_SEGMENTS)
                return(cache);
 #ifdef SMP
@@ -229,6 +232,9 @@ void
 bus_dma_tag_unlock(bus_dma_tag_t tag)
 {
 #ifdef SMP
+       if (tag->flags & BUS_DMA_PROTECTED)
+               return;
+
        if (tag->nsegments > BUS_DMA_CACHE_SEGMENTS)
                spin_unlock(&tag->spin);
 #endif
@@ -835,6 +841,10 @@ bus_dmamap_load(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf,
                KKASSERT((dmat->flags &
                          (BUS_DMA_PRIVBZONE | BUS_DMA_ALLOCALL)) !=
                         (BUS_DMA_PRIVBZONE | BUS_DMA_ALLOCALL));
+
+               if (dmat->flags & BUS_DMA_PROTECTED)
+                       panic("protected dmamap callback will be defered\n");
+
                bus_dma_tag_unlock(dmat);
                return error;
        }
index 6acedd5..1226a1c 100644 (file)
@@ -98,6 +98,8 @@
                                         * loaded memory is properly aligned */
 #define BUS_DMA_PRIVBZONE      0x0400  /* need private bounce zone */
 #define BUS_DMA_ALLOCALL       0x0800  /* allocate all needed resources */
+#define BUS_DMA_PROTECTED      0x1000  /* all busdma functions are already
+                                        * protected */
 
 /* Forwards needed by prototypes below. */
 struct mbuf;