Re: lpt stopped working

From: John Baldwin <jhb_at_freebsd.org>
Date: Tue, 10 Feb 2009 17:34:10 -0500
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);
 }


-- 
John Baldwin
Received on Tue Feb 10 2009 - 21:34:30 UTC

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