Subject: Re: Rev 1.19 of busdma.doc
To: Jason Thorpe <thorpej@nas.nasa.gov>
From: Justin T. Gibbs <gibbs@freefall.freebsd.org>
List: tech-kern
Date: 11/09/1996 17:26:59
>	bus_dmamap_load_func_t	A driver-dependent function used to load
>				a device's scatter-gather descriptors.
>				The type of the function should be:
>
>		typedef	int (*bus_dmamap_load_func_t) __P((bus_addr_t addr,
>		    bus_size_t size, void *arg));
>
>				This function will be called iteratively
>				by bus_dmamap_load() with the address
>				and length of a single, contiguous DMA
>				transfer, conforming to the constraints
>				of the device.  "arg" is a driver-dependent
>				cookie used by the driver to keep state
>				between iterations.

There is nothing here preventing it, but it would be nice to explicitly
allow the system to choose an inline variant of the specified function if it
is 'known' to the system.  For example, I expect many of the SCSI drivers
to use a single common routine to do this, and I don't see any reason why
some arches might not want to short circuit the function calls.  I think
you should also need to pass the index of the SG entry you are creating
for reasons I'll make clear below.

>int	bus_dmamap_load __P((bus_dma_tag_t tag, bus_dma_handle_t dmah,
>	    struct uio *uio, bus_dmamap_load_func_t func, void *funcarg,
>	    int flags));
>

...

>	func		For each physically contiguous DMA segment
>			in the uio, this function will be called
>			with an address and length suitable for
>			programming into DMA controller registers
>			or command blocks.  In addition, this function
>			will be passed a driver-dependent argument
>			which may be used to keep state between
>			calls to "func".
>
>			This function will be called no more than the
>			number of times specified by the "nsegments"
>			parameter passed to bus_dmamap_create().

How can you make this guarantee if you are going to support "compaction" of
the address to fit the limits of the target SG list.  I could imagine the
implementation attempting the map first and then resorting to compaction
and starting over with the first segment, only after it has exausted all of
the SG segments.  The only way to know if you fit is to walk the pages and
while you are walking the pages, you might as well fill in th SG values as
you go.  This is why I think this guarantee should be replaced by an
explaination as to why it may be called more than "nsegments" times and the
index should be added to bus_dmamap_load_func_t.

We also need an additional "BUS_DMA_COMPACTTOFIT" flag so that clients have
to explicitly ask for compaction to occur.  This allows clients that can
easily break up transfers to split the data up by filling their SG list up
and passing the residual back up to caller that generated the transaction.
At the same time, it cleanly addresses the needs of things like the st
driver.  For this to completly work, bus_dmamap_load would have to somehow
report the residual on error.

I haven't read all of the VAX issues yet, but other than the points above,
I'm quite happy with this spec.
--
Justin T. Gibbs
===========================================
  FreeBSD: Turning PCs into workstations
===========================================