[net.unix-wizards] Help with DMA on -750 under 4.2BSD

david@ukma.UUCP (David Herron, NPR Lover) (08/16/85)

I'm writing a device driver for the parallel ports on the DMF-32.

My specific application is to read in digitized tv pictures from
an ancient digitizer we have.  (Colorado Video 260)  It is producing
one byte every 63.5 microseconds.  This is for 256 byte bursts, about
10 bursts every second.  But I'm really interested in making a somewhat
generic parallel driver....

At any rate.


I'm currently using DMA for the read side, and DR-11 mode for the
write side.  In my write routine, I have a loop which looks like this:

#define DMFD_BUFSIZ 256

	do {
		n = min(DMFD_BUFSIZ, uio->uio_resid/sizeof(short));
		/* dmfd_buf is an short[DMFD_BUFSIZ]. */
		cp = &sc->dmfd_buf[0];
		sc->dmfl_info = info = 
			uballoc(ui->ui_ubanum, cp, n*sizeof(short), 0);
		DMFD_IR(addr, DMFD_PADR);
		/* bits <16:1> into bits <15:0> */
		addr->dmfdir = (info&0x1fffe) >> 1;
		DMFD_IR(addr, DMFD_PWCT);
		addr->dmfdir = n;
		/* DMA read, REQ A causes transfer */
		/* bit <17> into bit <15> */
		addr->dmfdrbuf = (((info & 0x20000) | DMFD_DMA3);
		addr->dmfdcsr |= DMFD_IENA;
		sc->dmfl_state = ASLP;
		sleep(sc->dmfd_buf, (PZERO+8));
		if (sc->dmfl_info != 0)
			ubarelse(ui->ui_ubanum, &sc->dmfl_info);
		error = uiomove(&sc->dmfd_buf[0], (int)n, UIO_READ, uio);
		if (error) return(error);
	} while(uio->uio_resid > 0);

Then dmfdaint() is:

	if (addr->dmfdcsr&DMFD_DMAE) {
		print a bunch of messages
	}
	if (sc->dmfl_info != 0)
		ubarelse(ui->ui_ubanum, &sc->dmfl_info);
	addr->dmfdrbuf = DMFD_DR11;

To test it, (we have two dmf's) I have a loopback cable attached from
the output of one dmf to the input of the other.  I write characters
out one side (the strobe pulse from the dmf is a real pulse, and in
dma mode it transfers characters on both edges of the pulse) and
read them on the other.  I know that the characters are being written
(because I see the strobe pulse on the scope) and I know that they
are being read by the dmf (because I see the acknowledgement pulse
(actually two of them) on the scope).  But after a few characters
(maybe 128, maybe 256) the system panics on a reserved operand.
Looking in the crash dump I find it's panicking on something completely
unrelated to this, some process had done a close() and it was at 
the very end of closef() at the time of the panic.  The current
process was "tset".

The implication is that my code has overwritten something in the
kernel, but I have no idea what.  I've spent quite a bit of time
looking through other device drivers for hints on how to use
uballoc() and ubarelse() properly.  And they all use it the
same way I've used it.  (Though some use a NEEDBDP flag)

My questions are:

  1) Is the map allocated with uballoc() only "one way"?  i.e.
     Can I only write through it?  And, no I don't really believe
     this, but it is one possible explanation for the occurences.
  2) My understanding of uballoc() is that it sets up mapping
     registers from certain unibus addresses to the memory
     area you specify.  And it tells you the resulting unibus
     address to use which is what you give to the device.  Is this
     correct?
  3) How long would a uballoc() take usually?  Right now I'm doing
     this mapping every time.  But from reading the code I see that
     there's conditions where you have to wait for uba addresses
     to free up.  Does this ever happen?  (The unibus in question
     has 2 dmf's, a emulex cs11/h2, and a dz on it)
  4) Buffered Data Paths are scarce resources (3 per unibus).  If I
     set NEEDBDP in the flags, will I ever have to wait?  For very
     long times?  Is it ok if I tie up one for a couple of milliseconds?
  5) Any suggestions you'd like to make?  This is my first time writing
     code at this level of a large system.  I see a lot but I may be
     missing something.
  6) Some of the drivers do a uballoc() in the open and ubarelse()
     in the close.  What are the implications of doing this?
  7) Does anybody already have a driver for the parallel part of the dmf?
     (I may scream if so, because I've looked around for one before,
     and only found someone in England who was needing to write one).
  8) Any other questions you'd like to answer?

As they say, thanks in advance.

-- 
--- David Herron
--- ARPA-> ukma!david@ANL-MCS.ARPA
--- UUCP-> {ucbvax,unmvax,boulder,oddjob}!anlams!ukma!david
---        {ihnp4,decvax,ucbvax}!cbosgd!ukma!david