lpt stopped working
Alexey Shuvaev
shuvaev at physik.uni-wuerzburg.de
Tue Feb 10 16:07:44 PST 2009
On Tue, Feb 10, 2009 at 05:34:10PM -0500, John Baldwin wrote:
> On Tuesday 10 February 2009 4:57:20 pm Alexey Shuvaev wrote:
> > On Tue, Feb 10, 2009 at 04:12:57PM -0500, John Baldwin wrote:
> > > Ok, so the first cat works, the second one gets EBUSY?
> > >
> > Mmm... I don't think the first cat really works.
> > It hangs, I suppose nothing goes to the wire,
> > and during this I got the above printigs from kgdb.
> >
> > > Hmm, I think I've found it. Due to a bug, lptclose() wasn't releasing the
> > > bus.
>
> Grr, lptopen() was also busted. The old lpt driver didn't actually check the
> HAVEBUS flag in lpt_release_ppbus() which masked the bugs in lptopen(). Try
> this:
>
> --- //depot/vendor/freebsd/src/sys/dev/ppbus/lpt.c 2009/01/26 21:00:15
> +++ //depot/user/jhb/acpipci/dev/ppbus/lpt.c 2009/02/10 22:32:11
> @@ -544,10 +544,10 @@
> 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 @@
> /* wait 1/4 second, give up if we get a signal */
> if (ppb_sleep(ppbus, lptdev, LPPRI | PCATCH, "lptinit",
> hz / 4) != EWOULDBLOCK) {
> + lpt_release_ppbus(lptdev);
> sc->sc_state = 0;
> -
> - lpt_release_ppbus(lptdev);
> ppb_unlock(ppbus);
> return (EBUSY);
> }
> @@ -577,7 +576,8 @@
>
> 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 @@
> 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 @@
> 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);
> }
>
Seems to work!
No messages in the console, like "interrupt storm", too.
Thanks!
Alexey.
More information about the freebsd-current
mailing list