diff options
author | Mathias Nyman <mathias.nyman@linux.intel.com> | 2021-01-29 15:00:32 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2021-01-29 14:16:51 +0100 |
commit | d8ac95001bea683d2088acb3e61613a27b8d2d5f (patch) | |
tree | 7c609683cf15b34ad15b83042123c10d91760cfa /drivers/usb | |
parent | b05dadb28f8779898229e399c21e5192c24beaf2 (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.c | 31 |
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; |