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);
	}
}