Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 25 Jan 2006 23:15:33 +1100
From:      Peter Jeremy <PeterJeremy@optushome.com.au>
To:        FreeBSD-gnats-submit@FreeBSD.org, freebsd-usb@FreeBSD.org
Subject:   Re: usb/91538: Unable to print to EPSON CX3500
Message-ID:  <20060125121533.GA39758@cirb503493.alcatel.com.au>
In-Reply-To: <200601090050.k090o3QG026924@freefall.freebsd.org>
References:  <200601090041.k090fk8o082824@server.vk2pj.dyndns.org> <200601090050.k090o3QG026924@freefall.freebsd.org>

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

--wRRV7LY7NUeQGEoC
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Following further investigation, I have discovered that the problem
is that the PIPS CX3500 driver expects to be able to read parts of
the printer responses whilst ulpt(4) will not accept more data over
the USB bus than the application asked for.  In the particular case,
the printer was sending 74 bytes whilst the driver wanted to read
the 6 byte header followed by a second 68 byte block.

My solution was to change ulpt(4) to internally buffer reads.  A
persistent 1024 byte read buffer is already available.  The attached
patch will always issue 1024 byte reads across the USB bus and any
surplus data will be saved for the next read(2) issued by the
application.

Note that whilst this allows communication between the printer and
the PIPS driver, there remain problems with the port that prevent
printing from working correctly.  I will address these in a separate
PR since they are related to the port, rather than the USB subsystem.

-- 
Peter Jeremy

--wRRV7LY7NUeQGEoC
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="ulpt.patch"

Index: ulpt.c
===================================================================
RCS file: /usr/ncvs/src/sys/dev/usb/ulpt.c,v
retrieving revision 1.68
diff -u -r1.68 ulpt.c
--- ulpt.c	12 Nov 2005 17:39:31 -0000	1.68
+++ ulpt.c	24 Jan 2006 22:14:17 -0000
@@ -113,7 +113,9 @@
 	int sc_in;
 	usbd_pipe_handle sc_in_pipe;	/* bulk in pipe */
 	usbd_xfer_handle sc_in_xfer;
-	void *sc_in_buf;
+	char *sc_in_buf;		/* start of bulk read buffer */
+	char *sc_in_bp;			/* start of valid data in sc_in_buf */
+	int sc_in_len;			/* length of valid data at sc_in_bp */
 
 	usb_callout_t sc_read_callout;
 	int sc_has_callout;
@@ -584,6 +586,8 @@
 			usb_callout(sc->sc_read_callout, hz/5, ulpt_tick, sc);
 			sc->sc_has_callout = 1;
 		}
+		sc->sc_in_bp = NULL;
+		sc->sc_in_len = 0;
 	}
 
 	sc->sc_state = ULPT_OPEN;
@@ -726,33 +730,51 @@
 {
 	u_int32_t n, on;
 	int error = 0;
-	void *bufp;
+	char *bufp;
 	usbd_xfer_handle xfer;
 	usbd_status err;
 
-	DPRINTF(("ulptread\n"));
+	DPRINTF(("ulptread request %d\n", uio->uio_resid));
 
 	if (sc->sc_in_pipe == NULL)
 		return 0;
+	if (sc->sc_in_len != 0) {
+		n = min(sc->sc_in_len, uio->uio_resid);
+		error = uiomove(sc->sc_in_bp, n, uio);
+		if (error)
+		    return (error);
+		sc->sc_in_len -= n;
+		sc->sc_in_bp += n;
+		if (uio->uio_resid == 0)	/* read satisfied */
+		    return (error);
+	}
 
 	xfer = sc->sc_in_xfer;
 	bufp = sc->sc_in_buf;
-	while ((n = min(ULPT_BSIZE, uio->uio_resid)) != 0) {
-		DPRINTFN(1, ("ulptread: transfer %d bytes\n", n));
-		on = n;
+	
+	while (1) {
+		n = ULPT_BSIZE;
 		err = usbd_bulk_transfer(xfer, sc->sc_in_pipe,
 			  USBD_NO_COPY | USBD_SHORT_XFER_OK,
 			  USBD_NO_TIMEOUT, bufp, &n, "ulptrd");
 		if (err) {
 			DPRINTF(("ulptread: error=%d\n", err));
-			error = EIO;
-			break;
+			return (EIO);
 		}
-		error = uiomove(bufp, n, uio);
-		if (error)
+		DPRINTFN(1, ("ulptread: got %d bytes\n", n));
+		on = min(n, uio->uio_resid);
+		error = uiomove(bufp, on, uio);
+		if (error) {
+			sc->sc_in_bp = bufp;
+			sc->sc_in_len = n;
 			break;
-		if (on != n)
+		}
+		if (uio->uio_resid == 0 || n != ULPT_BSIZE) {
+			/* read satisfied or short read from printer */
+			sc->sc_in_bp = bufp + on;
+			sc->sc_in_len = n - on;
 			break;
+		}
 	}
 
 	return (error);

--wRRV7LY7NUeQGEoC--



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