Proposed patch to ulpt.c

M. Warner Losh imp at bsdimp.com
Fri Jul 8 22:12:49 GMT 2005


While investigating why a recent HP printer returned EBUSY on startup,
I think I've discovered an unwise choice in the ulptopen routine.  It
always blocks until either the printer becomes online, or a timeout
happens.  It does this even with O_NONBLOCKing opens!  However, I
think the wait is bogus.  The reason that I think it is bogus is
because many newer priners can provide status about the printer via a
Bulk IN pipe.  ulpt actually connects to this pipe.  So, if one wanted
to read the status from the printer, one wouldn't be able to do this
unless the printer was online.  Writes will still return the right
thing, so lpd will do the right thing, at least in my initial testing,
when confronted by this condition.

In investigating this, I've discovered that Linux and Windows don't
wait for the printer to go online for the open to succeed.  I believe
this is a better policy for the ulpt driver.  As such, I'd like to
propose the following patch.  I believe it will even close a bug, as
well as resolve a message that was posted here:

http://lists.freebsd.org/pipermail/freebsd-usb/2005-March/000695.html
http://lists.freebsd.org/pipermail/freebsd-usb/2005-March/000853.html

As well as close bug 79524.

Comments?

Warner
-------------- next part --------------
Index: ulpt.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/usb/ulpt.c,v
retrieving revision 1.66
diff -u -r1.66 ulpt.c
--- ulpt.c	6 Jan 2005 01:43:28 -0000	1.66
+++ ulpt.c	8 Jul 2005 22:12:33 -0000
@@ -447,6 +447,7 @@
 	USETW(req.wIndex, sc->sc_ifaceno);
 	USETW(req.wLength, 1);
 	err = usbd_do_request(sc->sc_udev, &req, &status);
+	status = 0x18;
 	DPRINTFN(1, ("ulpt_status: status=0x%02x err=%d\n", status, err));
 	if (!err)
 		return (status);
@@ -543,28 +544,6 @@
 		}
 	}
 
-	for (spin = 0; (ulpt_status(sc) & LPS_SELECT) == 0; spin += STEP) {
-		DPRINTF(("ulpt_open: waiting a while\n"));
-		if (spin >= TIMEOUT) {
-			error = EBUSY;
-			sc->sc_state = 0;
-			goto done;
-		}
-
-		/* wait 1/4 second, give up if we get a signal */
-		error = tsleep(sc, LPTPRI | PCATCH, "ulptop", STEP);
-		if (error != EWOULDBLOCK) {
-			sc->sc_state = 0;
-			goto done;
-		}
-
-		if (sc->sc_dying) {
-			error = ENXIO;
-			sc->sc_state = 0;
-			goto done;
-		}
-	}
-
 	err = usbd_open_pipe(sc->sc_iface, sc->sc_out, 0, &sc->sc_out_pipe);
 	if (err) {
 		error = EIO;


More information about the freebsd-usb mailing list