Subject: Re: bce(4) and memory > 1GB problem
To: matthew green <mrg@eterna.com.au>
From: Yorick Hardy <yhardy@uj.ac.za>
List: tech-kern
Date: 01/22/2007 08:55:25
This is a multi-part message in MIME format.
--------------000300030009000702050405
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

matthew green wrote:
>    
>    Thanks for pointing that out.
>
>
> good stuff.  i plan to test and commit this in the next couple of days.
> i will probably add a __HAVE_BUS_DMATAG_SUBREGION (anyone have a better
> name??) define to show this function is available to MI code, and
> change bce(4) to barf if this is not present.
>
>
> thanks!
>
>
> .mrg.
>
>   
I created a patch where all other archs return an error for 
bus_dmatag_subregion.
bce then complains if bus_dmatag_subregion returns an error and falls 
back to the
parent tag. Is this the right way to go?

The patch can be applied independent of Manuel's patch for xen.

  http://mail-index.netbsd.org/tech-kern/2007/01/21/0009.html

I could not find bus_dma implementations for
    amiga
    amigappc
    cesfic
    hp300
    hpc
    hppa
    ia64
    luna68k
    news68k
    pc532
    pdp10
    sbmips
    sh3

is that correct?

In addition I added the ability to reuse tags on x86 in some circumstances,
would someone mind having a look over the new bus_dmatag_subregion
and bus_dmatag_destroy for x86 to see if it looks correct and is worth
doing? (I am using this patch at the moment.)

-- 
Kind regards,

Yorick Hardy


--------------000300030009000702050405
Content-Type: text/plain;
 name="bce7.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="bce7.patch"

--- sys/arch/arc/include/bus.h.orig	2007-01-20 12:06:45.000000000 +0200
+++ sys/arch/arc/include/bus.h	2007-01-20 12:47:59.000000000 +0200
@@ -799,6 +799,9 @@
 #define bus_dmamem_mmap(t, sg, n, o, p, f)			\
 	(*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f))
 
+#define bus_dmatag_subregion(t, mna, mxa, nt, f) EOPNOTSUPP
+#define bus_dmatag_destroy(t)
+
 /*
  *	bus_dmamap_t
  *
--- sys/arch/algor/include/bus.h.orig	2007-01-20 12:06:45.000000000 +0200
+++ sys/arch/algor/include/bus.h	2007-01-20 12:47:07.000000000 +0200
@@ -616,6 +616,9 @@
 #define	bus_dmamem_mmap(t, sg, n, o, p, f)			\
 	(*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f))
 
+#define bus_dmatag_subregion(t, mna, mxa, nt, f) EOPNOTSUPP
+#define bus_dmatag_destroy(t)
+
 /*
  *	bus_dmamap_t
  *
--- sys/arch/alpha/include/bus.h.orig	2007-01-20 12:06:45.000000000 +0200
+++ sys/arch/alpha/include/bus.h	2007-01-20 12:47:18.000000000 +0200
@@ -688,6 +688,9 @@
 #define	bus_dmamem_mmap(t, sg, n, o, p, f)			\
 	(*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f))
 
+#define bus_dmatag_subregion(t, mna, mxa, nt, f) EOPNOTSUPP
+#define bus_dmatag_destroy(t)
+
 /*
  *	bus_dmamap_t
  *
--- sys/arch/arm/include/bus.h.orig	2007-01-20 12:06:45.000000000 +0200
+++ sys/arch/arm/include/bus.h	2007-01-20 12:48:09.000000000 +0200
@@ -902,6 +902,9 @@
 #define	bus_dmamem_mmap(t, sg, n, o, p, f)			\
 	(*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f))
 
+#define bus_dmatag_subregion(t, mna, mxa, nt, f) EOPNOTSUPP
+#define bus_dmatag_destroy(t)
+
 /*
  *	bus_dmamap_t
  *
--- sys/arch/atari/include/bus.h.orig	2007-01-20 12:06:45.000000000 +0200
+++ sys/arch/atari/include/bus.h	2007-01-20 12:48:18.000000000 +0200
@@ -649,6 +649,8 @@
 	(void)((t)->_dmamap_sync ?				\
 	    (*(t)->_dmamap_sync)((t), (p), (o), (l), (ops)) : (void)0)
 
+#define bus_dmatag_subregion(t, mna, mxa, nt, f) EOPNOTSUPP
+#define bus_dmatag_destroy(t)
 
 /*
  *	bus_dmamap_t
--- sys/arch/cobalt/include/bus.h.orig	2007-01-20 12:06:45.000000000 +0200
+++ sys/arch/cobalt/include/bus.h	2007-01-20 12:49:02.000000000 +0200
@@ -658,6 +658,9 @@
 #define	bus_dmamem_mmap(t, sg, n, o, p, f)			\
 	(*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f))
 
+#define bus_dmatag_subregion(t, mna, mxa, nt, f) EOPNOTSUPP
+#define bus_dmatag_destroy(t)
+
 /*
  *	bus_dmamap_t
  *
--- sys/arch/dreamcast/include/bus.h.orig	2007-01-20 12:06:45.000000000 +0200
+++ sys/arch/dreamcast/include/bus.h	2007-01-20 12:49:12.000000000 +0200
@@ -566,6 +566,9 @@
 #define	bus_dmamem_mmap(t, sg, n, o, p, f)			\
 	(*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f))
 
+#define bus_dmatag_subregion(t, mna, mxa, nt, f) EOPNOTSUPP
+#define bus_dmatag_destroy(t)
+
 /*
  *	bus_dmamap_t
  *
--- sys/arch/ews4800mips/include/bus.h.orig	2007-01-20 12:06:45.000000000 +0200
+++ sys/arch/ews4800mips/include/bus.h	2007-01-20 12:50:26.000000000 +0200
@@ -805,6 +805,9 @@
 #define	bus_dmamem_mmap(t, sg, n, o, p, f)			\
 	(*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f))
 
+#define bus_dmatag_subregion(t, mna, mxa, nt, f) EOPNOTSUPP
+#define bus_dmatag_destroy(t)
+
 /*
  *	bus_dmamap_t
  *
--- sys/arch/hp700/include/bus.h.orig	2007-01-20 12:06:45.000000000 +0200
+++ sys/arch/hp700/include/bus.h	2007-01-20 12:50:42.000000000 +0200
@@ -424,6 +424,9 @@
 #define	bus_dmamem_mmap(t, sg, n, o, p, f)			\
 	(*(t)->_dmamem_mmap)((t)->_cookie, (sg), (n), (o), (p), (f))
 
+#define bus_dmatag_subregion(t, mna, mxa, nt, f) EOPNOTSUPP
+#define bus_dmatag_destroy(t)
+
 /*
  *	bus_dmamap_t
  *
--- sys/arch/hpcmips/include/bus.h.orig	2007-01-20 12:06:45.000000000 +0200
+++ sys/arch/hpcmips/include/bus.h	2007-01-20 12:51:04.000000000 +0200
@@ -1023,6 +1023,8 @@
 #define	bus_dmamem_mmap(t, sg, n, o, p, f)				\
 	(*__bd_ops(t).bd_mem_mmap)((t), (sg), (n), (o), (p), (f))
 
+#define bus_dmatag_subregion(t, mna, mxa, nt, f) EOPNOTSUPP
+#define bus_dmatag_destroy(t)
 
 /*
  * Macros to provide prototypes for all the functions used in the
--- sys/arch/hpcsh/include/bus.h.orig	2007-01-20 12:06:45.000000000 +0200
+++ sys/arch/hpcsh/include/bus.h	2007-01-20 12:51:11.000000000 +0200
@@ -716,6 +716,9 @@
 #define	bus_dmamem_mmap(t, sg, n, o, p, f)			\
 	(*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f))
 
+#define bus_dmatag_subregion(t, mna, mxa, nt, f) EOPNOTSUPP
+#define bus_dmatag_destroy(t)
+
 /*
  *	bus_dmamap_t
  *
--- sys/arch/landisk/include/bus.h.orig	2007-01-20 12:06:45.000000000 +0200
+++ sys/arch/landisk/include/bus.h	2007-01-20 12:52:08.000000000 +0200
@@ -567,6 +567,9 @@
 #define	bus_dmamem_mmap(t, sg, n, o, p, f)			\
 	(*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f))
 
+#define bus_dmatag_subregion(t, mna, mxa, nt, f) EOPNOTSUPP
+#define bus_dmatag_destroy(t)
+
 /*
  *	bus_dmamap_t
  *
--- sys/arch/m68k/include/bus_dma.h.orig	2007-01-20 12:38:54.000000000 +0200
+++ sys/arch/m68k/include/bus_dma.h	2007-01-20 12:39:07.000000000 +0200
@@ -199,6 +199,9 @@
 #define	bus_dmamem_mmap(t, sg, n, o, p, f)			\
 	(*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f))
 
+#define bus_dmatag_subregion(t, mna, mxa, nt, f) EOPNOTSUPP       
+#define bus_dmatag_destroy(t)
+
 /*
  *	bus_dmamap_t
  *
--- sys/arch/macppc/include/bus.h.orig	2007-01-20 12:06:45.000000000 +0200
+++ sys/arch/macppc/include/bus.h	2007-01-20 12:53:02.000000000 +0200
@@ -876,6 +876,9 @@
 #define bus_dmamem_mmap(t, sg, n, o, p, f)			\
 	(*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f))
 
+#define bus_dmatag_subregion(t, mna, mxa, nt, f) EOPNOTSUPP
+#define bus_dmatag_destroy(t)
+
 /*
  *	bus_dmamap_t
  *
--- sys/arch/mips/include/bus_dma.h.orig	2007-01-20 14:14:40.000000000 +0200
+++ sys/arch/mips/include/bus_dma.h	2007-01-20 14:15:25.000000000 +0200
@@ -196,6 +196,9 @@
 #define	bus_dmamem_mmap(t, sg, n, o, p, f)			\
 	(*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f))
 
+#define bus_dmatag_subregion(t, mna, mxa, nt, f) EOPNOTSUPP
+#define bus_dmatag_destroy(t)
+
 /*
  *	bus_dmamap_t
  *
--- sys/arch/mipsco/include/bus.h.orig	2007-01-20 12:06:45.000000000 +0200
+++ sys/arch/mipsco/include/bus.h	2007-01-20 12:30:07.000000000 +0200
@@ -894,6 +894,9 @@
 #define bus_dmamem_mmap(t, sg, n, o, p, f)			\
 	(*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f))
 
+#define bus_dmatag_subregion(t, mna, mxa, nt, f) EOPNOTSUPP
+#define bus_dmatag_destroy(t)
+
 /*
  *	bus_dmamap_t
  *
--- sys/arch/newsmips/include/bus.h.orig	2007-01-20 12:06:45.000000000 +0200
+++ sys/arch/newsmips/include/bus.h	2007-01-20 12:54:26.000000000 +0200
@@ -598,6 +598,9 @@
 #define	bus_dmamem_mmap(t, sg, n, o, p, f)			\
 	(*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f))
 
+#define bus_dmatag_subregion(t, mna, mxa, nt, f) EOPNOTSUPP
+#define bus_dmatag_destroy(t)
+
 /*
  *	bus_dmamap_t
  *
--- sys/arch/ofppc/include/bus.h.orig	2007-01-20 12:06:45.000000000 +0200
+++ sys/arch/ofppc/include/bus.h	2007-01-20 12:55:05.000000000 +0200
@@ -616,6 +616,9 @@
 #define	bus_dmamem_mmap(t, sg, n, o, p, f)			\
 	(*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f))
 
+#define bus_dmatag_subregion(t, mna, mxa, nt, f) EOPNOTSUPP
+#define bus_dmatag_destroy(t)
+
 /*
  *	bus_dmamap_t
  *
--- sys/arch/playstation2/include/bus.h.orig	2007-01-20 12:06:45.000000000 +0200
+++ sys/arch/playstation2/include/bus.h	2007-01-20 12:55:28.000000000 +0200
@@ -843,6 +843,9 @@
 #define	bus_dmamem_mmap(t, sg, n, o, p, f)			\
 	(*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f))
 
+#define bus_dmatag_subregion(t, mna, mxa, nt, f) EOPNOTSUPP
+#define bus_dmatag_destroy(t)
+
 /*
  *	bus_dmamap_t
  *
--- sys/arch/pmax/include/bus.h.orig	2007-01-20 12:06:45.000000000 +0200
+++ sys/arch/pmax/include/bus.h	2007-01-20 12:55:37.000000000 +0200
@@ -601,6 +601,9 @@
 #define	bus_dmamem_mmap(t, sg, n, o, p, f)			\
 	(*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f))
 
+#define bus_dmatag_subregion(t, mna, mxa, nt, f) EOPNOTSUPP
+#define bus_dmatag_destroy(t)
+
 /*
  *	bus_dmamap_t
  *
--- sys/arch/powerpc/include/bus.h.orig	2007-01-20 12:06:45.000000000 +0200
+++ sys/arch/powerpc/include/bus.h	2007-01-20 12:55:56.000000000 +0200
@@ -762,6 +762,9 @@
 #define	bus_dmamem_mmap(t, sg, n, o, p, f)			\
 	(*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f))
 
+#define bus_dmatag_subregion(t, mna, mxa, nt, f) EOPNOTSUPP
+#define bus_dmatag_destroy(t)
+
 /*
  *	bus_dmamap_t
  *
--- sys/arch/sgimips/include/bus.h.orig	2007-01-20 12:06:45.000000000 +0200
+++ sys/arch/sgimips/include/bus.h	2007-01-20 12:56:32.000000000 +0200
@@ -774,6 +774,9 @@
 #define	bus_dmamem_mmap(t, sg, n, o, p, f)			\
 	(*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f))
 
+#define bus_dmatag_subregion(t, mna, mxa, nt, f) EOPNOTSUPP
+#define bus_dmatag_destroy(t)
+
 /*
  *	bus_dmamap_t
  *
--- sys/arch/sh5/include/bus.h.orig	2007-01-20 12:06:45.000000000 +0200
+++ sys/arch/sh5/include/bus.h	2007-01-20 12:56:48.000000000 +0200
@@ -998,6 +998,9 @@
 #define	bus_dmamem_mmap(t, sg, n, o, p, f)			\
 	(*(t)->bd_dmamem_mmap)((t)->bd_cookie, (sg), (n), (o), (p), (f))
 
+#define bus_dmatag_subregion(t, mna, mxa, nt, f) EOPNOTSUPP
+#define bus_dmatag_destroy(t)
+
 /*
  *	bus_dmamap_t
  *
--- sys/arch/sparc/include/bus.h.orig	2007-01-20 12:06:45.000000000 +0200
+++ sys/arch/sparc/include/bus.h	2007-01-20 12:57:47.000000000 +0200
@@ -1679,6 +1679,9 @@
 #define	bus_dmamem_mmap(t, sg, n, o, p, f)			\
 	(*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f))
 
+#define bus_dmatag_subregion(t, mna, mxa, nt, f) EOPNOTSUPP
+#define bus_dmatag_destroy(t)
+
 /*
  *	bus_dmamap_t
  *
--- sys/arch/sparc64/include/bus.h.orig	2007-01-20 12:06:45.000000000 +0200
+++ sys/arch/sparc64/include/bus.h	2007-01-20 12:57:56.000000000 +0200
@@ -1526,6 +1526,9 @@
 #define	bus_dmamem_mmap(t, sg, n, o, p, f)			\
 	(*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f))
 
+#define bus_dmatag_subregion(t, mna, mxa, nt, f) EOPNOTSUPP
+#define bus_dmatag_destroy(t)
+
 /*
  *	bus_dmamap_t
  *
--- sys/arch/sun68k/include/bus.h.orig	2007-01-20 12:06:45.000000000 +0200
+++ sys/arch/sun68k/include/bus.h	2007-01-20 12:58:23.000000000 +0200
@@ -931,6 +931,9 @@
 #define	bus_dmamem_mmap(t, sg, n, o, p, f)			\
 	(*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f))
 
+#define bus_dmatag_subregion(t, mna, mxa, nt, f) EOPNOTSUPP
+#define bus_dmatag_destroy(t)
+
 /*
  *	bus_dmamap_t
  *
--- sys/arch/vax/include/bus.h.orig	2007-01-20 12:06:45.000000000 +0200
+++ sys/arch/vax/include/bus.h	2007-01-20 12:58:36.000000000 +0200
@@ -1029,6 +1029,9 @@
 #define	bus_dmamem_mmap(t, sg, n, o, p, f)			\
 	(*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f))
 
+#define bus_dmatag_subregion(t, mna, mxa, nt, f) EOPNOTSUPP
+#define bus_dmatag_destroy(t)
+
 /*
  *	bus_dmamap_t
  *
--- sys/arch/x68k/include/bus.h.orig	2007-01-20 12:06:45.000000000 +0200
+++ sys/arch/x68k/include/bus.h	2007-01-20 12:58:43.000000000 +0200
@@ -902,6 +902,9 @@
 #define	bus_dmamem_mmap(t,sg,n,o,p,f) \
 	((*((t)->x68k_dmamem_mmap)) ((t),(sg),(n),(o),(p),(f)))
 
+#define bus_dmatag_subregion(t, mna, mxa, nt, f) EOPNOTSUPP
+#define bus_dmatag_destroy(t)
+
 /*
  * Flags used in various bus DMA methods.
  */
--- sys/arch/x86/include/bus.h.orig	2007-01-10 16:49:27.000000000 +0200
+++ sys/arch/x86/include/bus.h	2007-01-20 13:01:50.000000000 +0200
@@ -1074,6 +1074,7 @@
 	 * bounce the transfer.  If this value is 0, it will be
 	 * ignored.
 	 */
+	int        _tag_needs_free;
 	bus_addr_t _bounce_thresh;
 	bus_addr_t _bounce_alloc_lo;
 	bus_addr_t _bounce_alloc_hi;
@@ -1108,6 +1109,9 @@
 	void	(*_dmamem_unmap)(bus_dma_tag_t, caddr_t, size_t);
 	paddr_t	(*_dmamem_mmap)(bus_dma_tag_t, bus_dma_segment_t *,
 		    int, off_t, int, int);
+	int 	(*_dmatag_subregion)(bus_dma_tag_t, bus_addr_t, bus_addr_t,
+		    bus_dma_tag_t *, int);
+	void	(*_dmatag_destroy)(bus_dma_tag_t);
 };
 
 static __inline void bus_dmamap_sync(bus_dma_tag_t, bus_dmamap_t,
@@ -1148,6 +1152,11 @@
 #define	bus_dmamem_mmap(t, sg, n, o, p, f)			\
 	(*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f))
 
+#define	bus_dmatag_subregion(t, mna, mxa, nt, f)		\
+	(*(t)->_dmatag_subregion)((t), (mna), (mxa), (nt), (f))
+#define	bus_dmatag_destroy(t)					\
+	(*(t)->_dmatag_destroy)((t))
+
 /*
  *	bus_dmamap_t
  *
--- sys/arch/x86/include/bus_private.h.orig	2007-01-13 09:27:46.000000000 +0200
+++ sys/arch/x86/include/bus_private.h	2007-01-15 10:54:39.000000000 +0200
@@ -98,6 +98,10 @@
 paddr_t	_bus_dmamem_mmap(bus_dma_tag_t tag, bus_dma_segment_t *segs,
 	    int nsegs, off_t off, int prot, int flags);
 
+int	_bus_dmatag_subregion(bus_dma_tag_t tag, bus_addr_t min_addr,
+	    bus_addr_t max_addr, bus_dma_tag_t *newtag, int flags);
+void	_bus_dmatag_destroy(bus_dma_tag_t tag);
+
 #ifndef _BUS_DMAMEM_ALLOC_RANGE
 int	_bus_dmamem_alloc_range(bus_dma_tag_t tag, bus_size_t size,
 	    bus_size_t alignment, bus_size_t boundary,
--- sys/arch/x86/isa/isa_machdep.c.orig	2007-01-13 09:05:26.000000000 +0200
+++ sys/arch/x86/isa/isa_machdep.c	2007-01-20 13:02:36.000000000 +0200
@@ -104,6 +104,7 @@
 static int _isa_dma_may_bounce(bus_dma_tag_t, bus_dmamap_t, int, int *);
 
 struct x86_bus_dma_tag isa_bus_dma_tag = {
+	0,				/* _tag_needs_free */
 	ISA_DMA_BOUNCE_THRESHOLD,	/* _bounce_thresh */
 	0,				/* _bounce_alloc_lo */
 	ISA_DMA_BOUNCE_THRESHOLD,	/* _bounce_alloc_hi */
@@ -121,6 +122,8 @@
 	_bus_dmamem_map,
 	_bus_dmamem_unmap,
 	_bus_dmamem_mmap,
+	_bus_dmatag_subregion,
+	_bus_dmatag_destroy,
 };
 
 #define	IDTVEC(name)	__CONCAT(X,name)
--- sys/arch/x86/pci/pci_machdep.c.orig	2007-01-06 13:42:22.000000000 +0200
+++ sys/arch/x86/pci/pci_machdep.c	2007-01-20 13:03:09.000000000 +0200
@@ -181,6 +181,7 @@
  * of these functions.
  */
 struct x86_bus_dma_tag pci_bus_dma_tag = {
+	0,				/* tag_needs_free */
 #if defined(_LP64) || defined(PAE)
 	PCI32_DMA_BOUNCE_THRESHOLD,	/* bounce_thresh */
 	ISA_DMA_BOUNCE_THRESHOLD,	/* bounce_alloclo */
@@ -198,16 +199,14 @@
 	_bus_dmamap_load_uio,
 	_bus_dmamap_load_raw,
 	_bus_dmamap_unload,
-#if defined(_LP64) || defined(PAE)
 	_bus_dmamap_sync,
-#else
-	NULL,
-#endif
 	_bus_dmamem_alloc,
 	_bus_dmamem_free,
 	_bus_dmamem_map,
 	_bus_dmamem_unmap,
 	_bus_dmamem_mmap,
+	_bus_dmatag_subregion,
+	_bus_dmatag_destroy,
 };
 
 #ifdef _LP64
@@ -229,6 +228,8 @@
 	_bus_dmamem_map,
 	_bus_dmamem_unmap,
 	_bus_dmamem_mmap,
+	_bus_dmatag_subregion,
+	_bus_dmatag_destroy,
 };
 #endif
 
--- sys/arch/x86/x86/bus_dma.c.orig	2007-01-06 12:04:01.000000000 +0200
+++ sys/arch/x86/x86/bus_dma.c	2007-01-20 13:24:15.000000000 +0200
@@ -1192,3 +1192,44 @@
 	return (0);
 }
 
+int
+_bus_dmatag_subregion(bus_dma_tag_t tag, bus_addr_t min_addr,
+		      bus_addr_t max_addr, bus_dma_tag_t *newtag, int flags)
+{
+	if((tag->_bounce_thresh != 0   && max_addr >= tag->_bounce_thresh)   &&
+	   (tag->_bounce_alloc_hi != 0 && max_addr >= tag->_bounce_alloc_hi) &&
+	   (min_addr <= tag->_bounce_alloc_lo)) {
+		*newtag = tag;
+		/* if the tag must be freed, add a reference */
+		if(tag->_tag_needs_free) (tag->_tag_needs_free)++;
+		return 0;
+	}
+
+	if ((*newtag = malloc(sizeof(struct x86_bus_dma_tag), M_DMAMAP,
+	    (flags & BUS_DMA_NOWAIT) ? M_NOWAIT : M_WAITOK)) == NULL) {
+		return ENOMEM;
+	}
+
+	**newtag = *tag;
+	(*newtag)->_tag_needs_free = 1;
+
+	if(tag->_bounce_thresh == 0 || max_addr < tag->_bounce_thresh)
+		(*newtag)->_bounce_thresh = max_addr;
+	if(tag->_bounce_alloc_hi == 0 || max_addr < tag->_bounce_alloc_hi)
+		(*newtag)->_bounce_alloc_hi = max_addr;
+	if(min_addr > tag->_bounce_alloc_lo)
+		(*newtag)->_bounce_alloc_lo = min_addr;
+
+	return 0;
+}
+
+void
+_bus_dmatag_destroy(bus_dma_tag_t tag)
+{
+	switch(tag->_tag_needs_free) {
+		case 0:	 break;			/* not allocated with malloc */
+		case 1:  free(tag, M_DMAMAP);	/* last reference to tag */
+			 break;
+		default: (tag->_tag_needs_free)--; /* one less reference */
+	}
+}
--- sys/dev/pci/if_bce.c.orig	2007-01-06 11:49:53.000000000 +0200
+++ sys/dev/pci/if_bce.c	2007-01-17 15:43:12.000000000 +0200
@@ -293,7 +293,16 @@
 	KASSERT(bp != NULL);
 
 	sc->bce_pa = *pa;
-	sc->bce_dmatag = pa->pa_dmat;
+
+	/* BCM440x can only address 30 bits (1GB) */
+	if(bus_dmatag_subregion(pa->pa_dmat, 0, (1 << 30) - 1,
+			       &(sc->bce_dmatag), BUS_DMA_NOWAIT) != 0)
+	{
+		APRINT_ERROR("WARNING: %s failed to restrict dma range,"
+			     " falling back to parent bus dma range\n",
+			     sc->bce_dev.dv_xname);
+		sc->bce_dmatag = pa->pa_dmat;
+	}
 
 #if __NetBSD_Version__ >= 106120000
 	 aprint_naive(": Ethernet controller\n");


--------------000300030009000702050405--