diff options
Diffstat (limited to 'drivers/usb/host/xhci-ring.c')
-rw-r--r-- | drivers/usb/host/xhci-ring.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index b46b5b98a943..5fb66db89e05 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
@@ -1946,7 +1946,7 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td, | |||
1946 | if (event_trb != ep_ring->dequeue) { | 1946 | if (event_trb != ep_ring->dequeue) { |
1947 | /* The event was for the status stage */ | 1947 | /* The event was for the status stage */ |
1948 | if (event_trb == td->last_trb) { | 1948 | if (event_trb == td->last_trb) { |
1949 | if (td->urb->actual_length != 0) { | 1949 | if (td->urb_length_set) { |
1950 | /* Don't overwrite a previously set error code | 1950 | /* Don't overwrite a previously set error code |
1951 | */ | 1951 | */ |
1952 | if ((*status == -EINPROGRESS || *status == 0) && | 1952 | if ((*status == -EINPROGRESS || *status == 0) && |
@@ -1960,7 +1960,13 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td, | |||
1960 | td->urb->transfer_buffer_length; | 1960 | td->urb->transfer_buffer_length; |
1961 | } | 1961 | } |
1962 | } else { | 1962 | } else { |
1963 | /* Maybe the event was for the data stage? */ | 1963 | /* |
1964 | * Maybe the event was for the data stage? If so, update | ||
1965 | * already the actual_length of the URB and flag it as | ||
1966 | * set, so that it is not overwritten in the event for | ||
1967 | * the last TRB. | ||
1968 | */ | ||
1969 | td->urb_length_set = true; | ||
1964 | td->urb->actual_length = | 1970 | td->urb->actual_length = |
1965 | td->urb->transfer_buffer_length - | 1971 | td->urb->transfer_buffer_length - |
1966 | EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)); | 1972 | EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)); |