From 3b90b5c5c4b869fac5b991b9d614f01436580193 Mon Sep 17 00:00:00 2001 From: eeh Date: Wed, 17 May 2000 02:31:12 +0000 Subject: [PATCH] Add support for bus_dma_load_raw() so the le driver will work again. --- sys/arch/sparc64/dev/iommu.c | 96 ++++++++++++++++++++++++++++++++- sys/arch/sparc64/dev/iommuvar.h | 4 +- sys/arch/sparc64/dev/psycho.c | 21 +++++++- sys/arch/sparc64/dev/sbus.c | 20 ++++++- 4 files changed, 135 insertions(+), 6 deletions(-) diff --git a/sys/arch/sparc64/dev/iommu.c b/sys/arch/sparc64/dev/iommu.c index d6ece42f4c76..847a12391f53 100644 --- a/sys/arch/sparc64/dev/iommu.c +++ b/sys/arch/sparc64/dev/iommu.c @@ -1,4 +1,4 @@ -/* $NetBSD: iommu.c,v 1.8 2000/04/25 14:59:38 mrg Exp $ */ +/* $NetBSD: iommu.c,v 1.9 2000/05/17 02:31:12 eeh Exp $ */ /* * Copyright (c) 1999, 2000 Matthew R. Green @@ -560,6 +560,100 @@ iommu_dvmamap_unload(t, is, map) cache_flush((caddr_t)(u_long)dvmaddr, (u_int)sgsize); } + +int +iommu_dvmamap_load_raw(t, is, map, segs, nsegs, size, flags) + bus_dma_tag_t t; + struct iommu_state *is; + bus_dmamap_t map; + bus_dma_segment_t *segs; + int nsegs; + bus_size_t size; + int flags; +{ + vm_page_t m; + int s; + int err; + bus_size_t sgsize; + paddr_t pa; + u_long boundary; + u_long dvmaddr; + struct pglist *mlist; + int pagesz = PAGE_SIZE; + + if (map->dm_nsegs) { + /* Already in use?? */ +#ifdef DIAGNOSTIC + printf("iommu_dvmamap_load_raw: map still in use\n"); +#endif + bus_dmamap_unload(t, map); + } + /* + * Make sure that on error condition we return "no valid mappings". + */ + map->dm_nsegs = 0; +#ifdef DIAGNOSTIC + /* XXX - unhelpful since we can't reset these in map_unload() */ + if (segs[0].ds_addr != 0 || segs[0].ds_len != 0) + panic("iommu_dmamap_load_raw: segment already loaded: " + "addr 0x%lx, size 0x%lx", + segs[0].ds_addr, segs[0].ds_len); +#endif + sgsize = round_page(size); + + /* + * A boundary presented to bus_dmamem_alloc() takes precedence + * over boundary in the map. + */ + if ((boundary = segs[0]._ds_boundary) == 0) + boundary = map->_dm_boundary; + + + s = splhigh(); + err = extent_alloc(is->is_dvmamap, sgsize, NBPG, boundary, + (flags & BUS_DMA_NOWAIT) == 0 ? EX_WAITOK : EX_NOWAIT, + (u_long *)&dvmaddr); + splx(s); + + if (err != 0) + return (err); + +#ifdef DEBUG + if (dvmaddr == (bus_addr_t)-1) + { + printf("iommu_dvmamap_load_raw(): extent_alloc(%d, %x) failed!\n", + sgsize, flags); + Debugger(); + } +#endif + if (dvmaddr == (bus_addr_t)-1) + return (ENOMEM); + + /* + * We always use just one segment. + */ + map->dm_mapsize = size; + map->dm_nsegs = 1; + map->dm_segs[0].ds_addr = dvmaddr; + map->dm_segs[0].ds_len = size; + + mlist = segs[0]._ds_mlist; + for (m = TAILQ_FIRST(mlist); m != NULL; m = TAILQ_NEXT(m,pageq)) { + if (sgsize == 0) + panic("iommu_dmamap_load_raw: size botch"); + pa = VM_PAGE_TO_PHYS(m); + + DPRINTF(IDB_DVMA, + ("iommu_dvmamap_load_raw: map %p loading va %lx at pa %lx\n", + map, (long)dvmaddr, (long)(pa))); + iommu_enter(is, dvmaddr, pa, flags); + + dvmaddr += pagesz; + sgsize -= pagesz; + } + return (0); +} + void iommu_dvmamap_sync(t, is, map, offset, len, ops) bus_dma_tag_t t; diff --git a/sys/arch/sparc64/dev/iommuvar.h b/sys/arch/sparc64/dev/iommuvar.h index 8f5aa741cc7f..8ee79bd8012e 100644 --- a/sys/arch/sparc64/dev/iommuvar.h +++ b/sys/arch/sparc64/dev/iommuvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: iommuvar.h,v 1.3 2000/04/22 17:06:03 mrg Exp $ */ +/* $NetBSD: iommuvar.h,v 1.4 2000/05/17 02:31:13 eeh Exp $ */ /* * Copyright (c) 1999 Matthew R. Green @@ -63,6 +63,8 @@ int iommu_dvmamap_load __P((bus_dma_tag_t, struct iommu_state *, bus_dmamap_t, void *, bus_size_t, struct proc *, int)); void iommu_dvmamap_unload __P((bus_dma_tag_t, struct iommu_state *, bus_dmamap_t)); +int iommu_dvmamap_load_raw __P((bus_dma_tag_t, struct iommu_state *, + bus_dmamap_t, bus_dma_segment_t *, int, bus_size_t, int)); void iommu_dvmamap_sync __P((bus_dma_tag_t, struct iommu_state *, bus_dmamap_t, bus_addr_t, bus_size_t, int)); int iommu_dvmamem_alloc __P((bus_dma_tag_t, struct iommu_state *, diff --git a/sys/arch/sparc64/dev/psycho.c b/sys/arch/sparc64/dev/psycho.c index 4066c218bdcf..d0826583b9b3 100644 --- a/sys/arch/sparc64/dev/psycho.c +++ b/sys/arch/sparc64/dev/psycho.c @@ -1,4 +1,4 @@ -/* $NetBSD: psycho.c,v 1.8 2000/05/06 04:15:35 mrg Exp $ */ +/* $NetBSD: psycho.c,v 1.9 2000/05/17 02:31:12 eeh Exp $ */ /* * Copyright (c) 1999, 2000 Matthew R. Green @@ -101,6 +101,8 @@ static void *psycho_intr_establish __P((bus_space_tag_t, int, int, static int psycho_dmamap_load __P((bus_dma_tag_t, bus_dmamap_t, void *, bus_size_t, struct proc *, int)); static void psycho_dmamap_unload __P((bus_dma_tag_t, bus_dmamap_t)); +static int psycho_dmamap_load_raw __P((bus_dma_tag_t, bus_dmamap_t, + bus_dma_segment_t *, int, bus_size_t, int)); static void psycho_dmamap_sync __P((bus_dma_tag_t, bus_dmamap_t, bus_addr_t, bus_size_t, int)); int psycho_dmamem_alloc __P((bus_dma_tag_t, bus_size_t, bus_size_t, bus_size_t, @@ -682,7 +684,7 @@ psycho_alloc_dma_tag(pp) dt->_dmamap_load = psycho_dmamap_load; PCOPY(_dmamap_load_mbuf); PCOPY(_dmamap_load_uio); - PCOPY(_dmamap_load_raw); + dt->_dmamap_load_raw = psycho_dmamap_load_raw; dt->_dmamap_unload = psycho_dmamap_unload; dt->_dmamap_sync = psycho_dmamap_sync; dt->_dmamem_alloc = psycho_dmamem_alloc; @@ -974,6 +976,21 @@ psycho_dmamap_unload(t, map) iommu_dvmamap_unload(t, &sc->sc_is, map); } +int +psycho_dmamap_load_raw(tag, map, segs, nsegs, size, flags) + bus_dma_tag_t tag; + bus_dmamap_t map; + bus_dma_segment_t *segs; + int nsegs; + bus_size_t size; + int flags; +{ + struct psycho_pbm *pp = (struct psycho_pbm *)t->_cookie; + struct psycho_softc *sc = pp->pp_sc; + + return (iommu_dvmamap_load_raw(tag, &sc->sc_is, segs, nsegs, size, flags)); +} + void psycho_dmamap_sync(t, map, offset, len, ops) bus_dma_tag_t t; diff --git a/sys/arch/sparc64/dev/sbus.c b/sys/arch/sparc64/dev/sbus.c index b3004652d5ef..3b185340e86a 100644 --- a/sys/arch/sparc64/dev/sbus.c +++ b/sys/arch/sparc64/dev/sbus.c @@ -1,4 +1,4 @@ -/* $NetBSD: sbus.c,v 1.28 2000/04/22 17:06:05 mrg Exp $ */ +/* $NetBSD: sbus.c,v 1.29 2000/05/17 02:31:13 eeh Exp $ */ /*- * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -179,6 +179,8 @@ extern struct cfdriver sbus_cd; int sbus_dmamap_load __P((bus_dma_tag_t, bus_dmamap_t, void *, bus_size_t, struct proc *, int)); void sbus_dmamap_unload __P((bus_dma_tag_t, bus_dmamap_t)); +int sbus_dmamap_load_raw __P((bus_dma_tag_t, bus_dmamap_t, + bus_dma_segment_t *, int, bus_size_t, int)); void sbus_dmamap_sync __P((bus_dma_tag_t, bus_dmamap_t, bus_addr_t, bus_size_t, int)); int sbus_dmamem_alloc __P((bus_dma_tag_t tag, bus_size_t size, @@ -747,7 +749,7 @@ sbus_alloc_dmatag(sc) sdt->_dmamap_load = sbus_dmamap_load; PCOPY(_dmamap_load_mbuf); PCOPY(_dmamap_load_uio); - PCOPY(_dmamap_load_raw); + sdt->_dmamap_load_raw = sbus_dmamap_load_raw; sdt->_dmamap_unload = sbus_dmamap_unload; sdt->_dmamap_sync = sbus_dmamap_sync; sdt->_dmamem_alloc = sbus_dmamem_alloc; @@ -774,6 +776,20 @@ sbus_dmamap_load(tag, map, buf, buflen, p, flags) return (iommu_dvmamap_load(tag, &sc->sc_is, map, buf, buflen, p, flags)); } +int +sbus_dmamap_load_raw(tag, map, segs, nsegs, size, flags) + bus_dma_tag_t tag; + bus_dmamap_t map; + bus_dma_segment_t *segs; + int nsegs; + bus_size_t size; + int flags; +{ + struct sbus_softc *sc = (struct sbus_softc *)tag->_cookie; + + return (iommu_dvmamap_load_raw(tag, &sc->sc_is, map, segs, nsegs, size, flags)); +} + void sbus_dmamap_unload(tag, map) bus_dma_tag_t tag;