From owner-freebsd-usb@FreeBSD.ORG Wed Jan 25 12:15:37 2006 Return-Path: X-Original-To: freebsd-usb@FreeBSD.org Delivered-To: freebsd-usb@FreeBSD.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 4EE4616A41F; Wed, 25 Jan 2006 12:15:37 +0000 (GMT) (envelope-from PeterJeremy@optushome.com.au) Received: from mail22.syd.optusnet.com.au (mail22.syd.optusnet.com.au [211.29.133.160]) by mx1.FreeBSD.org (Postfix) with ESMTP id 7EF0E43D5C; Wed, 25 Jan 2006 12:15:36 +0000 (GMT) (envelope-from PeterJeremy@optushome.com.au) Received: from cirb503493.alcatel.com.au (c220-239-19-236.belrs4.nsw.optusnet.com.au [220.239.19.236]) by mail22.syd.optusnet.com.au (8.12.11/8.12.11) with ESMTP id k0PCFXXg023499 (version=TLSv1/SSLv3 cipher=EDH-RSA-DES-CBC3-SHA bits=168 verify=NO); Wed, 25 Jan 2006 23:15:34 +1100 Received: from cirb503493.alcatel.com.au (localhost.alcatel.com.au [127.0.0.1]) by cirb503493.alcatel.com.au (8.12.10/8.12.10) with ESMTP id k0PCFXHh040083; Wed, 25 Jan 2006 23:15:33 +1100 (EST) (envelope-from pjeremy@cirb503493.alcatel.com.au) Received: (from pjeremy@localhost) by cirb503493.alcatel.com.au (8.12.10/8.12.9/Submit) id k0PCFXjh040082; Wed, 25 Jan 2006 23:15:33 +1100 (EST) (envelope-from pjeremy) Date: Wed, 25 Jan 2006 23:15:33 +1100 From: Peter Jeremy To: FreeBSD-gnats-submit@FreeBSD.org, freebsd-usb@FreeBSD.org Message-ID: <20060125121533.GA39758@cirb503493.alcatel.com.au> References: <200601090041.k090fk8o082824@server.vk2pj.dyndns.org> <200601090050.k090o3QG026924@freefall.freebsd.org> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="wRRV7LY7NUeQGEoC" Content-Disposition: inline In-Reply-To: <200601090050.k090o3QG026924@freefall.freebsd.org> X-PGP-Key: http://members.optusnet.com.au/peterjeremy/pubkey.asc User-Agent: Mutt/1.5.11 Cc: Subject: Re: usb/91538: Unable to print to EPSON CX3500 X-BeenThere: freebsd-usb@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: FreeBSD support for USB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 25 Jan 2006 12:15:37 -0000 --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--