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
>