XHCI: Add a few comments and remove the documentation file.
The documentation file (which PulkoMandy only merged today) was created over a year ago from a short conversation I had with him, and by now a lot of its information is already outdated or has been merged into comments in the driver already (specifically, the notes at the end about error messages no longer apply as there are different ones, and the bugs causing those errors have since been fixed.) A few of the statements in it were not noted in the driver, though, so I have added those as comments.
This commit is contained in:
parent
4aa9da6843
commit
913f009e94
|
@ -1,47 +0,0 @@
|
|||
anyway, here's the summary of XHCI stuff:
|
||||
- XHCI operates in units of "TRBs", which consist of a pointer and two 32-bit
|
||||
fields holding varying types of data based on the TRB type. A "normal" type
|
||||
TRB usually has a pointer to a physical buffer and then in one of the fields,
|
||||
an indicator of how many bytes are stored there
|
||||
- XHCI concept of "rings" is not, as you might expect, circular buffers.
|
||||
Instead, it uses "Link TRBs", that is, a TRB in which the pointer field
|
||||
points to the next place the hardware should read TRBs from, and it will do
|
||||
so until hitting another Link TRB, etc. So it is in fact more like a linked
|
||||
list. This allows easier management of the event queue, there is no need for
|
||||
a fixed size ring, managing edge cases when the buffer wraps around, etc.
|
||||
|
||||
The way we handle transfers in the XHCI driver is:
|
||||
- We allocate a "ring" of a small fixed amount for each endpoint (currently,
|
||||
defined as XHCI_MAX_TRANSFERS*2+1, because we need 2 TRBs on the "ring" for
|
||||
each transfer, and 1 at the end for the link to go back to the beginning)
|
||||
- When the stack calls SubmitTransfer(), we allocate a new run of TRBs to
|
||||
handle this transfer, and populate them with all the data. Then we insert one
|
||||
Link TRB on the endpoint ring pointing to the first in the "transfer ring" we
|
||||
just made, a link TRB at the end of the "transfer ring" pointing back to the
|
||||
"endpoint ring", and then an "Event Status" TRB on the "endpoint ring" which
|
||||
tells the XHCI to send an event back to us to tell us the transfer is done
|
||||
- For easier tracking, the driver also keeps a TD (transfer descriptor), which
|
||||
is a sideband structure not sent to the hardware, but used to keep track of
|
||||
the TRBs in a given endpoint ring.
|
||||
|
||||
So under normal circumstances (i.e. all transfers submitted are successful), we
|
||||
will get back only "Event" TRBs generated by the "Event Data" TRBs from the
|
||||
"endpoint ring"s, and these will tell us what transfer they correspond to, we
|
||||
will notify it as successful, and all is well.
|
||||
|
||||
If a transfer fails, then XHCI will generate an event that does *not*
|
||||
correspond to an Event Status TRB (src/add-ons/kernel/busses/usb/xhci.cpp#L2372).
|
||||
The pointer field in this TRB will point to the TRB that caused XHCI to
|
||||
generate the event (i.e. the failed TRB), and so we look through the transfers
|
||||
in progress on this endpoint and try to find which one corresponds to that TRB.
|
||||
|
||||
However, it seems in your case we are failing to find it, and so we get a
|
||||
"TRB xxxx was not found in the endpoint!"
|
||||
Most likely this TRB is on the "endpoint ring" itself. However as noted before,
|
||||
only 2 TRBs for each transfer are actually on the endpoint ring: the Link TRB
|
||||
going to the "transfer ring", and the Event Data TRB telling XHCI to fire an
|
||||
interrupt.
|
||||
|
||||
Valid Link TRBs should never fail to execute; and to my knowledge Event Data
|
||||
TRBs should not either.
|
||||
|
|
@ -2467,6 +2467,7 @@ XHCI::HandleTransferComplete(xhci_trb* trb)
|
|||
(flags & TRB_3_EVENT_DATA_BIT), completionCode, transferred);
|
||||
|
||||
if ((flags & TRB_3_EVENT_DATA_BIT) == 0) {
|
||||
// This should only occur under error conditions.
|
||||
TRACE("got an interrupt for a non-Event Data TRB!\n");
|
||||
remainder = transferred;
|
||||
transferred = -1;
|
||||
|
|
|
@ -25,6 +25,9 @@ struct xhci_endpoint;
|
|||
class XHCIRootHub;
|
||||
|
||||
|
||||
/* Each transfer requires 2 TRBs on the endpoint "ring" (one for the link TRB,
|
||||
* and one for the Event Data TRB), plus one more at the end for the link TRB
|
||||
* to the start. */
|
||||
#define XHCI_ENDPOINT_RING_SIZE (XHCI_MAX_TRANSFERS * 2 + 1)
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue