usb: xhci: Issue stop EP command only when the EP state is running
on AMD platforms with SNPS 3.1 USB controller if stop endpoint command is issued the controller does not respond, when the EP is not in running state. HW completes the command execution and reports "Context State Error" completion code. This is as per the spec. However HW on receiving the second command additionally marks EP to Flow control state in HW which is RTL bug. This bug causes the HW not to respond to any further doorbells that are rung by the driver. This makes the EP to not functional anymore and causes gross functional failures. As a workaround, not to hit this problem, it's better to check the EP state and issue a stop EP command only when the EP is in running state. As a sidenote, even with this patch there is still a possibility of triggering the RTL bug if the context state races with the stop endpoint command as described in xHCI spec 4.6.9 [code simplification and reworded sidenote in commit message -Mathias] Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com> Signed-off-by: Nehal Shah <Nehal-bakulchandra.Shah@amd.com> Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
9da5a1092b
commit
28a2369f7d
@ -398,14 +398,21 @@ static int xhci_stop_device(struct xhci_hcd *xhci, int slot_id, int suspend)
|
||||
spin_lock_irqsave(&xhci->lock, flags);
|
||||
for (i = LAST_EP_INDEX; i > 0; i--) {
|
||||
if (virt_dev->eps[i].ring && virt_dev->eps[i].ring->dequeue) {
|
||||
struct xhci_ep_ctx *ep_ctx;
|
||||
struct xhci_command *command;
|
||||
|
||||
ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->out_ctx, i);
|
||||
|
||||
/* Check ep is running, required by AMD SNPS 3.1 xHC */
|
||||
if (GET_EP_CTX_STATE(ep_ctx) != EP_STATE_RUNNING)
|
||||
continue;
|
||||
|
||||
command = xhci_alloc_command(xhci, false, false,
|
||||
GFP_NOWAIT);
|
||||
if (!command) {
|
||||
spin_unlock_irqrestore(&xhci->lock, flags);
|
||||
xhci_free_command(xhci, cmd);
|
||||
return -ENOMEM;
|
||||
|
||||
}
|
||||
xhci_queue_stop_endpoint(xhci, command, slot_id, i,
|
||||
suspend);
|
||||
|
Loading…
Reference in New Issue
Block a user