diff options
author | jhb <jhb@FreeBSD.org> | 2009-02-11 14:25:09 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2009-02-11 14:25:09 +0000 |
commit | 7f7a900649f0ccc1a1d1f9c9c65ded68f1fe215e (patch) | |
tree | b295b188099b5496413c1f37e69b696eb61f372a /sys/dev/ppbus/lpt.c | |
parent | 67e0c1a7505996ee05c0b9efe0b6cea95d82d244 (diff) | |
download | FreeBSD-src-7f7a900649f0ccc1a1d1f9c9c65ded68f1fe215e.zip FreeBSD-src-7f7a900649f0ccc1a1d1f9c9c65ded68f1fe215e.tar.gz |
Fix lptopen() and lptclose() to not trash the state of the HAVEBUS flag
in 'sc_state'. This allows the lpt_release_ppbus() calls in those two
routines to actually release the ppbus and thus fixes the hangs noticed
with the lpt(4) driver since the recent ppbus changes. The old lpt(4)
driver didn't actually check the HAVEBUS flag in lpt_release_ppbus() which
is why these bugs weren't noticed before.
Diffstat (limited to 'sys/dev/ppbus/lpt.c')
-rw-r--r-- | sys/dev/ppbus/lpt.c | 19 |
1 files changed, 8 insertions, 11 deletions
diff --git a/sys/dev/ppbus/lpt.c b/sys/dev/ppbus/lpt.c index 6da65f1..10d67d9 100644 --- a/sys/dev/ppbus/lpt.c +++ b/sys/dev/ppbus/lpt.c @@ -544,10 +544,10 @@ lptopen(struct cdev *dev, int flags, int fmt, struct thread *td) do { /* ran out of waiting for the printer */ if (trys++ >= LPINITRDY*4) { - sc->sc_state = 0; lprintf(("status %x\n", ppb_rstr(ppbus))); lpt_release_ppbus(lptdev); + sc->sc_state = 0; ppb_unlock(ppbus); return (EBUSY); } @@ -555,9 +555,8 @@ lptopen(struct cdev *dev, int flags, int fmt, struct thread *td) /* wait 1/4 second, give up if we get a signal */ if (ppb_sleep(ppbus, lptdev, LPPRI | PCATCH, "lptinit", hz / 4) != EWOULDBLOCK) { - sc->sc_state = 0; - lpt_release_ppbus(lptdev); + sc->sc_state = 0; ppb_unlock(ppbus); return (EBUSY); } @@ -577,7 +576,8 @@ lptopen(struct cdev *dev, int flags, int fmt, struct thread *td) ppb_wctr(ppbus, sc->sc_control); - sc->sc_state = OPEN; + sc->sc_state &= ~LPTINIT; + sc->sc_state |= OPEN; sc->sc_xfercnt = 0; /* only use timeout if using interrupt */ @@ -611,11 +611,8 @@ lptclose(struct cdev *dev, int flags, int fmt, struct thread *td) int err; ppb_lock(ppbus); - if (sc->sc_flags & LP_BYPASS) { - sc->sc_state = 0; - ppb_unlock(ppbus); + if (sc->sc_flags & LP_BYPASS) goto end_close; - } if ((err = lpt_request_ppbus(lptdev, PPB_WAIT|PPB_INTR)) != 0) { ppb_unlock(ppbus); @@ -635,16 +632,16 @@ lptclose(struct cdev *dev, int flags, int fmt, struct thread *td) sc->sc_state &= ~OPEN; callout_stop(&sc->sc_timer); ppb_wctr(ppbus, LPC_NINIT); - sc->sc_state = 0; - sc->sc_xfercnt = 0; /* * unregistration of interrupt forced by release */ lpt_release_ppbus(lptdev); - ppb_unlock(ppbus); end_close: + sc->sc_state = 0; + sc->sc_xfercnt = 0; + ppb_unlock(ppbus); lprintf(("closed.\n")); return(0); } |