Date: Sat, 11 Mar 2006 05:42:06 GMT From: Lonnie Mendez <lmendez19@austin.rr.com> To: freebsd-gnats-submit@FreeBSD.org Subject: usb/94311: [ugen][PATCH] allow interrupt IN transactions to be affected by USB_SET_TIMEOUT Message-ID: <200603110542.k2B5g6ln053436@www.freebsd.org> Resent-Message-ID: <200603110550.k2B5oKuJ078878@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 94311 >Category: usb >Synopsis: [ugen][PATCH] allow interrupt IN transactions to be affected by USB_SET_TIMEOUT >Confidential: no >Severity: non-critical >Priority: medium >Responsible: freebsd-usb >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Sat Mar 11 05:50:20 GMT 2006 >Closed-Date: >Last-Modified: >Originator: Lonnie Mendez >Release: 6.1-BETA2 >Organization: >Environment: FreeBSD twind 6.1-BETA2 FreeBSD 6.1-BETA2 #4: Fri Mar 10 22:09:38 CST 2006 root@twind:/usr/src/sys/i386/compile/MYKERNEL i386 >Description: While developing the usb redirector for qemu on FreeBSD I ran into the fact that the interrupt transaction process in ugen.c:ugen_do_read() does not allow for a timeout value (hangs process without O_NONBLOCK and no data). The man page for ugen also does not mention that USB_SET_TIMEOUT ioctl has no effect for interrupt IN transaction so I'm led to believe this is a bug/feature not yet fixed: USB_SET_TIMEOUT (int) Set the timeout on the device operations, the time is specified in milliseconds. The value 0 is used to indicate that there is no timeout. The patch below I believe corrects for this by using the timeout value that can be set from USB_SET_TIMEOUT ioctl in the tsleep call. With this patch the redirector can maintain the KISS principle while functioning properly. >How-To-Repeat: >Fix: --- sys/dev/usb/ugen.c Fri Mar 10 23:17:56 2006 +++ sys/dev/usb/ugen.c Fri Mar 10 22:28:32 2006 @@ -726,12 +726,15 @@ } 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*hz+999)/1000); DPRINTFN(5, ("ugenread: woke, error=%d\n", error)); if (sc->sc_dying) error = EIO; if (error) { sce->state &= ~UGEN_ASLP; + if (error == EWOULDBLOCK) + error = ETIMEDOUT; break; } } >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200603110542.k2B5g6ln053436>