Subject: bus_dma(9) - q WRT bus_dmamap_load()
To: None <tech-kern@netbsd.org>
From: Jaromír <jdolecek@netbsd.org>
List: tech-kern
Date: 04/13/2001 14:10:46
Hi,
I'm trying to write a MCA disk device driver. The device uses DMA.
I know how to setup the DMA controller for DMA transfer. Only remaining
is feeding it with DMA safe memory. The controller seems to only
support one piece of phys memory, so I have to feed it buffer as
single segment.

I use a dmamap created by bus_dmamap_create() in driver's attach
function, like:
	error = bus_dmamap_create(dmat, 65536, 1, 65536, 0,
			BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &dmamap);

Then, then data are to be transferred to/from device, I use
bus_dmamem_load() to arrange for the DMA to happen directly to the
i/o buf, like this:

	error = bus_dmamap_load(dmat, dmamap, bp->b_data, bp->b_bcount,
			NULL, BUS_DMA_STREAMING);

This sometimes works, but sometimes the bus_dmamap_load() doesn't
find suitable segment. If I try to raise nsegments for bus_dmamap_create(),
bus_dmamap_load() then returns two segments, split like
94 bytes and 418 bytes. Of course, this is not particularily useful
for me, since the MCA DMA controller can accept only one dma
address.

What is the canonical way to solve this? I looked at ISA DMA
controller code (sys/dev/isa/isadma.c) and it seems it's also
restricted to one DMA address at time. It doesn't
seem to do anything special WRT bp->b_data; e.g. sys/dev/isa/fd.c
passes bp->b_data ~directly to isa_dmastart() (which in turn
calls bus_dmamap_load()). How come it works there?
 
Jaromir
-- 
Jaromir Dolecek <jdolecek@NetBSD.org>      http://www.ics.muni.cz/~dolecek/
NetBSD - just plain best OS! -=<>=- Got spare MCA cards or docs? Hand me them!