Subject: Re: bce(4) and memory > 1GB problem
To: Matt Thomas <matt@3am-software.com>
From: Yorick Hardy <yhardy@uj.ac.za>
List: tech-kern
Date: 01/18/2007 13:24:28
This is a multi-part message in MIME format.
--------------090601080300050803020104
Content-Type: text/plain; charset=US-ASCII; format=flowed
Content-Transfer-Encoding: 7bit
Matt Thomas wrote:
>
> On Jan 17, 2007, at 4:08 AM, Yorick Hardy wrote:
>
>> + memcpy((void*)*newtag, (void*)tag, sizeof(struct x86_bus_dma_tag));
>
> Please use structure copy for this.
>
> **newtag = *tag;
>
>
Thanks. Updated.
--
Kind regards,
Yorick Hardy
--------------090601080300050803020104
Content-Type: text/plain;
name="bce6.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="bce6.patch"
--- sys/arch/x86/include/bus.h.orig 2007-01-10 16:49:27.000000000 +0200
+++ sys/arch/x86/include/bus.h 2007-01-15 10:48:34.000000000 +0200
@@ -1108,6 +1108,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,
@@ -1147,6 +1150,10 @@
(*(t)->_dmamem_unmap)((t), (k), (s))
#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-15 11:41:00.000000000 +0200
@@ -121,6 +121,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-15 10:50:43.000000000 +0200
@@ -198,16 +198,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 +227,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-18 13:01:27.000000000 +0200
@@ -1192,3 +1192,29 @@
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 ((*newtag = malloc(sizeof(struct x86_bus_dma_tag), M_DMAMAP,
+ (flags & BUS_DMA_NOWAIT) ? M_NOWAIT : M_WAITOK)) == NULL) {
+ return ENOMEM;
+ }
+
+ **newtag = *tag;
+
+ 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)
+{
+ free(tag, M_DMAMAP);
+}
--- 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");
--------------090601080300050803020104--