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