Comply with bus_dma(9) specs.

This commit is contained in:
pk 2000-06-16 11:47:34 +00:00
parent a2c3edb415
commit 6e94b922a1
2 changed files with 46 additions and 27 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: apcdmareg.h,v 1.1 1999/06/05 14:29:10 mrg Exp $ */
/* $NetBSD: apcdmareg.h,v 1.2 2000/06/16 11:47:34 pk Exp $ */
/*-
* Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
@ -103,9 +103,10 @@ struct apc_dma {
* List of device memory allocations (see cs4231_malloc/cs4231_free).
*/
struct cs_dma {
struct cs_dma *next;
caddr_t addr;
struct cs_dma *next;
caddr_t addr;
bus_dmamap_t dmamap;
bus_dma_segment_t segs[1];
int nsegs;
size_t size;
int nsegs;
size_t size;
};

View File

@ -1,4 +1,4 @@
/* $NetBSD: cs4231.c,v 1.3 2000/03/30 12:45:30 augustss Exp $ */
/* $NetBSD: cs4231.c,v 1.4 2000/06/16 11:47:35 pk Exp $ */
/*-
* Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
@ -238,33 +238,48 @@ cs4231_malloc(addr, direction, size, pool, flags)
int pool, flags;
{
struct cs4231_softc *sc = addr;
bus_dma_tag_t dmatag = sc->sc_dmatag;
struct cs_dma *p;
int error;
p = malloc(sizeof(*p), pool, flags);
if (p == NULL)
return (NULL);
p->size = size;
error = bus_dmamem_alloc(sc->sc_dmatag, size, 64*1024, 0,
p->segs, sizeof(p->segs)/sizeof(p->segs[0]),
&p->nsegs, BUS_DMA_NOWAIT);
if (error) {
free(p, pool);
return (NULL);
}
/* Allocate a DMA map */
if (bus_dmamap_create(dmatag, size, 1, size, 0,
BUS_DMA_NOWAIT, &p->dmamap) != 0)
goto fail1;
error = bus_dmamem_map(sc->sc_dmatag, p->segs, p->nsegs, p->size,
&p->addr, BUS_DMA_NOWAIT|BUS_DMA_COHERENT);
if (error) {
bus_dmamem_free(sc->sc_dmatag, p->segs, p->nsegs);
free(p, pool);
return (NULL);
}
/* Allocate DMA memory */
p->size = size;
if (bus_dmamem_alloc(dmatag, size, 64*1024, 0,
p->segs, sizeof(p->segs)/sizeof(p->segs[0]),
&p->nsegs, BUS_DMA_NOWAIT) != 0)
goto fail2;
/* Map DMA memory into kernel space */
if (bus_dmamem_map(dmatag, p->segs, p->nsegs, p->size,
&p->addr, BUS_DMA_NOWAIT|BUS_DMA_COHERENT) != 0)
goto fail3;
/* Load the buffer */
if (bus_dmamap_load(dmatag, p->dmamap,
p->addr, size, NULL, BUS_DMA_NOWAIT) != 0)
goto fail4;
p->next = sc->sc_dmas;
sc->sc_dmas = p;
return (p->addr);
fail4:
bus_dmamem_unmap(dmatag, p->addr, p->size);
fail3:
bus_dmamem_free(dmatag, p->segs, p->nsegs);
fail2:
bus_dmamap_destroy(dmatag, p->dmamap);
fail1:
free(p, pool);
return (NULL);
}
void
@ -274,13 +289,16 @@ cs4231_free(addr, ptr, pool)
int pool;
{
struct cs4231_softc *sc = addr;
bus_dma_tag_t dmatag = sc->sc_dmatag;
struct cs_dma *p, **pp;
for (pp = &sc->sc_dmas; (p = *pp) != NULL; pp = &(*pp)->next) {
if (p->addr != ptr)
continue;
bus_dmamem_unmap(sc->sc_dmatag, p->addr, p->size);
bus_dmamem_free(sc->sc_dmatag, p->segs, p->nsegs);
bus_dmamap_unload(dmatag, p->dmamap);
bus_dmamem_unmap(dmatag, p->addr, p->size);
bus_dmamem_free(dmatag, p->segs, p->nsegs);
bus_dmamap_destroy(dmatag, p->dmamap);
*pp = p->next;
free(p, pool);
return;
@ -653,11 +671,11 @@ cs4231_trigger_output(addr, start, end, blksize, intr, arg, param)
DPRINTF(("trigger_out: start %p, end %p, size %lu; "
"dmaaddr 0x%lx, dmacnt %lu, segsize %lu\n",
start, end, (u_long)sc->sc_playsegsz,
(u_long)p->segs[0].ds_addr,
(u_long)p->dmamap->dm_segs[0].ds_addr,
(u_long)n, (u_long)p->size));
csr = dma->dmacsr;
dma->dmapnva = (u_long)p->segs[0].ds_addr;
dma->dmapnva = (u_long)p->dmamap->dm_segs[0].ds_addr;
dma->dmapnc = (u_long)n;
if ((csr & PDMA_GO) == 0 || (csr & APC_PPAUSE) != 0) {
int reg;
@ -784,7 +802,7 @@ cs4231_intr(arg)
togo = sc->sc_playsegsz - sc->sc_playcnt;
if (togo == 0) {
/* Roll over */
nextaddr = (u_long)p->segs[0].ds_addr;
nextaddr = (u_long)p->dmamap->dm_segs[0].ds_addr;
sc->sc_playcnt = togo = APC_MAX;
} else {
nextaddr = dma->dmapnva + APC_MAX;