[net.bugs.4bsd] 4.[123]bsd dev/lp hoards final form feed

ado@elsie.UUCP (Arthur David Olson) (02/26/86)

Index:	sys/vaxuba/lp.c

Description:
	The lp driver will, with certain interfaces and printers (we've got a
	Printronix 600 ourselves), hold the the final form feed generated by
	closing the device until the device is reopened.  Not a problem for
	high-print-volume sites; a paper waster at low-volume sites, though
	(details upon request).

Repeat-By:
	Using the command
		echo HI > /dev/lp
	If you've got the problem, the page with the word HI on it will not be
	feed out of the printer, despite the fact that "lpclose" generated a
	form feed.

Fix:
	The problem comes about because various parts of the code test
		sc_outq.c_cc > 0
	to see if there's work to do.  But if the driver has read a character
	out of the above queue and was unable to output the character, the
	driver saves the character away in sc_lpchar.  So even if sc_outq.c_cc
	is zero, there may be work to do.

	Here are the changes to the 4.1bsd version of lp.c, conditioned on
	"OLDVERSION."

	First, a change to "lpintr":

	...
	sc->sc_state |= MOD;
#ifdef OLDVERSION
	if (sc->sc_outq.c_cc > 0 && (lpaddr->lpsr&ERROR)==0)
#else
	if (sc->sc_lpchar >= 0 && (lpaddr->lpsr&ERROR)==0)
#endif
		lpaddr->lpsr |= IENABLE;	/* ok and more to do later */
	if (n>LPLWAT && sc->sc_outq.c_cc<=LPLWAT && sc->sc_state&ASLP) {
		sc->sc_state &= ~ASLP;
		wakeup((caddr_t)sc);		/* top half should go on */
	}
	...

	There are also two changes to "lptout":

	...
#ifdef OLDVERSION
	if ((sc->sc_state&OPEN) == 0) {
#else
	if ((sc->sc_state&OPEN) == 0 && sc->sc_lpchar < 0) {
#endif
		sc->sc_state &= ~TOUT;		/* no longer open */
		lpaddr->lpsr = 0;
		return;
	}
#ifdef OLDVERSION
	if (sc->sc_outq.c_cc && (lpaddr->lpsr&DONE) && (lpaddr->lpsr&ERROR)==0)
#else
	if (sc->sc_lpchar>=0 && (lpaddr->lpsr&DONE) && (lpaddr->lpsr&ERROR)==0)
#endif
		lpintr(LPUNIT(dev));			/* ready to go */
	timeout(lptout, (caddr_t)dev, 10*hz);
	...
--
Bugs is a Warner Brothers trademark.
LP may have been a Columbia trademark at one time.
--
	UUCP: ..decvax!seismo!elsie!ado    ARPA: elsie!ado@seismo.ARPA
	DEC, VAX and Elsie are Digital Equipment and Borden trademarks

chris@umcp-cs.UUCP (Chris Torek) (02/26/86)

A perhaps better fix is to eliminate sc_lpchar completely.  Here
are the changes I installed back when we were using one of these
(this is for 4.3 beta, but probably fits in 4.1 and 4.2 too).

RCS file: RCS/lp.c,v
retrieving revision 1.1.1.3
retrieving revision 1.2
diff -c2 -r1.1.1.3 -r1.2
*** /tmp/,RCSt1000977	Wed Feb 26 14:31:33 1986
--- /tmp/,RCSt2000977	Wed Feb 26 14:31:36 1986
***************
*** 55,59 ****
  	char	sc_flags;
  	short	sc_maxcol;
- 	int	sc_lpchar;
  	struct	buf *sc_inbuf;
  } lp_softc[NLP];
--- 55,58 ----
***************
*** 80,84 ****
  
  	sc = &lp_softc[ui->ui_unit];
- 	sc->sc_lpchar = -1;
  	if (ui->ui_flags)
  		sc->sc_maxcol = ui->ui_flags;
--- 79,82 ----
***************
*** 285,289 ****
  	int lp11;
  {
! 	register int n;
  	register struct lp_softc *sc = &lp_softc[lp11];
  	register struct uba_device *ui = lpinfo[lp11];
--- 283,287 ----
  	int lp11;
  {
! 	register int n, c;
  	register struct lp_softc *sc = &lp_softc[lp11];
  	register struct uba_device *ui = lpinfo[lp11];
***************
*** 292,300 ****
  	lpaddr->lpsr &= ~IENABLE;
  	n = sc->sc_outq.c_cc;
! 	if (sc->sc_lpchar < 0)
! 		sc->sc_lpchar = getc(&sc->sc_outq);
! 	while ((lpaddr->lpsr&DONE) && sc->sc_lpchar >= 0) {
! 		lpaddr->lpbuf = sc->sc_lpchar;
! 		sc->sc_lpchar = getc(&sc->sc_outq);
  	}
  	sc->sc_state |= MOD;
--- 290,304 ----
  	lpaddr->lpsr &= ~IENABLE;
  	n = sc->sc_outq.c_cc;
! 	for (;;) {
! 		/* a weird sort of busy wait */
! 		if ((lpaddr->lpsr&DONE) == 0 && (lpaddr->lpsr&DONE) == 0 &&
! 		    (lpaddr->lpsr&DONE) == 0 && (lpaddr->lpsr&DONE) == 0 &&
! 		    (lpaddr->lpsr&DONE) == 0 && (lpaddr->lpsr&DONE) == 0 &&
! 		    (lpaddr->lpsr&DONE) == 0 && (lpaddr->lpsr&DONE) == 0 &&
! 		    (lpaddr->lpsr&DONE) == 0 && (lpaddr->lpsr&DONE) == 0)
! 			break;
! 		if ((c = getc(&sc->sc_outq)) < 0)
! 			break;
! 		lpaddr->lpbuf = c;
  	}
  	sc->sc_state |= MOD;
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 1415)
UUCP:	seismo!umcp-cs!chris
CSNet:	chris@umcp-cs		ARPA:	chris@mimsy.umd.edu