RE: Question about HALT bit set of qTD in EHCI driver

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

 



Dave:

Can you help with this issue?  Do you remember why the code below in
qh_completions() sets the HALT bit in the QH overlay region?  The
comment doesn't seem to be relevant any more.

			/* force halt for unlinked or blocked qh, so we'll
			 * patch the qh later and so that completions can't
			 * activate it while we "know" it's stopped.
			 */
			if ((halt & hw->hw_token) == 0) {
halt:
				hw->hw_token |= halt;
				wmb ();
			}

Can we eliminate these statements?  The fact that HALT is set in
hw_token won't prevent the driver from doing anything: Contrary to
what the comment says, whether or not the QH gets "patched" or
reactivated has nothing to do with the HALT bit.

In fact, there are circumstances in which the QH gets reactivated
_without_ being updated (i.e., when an URB is unlinked before the
hardware starts executing it.  After the URB is given back the queue
picks up right where it left off, so qh_refresh() doesn't call
qh_update()).  In this case setting the HALT bit would be a definite
mistake!

In fact, maybe that mistake is the reason for Andiry's problem...


On Mon, 14 Mar 2011, Xu, Andiry wrote:

> > Furthermore, these statements get executed in only three ways:
> > 
> > 	The QH is unlinked.  In this case the hardware should never
> > 	see the QH so it shouldn't be confused by it.
> > 
> > 	The QH is halted because an earlier qTD terminated with an
> > 	error.  In this case the Active bit should already be turned
> > 	off, so turning on the Halt bit shouldn't hurt.
> > 
> > 	A short read occurred.  Is this the case that's bothering you?
> > 
> > Now, I have to admit that I don't remember why this code sets the Halt
> > bit.  Maybe it doesn't have to be done at all; I'm not sure.

> The qh state is QH_STATE_IDLE when the driver set the Halt bit. No error
> or short read occurs. In this case HW should not see this qh, right?

Right.  QH_STATE_IDLE means the QH is no longer on the async list _and_ 
an IAA interrupt has occurred since it was removed.

If there was no error and no short read, then this statement must have
been executed because an URB was unlinked.  Is that what happened?

> I've verified clear either the Active bit or the Halt bit in this case
> can workaround this issue.
> 
> I've found that when disable async qh/qtd cache (a HW feature on our
> platform), the issue disappears. Seems the HW caches the idle qh and be
> able to see it. 

That really sounds like a bug in the hardware design.  The HW should
_never_ cache QHs that have been fully removed from the async list.  
In fact, that's exactly what the IAA interrupt is supposed to mean --
it means that any QHs removed from the async list before the IAAD bit
was set are no longer present in the HW cache.  See section 4.8.2 in 
the EHCI spec.

> Can I propose a workaround, do not set halt bit if it's an affected
> platform and Active bit is set in this case? 

We may be able to avoid setting the halt bit entirely.  Let's see what 
Dave says.

Alan Stern

--
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