Ping?

On Thu, May 18, 2017 at 07:35:31PM -0700, patrick keshishian wrote:
> Hello,
> 
> I would like to propose adding a ulptread call to the ulpt(4).
> 
> This diff adds ulptread and ulpt_do_read functions, similar to
> ultpwrite and ulpt_do_write (essentially copy/paste/edit), as well
> as looking at ugen_do_read (for BULK).
> 
> 
> One thing to note is the current ultp driver runs two continuous
> transfers and stashes any data into sc_junk. This was added in:
> 
> | revision 1.7
> | date: 2001/05/03 02:20:34;  author: aaron;  state: Exp;  lines: +165 -40;
> | branches:  1.7.2;
> | Sync with NetBSD. Tested with a USB keyboard, USB mouse, and three different
> | kue(4) Ethernet devices.
> 
> I think this matches revision 1.42 on NetBSD.
> 
> I am not sure of the original reason for this continuous read.
> Therefore, to minimize any potential fallout, this diff checks
> the flag to ulptopen call for FREAD, and if set, it doesn't
> start the continuous transfers to sc_junk.
> 
> 
> Looking at NetBSD source history now, they added read to their driver
> in revision 1.60:
> 
> | Several changes:
> | * Implement read for ulpt.
> | * If the device is not opened for reading, occasionally drain any
> |   data the printer might have (but don't hammer the printer with reads).
> | * Lower the buffer size to one page.
> |   The driver seems to work with more printers now.
> 
> 
> They similarly check for FREAD in their open, and if "it's not
> opened for read the [sic] set up a reader."
> 
> 
> The reason for the proposal is that I have a USB thermal printer
> which attaches to ulpt and for me to "drive" the printer, I need
> the status messages the printer sends back.
> 
> I initially got the device working with ulpt disabled and using
> libusb1 from ports. It would be much more convenient not to bother
> with disabling ulpt.
> 
> 
> Comments?
> 
> --patrick
> 
> 
> 
> 
> Index: sys/conf.h
> ===================================================================
> RCS file: /cvs/obsd/src/sys/sys/conf.h,v
> retrieving revision 1.143
> diff -u -p -u -p -r1.143 conf.h
> --- sys/conf.h        4 Sep 2016 10:51:24 -0000       1.143
> +++ sys/conf.h        19 May 2017 01:39:18 -0000
> @@ -356,9 +356,9 @@ extern struct cdevsw cdevsw[];
>       (dev_type_stop((*))) enodev, 0, selfalse, \
>       (dev_type_mmap((*))) enodev }
>  
> -/* open, close, write */
> +/* open, close, read, write */
>  #define cdev_ulpt_init(c,n) { \
> -     dev_init(c,n,open), dev_init(c,n,close), (dev_type_read((*))) enodev, \
> +     dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \
>       dev_init(c,n,write), (dev_type_ioctl((*))) enodev, \
>       (dev_type_stop((*))) enodev, 0, selfalse, (dev_type_mmap((*))) enodev }
>  
> Index: dev/usb/ulpt.c
> ===================================================================
> RCS file: /cvs/obsd/src/sys/dev/usb/ulpt.c,v
> retrieving revision 1.54
> diff -u -p -u -p -r1.54 ulpt.c
> --- dev/usb/ulpt.c    26 Mar 2017 15:31:15 -0000      1.54
> +++ dev/usb/ulpt.c    19 May 2017 01:39:18 -0000
> @@ -42,6 +42,7 @@
>  #include <sys/device.h>
>  #include <sys/uio.h>
>  #include <sys/conf.h>
> +#include <sys/fcntl.h>
>  #include <sys/vnode.h>
>  #include <sys/syslog.h>
>  #include <sys/types.h>
> @@ -486,7 +487,7 @@ ulptopen(dev_t dev, int flag, int mode, 
>               if (usbd_is_dying(sc->sc_udev)) {
>                       error = ENXIO;
>                       sc->sc_state = 0;
> -                     goto done;
> +                     goto bad;
>               }
>       }
>  
> @@ -494,18 +495,20 @@ ulptopen(dev_t dev, int flag, int mode, 
>       if (err) {
>               sc->sc_state = 0;
>               error = EIO;
> -             goto done;
> +             goto bad;
>       }
>       if (ulptusein && sc->sc_in != -1) {
> -             DPRINTF(("ulpt_open: open input pipe\n"));
> +             DPRINTF(("ulptopen: open input pipe\n"));
>               err = usbd_open_pipe(sc->sc_iface, sc->sc_in,0,&sc->sc_in_pipe);
>               if (err) {
>                       error = EIO;
>                       usbd_close_pipe(sc->sc_out_pipe);
>                       sc->sc_out_pipe = NULL;
>                       sc->sc_state = 0;
> -                     goto done;
> +                     goto bad;
>               }
> +             if ((flag & FREAD) == FREAD)
> +                     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) {
> @@ -534,9 +537,10 @@ ulptopen(dev_t dev, int flag, int mode, 
>               usbd_transfer(sc->sc_in_xfer1); /* ignore failed start */
>       }
>  
> + done:
>       sc->sc_state = ULPT_OPEN;
>  
> - done:
> + bad:
>       if (--sc->sc_refcnt < 0)
>               usb_detach_wakeup(&sc->sc_dev);
>  
> @@ -596,6 +600,71 @@ ulptclose(dev_t dev, int flag, int mode,
>  
>       DPRINTF(("ulptclose: closed\n"));
>       return (0);
> +}
> +
> +int
> +ulpt_do_read(struct ulpt_softc *sc, struct uio *uio, int flags)
> +{
> +     size_t n;
> +     int error = 0;
> +     uint32_t bytes;
> +     void *bufp;
> +     struct usbd_xfer *xfer;
> +     usbd_status err;
> +
> +     DPRINTF(("ulptread\n"));
> +     xfer = usbd_alloc_xfer(sc->sc_udev);
> +     if (xfer == NULL)
> +             return (ENOMEM);
> +     bufp = usbd_alloc_buffer(xfer, ULPT_BSIZE);
> +     if (bufp == NULL) {
> +             usbd_free_xfer(xfer);
> +             return (ENOMEM);
> +     }
> +     while ((n = ulmin(ULPT_BSIZE, uio->uio_resid)) != 0) {
> +             ulpt_statusmsg(ulpt_status(sc), sc);
> +             DPRINTFN(1, ("ulptread: transfer %zu bytes\n", n));
> +             usbd_setup_xfer(xfer, sc->sc_in_pipe, 0, bufp, n,
> +                 USBD_NO_COPY | USBD_SYNCHRONOUS | USBD_CATCH |
> +                 USBD_SHORT_XFER_OK, 0, NULL);
> +             err = usbd_transfer(xfer);
> +             if (err) {
> +                     usbd_clear_endpoint_stall(sc->sc_in_pipe);
> +                     DPRINTF(("ulptread: error=%d\n", err));
> +                     error = EIO;
> +                     break;
> +             }
> +             usbd_get_xfer_status(xfer, NULL, NULL, &bytes, NULL);
> +             if (bytes == 0)
> +                     break;
> +             error = uiomove(bufp, bytes, uio);
> +             if (error)
> +                     break;
> +     }
> +     usbd_free_xfer(xfer);
> +
> +     return (error);
> +}
> +
> +int
> +ulptread(dev_t dev, struct uio *uio, int flags)
> +{
> +     struct ulpt_softc *sc;
> +     int error;
> +
> +     sc = ulpt_cd.cd_devs[ULPTUNIT(dev)];
> +
> +     if (usbd_is_dying(sc->sc_udev) || (sc->sc_flags & ULPT_EFIRMWARE))
> +             return (EIO);
> +
> +     if (sc->sc_in == -1)
> +             return (ENODEV);
> +
> +     sc->sc_refcnt++;
> +     error = ulpt_do_read(sc, uio, flags);
> +     if (--sc->sc_refcnt < 0)
> +             usb_detach_wakeup(&sc->sc_dev);
> +     return (error);
>  }
>  
>  int
> 

Reply via email to