RE: xhci ASMedia lockups - a theory

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

 



From: Alan Stern 
> On Wed, 15 Jan 2014, David Laight wrote:
> 
> > I have a theory, I'll try to write a non-invasive patch.
> >
> > In spite of the comments and some code paths inc_enq() is only
> > called by (and has only ever been called by) queue_trb(), so
> > is only called for transfer and command rings.
> >
> > It takes care to avoid advancing past the LINK TRB.
> > The coding would be much simpler if it did, and I postulate
> > that the reason for this was that some hardware didn't like it.
> > In particular doing so with TRB_CHAIN set could well cause issues.
> >
> > So assume that the ASMedia controller doesn't like LINK TRB if the
> > link-to trb can't be processed. If the hardware test vectors
> > don't test this is could easily be a bug.
> >
> > Now, under normal conditions the controller will be idle and
> > won't look at the ring until the doorbell is rung - by which
> > time the ownership bits are set through to the end of the command.
> >
> > But consider what happens if the controller is active and
> > is looking for work....
> >
> > prepare_ring() will change the ownership bit of any NOP TRB
> > it writes and of the LINK TRB. The ownership on the first
> > transfer TRB is set much later.
> >
> > This makes it not impossible for the controller to find a TRB
> > it doesn't own after processing a LINK TRB.
> 
> Doesn't this mean you shouldn't change the ownership of a LINK TRB
> until after you change the ownership of the TRB it points to?

That is what I assume.
In practise this means that the 'first_trb' (whose ownership is set
last) has to be the one that is valid when prepare_ring() is called.

The plan for the patch is:
- Save the enq pointer in prepare_ring (in the ep_ring structure).
- When writing a trb set the ownership unless it is the saved one
  (ignoring the value set by the caller).
- At the end invert the ownership on the saved entry.

This is made slightly more complex by the way the isoc code abuses
prepare_ring() and prepare_transfer().

If I get the code right a lot of stuff can get deleted.
For instance the 'more_trbs_coming' flag to inc_enc() could
cause the ownership of the first entry be inverted and the
correct doorbell rung.

I also think the doorbell address and value are fixed properties
of a ring and could usefully be saved in the ring structure.

	David



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