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

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

 



> -----Original Message-----
> From: Alan Stern [mailto:stern@xxxxxxxxxxxxxxxxxxx]
> Sent: Saturday, February 26, 2011 6:06 AM
> To: Xu, Andiry
> Cc: dbrownell@xxxxxxxxxxxxxxxxxxxxx; linux-usb@xxxxxxxxxxxxxxx
> Subject: Re: Question about HALT bit set of qTD in EHCI driver
> 
> On Fri, 25 Feb 2011, Xu, Andiry wrote:
> 
> > Hi Alan & David,
> >
> > Currently we're debugging an issue reported by our OEM with an USB
WWLAN
> device. When this device is plugged in to EHCI controller on our
platform,
> the host controller is hung. From the traces we found that the qh
prepared
> by the driver has one qTD that has active work load followed by an
Idle
> qTD and then subsequently followed by a qTD that has both the Active
bit
> and Halt bit set.
> 
> What do you mean by an "Idle" qTD?
> 
> As far as I know, ehci-hcd never sets both the Active and Halt bits in
> a qTD.  Where do you see this happening?
> 

Sorry for the confusion. It's a qh overlay region.

> > The last qTD is confusing the hardware: the host controller does not
> know how to handle a qTD with both ACTIVE and HALT bit set and it
hangs.
> >
> > The patch below works for us:
> >
> > diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
> > index fe99895..8612ff0 100644
> > --- a/drivers/usb/host/ehci-q.c
> > +++ b/drivers/usb/host/ehci-q.c
> > @@ -464,6 +464,7 @@ qh_completions (struct ehci_hcd *ehci, struct
> ehci_qh *qh)
> >  			if ((halt & hw->hw_token) == 0) {
> >  halt:
> >  				hw->hw_token |= halt;
> > +				hw->hw_token &= ~ACTIVE_BIT(ehci);
> >  				wmb ();
> >  			}
> >  		}
> 
> I don't see why this should make any difference.  Here hw doesn't
point
> to a qTD; it points to the overlay region inside a QH.
> 
> 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?
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. 

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

Thanks,
Andiry


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