提交 b90973b2 编写于 作者: M Mathias Nyman 提交者: sanglipeng

xhci: Add xhci_reset_halted_ep() helper function

stable inclusion
from stable-v5.10.164
commit 44c635c60f78a693b5e6ad80e18c7e9a97a0c4cd
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I7T7G4

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=44c635c60f78a693b5e6ad80e18c7e9a97a0c4cd

--------------------------------

[ Upstream commit d8ac9500 ]

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: NMathias Nyman <mathias.nyman@linux.intel.com>
Link: https://lore.kernel.org/r/20210129130044.206855-16-mathias.nyman@linux.intel.comSigned-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Stable-dep-of: a1575120 ("xhci: Prevent infinite loop in transaction errors recovery for streams")
Signed-off-by: NSasha Levin <sashal@kernel.org>
Signed-off-by: Nsanglipeng <sanglipeng1@jd.com>
上级 82904f38
...@@ -773,6 +773,26 @@ static void xhci_unmap_td_bounce_buffer(struct xhci_hcd *xhci, ...@@ -773,6 +773,26 @@ static void xhci_unmap_td_bounce_buffer(struct xhci_hcd *xhci,
seg->bounce_offs = 0; 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 * 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: * unlink any cancelled TDs from the ring. There are two ways to do that:
...@@ -1933,8 +1953,9 @@ static void xhci_cleanup_halted_endpoint(struct xhci_hcd *xhci, ...@@ -1933,8 +1953,9 @@ static void xhci_cleanup_halted_endpoint(struct xhci_hcd *xhci,
struct xhci_td *td, struct xhci_td *td,
enum xhci_ep_reset_type reset_type) enum xhci_ep_reset_type reset_type)
{ {
struct xhci_command *command;
unsigned int slot_id = ep->vdev->slot_id; unsigned int slot_id = ep->vdev->slot_id;
int err;
/* /*
* Avoid resetting endpoint if link is inactive. Can cause host hang. * 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 * Device will be reset soon to recover the link so don't do anything
...@@ -1942,13 +1963,11 @@ static void xhci_cleanup_halted_endpoint(struct xhci_hcd *xhci, ...@@ -1942,13 +1963,11 @@ static void xhci_cleanup_halted_endpoint(struct xhci_hcd *xhci,
if (ep->vdev->flags & VDEV_PORT_ERROR) if (ep->vdev->flags & VDEV_PORT_ERROR)
return; return;
command = xhci_alloc_command(xhci, false, GFP_ATOMIC);
if (!command)
return;
ep->ep_state |= EP_HALTED; 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) { if (reset_type == EP_HARD_RESET) {
ep->ep_state |= EP_HARD_CLEAR_TOGGLE; ep->ep_state |= EP_HARD_CLEAR_TOGGLE;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册