Bug #9818
closedxhci_transfer_get_tdsize can return values that are too large
100%
Description
While testing other changes in xhci, I discovered a case where we had a bunch of bulk transfers stall and hang. When I had a bunch of additional debugging information from a rather large D script, I noticed that the TRBs of those transfers had something. In the middle of the set of transfers, one of them had a TD Size of zero.
The TD Size field of a TRB is used to indicate the number of remaining USB-level packets that are to be transmitted. By definition, if we have a zero value, this should represent the last TRB. Instead, finding it in the 3rd of 8 is definitely incorrect. I instrumented the return value of xhci_transfer_get_tdsize() and was surprised to see a return value of 32. Unfortunately, this explained everything.
In the TRB, the TD size value is 5 bits. So the maximum value is 31. Unfortunately, the way our loop was constructed, it allowed a larger value to erroneously be returned when we hit the breaking condition of the loop. In the end, I decided to remove the short circuit logic and make sure we correctly check this before we return.
This was tested as part of 9816. Please see 9816 for testing notes.