Index: sys/arch/mips/mips/bus_dma.c =================================================================== RCS file: /cvsroot/src/sys/arch/mips/mips/bus_dma.c,v retrieving revision 1.30 diff -u -p -r1.30 bus_dma.c --- sys/arch/mips/mips/bus_dma.c 5 Feb 2014 19:09:06 -0000 1.30 +++ sys/arch/mips/mips/bus_dma.c 25 May 2014 20:33:54 -0000 @@ -856,13 +856,27 @@ _bus_dmamap_sync(bus_dma_tag_t t, bus_dm mips_dcache_wbinv_range(vaddr, minlen); break; - case BUS_DMASYNC_PREREAD: -#if 1 - mips_dcache_wbinv_range(vaddr, minlen); -#else - mips_dcache_inv_range(vaddr, minlen); -#endif + case BUS_DMASYNC_PREREAD: { + struct mips_cache_info * const mci = &mips_cache_info; + vaddr_t start = vaddr; + vaddr_t end = vaddr + minlen; + vaddr_t preboundary, firstboundary, lastboundary; + + preboundary = start & ~mci->mci_dcache_align_mask; + firstboundary = (start + mci->mci_dcache_align_mask) + & ~mci->mci_dcache_align_mask; + lastboundary = end & ~mci->mci_dcache_align_mask; + if (preboundary < start && preboundary < lastboundary) + mips_dcache_wbinv_range(preboundary, + mci->mci_dcache_align); + if (firstboundary < lastboundary) + mips_dcache_inv_range(firstboundary, + lastboundary - firstboundary); + if (lastboundary < end) + mips_dcache_wbinv_range(lastboundary, + mci->mci_dcache_align); break; + } case BUS_DMASYNC_PREWRITE: mips_dcache_wb_range(vaddr, minlen);