Subject: SCSI driver status update
To: None <port-next68k@netbsd.org>
From: Darrin B. Jewell <jewell@mit.edu>
List: port-next68k
Date: 12/30/1998 16:40:37
I had a breakthrough regarding the SCSI driver this morning, and
finally managed to get a SCSI DMA transaction to complete from the
kernel.  This is a status report plus a little background information
on the structure of the driver.

The NeXT SCSI uses the ncr53c90a chip, supported in NetBSD by the
machine independant ncr53c9x.c driver.  NetBSD/next68k has has a DMA
device driver that serves both the ethernet and the SCSI disk.  This
DMA driver should be able to be connected to other NeXT devices as
well.  The glue to connect the machine independant driver to the DMA
driver is in esp.c.  This is where most of the work for the SCSI
driver has been taking place.

The main factor I had been missing was re-setting the DMA direction
bit in the DMA driver each time the DMA CSR is updated.  Apparently
for the ethernet, this wasn't necessary.  This was probably because
the ethernet has two DMA channels, one dedicated to reading and one
for writing.  This problem is now fixed in the DMA driver.  In
addition, the scsi driver has been complicated by an additional
mysterious NeXT specific control regster.  It looks like I've started
to get enough of a handle on how to frob that register to get some
bits transferred from the SCSI disk.

The next problem on the plate for the SCSI driver is the never ending
battle with the alignment of DMA buffers.  It appears that NeXT DMA
buffers have to end on an address which is a multiple of 16 and start
on an address which is a multiple of 4.  At mycroft's suggestion, my
driver attempts to work around the alignment issues by using the SCSI
chip's built in FIFO to poke and peek extra bytes at the beginning and
end of a DMA transfer so that the actual transfer is correctly
aligned.

This strategy using the FIFO encounters a few problems, but not enough
that I have completely abandoned this approach.  First off, the
machine independant driver expects to manage a DMA transfer.
Therefore, it doesn't handle a short misaligned buffer very well
because the current incarnation stuffs the entire thing into the FIFO,
and the DMA cycle never occurs.  I've pondered ways to fix this
without modifying the MI code.  The one I currently have in mind is to
just memcpy the short buffer into an apropriately aligned buffer and
do the DMA cycle anyway.

A slightly larger problem with the DMA alignment requirement is
dealing with the buffer end address.  As I mentioned, I tried to chop
off the buffer at the last aligned address and then fifo the remaining
bytes.  (I refer to these remaining bytes as the "end slop")
Unfortunately, when I tried this I was unable to read sensible
leftover bytes from the fifo.  I need to do a little experimentation
here to figure out if can work around this by using one end address
(transfer count) for the SCSI chip and a different address for the DMA
chip.  In addition, to get the DMA to complete I have to toggle some
sort of "flush" bit in the mystery register.  This may have something
to do with why the extra bytes are gone before I can fifo them
cleanly.  More experimentation hopefully will lead to a little more
understanding of the best use of this "flush" bit.

One way to get the bytes to transfer cleanly is to extend the DMA
buffer to the next aligned address rather than truncating it.  This is
what the boot loader currently does, and it seems to work well.
Unfortunately, I have no control over where the buffer being DMA'd was
allocated.  In one experimental test using this method, a short buffer
had been allocated on the stack from deep inside the machine
independent scsi code (scsipi).  The scsi data transferred fine, but
when it tried to return from the scsi function, the stack frame had
been smashed by the DMA driver overwriting the next word on the stack.

If I can't get the fifo-the-end-slop method to work sensibly, I have
one trick in mind that may still let me work around the problem.  I
will just copy the end slop into a separately allocated DMA buffer and
tack it onto the end of the DMA transfer as an extra chained segment.
Since I can control the allocation of this buffer, I can allow the DMA
to continue past its end to an aligned address without causing harm.

Hopefully, we will have a working SCSI driver for the NeXT port before
too long.  If you have any ideas, questions or feedback on the DMA
alignment or the driver in general, please pass them along.

Thanks,
Darrin