diff options
author | joerg <joerg@FreeBSD.org> | 1996-04-04 12:28:36 +0000 |
---|---|---|
committer | joerg <joerg@FreeBSD.org> | 1996-04-04 12:28:36 +0000 |
commit | e20b65055040492dca7ffca351ee80f5da211dca (patch) | |
tree | a2f57a065219235e331dc13e41256e3588cde18a /sys/i386 | |
parent | 8fad3d6dbca480451b498d8ab35d29929a194d5f (diff) | |
download | FreeBSD-src-e20b65055040492dca7ffca351ee80f5da211dca.zip FreeBSD-src-e20b65055040492dca7ffca351ee80f5da211dca.tar.gz |
Work around a braindead signal handling in many newer HP printers.
They don't have BUSY de-asserted by the time they ACK (and thus cause
an interrupt). The workaround is to try seeing if the BUSY will be
de-asserted soon, and if not, to use an incremental backoff and
semi-polled mode instead of the fixed timeout with 1/2 s we've been
using previously (that caused the printer to run really slooow).
Printers that have been working previously should not be affected by
this.
Diffstat (limited to 'sys/i386')
-rw-r--r-- | sys/i386/isa/lpt.c | 34 |
1 files changed, 26 insertions, 8 deletions
diff --git a/sys/i386/isa/lpt.c b/sys/i386/isa/lpt.c index 20437c3..d11c49bd 100644 --- a/sys/i386/isa/lpt.c +++ b/sys/i386/isa/lpt.c @@ -46,7 +46,7 @@ * SUCH DAMAGE. * * from: unknown origin, 386BSD 0.1 - * $Id: lpt.c,v 1.51 1996/03/28 14:28:44 scrappy Exp $ + * $Id: lpt.c,v 1.52 1996/03/29 11:54:56 bde Exp $ */ /* @@ -149,7 +149,8 @@ #define LPINITRDY 4 /* wait up to 4 seconds for a ready */ -#define LPTOUTTIME 4 /* wait up to 4 seconds for a ready */ +#define LPTOUTINITIAL 10 /* initial timeout to wait for ready 1/10 s */ +#define LPTOUTMAX 1 /* maximal timeout 1 s */ #define LPPRI (PZERO+8) #define BUFSIZE 1024 @@ -221,6 +222,7 @@ static struct lpt_softc { #define LP_HAS_IRQ 0x01 /* we have an irq available */ #define LP_USE_IRQ 0x02 /* we are using our irq */ #define LP_ENABLE_IRQ 0x04 /* enable IRQ on open */ + u_char sc_backoff ; /* time to call lptout() again */ #ifdef INET struct ifnet sc_if; @@ -590,7 +592,8 @@ lptopen (dev_t dev, int flags, int fmt, struct proc *p) lprintf("irq %x\n", sc->sc_irq); if (sc->sc_irq & LP_USE_IRQ) { sc->sc_state |= TOUT; - timeout ((timeout_func_t)lptout, (caddr_t)sc, hz/2); + timeout ((timeout_func_t)lptout, (caddr_t)sc, + (sc->sc_backoff = hz/LPTOUTINITIAL)); } lprintf("opened.\n"); @@ -602,9 +605,12 @@ lptout (struct lpt_softc * sc) { int pl; lprintf ("T %x ", inb(sc->sc_port+lpt_status)); - if (sc->sc_state & OPEN) - timeout ((timeout_func_t)lptout, (caddr_t)sc, hz/2); - else + if (sc->sc_state & OPEN) { + sc->sc_backoff++; + if (sc->sc_backoff > hz/LPTOUTMAX) + sc->sc_backoff = sc->sc_backoff > hz/LPTOUTMAX; + timeout ((timeout_func_t)lptout, (caddr_t)sc, sc->sc_backoff); + } else sc->sc_state &= ~TOUT; if (sc->sc_state & ERROR) @@ -785,6 +791,7 @@ lptintr(int unit) { struct lpt_softc *sc = lpt_sc + unit; int port = sc->sc_port, sts; + int i; #ifdef INET if(sc->sc_if.if_flags & IFF_UP) { @@ -793,9 +800,19 @@ lptintr(int unit) } #endif /* INET */ - /* is printer online and ready for output */ - if (((sts=inb(port+lpt_status)) & RDY_MASK) == LP_READY) { + /* + * Is printer online and ready for output? + * + * Avoid falling back to lptout() too quickly. First spin-loop + * to see if the printer will become ready ``really soon now''. + */ + for (i = 0; + i < 100 && + ((sts=inb(port+lpt_status)) & RDY_MASK) != LP_READY; + i++) ; + if ((sts & RDY_MASK) == LP_READY) { sc->sc_state = (sc->sc_state | OBUSY) & ~ERROR; + sc->sc_backoff = hz/LPTOUTINITIAL; if (sc->sc_xfercnt) { /* send char */ @@ -822,6 +839,7 @@ lptintr(int unit) if(((sts & (LPS_NERR | LPS_OUT) ) != LPS_NERR) && (sc->sc_state & OPEN)) sc->sc_state |= ERROR; + /* lptout() will jump in and try to restart. */ } lprintf("sts %x ", sts); } |