Subject: kern/25041: Isochronous USB transfers from a ugen lock up DIAGNOSTIC kernel
To: None <>
From: None <>
List: netbsd-bugs
Date: 04/03/2004 13:36:43
>Number:         25041
>Category:       kern
>Synopsis:       Isochronous USB transfers from a ugen lock up DIAGNOSTIC kernel
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat Apr 03 19:21:00 UTC 2004
>Originator:     Rafal Boni
>Release:        NetBSD 2.0B
System: NetBSD groo-the-wanderer 2.0B NetBSD 2.0B (T30) #9: Thu Apr 1 20:35:38 EST 2004 rafal@groo-the-wanderer:/home/rafal/netbsd-obj/sys/arch/i386/compile/T30 i386
Architecture: i386
Machine: i386
	I have a userland tool to drive and collect video from a IBM
	[POS - ed.] USB cam (really a Xirlink device).  If I run the
	tool with a kernel compiled with DIAGNOSTIC, the machine locks
	up hard, and if I'm not in X, I can see a more-or-less endless
	stream of:

	    uhci_device_isoc_done: xfer=<someaddr> not busy 0x4f4e5155

	Along with some:

	    uhci_idone: ii=<someaddr> done!

	interspersed.  Userland is non-responsive at this point, though
	I can get to DDB.  Killing the process from DDB doesn't seem to
	stop the stream, however, nor stop the process (I'm not sure I
	tried kill <proc>,9 but see below) and attempting to reboot seems
	to stop the "idone" messages but not the stream of isoc_done ones.
	At this point the only thing to do is lean on the powerbutton...

	Try to use isochronous transfers from a device connected via
	a UHCI controller.  In my case, it's a ugen which I'm driving
	via the USB ioctl interface from userland and collecting video
	data via the same program.


	The following patch "fixes" it for me; I'm not sure if this
	is "The Right Thing" or if some other piece of DIAGNOSTIC 
	code should be setting the xfer state to BUSY elsewhere,
	but at least it keeps my machine from locking up and the
	data returned from the USB device seems reasonable.

Index: uhci.c
RCS file: /cvsroot/src/sys/dev/usb/uhci.c,v
retrieving revision 1.178
diff -u -p -r1.178 uhci.c
--- uhci.c	2 Mar 2004 16:32:05 -0000	1.178
+++ uhci.c	3 Apr 2004 17:58:42 -0000
@@ -2603,11 +2603,19 @@ uhci_device_isoc_done(usbd_xfer_handle x
+#if 0	/* 
+ 	 * XXXrkb: the xfer seems ~ never to be BUSY here (it seems to
+	 * mostly be ONQU), so just nuke this check, since it locks up
+	 * my machine when I try to do isoc transfers to a ugen at uhci
+	 */
 	if (xfer->busy_free != XFER_BUSY) {
 		printf("uhci_device_isoc_done: xfer=%p not busy 0x%08x\n",
 		       xfer, xfer->busy_free);
+	DPRINTFN(5, ("uhci_isoc_done: xfer=%p, busy=%08x\n", xfer, xfer->busy_free));
         if (ii->stdend == NULL) {
                 printf("uhci_device_isoc_done: xfer=%p stdend==NULL\n", xfer);