diff options
author | imp <imp@FreeBSD.org> | 2007-06-28 05:15:33 +0000 |
---|---|---|
committer | imp <imp@FreeBSD.org> | 2007-06-28 05:15:33 +0000 |
commit | d41693b3d917bde132e136894b9aea4ad543b17a (patch) | |
tree | 6e53ed0a474034680d51bf2fc3d02266398ff0d6 /sys/dev | |
parent | c3b316d5381bdc81f16ea51de24c30a6042dac73 (diff) | |
download | FreeBSD-src-d41693b3d917bde132e136894b9aea4ad543b17a.zip FreeBSD-src-d41693b3d917bde132e136894b9aea4ad543b17a.tar.gz |
For both interrupt and isochronous (the patch was unclear which one it
applied to, but I'd think both), honor the timeout that's been set.
Return 0 bytes to be consistant with what libusb expects. By default,
the timeout will be zero, so only applications that change the default
will see a change. The patch only seems to apply to the interrupt end
points, but it should also apply to isochronous endpoints as well.
Submitted by: Maurice Castro
PR: 110122
Approved by: re (blanket)
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/usb/ugen.c | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/sys/dev/usb/ugen.c b/sys/dev/usb/ugen.c index 68b6011..50fed1f 100644 --- a/sys/dev/usb/ugen.c +++ b/sys/dev/usb/ugen.c @@ -714,11 +714,16 @@ ugen_do_read(struct ugen_softc *sc, int endpt, struct uio *uio, int flag) } sce->state |= UGEN_ASLP; DPRINTFN(5, ("ugenread: sleep on %p\n", sce)); - error = tsleep(sce, PZERO | PCATCH, "ugenri", 0); + error = tsleep(sce, PZERO | PCATCH, "ugenri", + sce->timeout); sce->state &= ~UGEN_ASLP; DPRINTFN(5, ("ugenread: woke, error=%d\n", error)); if (sc->sc_dying) error = EIO; + if (error == EAGAIN) { + error = 0; /* timeout, return 0 bytes */ + break; + } if (error) break; } @@ -779,17 +784,22 @@ ugen_do_read(struct ugen_softc *sc, int endpt, struct uio *uio, int flag) } sce->state |= UGEN_ASLP; DPRINTFN(5, ("ugenread: sleep on %p\n", sce)); - error = tsleep(sce, PZERO | PCATCH, "ugenri", 0); + error = tsleep(sce, PZERO | PCATCH, "ugenri", + sce->timeout); sce->state &= ~UGEN_ASLP; DPRINTFN(5, ("ugenread: woke, error=%d\n", error)); if (sc->sc_dying) error = EIO; + if (error == EAGAIN) { + error = 0; /* timeout, return 0 bytes */ + break; + } if (error) break; } while (sce->cur != sce->fill && uio->uio_resid > 0 && !error) { - if(sce->fill > sce->cur) + if (sce->fill > sce->cur) n = min(sce->fill - sce->cur, uio->uio_resid); else n = min(sce->limit - sce->cur, uio->uio_resid); |