Index: include/bus_private.h =================================================================== --- include/bus_private.h (revision 182964) +++ include/bus_private.h (working copy) @@ -66,9 +66,10 @@ int dm_flags; /* (p) */ }; -/* Flag values. */ -#define DMF_LOADED 1 /* Map is loaded */ -#define DMF_COHERENT 2 /* Coherent mapping requested */ +/* Flag values */ +#define DMF_LOADED (1 << 0) /* Map is loaded. */ +#define DMF_COHERENT (1 << 1) /* Coherent mapping requested. */ +#define DMF_STREAMED (1 << 2) /* Streaming cache used. */ int sparc64_dma_alloc_map(bus_dma_tag_t dmat, bus_dmamap_t *mapp); void sparc64_dma_free_map(bus_dma_tag_t dmat, bus_dmamap_t map); Index: pci/schizo.c =================================================================== --- pci/schizo.c (revision 186290) +++ pci/schizo.c (working copy) @@ -449,14 +449,18 @@ tc_init(tc); } - /* Set up the IOMMU. Both Schizo and Tomatillo have one per PBM. */ + /* + * Set up the IOMMU. Schizo, Tomatillo and XMITS all have + * one per PBM. Schizo and XMITS also have a streaming buffer, + * in Schizo version < 5 (i.e. revision < 2.3) it's affected + * by several errata and basically unusable though. + */ sc->sc_is.is_pmaxaddr = IOMMU_MAXADDR(STX_IOMMU_BITS); sc->sc_is.is_sb[0] = 0; sc->sc_is.is_sb[1] = 0; -#ifdef notyet - if (OF_getproplen(node, "no-streaming-cache") < 0) + if (OF_getproplen(node, "no-streaming-cache") < 0 && + !(sc->sc_mode == SCHIZO_MODE_SCZ && sc->sc_ver < 5)) sc->sc_is.is_sb[0] = STX_PCI_STRBUF; -#endif #define TSBCASE(x) \ case (IOTSB_BASESZ << (x)) << (IO_PAGE_SHIFT - IOTTE_SHIFT): \ Index: sparc64/iommu.c =================================================================== --- sparc64/iommu.c (revision 185008) +++ sparc64/iommu.c (working copy) @@ -119,7 +119,6 @@ * - When running out of DVMA space, return EINPROGRESS in the non- * BUS_DMA_NOWAIT case and delay the callback until sufficient space * becomes available. - * - Use the streaming cache unless BUS_DMA_COHERENT is specified. */ #include "opt_iommu.h" @@ -527,17 +526,8 @@ iommu_use_streaming(struct iommu_state *is, bus_dmamap_t map, bus_size_t size) { - /* - * This cannot be enabled yet, as many driver are still missing - * bus_dmamap_sync() calls. As soon as there is a BUS_DMA_STREAMING - * flag, this should be reenabled conditionally on it. - */ -#ifdef notyet return (size >= IOMMU_STREAM_THRESH && IOMMU_HAS_SB(is) && (map->dm_flags & DMF_COHERENT) == 0); -#else - return (0); -#endif } /* @@ -833,8 +823,8 @@ bus_size_t sgsize, esize; vm_offset_t vaddr, voffs; vm_paddr_t curaddr; - int error, sgcnt, firstpg, stream; pmap_t pmap = NULL; + int error, firstpg, sgcnt; KASSERT(buflen != 0, ("%s: buflen == 0!", __func__)); if (buflen > dt->dt_maxsize) @@ -855,7 +845,9 @@ sgcnt = *segp; firstpg = 1; - stream = iommu_use_streaming(is, map, buflen); + map->dm_flags &= ~DMF_STREAMED; + map->dm_flags |= iommu_use_streaming(is, map, buflen) != 0 ? + DMF_STREAMED : 0; for (; buflen > 0; ) { /* * Get the physical address for this page. @@ -876,7 +868,7 @@ vaddr += sgsize; iommu_enter(is, trunc_io_page(dvmaddr), trunc_io_page(curaddr), - stream, flags); + (map->dm_flags & DMF_STREAMED) != 0, flags); /* * Chop the chunk up into segments of at most maxsegsz, but try @@ -1141,7 +1133,7 @@ /* XXX This is probably bogus. */ if ((op & BUS_DMASYNC_PREREAD) != 0) membar(Sync); - if ((map->dm_flags & DMF_COHERENT) == 0 && IOMMU_HAS_SB(is) && + if ((map->dm_flags & DMF_STREAMED) != 0 && ((op & BUS_DMASYNC_POSTREAD) != 0 || (op & BUS_DMASYNC_PREWRITE) != 0)) { IS_LOCK(is);