Subject: Re: interrupting parallel port lossage
To: Bruce Evans <bde@zeta.org.au>
From: Bakul Shah <bakul@netcom.com>
List: port-i386
Date: 03/23/1995 01:06:57
> Some printers raise *ACK before lowering BUSY.  This isn't related to
> the current problem, but causes very slow printing if the interrupt
> handler gets control while BUSY is still low.

Then they are violating the Centronics interface.  After a
long search I found at least a timing diagram in the good
old Art of Electronics, Second ed.  (page 731)  That might
be of some help:
		    A  B  C  D
		     ________                    _ _ _ _ _
DATA    ------------<________>------S S---------<_ _ _ _ _
	_______________    _________   ____________
*STROBE                \__/         S S            \_
			  __________   _________
BUSY    _________________/          S S         \________
	____________________________   ____         ____
*ACK                                S S    \_______/
					   E    F   G

A->B == DATA out to *STROBE low time = 0.5 us min.
B->C == *STROBE low to *STROBE high time = 0.5 us min.
C->D == *STROBE high to DATA tri-state == 0.5 us min.

E->F == *ACK low to BUSY low == 7 us min.
F->G == BUSY low to *ACK high = 5 us min.

Notice that BUSY must be _low_ before outputting the DATA
and must go =high= some time soon after *STROBE goes low.

So one more thing the driver can do is check that BUSY is
really low *before* outputting and right after setting
*STROBE low, check BUSY goes high (via a timed loop;
breakout after 5 us or BUSY hight).

To guard against errant printers, lptintr() should check
BUSY is low in a timed loop (breakout 5 us or BUSY low).
Normal printers won't cause any slow down.

I also noticed that the printer is never reset.  Normally I
woulnd't want my printer reset on every close but it'll be
nice to allow resetting under user control.  Shouldn't there
be an ioctl or something for that?

> everything, but there are still problems, perhaps because some printers
> don't meet the 500 nsec spec.

The 500ns spec is on the PC side: the data should be stable
for that period on both sides of the *STROBE pulse.  I'd be
very surprised if any printer controller does worse than
that.  Also note that data is latched so the C->D timing is
always met (and may only matter for bidir. PIOs).

Another thing.  The initial check in lptintr does check
status twice in quick succession:

>	if (NOT_READY() && NOT_READY_ERR())
>		return 0;

This should probably along the lines of:

	for (i=5; ;i--) {
		status = inb(..) ...
		if (status-has-error)
			print-error and return 0;
		if (i == 0)
			return 0;
		wait-for-a-microsecond
	}

Parallel port stuff is usually so solid under MSDOS that
everyone takes it for granted.

-- Bakul