Add support for bus_dma_load_raw() so the le driver will work again.

This commit is contained in:
eeh 2000-05-17 02:31:12 +00:00
parent 010dad14ae
commit 3b90b5c5c4
4 changed files with 135 additions and 6 deletions

View File

@ -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;

View File

@ -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 *,

View File

@ -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;

View File

@ -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;