[comp.periphs.scsi] NCR53C90A Question

mjacob@wonky.Eng.Sun.COM (Matt Jacob) (07/07/90)

In article <815@intelisc.isc.intel.com> cfj@isc.intel.com (Charlie Johnson) writes:
>
>My question is, how closely tied is the DMA/FIFO side of the 53C90A to
>the SCSI bus side ??  Here is a description of my problem :
>
>   1. We're in DATA OUT phase happily DMAing bytes into the fifo and having
>      those byte go out to an Exabyte 8200 tape drive.
>
>   2. We take an interrupt and when the 53C90A status register is read, it 
>      indicates a phase change to MSG IN. 
>
>   3. The Terminal Count bit is set indicating that the last data transfer
>      had finished.
>
>   4. When we read the FIFO Flags register, it indicates that the are still
>      bytes in the fifo.
>
>Is this a legal state or am I just confused ?? It seems to me that this
>should be an illegal state unless the input & output sides of the chip
>are very asynchronous and the data bytes in the fifo just have drain
>out onto the SCSI bus.  I'm strictly a software type and from the
>device driver point of view, this seems like a problem.  Is there
>anyone out there who could give me a hint.


No- this is a perfectly reasonable state for the chip to be in. Steps 1 && 2
are pretty straightforward. Step 3 inidicates a subtlety for the 90A- the
transfer counter is clocked by DACK/ (data ack signals on the DMA side of
the chip) *except* for synchronous DATA IN phase (where it is clocked by
ACKO/). Step #4 is also reasonable- these are the bytes left over not
requested by the target. This is true for both Sync and Async modes of
operation for DATA OUT. The fifo can be more or less safely flushed of
these bytes, and you adjust your dma count appropriately. This particular
target (Exabyte) is also noted for odd-byte disconnects, so I wouldn't
be a bit surprised if you end up with left over untransferred bytes.

Example (for counting transfers):

	/*
	 * Figure out how far we got.
	 * Latch up fifo amount first.
	 */

	fifoamt = FIFO_CNT(ep);

	if (stat & ESP_STAT_XZERO) {
		xfer_amt = esp->e_lastcount;
	} else {
		GET_ESP_COUNT(ep, xfer_amt);
		xfer_amt = esp->e_lastcount - xfer_amt;
	}
	/*
	 * Unconditionally knock off by the amount left
	 * in the fifo if we were sending out the SCSI bus.
	 *
	 * If we were receiving from the SCSI bus, believe
	 * what the chip told us (either XZERO or by the
	 * value calculated from the counter register).
	 * The reason we don't look at the fifo for
	 * incoming data is that in synchronous mode
	 * the fifo may have further data bytes, and
	 * for async mode we assume that all data in
	 * the fifo will have been transferred before
	 * the esp asserts an interrupt.
	 */

	if (was_sending) {
		xfer_amt -= fifoamt;
	}

-matt mjacob
 mjacob@Eng.sun.com

p.s.: there are an extremely excellent set of chip app notes and errate
sheets for the Emulex flavor of this product (ESP200/ESP100A). I spent
two years with this chip finding out about things the hard way- then the
manuals came out....*sigh*