summaryrefslogtreecommitdiff
path: root/drivers/usb
diff options
context:
space:
mode:
authorMathias Nyman <mathias.nyman@linux.intel.com>2021-01-29 15:00:32 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2021-01-29 14:16:51 +0100
commitd8ac95001bea683d2088acb3e61613a27b8d2d5f (patch)
tree7c609683cf15b34ad15b83042123c10d91760cfa /drivers/usb
parentb05dadb28f8779898229e399c21e5192c24beaf2 (diff)
xhci: Add xhci_reset_halted_ep() helper function
Create a separate helper function to issue reset endpont commands to clear halted endpoints. This is useful for cases where a halted endpoint is discovered while completing another command, and the endpoint halt needs to be cleared with a endpoint reset first. No functional changes Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> Link: https://lore.kernel.org/r/20210129130044.206855-16-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/host/xhci-ring.c31
1 files changed, 25 insertions, 6 deletions
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index d9714cea6dfa..7011b1640a35 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -749,6 +749,26 @@ static void xhci_unmap_td_bounce_buffer(struct xhci_hcd *xhci,
seg->bounce_offs = 0;
}
+static int xhci_reset_halted_ep(struct xhci_hcd *xhci, unsigned int slot_id,
+ unsigned int ep_index, enum xhci_ep_reset_type reset_type)
+{
+ struct xhci_command *command;
+ int ret = 0;
+
+ command = xhci_alloc_command(xhci, false, GFP_ATOMIC);
+ if (!command) {
+ ret = -ENOMEM;
+ goto done;
+ }
+
+ ret = xhci_queue_reset_ep(xhci, command, slot_id, ep_index, reset_type);
+done:
+ if (ret)
+ xhci_err(xhci, "ERROR queuing reset endpoint for slot %d ep_index %d, %d\n",
+ slot_id, ep_index, ret);
+ return ret;
+}
+
/*
* When we get a command completion for a Stop Endpoint Command, we need to
* unlink any cancelled TDs from the ring. There are two ways to do that:
@@ -1907,8 +1927,9 @@ static void xhci_cleanup_halted_endpoint(struct xhci_hcd *xhci,
struct xhci_td *td,
enum xhci_ep_reset_type reset_type)
{
- struct xhci_command *command;
unsigned int slot_id = ep->vdev->slot_id;
+ int err;
+
/*
* Avoid resetting endpoint if link is inactive. Can cause host hang.
* Device will be reset soon to recover the link so don't do anything
@@ -1916,13 +1937,11 @@ static void xhci_cleanup_halted_endpoint(struct xhci_hcd *xhci,
if (ep->vdev->flags & VDEV_PORT_ERROR)
return;
- command = xhci_alloc_command(xhci, false, GFP_ATOMIC);
- if (!command)
- return;
-
ep->ep_state |= EP_HALTED;
- xhci_queue_reset_ep(xhci, command, slot_id, ep->ep_index, reset_type);
+ err = xhci_reset_halted_ep(xhci, slot_id, ep->ep_index, reset_type);
+ if (err)
+ return;
if (reset_type == EP_HARD_RESET) {
ep->ep_state |= EP_HARD_CLEAR_TOGGLE;