Re: Help needed for EHCI problem: removing an active bulk-in QH

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, 2 Nov 2015, Michael Reutman wrote:

> On Wed, Oct 28, 2015 at 10:48 AM, Alan Stern <stern@xxxxxxxxxxxxxxxxxxx> wrote:
> > The patch below is meant to apply on top of the previous patch.  It's a
> > quick-and-dirty workaround which ought to prevent the problem from
> > occurring.  Let's see if it does.
> 
> Unfortunately, I have some bad news. It appears that the last patch
> just pushes the issue further on down in time. Ran the test fresh
> today and usb got "stuck" in around 15 to 20 minutes. This has
> definitely improved things from before where it took less than a
> minute to get everything out of sorts, so maybe we are on the right
> track?

Here's a revised quick-and-dirty workaround.  It replaces the earlier 
one.  (And like the earlier one, it is meant to apply on top of 
the usbfs-snoop patch, but I don't think that makes any difference 
now.)

The idea is to wait until the QH has remain unchanged for at least 2 ms 
before deciding that the host controller has stopped using it.  If this 
doesn't fix the problem then I will be completely out of ideas and will 
have to ask for help from someone at AMD.

When testing this, don't bother with the usbfs-snoop stuff.  With luck 
it won't matter, because the test program won't hang.

Alan Stern




Index: usb-4.3/drivers/usb/host/ehci-q.c
===================================================================
--- usb-4.3.orig/drivers/usb/host/ehci-q.c
+++ usb-4.3/drivers/usb/host/ehci-q.c
@@ -1341,8 +1341,22 @@ static void end_unlink_async(struct ehci
 	}
 
 	/* Otherwise process only the first waiting QH (NVIDIA bug?) */
-	else
+	else {
+		__hc32		qh_current, qh_token, old_current, old_token;
+
 		list_move_tail(&qh->unlink_node, &ehci->async_idle);
+		old_current = qh->hw->hw_current;
+		old_token = qh->hw->hw_token;
+		for (;;) {
+			udelay(2000);
+			qh_current = READ_ONCE(qh->hw->hw_current);
+			qh_token = READ_ONCE(qh->hw->hw_token);
+			if (qh_current == old_current && qh_token == old_token)
+				break;
+			old_current = qh_current;
+			old_token = qh_token;
+		}
+	}
 
 	/* Start a new IAA cycle if any QHs are waiting for it */
 	if (!list_empty(&ehci->async_unlink))

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux