From owner-freebsd-hackers@FreeBSD.ORG Mon Oct 27 01:47:42 2003 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id B801B16A4B3 for ; Mon, 27 Oct 2003 01:47:42 -0800 (PST) Received: from proxy.riic.at (postoffice.riic.at [140.78.161.123]) by mx1.FreeBSD.org (Postfix) with ESMTP id 2743143FB1 for ; Mon, 27 Oct 2003 01:47:41 -0800 (PST) (envelope-from hueber@riic.at) Received: from hanni.riic.uni-linz.ac.at (hanni.riic.uni-linz.ac.at [140.78.161.78])h9R9laPw007829 for ; Mon, 27 Oct 2003 10:47:36 +0100 Date: Mon, 27 Oct 2003 10:47:36 +0100 From: Gernot Hueber To: freebsd-hackers@freebsd.org Message-ID: <20031027094736.GW36100@hanni.riic.uni-linz.ac.at> Mime-Version: 1.0 Content-Type: text/plain; format=flowed; charset=ISO-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit X-Mailer: Balsa 2.0.13 Lines: 280 X-Virus-Scanned: by AMaViS - amavis-milter (http://www.amavis.org/) Subject: Patch Review: ulpt read patch X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 27 Oct 2003 09:47:42 -0000 Hi, I have written a patch for ulpt.c which allows reading the lpt device. This operation is required to get status information of some printers (eg. Epson Stylus) when connected via usb. Please can you review this patch (it applies to 5.1 P6) Thanks, Gernot *** 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 -- Dipl.-Ing. Gernot Hueber Institut f. Integrierte Schaltungen Altenbergerstr. 69 4040 Linz Tel: +43 732 2468-7120, Fax: -7126 E-mail: hueber@riic.at WWW: www.riic.at