summaryrefslogtreecommitdiff
path: root/drivers/usb/host/xhci-ring.c
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2015-04-14 21:28:32 (GMT)
committerRussell King <rmk+kernel@arm.linux.org.uk>2015-04-14 21:28:32 (GMT)
commit4b2f8838479eb2abe042e094f7d2cced6d5ea772 (patch)
tree5ef3236b354a494c8d71a572896283e44989c696 /drivers/usb/host/xhci-ring.c
parentc848791f0336914a3081ea3fe029cf177d81de81 (diff)
parent9fd85eb502a78bd812db58bd1f668b2a06ee30a5 (diff)
downloadlinux-4b2f8838479eb2abe042e094f7d2cced6d5ea772.tar.xz
Merge branch 'devel-stable' into for-next
Diffstat (limited to 'drivers/usb/host/xhci-ring.c')
-rw-r--r--drivers/usb/host/xhci-ring.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 88da8d6..5fb66db 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1729,7 +1729,7 @@ static void xhci_cleanup_halted_endpoint(struct xhci_hcd *xhci,
if (!command)
return;
- ep->ep_state |= EP_HALTED;
+ ep->ep_state |= EP_HALTED | EP_RECENTLY_HALTED;
ep->stopped_stream = stream_id;
xhci_queue_reset_ep(xhci, command, slot_id, ep_index);
@@ -1946,7 +1946,7 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td,
if (event_trb != ep_ring->dequeue) {
/* The event was for the status stage */
if (event_trb == td->last_trb) {
- if (td->urb->actual_length != 0) {
+ if (td->urb_length_set) {
/* Don't overwrite a previously set error code
*/
if ((*status == -EINPROGRESS || *status == 0) &&
@@ -1960,7 +1960,13 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td,
td->urb->transfer_buffer_length;
}
} else {
- /* Maybe the event was for the data stage? */
+ /*
+ * Maybe the event was for the data stage? If so, update
+ * already the actual_length of the URB and flag it as
+ * set, so that it is not overwritten in the event for
+ * the last TRB.
+ */
+ td->urb_length_set = true;
td->urb->actual_length =
td->urb->transfer_buffer_length -
EVENT_TRB_LEN(le32_to_cpu(event->transfer_len));