Re: lpt stopped working

From: Alexey Shuvaev <shuvaev_at_physik.uni-wuerzburg.de>
Date: Wed, 11 Feb 2009 01:07:41 +0100
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
> _at__at_ -544,10 +544,10 _at__at_
>  	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);
>  		}
> _at__at_ -555,9 +555,8 _at__at_
>  		/* 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);
>  		}
> _at__at_ -577,7 +576,8 _at__at_
>  
>  	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 */
> _at__at_ -611,11 +611,8 _at__at_
>  	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);
> _at__at_ -635,16 +632,16 _at__at_
>  	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.
Received on Tue Feb 10 2009 - 23:07:44 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:39:42 UTC