Index: busdma_machdep.c
===================================================================
RCS file: /space2/ncvs/src/sys/i386/i386/busdma_machdep.c,v
retrieving revision 1.34
diff -u -p -r1.34 busdma_machdep.c
--- busdma_machdep.c	26 Feb 2003 02:16:05 -0000	1.34
+++ busdma_machdep.c	13 Mar 2003 16:42:59 -0000
@@ -31,6 +31,7 @@
 #include <sys/malloc.h>
 #include <sys/bus.h>
 #include <sys/interrupt.h>
+#include <sys/kernel.h>
 #include <sys/lock.h>
 #include <sys/proc.h>
 #include <sys/mutex.h>
@@ -95,6 +96,7 @@ static STAILQ_HEAD(, bus_dmamap) bounce_
 static STAILQ_HEAD(, bus_dmamap) bounce_map_callbacklist;
 static struct bus_dmamap nobounce_dmamap;
 
+static void init_bounce_pages(void *dummy);
 static int alloc_bounce_pages(bus_dma_tag_t dmat, u_int numpages);
 static int reserve_bounce_pages(bus_dma_tag_t dmat, bus_dmamap_t map);
 static vm_offset_t add_bounce_page(bus_dma_tag_t dmat, bus_dmamap_t map,
@@ -102,6 +104,9 @@ static vm_offset_t add_bounce_page(bus_d
 static void free_bounce_page(bus_dma_tag_t dmat, struct bounce_page *bpage);
 static __inline int run_filter(bus_dma_tag_t dmat, bus_addr_t paddr);
 
+/* To protect all the the bounce pages related lists and data. */
+static struct mtx bpages_mtx;
+
 /*
  * Return true if a match is made.
  * 
@@ -348,10 +353,12 @@ bus_dmamem_alloc_size(bus_dma_tag_t dmat
 		 *     and handles multi-seg allocations.  Nobody is doing
 		 *     multi-seg allocations yet though.
 		 */
+		mtx_lock(&Giant);
 		*vaddr = contigmalloc(size, M_DEVBUF,
 		    (flags & BUS_DMA_NOWAIT) ? M_NOWAIT : M_WAITOK,
 		    0ul, dmat->lowaddr, dmat->alignment? dmat->alignment : 1ul,
 		    dmat->boundary);
+		mtx_unlock(&Giant);
 	}
 	if (*vaddr == NULL)
 		return (ENOMEM);
@@ -381,8 +388,11 @@ bus_dmamem_free_size(bus_dma_tag_t dmat,
 		panic("bus_dmamem_free: Invalid map freed\n");
 	if ((size <= PAGE_SIZE) && dmat->lowaddr >= ptoa(Maxmem))
 		free(vaddr, M_DEVBUF);
-	else
+	else {
+		mtx_lock(&Giant);
 		contigfree(vaddr, size, M_DEVBUF);
+		mtx_unlock(&Giant);
+	}
 }
 
 void
@@ -443,9 +453,6 @@ bus_dmamap_load(bus_dma_tag_t dmat, bus_
 
 	/* Reserve Necessary Bounce Pages */
 	if (map->pagesneeded != 0) {
-		int s;
-
-		s = splhigh();
 	 	if (reserve_bounce_pages(dmat, map) != 0) {
 
 			/* Queue us for resources */
@@ -455,12 +462,11 @@ bus_dmamap_load(bus_dma_tag_t dmat, bus_
 			map->callback = callback;
 			map->callback_arg = callback_arg;
 
+			mtx_lock(&bpages_mtx);
 			STAILQ_INSERT_TAIL(&bounce_map_waitinglist, map, links);
-			splx(s);
-
+			mtx_unlock(&bpages_mtx);
 			return (EINPROGRESS);
 		}
-		splx(s);
 	}
 
 	vaddr = (vm_offset_t)buf;
@@ -772,42 +778,52 @@ _bus_dmamap_sync(bus_dma_tag_t dmat, bus
 	}
 }
 
+static void
+init_bounce_pages(void *dummy __unused)
+{
+
+	free_bpages = 0;
+	reserved_bpages = 0;
+	active_bpages = 0;
+	total_bpages = 0;
+	STAILQ_INIT(&bounce_page_list);
+	STAILQ_INIT(&bounce_map_waitinglist);
+	STAILQ_INIT(&bounce_map_callbacklist);
+	mtx_init(&bpages_mtx, "bounce pages mutex", NULL, MTX_DEF);
+}
+SYSINIT(bpages, SI_SUB_LOCK, SI_ORDER_ANY, init_bounce_pages, NULL);
+
 static int
 alloc_bounce_pages(bus_dma_tag_t dmat, u_int numpages)
 {
 	int count;
 
 	count = 0;
-	if (total_bpages == 0) {
-		STAILQ_INIT(&bounce_page_list);
-		STAILQ_INIT(&bounce_map_waitinglist);
-		STAILQ_INIT(&bounce_map_callbacklist);
-	}
-	
 	while (numpages > 0) {
 		struct bounce_page *bpage;
-		int s;
 
 		bpage = (struct bounce_page *)malloc(sizeof(*bpage), M_DEVBUF,
 						     M_NOWAIT | M_ZERO);
 
 		if (bpage == NULL)
 			break;
+		mtx_lock(&Giant);
 		bpage->vaddr = (vm_offset_t)contigmalloc(PAGE_SIZE, M_DEVBUF,
 							 M_NOWAIT, 0ul,
 							 dmat->lowaddr,
 							 PAGE_SIZE,
 							 0);
+		mtx_unlock(&Giant);
 		if (bpage->vaddr == 0) {
 			free(bpage, M_DEVBUF);
 			break;
 		}
 		bpage->busaddr = pmap_kextract(bpage->vaddr);
-		s = splhigh();
+		mtx_lock(&bpages_mtx);
 		STAILQ_INSERT_TAIL(&bounce_page_list, bpage, links);
 		total_bpages++;
 		free_bpages++;
-		splx(s);
+		mtx_unlock(&bpages_mtx);
 		count++;
 		numpages--;
 	}
@@ -819,9 +835,11 @@ reserve_bounce_pages(bus_dma_tag_t dmat,
 {
 	int pages;
 
+	mtx_lock(&bpages_mtx);
 	pages = MIN(free_bpages, map->pagesneeded - map->pagesreserved);
 	free_bpages -= pages;
 	reserved_bpages += pages;
+	mtx_unlock(&bpages_mtx);
 	map->pagesreserved += pages;
 	pages = map->pagesneeded - map->pagesreserved;
 
@@ -832,7 +850,6 @@ static vm_offset_t
 add_bounce_page(bus_dma_tag_t dmat, bus_dmamap_t map, vm_offset_t vaddr,
 		bus_size_t size)
 {
-	int s;
 	struct bounce_page *bpage;
 
 	if (map->pagesneeded == 0)
@@ -843,7 +860,7 @@ add_bounce_page(bus_dma_tag_t dmat, bus_
 		panic("add_bounce_page: map doesn't need any pages");
 	map->pagesreserved--;
 
-	s = splhigh();
+	mtx_lock(&bpages_mtx);
 	bpage = STAILQ_FIRST(&bounce_page_list);
 	if (bpage == NULL)
 		panic("add_bounce_page: free page list is empty");
@@ -851,7 +868,7 @@ add_bounce_page(bus_dma_tag_t dmat, bus_
 	STAILQ_REMOVE_HEAD(&bounce_page_list, links);
 	reserved_bpages--;
 	active_bpages++;
-	splx(s);
+	mtx_unlock(&bpages_mtx);
 
 	bpage->datavaddr = vaddr;
 	bpage->datacount = size;
@@ -862,13 +879,12 @@ add_bounce_page(bus_dma_tag_t dmat, bus_
 static void
 free_bounce_page(bus_dma_tag_t dmat, struct bounce_page *bpage)
 {
-	int s;
 	struct bus_dmamap *map;
 
 	bpage->datavaddr = 0;
 	bpage->datacount = 0;
 
-	s = splhigh();
+	mtx_lock(&bpages_mtx);
 	STAILQ_INSERT_HEAD(&bounce_page_list, bpage, links);
 	free_bpages++;
 	active_bpages--;
@@ -881,22 +897,21 @@ free_bounce_page(bus_dma_tag_t dmat, str
 			swi_sched(vm_ih, 0);
 		}
 	}
-	splx(s);
+	mtx_unlock(&bpages_mtx);
 }
 
 void
 busdma_swi(void)
 {
-	int s;
 	struct bus_dmamap *map;
 
-	s = splhigh();
+	mtx_lock(&bpages_mtx);
 	while ((map = STAILQ_FIRST(&bounce_map_callbacklist)) != NULL) {
 		STAILQ_REMOVE_HEAD(&bounce_map_callbacklist, links);
-		splx(s);
+		mtx_unlock(&bpages_mtx);
 		bus_dmamap_load(map->dmat, map, map->buf, map->buflen,
 				map->callback, map->callback_arg, /*flags*/0);
-		s = splhigh();
+		mtx_lock(&bpages_mtx);
 	}
-	splx(s);
+	mtx_unlock(&bpages_mtx);
 }
