diff options
Diffstat (limited to 'sys/arch/i386')
-rw-r--r-- | sys/arch/i386/i386/machdep.c | 29 |
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; } |