From root@midori.riic.uni-linz.ac.at Tue Nov 11 00:12:06 2003 Return-Path: Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id EBC4216A4CE for ; Tue, 11 Nov 2003 00:12:05 -0800 (PST) Received: from proxy.riic.at (www.riic.uni-linz.ac.at [140.78.161.123]) by mx1.FreeBSD.org (Postfix) with ESMTP id D42C843F93 for ; Tue, 11 Nov 2003 00:12:03 -0800 (PST) (envelope-from root@midori.riic.uni-linz.ac.at) Received: from midori.riic.uni-linz.ac.at (midori.riic.uni-linz.ac.at [140.78.161.56]) by proxy.riic.at (8.12.7/8.12.7/SuSE Linux 0.6) with ESMTP id hAB8BwPw008254 for ; Tue, 11 Nov 2003 09:11:59 +0100 Received: from midori.riic.uni-linz.ac.at (localhost [127.0.0.1]) by midori.riic.uni-linz.ac.at (8.12.9/8.12.9) with ESMTP id hAB8BBXf000879 for ; Tue, 11 Nov 2003 09:11:21 +0100 (CET) (envelope-from root@midori.riic.uni-linz.ac.at) Received: (from root@localhost) by midori.riic.uni-linz.ac.at (8.12.9/8.12.9/Submit) id hAB89mpw000852; Tue, 11 Nov 2003 09:09:48 +0100 (CET) Message-Id: <200311110809.hAB89mpw000852@midori.riic.uni-linz.ac.at> Date: Tue, 11 Nov 2003 09:09:48 +0100 (CET) From: Gernot Hueber Reply-To: Gernot Hueber To: FreeBSD-gnats-submit@freebsd.org Cc: Subject: ulpt is missing read operation X-Send-Pr-Version: 3.113 X-GNATS-Notify: >Number: 59169 >Category: usb >Synopsis: [ulpt] [patch] ulpt is missing read operation >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-usb >State: closed >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Tue Nov 11 00:20:11 PST 2003 >Closed-Date: Sat Nov 12 18:00:16 GMT 2005 >Last-Modified: Sat Nov 12 18:00:16 GMT 2005 >Originator: Gernot Hueber >Release: FreeBSD 5.1-RELEASE-p6 i386 >Organization: >Environment: System: FreeBSD midori.riic.uni-linz.ac.at 5.1-RELEASE-p6 FreeBSD 5.1-RELEASE-p6 #5: Wed Oct 22 20:34:05 CEST 2003 root@midori.riic.uni-linz.ac.at:/usr/src/sys/i386/compile/MIDORI i386 >Description: The ulpt driver is missing the read operation, which is required for some tools to report the status of the printer (eg. the ink level of ink jet printers). >How-To-Repeat: Try esputil (included with gimpprint) for Epson printers >Fix: Apply patch below. --- ulpt.diff begins here --- *** ulpt.c.orig Wed Oct 22 10:59:53 2003 --- ulpt.c Fri Oct 24 21:40:57 2003 *************** *** 71,76 **** --- 71,77 ---- #define LPTPRI (PZERO+8) #define ULPT_BSIZE 16384 + #define ULPT_IN_BUFFERLEN 1024 #ifdef USB_DEBUG #define DPRINTF(x) if (ulptdebug) logprintf x *************** *** 105,112 **** int sc_in; usbd_pipe_handle sc_in_pipe; /* bulk in pipe */ ! usbd_xfer_handle sc_in_xfer1; ! usbd_xfer_handle sc_in_xfer2; u_char sc_junk[64]; /* somewhere to dump input */ u_char sc_state; --- 106,114 ---- int sc_in; usbd_pipe_handle sc_in_pipe; /* bulk in pipe */ ! usbd_xfer_handle sc_in_xfer; ! void *sc_in_buffer; ! int sc_in_bufferlen; u_char sc_junk[64]; /* somewhere to dump input */ u_char sc_state; *************** *** 141,146 **** --- 143,149 ---- #elif defined(__FreeBSD__) Static d_open_t ulptopen; Static d_close_t ulptclose; + Static d_read_t ulptread; Static d_write_t ulptwrite; Static d_ioctl_t ulptioctl; *************** *** 149,154 **** --- 152,158 ---- Static struct cdevsw ulpt_cdevsw = { .d_open = ulptopen, .d_close = ulptclose, + .d_read = ulptread, .d_write = ulptwrite, .d_ioctl = ulptioctl, .d_name = "ulpt", *************** *** 162,167 **** --- 166,172 ---- void ulpt_disco(void *); int ulpt_do_write(struct ulpt_softc *, struct uio *uio, int); + int ulpt_do_read(struct ulpt_softc *, struct uio *uio, int); int ulpt_status(struct ulpt_softc *); void ulpt_reset(struct ulpt_softc *); int ulpt_statusmsg(u_char, struct ulpt_softc *); *************** *** 344,349 **** --- 349,356 ---- UID_ROOT, GID_OPERATOR, 0644, "unlpt%d", device_get_unit(self)); #endif + + usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, USBDEV(sc->sc_dev)); *************** *** 473,497 **** } } - static void - ulpt_input(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) - { - struct ulpt_softc *sc = priv; - u_int32_t count; - - /* Don't loop on errors or 0-length input. */ - usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL); - if (status != USBD_NORMAL_COMPLETION || count == 0) - return; - - DPRINTFN(2,("ulpt_input: got some data\n")); - /* Do it again. */ - if (xfer == sc->sc_in_xfer1) - usbd_transfer(sc->sc_in_xfer2); - else - usbd_transfer(sc->sc_in_xfer1); - } - int ulptusein = 1; /* --- 480,485 ---- *************** *** 517,522 **** --- 505,513 ---- sc->sc_flags = flags; DPRINTF(("ulptopen: flags=0x%x\n", (unsigned)flags)); + sc->sc_in_buffer = malloc(ULPT_IN_BUFFERLEN, M_USBDEV, M_WAITOK); + sc->sc_in_bufferlen = ULPT_IN_BUFFERLEN; + #if defined(USB_DEBUG) && defined(__FreeBSD__) /* Ignoring these flags might not be a good idea */ if ((flags & ~ULPT_NOPRIME) != 0) *************** *** 569,600 **** sc->sc_state = 0; goto done; } ! sc->sc_in_xfer1 = usbd_alloc_xfer(sc->sc_udev); ! sc->sc_in_xfer2 = usbd_alloc_xfer(sc->sc_udev); ! if (sc->sc_in_xfer1 == NULL || sc->sc_in_xfer2 == NULL) { ! error = ENOMEM; ! if (sc->sc_in_xfer1 != NULL) { ! usbd_free_xfer(sc->sc_in_xfer1); ! sc->sc_in_xfer1 = NULL; ! } ! if (sc->sc_in_xfer2 != NULL) { ! usbd_free_xfer(sc->sc_in_xfer2); ! sc->sc_in_xfer2 = NULL; ! } ! usbd_close_pipe(sc->sc_out_pipe); ! sc->sc_out_pipe = NULL; ! usbd_close_pipe(sc->sc_in_pipe); ! sc->sc_in_pipe = NULL; ! sc->sc_state = 0; ! goto done; ! } ! usbd_setup_xfer(sc->sc_in_xfer1, sc->sc_in_pipe, sc, ! sc->sc_junk, sizeof sc->sc_junk, USBD_SHORT_XFER_OK, ! USBD_NO_TIMEOUT, ulpt_input); ! usbd_setup_xfer(sc->sc_in_xfer2, sc->sc_in_pipe, sc, ! sc->sc_junk, sizeof sc->sc_junk, USBD_SHORT_XFER_OK, ! USBD_NO_TIMEOUT, ulpt_input); ! usbd_transfer(sc->sc_in_xfer1); /* ignore failed start */ } sc->sc_state = ULPT_OPEN; --- 560,571 ---- sc->sc_state = 0; goto done; } ! ! sc->sc_in_xfer = usbd_alloc_xfer(sc->sc_udev); ! if (sc->sc_in_xfer == NULL) { ! error=ENOMEM; ! goto done; ! } } sc->sc_state = ULPT_OPEN; *************** *** 645,664 **** usbd_abort_pipe(sc->sc_in_pipe); usbd_close_pipe(sc->sc_in_pipe); sc->sc_in_pipe = NULL; - if (sc->sc_in_xfer1 != NULL) { - usbd_free_xfer(sc->sc_in_xfer1); - sc->sc_in_xfer1 = NULL; - } - if (sc->sc_in_xfer2 != NULL) { - usbd_free_xfer(sc->sc_in_xfer2); - sc->sc_in_xfer2 = NULL; - } } sc->sc_state = 0; DPRINTF(("ulptclose: closed\n")); return (0); } int --- 616,690 ---- usbd_abort_pipe(sc->sc_in_pipe); usbd_close_pipe(sc->sc_in_pipe); sc->sc_in_pipe = NULL; } + if (sc->sc_in_xfer) { + usbd_free_xfer(sc->sc_in_xfer); + sc->sc_in_xfer = NULL; + } + if (sc->sc_in_buffer) { + free(sc->sc_in_buffer, M_USBDEV); + sc->sc_in_buffer = NULL; + } sc->sc_state = 0; DPRINTF(("ulptclose: closed\n")); return (0); + } + + int + ulpt_do_read(struct ulpt_softc *sc, struct uio *uio, int flag) + { + u_int32_t n, tn; + usbd_status err; + int error = 0; + + DPRINTFN(5, ("%s: ulptread\n", USBDEVNAME(sc->sc_dev))); + + if (sc->sc_dying) + return (EIO); + + while ((n = min(sc->sc_in_bufferlen, uio->uio_resid)) != 0) { + DPRINTFN(1, ("ulptread: start transfer %d bytes\n",n)); + tn = n; + + err = usbd_bulk_transfer( + sc->sc_in_xfer, sc->sc_in_pipe, + USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, + sc->sc_in_buffer, &tn, + "uscnrb"); + if (err) { + if (err == USBD_INTERRUPTED) + error = EINTR; + else if (err == USBD_TIMEOUT) + error = ETIMEDOUT; + else + error = EIO; + break; + } + DPRINTFN(1, ("ulptread: got %d bytes\n", tn)); + error = uiomove(sc->sc_in_buffer, tn, uio); + if (error || tn < n) + break; + } + + return (error); + } + + int + ulptread(dev_t dev, struct uio *uio, int flag) + { + struct ulpt_softc *sc; + int error; + + USB_GET_SC(ulpt, ULPTUNIT(dev), sc); + + sc->sc_refcnt++; + error = ulpt_do_read(sc, uio, flag); + if (--sc->sc_refcnt < 0) + usb_detach_wakeup(USBDEV(sc->sc_dev)); + + return (error); } int --- ulpt.diff ends here --- >Release-Note: >Audit-Trail: Responsible-Changed-From-To: freebsd-bugs->joe Responsible-Changed-By: ceri Responsible-Changed-When: Tue Nov 11 03:46:55 PST 2003 Responsible-Changed-Why: Assign to joe. http://www.freebsd.org/cgi/query-pr.cgi?pr=59169 Responsible-Changed-From-To: joe->freebsd-usb Responsible-Changed-By: joe Responsible-Changed-When: Wed Nov 10 11:07:21 GMT 2004 Responsible-Changed-Why: Hand this over to the usb mailling list. http://www.freebsd.org/cgi/query-pr.cgi?pr=59169 State-Changed-From-To: open->closed State-Changed-By: iedowse State-Changed-When: Sat Nov 12 17:59:16 GMT 2005 State-Changed-Why: Read support appears to have been added to the ulpt driver some time ago. http://www.freebsd.org/cgi/query-pr.cgi?pr=59169 >Unformatted: