A control transfer that stopped at the status stage incorrectly warned about a "unexpected TRB Type 4", and did not set the transferred actual_length for the URB. The transferred actual_length should be set the same way for COMP_STOPPED control transfers as in the generic cases. generic case if we get an event at: TRB_SETUP stage: length = 0; TRB_DATA/TRB_NORMAL state: length = requested - remaining; TRB_STATUS stage: length = requested The URB actual_length for control transfers doesn't care about sent bytes of the SETUP stage, or remaining bytes of the STATUS stage. Cc: <stable@xxxxxxxxxxxxxxx> Signed-off-by: Mathias Nyman <mathias.nyman@xxxxxxxxxxxxxxx> --- drivers/usb/host/xhci-ring.c | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index d9936c7..584b6fe 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -1975,25 +1975,15 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td, *status = 0; break; case COMP_STOPPED_SHORT_PACKET: - if (trb_type == TRB_DATA || trb_type == TRB_NORMAL) + if (trb_type == TRB_DATA || trb_type == TRB_NORMAL) { + td->urb_length_set = true; td->urb->actual_length = remaining; - else + } else { xhci_warn(xhci, "WARN: Stopped Short Packet on ctrl setup or status TRB\n"); + } goto finish_td; case COMP_STOPPED: - switch (trb_type) { - case TRB_SETUP: - td->urb->actual_length = 0; - goto finish_td; - case TRB_DATA: - case TRB_NORMAL: - td->urb->actual_length = requested - remaining; - goto finish_td; - default: - xhci_warn(xhci, "WARN: unexpected TRB Type %d\n", - trb_type); - goto finish_td; - } + break; case COMP_STOPPED_LENGTH_INVALID: goto finish_td; default: -- 1.9.1