summaryrefslogtreecommitdiff
path: root/sys/arch/i386
diff options
context:
space:
mode:
authorJason Downs <downsj@cvs.openbsd.org>1998-08-16 03:54:22 +0000
committerJason Downs <downsj@cvs.openbsd.org>1998-08-16 03:54:22 +0000
commit4f805dc3acc9d01179722e417454503f671d0ab9 (patch)
treedaf8a9d9985709108c7b2c40c99a501fb796c880 /sys/arch/i386
parentbfaba4478e76a2609cf52c8a6a21e1ce47cc473a (diff)
don't map DMA across boundaries; from NetBSD (don't know who).
Diffstat (limited to 'sys/arch/i386')
-rw-r--r--sys/arch/i386/i386/machdep.c29
1 files changed, 20 insertions, 9 deletions
diff --git a/sys/arch/i386/i386/machdep.c b/sys/arch/i386/i386/machdep.c
index 00dece5fc00..53e317c6ab8 100644
--- a/sys/arch/i386/i386/machdep.c
+++ b/sys/arch/i386/i386/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.90 1998/08/04 20:40:46 downsj Exp $ */
+/* $OpenBSD: machdep.c,v 1.91 1998/08/16 03:54:21 downsj Exp $ */
/* $NetBSD: machdep.c,v 1.214 1996/11/10 03:16:17 thorpej Exp $ */
/*-
@@ -2281,7 +2281,7 @@ _bus_dmamap_load(t, map, buf, buflen, p, flags)
int flags;
{
bus_size_t sgsize;
- bus_addr_t curaddr, lastaddr;
+ bus_addr_t curaddr, lastaddr, baddr, bmask;
caddr_t vaddr = buf;
int first, seg;
pmap_t pmap;
@@ -2294,17 +2294,15 @@ _bus_dmamap_load(t, map, buf, buflen, p, flags)
if (buflen > map->_dm_size)
return (EINVAL);
- /*
- * XXX Need to implement "don't dma across this boundry".
- */
-
if (p != NULL)
pmap = p->p_vmspace->vm_map.pmap;
else
pmap = pmap_kernel();
lastaddr = ~0; /* XXX gcc */
- for (first = 1, seg = 0; buflen > 0 && seg < map->_dm_segcnt; ) {
+ bmask = ~(map->_dm_boundary - 1);
+
+ for (first = 1, seg = 0; buflen > 0; ) {
/*
* Get the physical address for this segment.
*/
@@ -2318,6 +2316,15 @@ _bus_dmamap_load(t, map, buf, buflen, p, flags)
sgsize = buflen;
/*
+ * Make sure we don't cross any boundaries.
+ */
+ if (map->_dm_boundary > 0) {
+ baddr = (curaddr + map->_dm_boundary) & bmask;
+ if (sgsize > (baddr - curaddr))
+ sgsize = (baddr - curaddr);
+ }
+
+ /*
* Insert chunk into a segment, coalescing with
* previous segment if possible.
*/
@@ -2328,10 +2335,14 @@ _bus_dmamap_load(t, map, buf, buflen, p, flags)
} else {
if (curaddr == lastaddr &&
(map->dm_segs[seg].ds_len + sgsize) <=
- map->_dm_maxsegsz)
+ map->_dm_maxsegsz &&
+ (map->_dm_boundary == 0 ||
+ (map->dm_segs[seg].ds_addr & bmask) ==
+ (curaddr & bmask)))
map->dm_segs[seg].ds_len += sgsize;
else {
- seg++;
+ if (++seg >= map->_dm_segcnt)
+ break;
map->dm_segs[seg].ds_addr = curaddr;
map->dm_segs[seg].ds_len = sgsize;
}