Date: Wed, 25 Jan 2006 12:20:15 GMT From: Peter Jeremy <PeterJeremy@optushome.com.au> To: freebsd-usb@FreeBSD.org Subject: Re: usb/91538: Unable to print to EPSON CX3500 Message-ID: <200601251220.k0PCKFKr098314@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
The following reply was made to PR usb/91538; it has been noted by GNATS. From: Peter Jeremy <PeterJeremy@optushome.com.au> To: FreeBSD-gnats-submit@FreeBSD.org, freebsd-usb@FreeBSD.org Cc: Subject: Re: usb/91538: Unable to print to EPSON CX3500 Date: Wed, 25 Jan 2006 23:15:33 +1100 --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?200601251220.k0PCKFKr098314>