summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoriedowse <iedowse@FreeBSD.org>2006-06-03 10:37:42 +0000
committeriedowse <iedowse@FreeBSD.org>2006-06-03 10:37:42 +0000
commit5043515219e047866dce984edceee122e55ac93f (patch)
tree3a6392f8780b9fc3958a805db522d6344a7b4335
parent903090f356bea72c268f6abb8121d29e264155d4 (diff)
downloadFreeBSD-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.c17
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;
OpenPOWER on IntegriCloud