Subject: Re: DMA using Interrupt
To: Mahadeva Swamy T L <Swamy@soc-soft.com>
From: Jachym Holecek <freza@psi.cz>
List: tech-kern
Date: 02/01/2004 01:44:40
Hello,

> I want to initialize the DMA using Interrupt Mode, how shall I use the
> concept of Top-Half and Bottom-Half in case of DMA operation.

Simple example might look like this:

	1) Userland process request DMA transfer (a write() on your device
	   file for instance)
	
	2) In the write() handler you initialize the DMA transfer and wait for
	   completion (using [t]sleep(9))
	
	3) Once the transfer is done, your interrupt handler is invoked and
	   wakeup(9)s your process. In effect, the [t]sleep(9) from 2) returns,
	   you finish write()s job and return to userland.
	
> How shall I communicate between the Top-Half and the Bottom-Half?

When you register an interrupt handler, you can provide a (void *) argument
which will then be passed to the interrupt handler. Usually, this will be
your driver's softc structure, you can use some of its fields to communicate
state between the two "levels". When touching some of this shared state, it's
important to protect given section with splXXX(9), so that the interrupt doesn't
come in the middle and see half-updated half-obsolete state. In the example
above, step 2) could look like:

	int 		s;
	...
	s = splnet(); /* or whatever level set during intr registration */
	...
	/* modify state shared between the two halves */
	/* access device registers and fire DMA */
	...
	sleep(softc, PRIZERO | PRIMASK);
	splx(s);

Hope this helps,
	-- Jachym Holecek