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:
Augustin Cavalier 2020-07-19 15:44:58 -04:00
parent 4aa9da6843
commit 913f009e94
3 changed files with 4 additions and 47 deletions

View File

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

View File

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

View File

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