xhci_transfer_get_tdsize can return values that are too large
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.
Updated by Electric Monk about 5 years ago
- Status changed from New to Closed
commit 2aba3acda67326648fd60aaf2bfb4e18ee8c04ed Author: Robert Mustacchi <email@example.com> Date: 2018-12-01T05:49:03.000Z 9816 Multi-TRB xhci transfers should use event data 9817 xhci needs to always set slot context 8550 increase xhci bulk transfer sgl count 9818 xhci_transfer_get_tdsize can return values that are too large Reviewed by: Alex Wilson <firstname.lastname@example.org> Reviewed by: Jerry Jelinek <email@example.com> Approved by: Joshua M. Clulow <firstname.lastname@example.org>