summaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/xhci-ring.c
diff options
context:
space:
mode:
authorMathias Nyman <mathias.nyman@linux.intel.com>2017-06-15 11:55:44 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-06-15 22:17:46 +0200
commit217491487c43892318c18b6dcafe33b6353efd40 (patch)
tree5f7b199d30f0b992ace574fa10aa4b59f4cbf586 /drivers/usb/host/xhci-ring.c
parentb3368382efe6e987961e1aaec6b29507e2175954 (diff)
downloadlinux-217491487c43892318c18b6dcafe33b6353efd40.tar.bz2
xhci: Add support for endpoint soft reset
xhci supports soft retry recovery when the host halted the host side of an endopint but the connected USB device is not aware of the halt. In this case xhci needs to issue a reset endopint command with a TSP (Transfer State Preserve) flag set which preserves the Data toggle and Sequence number of the endpoint. This feature is needed to handle a few special transfer event types such as USB Transaction error that don't always point to a causing TRB. see xhci 4.6.8.1 for more details Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/host/xhci-ring.c')
-rw-r--r--drivers/usb/host/xhci-ring.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 417b3c61fd82..ae55ed1c3f08 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1830,7 +1830,7 @@ static void xhci_cleanup_halted_endpoint(struct xhci_hcd *xhci,
ep->ep_state |= EP_HALTED;
ep->stopped_stream = stream_id;
- xhci_queue_reset_ep(xhci, command, slot_id, ep_index);
+ xhci_queue_reset_ep(xhci, command, slot_id, ep_index, EP_HARD_RESET);
xhci_cleanup_stalled_ring(xhci, ep_index, td);
ep->stopped_stream = 0;
@@ -4046,12 +4046,16 @@ void xhci_queue_new_dequeue_state(struct xhci_hcd *xhci,
}
int xhci_queue_reset_ep(struct xhci_hcd *xhci, struct xhci_command *cmd,
- int slot_id, unsigned int ep_index)
+ int slot_id, unsigned int ep_index,
+ enum xhci_ep_reset_type reset_type)
{
u32 trb_slot_id = SLOT_ID_FOR_TRB(slot_id);
u32 trb_ep_index = EP_ID_FOR_TRB(ep_index);
u32 type = TRB_TYPE(TRB_RESET_EP);
+ if (reset_type == EP_SOFT_RESET)
+ type |= TRB_TSP;
+
return queue_command(xhci, cmd, 0, 0, 0,
trb_slot_id | trb_ep_index | type, false);
}