Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 13 Aug 1997 17:27:54 -0700 (PDT)
From:      Matt Dillon <dillon@best.net>
To:        FreeBSD-gnats-submit@FreeBSD.ORG
Subject:   i386/4300: bug in lpt driver
Message-ID:  <199708140027.RAA27163@flea.best.net>
Resent-Message-ID: <199708140030.RAA10112@hub.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         4300
>Category:       i386
>Synopsis:       The initial timeout on open("/dev/lpt0"...) is too small
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Aug 13 17:30:00 PDT 1997
>Last-Modified:
>Originator:     Matt Dillon
>Organization:
BEST Internet
>Release:        FreeBSD 2.2-STABLE i386
>Environment:

>Description:

	When using /dev/lpt0 directly from programs or shell scripts that
	send multiple pages to the printer as separate transactions 
	(open, write a few pages, close, open, write a few pages, close),
	printers with large internal buffers (read: nearly all laser printers)
	may hold the printer in a non-ready state for long periods of
	time while draining the buffer.  If an open() attempt is made
	in this case, the 4 second timeout is insufficient and we have
	found that the open fails several times an hour, causing our scripts
	to abort.

	The problem occurs even more often when the printer runs out of
	paper.  If the operator is unable to load new paper into the printer
	fast enough, opens of /dev/lpt0 begin to fail.   Since many printers
	are left alone for long periods of time, my suggestion is that there
	be NO ready timeout whatsoever in the lpt driver.  Instead, check for
	an ERROR condition on open.

	Since there is nothing wrong with the printer, I consider the failure
	a bug.

>How-To-Repeat:

	

>Fix:
	
	The fix is to not have an LP ready timeout in the open().  In
	/usr/src/sys/i386/isa/lpt.c, around line 530, #ifdef out
	the code as shown below.  I suggest making the default be 
	NO timeout, and have an option to force a timeout.

	It should also be noted that since the open() is interruptable,
	removing the timeout should not have any effect on the ability
	of the operator to kill off blocked processes in the case where
	the printer truely has a problem.



        trys = 0;
        do {
                /* ran out of waiting for the printer */
#ifdef DOLPTIMEOUT		/* ADD THIS */
                if (trys++ >= LPINITRDY*4) {
                        splx(s);
                        sc->sc_state = 0;
                        lprintf ("status %x\n", inb(port+lpt_status) );
                        return (EBUSY);
                }
#endif				/* ADD THIS */

                /* wait 1/4 second, give up if we get a signal */
                if (tsleep ((caddr_t)sc, LPPRI|PCATCH, "lptinit", hz/4) !=
                    EWOULDBLOCK) {
                        sc->sc_state = 0;





>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199708140027.RAA27163>