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 trademarkschris@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