diff options
author | iedowse <iedowse@FreeBSD.org> | 2006-06-03 10:37:42 +0000 |
---|---|---|
committer | iedowse <iedowse@FreeBSD.org> | 2006-06-03 10:37:42 +0000 |
commit | 5043515219e047866dce984edceee122e55ac93f (patch) | |
tree | 3a6392f8780b9fc3958a805db522d6344a7b4335 | |
parent | 903090f356bea72c268f6abb8121d29e264155d4 (diff) | |
download | FreeBSD-src-5043515219e047866dce984edceee122e55ac93f.zip FreeBSD-src-5043515219e047866dce984edceee122e55ac93f.tar.gz |
Allow zero-length read/write operations to get through to the
hardware. Also set both the read and write timeouts from the
USB_SET_TIMEOUT ioctl.
-rw-r--r-- | sys/dev/usb/ugen.c | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/sys/dev/usb/ugen.c b/sys/dev/usb/ugen.c index 8efee96..4467ab7 100644 --- a/sys/dev/usb/ugen.c +++ b/sys/dev/usb/ugen.c @@ -693,7 +693,7 @@ ugen_do_read(struct ugen_softc *sc, int endpt, struct uio *uio, int flag) usbd_xfer_handle xfer; usbd_status err; int s; - int error = 0; + int error = 0, doneone = 0; u_char buffer[UGEN_CHUNK]; DPRINTFN(5, ("%s: ugenread: %d\n", USBDEVNAME(sc->sc_dev), endpt)); @@ -757,9 +757,11 @@ ugen_do_read(struct ugen_softc *sc, int endpt, struct uio *uio, int flag) xfer = usbd_alloc_xfer(sc->sc_udev); if (xfer == 0) return (ENOMEM); - while ((n = min(UGEN_BBSIZE, uio->uio_resid)) != 0) { + while ((n = min(UGEN_BBSIZE, uio->uio_resid)) != 0 || + !doneone) { DPRINTFN(1, ("ugenread: start transfer %d bytes\n",n)); tn = n; + doneone = 1; err = usbd_bulk_transfer( xfer, sce->pipeh, sce->state & UGEN_SHORT_OK ? @@ -846,7 +848,7 @@ ugen_do_write(struct ugen_softc *sc, int endpt, struct uio *uio, int flag) { struct ugen_endpoint *sce = &sc->sc_endpoints[endpt][OUT]; u_int32_t n; - int error = 0; + int error = 0, doneone = 0; char buf[UGEN_BBSIZE]; usbd_xfer_handle xfer; usbd_status err; @@ -875,7 +877,9 @@ ugen_do_write(struct ugen_softc *sc, int endpt, struct uio *uio, int flag) xfer = usbd_alloc_xfer(sc->sc_udev); if (xfer == 0) return (EIO); - while ((n = min(UGEN_BBSIZE, uio->uio_resid)) != 0) { + while ((n = min(UGEN_BBSIZE, uio->uio_resid)) != 0 || + !doneone) { + doneone = 1; error = uiomove(buf, n, uio); if (error) break; @@ -899,7 +903,8 @@ ugen_do_write(struct ugen_softc *sc, int endpt, struct uio *uio, int flag) if (xfer == 0) return (EIO); while ((n = min(UGETW(sce->edesc->wMaxPacketSize), - uio->uio_resid)) != 0) { + uio->uio_resid)) != 0 || !doneone) { + doneone = 1; error = uiomove(buf, n, uio); if (error) break; @@ -1305,6 +1310,8 @@ ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd, case USB_SET_TIMEOUT: sce = &sc->sc_endpoints[endpt][IN]; sce->timeout = *(int *)addr; + sce = &sc->sc_endpoints[endpt][OUT]; + sce->timeout = *(int *)addr; return (0); default: break; |