From c26842b6106804dc56cbcd5031662d4553b57a0c Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Mon, 27 Dec 2010 16:24:03 +0800 Subject: [PATCH] busdma: Add PROTECTED bus_dma_tag_create() flag. 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 | 10 ++++++++++ sys/platform/pc64/x86_64/busdma_machdep.c | 10 ++++++++++ sys/sys/bus_dma.h | 2 ++ 3 files changed, 22 insertions(+), 0 deletions(-) diff --git a/sys/platform/pc32/i386/busdma_machdep.c b/sys/platform/pc32/i386/busdma_machdep.c index 354d708..3a24893 100644 --- a/sys/platform/pc32/i386/busdma_machdep.c +++ b/sys/platform/pc32/i386/busdma_machdep.c @@ -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; } diff --git a/sys/platform/pc64/x86_64/busdma_machdep.c b/sys/platform/pc64/x86_64/busdma_machdep.c index fe62403..ed3e6aa 100644 --- a/sys/platform/pc64/x86_64/busdma_machdep.c +++ b/sys/platform/pc64/x86_64/busdma_machdep.c @@ -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; } diff --git a/sys/sys/bus_dma.h b/sys/sys/bus_dma.h index 6acedd5..1226a1c 100644 --- a/sys/sys/bus_dma.h +++ b/sys/sys/bus_dma.h @@ -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; -- 1.7.7.2