Subject: Re: allocating physically contiguous buffers in attach?
To: Jason Thorpe <thorpej@nas.nasa.GOV>
From: Darrin B. Jewell <jewell@mit.EDU>
List: tech-kern
Date: 08/06/1999 03:58:08
Jason Thorpe <thorpej@nas.nasa.GOV> writes:
> On Tue, 20 Jul 1999 06:25:45 -0400 (EDT)
> "Darrin B. Jewell" <jewell@mit.edu> wrote:
>
> > I would like to allocate a couple of 64k buffers in the attach routine
> > of an experimental next68k esp driver. These are to be used as dma
> > i/o buffers and so need to be physically contigous, although it's ok
> > if they are placed anywhere in memory loaded by VM_FREELIST_DEFAULT.
> >
> > What is the correct way to allocate this memory?
>
> bus_dmamem_alloc(), and map that memory into kva space w/ bus_dmamem_map().
>
> -- Jason R. Thorpe <thorpej@nas.nasa.gov>
So, on your statement, I came up with the following. Is this the
right idea? I wasn't sure if I should be storing the segments
returned from bus_dmamem_alloc in the map returned by
bus_dmamap_create. Also, if bus_dmamem_alloc sets up the physical
addresses in the segment, what is left for bus_dmamap_load_raw to do?
Since I took most of the next68k bus_dma functionality from
alpha/common/bus_dma.c, I still need to implement bus_dmamap_load_raw
and want to make sure I'm not doing something wrong.
Thanks,
Darrin
{
int error;
error = bus_dmamap_create(esc->sc_scsi_dma.nd_dmat,
sc->sc_maxxfer, 1, sc->sc_maxxfer, 0,
BUS_DMA_ALLOCNOW, &esc->sc_dmamap);
if (error != 0) {
panic("%s: can't create i/o DMA map, error = %d",
sc->sc_dev.dv_xname,error);
}
}
{
int error;
int rsegs;
error = bus_dmamem_alloc(esc->sc_scsi_dma.nd_dmat,
sc->sc_maxxfer, NBPG, sc->sc_maxxfer,
esc->sc_dmamap.dm_segs, esc->sc_dmamap.dm_nsegs, &rsegs,
BUS_DMA_WAITOK);
if (error != 0) {
panic("%s: can't alloc i/o DMA memory, error = %d",
sc->sc_dev.dv_xname,error);
}
#ifdef DIAGNOSTIC
if ((rsegs != esc->sc_dmamap.dm_nsegs) || (rsegs != 1)) {
panic("%s: alloc of DMA map resulted in %d segments, expecting %d == 1 ",
sc->sc_dev.dv_xname,rsegs,esc->sc_dmamap.dm_nsegs);
}
#endif
}
{
int error;
error = bus_dmamem_map(esc->sc_scsi_dma.nd_dmat,
esc->sc_dmamap.dm_segs, esc->sc_dmamap.dm_nsegs, sc->sc_maxxfer,
&esc->sc_mem, BUS_DMA_WAITOK | BUS_DMA_COHERENT);
if (error != 0) {
panic("%s: can't map i/o DMA memory, error = %d",
sc->sc_dev.dv_xname,error);
}
}
{
int error;
error = bus_dmamap_load_raw(esc->sc_scsi_dma.nd_dmat, esc->sc_dmamap,
esc->sc_dmamap.dm_segs, esc->sc_dmamap.dm_nsegs, sc->sc_maxxfer,
BUS_DMA_WAITOK);
if (error != 0) {
panic("%s: can't load i/o DMA memory, error = %d",
sc->sc_dev.dv_xname,error);
}
}