]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/2.6.36.2/xhci-fix-reset-device-and-configure-endpoint-commands.patch
fixes for 4.19
[thirdparty/kernel/stable-queue.git] / releases / 2.6.36.2 / xhci-fix-reset-device-and-configure-endpoint-commands.patch
CommitLineData
3d6a91bc
GKH
1From 7a3783efffc7bc2e702d774e47fad5b8e37e9ad1 Mon Sep 17 00:00:00 2001
2From: Paul Zimmerman <Paul.Zimmerman@synopsys.com>
3Date: Wed, 17 Nov 2010 16:26:50 -0800
4Subject: xhci: Fix reset-device and configure-endpoint commands
5
6From: Paul Zimmerman <Paul.Zimmerman@synopsys.com>
7
8commit 7a3783efffc7bc2e702d774e47fad5b8e37e9ad1 upstream.
9
10We have been having problems with the USB-IF Gold Tree tests when plugging
11and unplugging devices from the tree. I have seen that the reset-device
12and configure-endpoint commands, which are invoked from
13xhci_discover_or_reset_device() and xhci_configure_endpoint(), will sometimes
14time out.
15
16After much debugging, I determined that the commands themselves do not actually
17time out, but rather their completion events do not get delivered to the right
18place.
19
20This happens when the command ring has just wrapped around, and it's enqueue
21pointer is left pointing to the link TRB. xhci_discover_or_reset_device() and
22xhci_configure_endpoint() use the enqueue pointer directly as their command
23TRB pointer, without checking whether it's pointing to the link TRB.
24
25When the completion event arrives, if the command TRB is pointing to the link
26TRB, the check against the command ring dequeue pointer in
27handle_cmd_in_cmd_wait_list() fails, so the completion inside the command does
28not get signaled.
29
30The patch below fixes the timeout problem for me.
31
32This should be queued for the 2.6.35 and 2.6.36 stable trees.
33
34Signed-off-by: Paul Zimmerman <paulz@synopsys.com>
35Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
36Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
37
38---
39 drivers/usb/host/xhci.c | 18 ++++++++++++++++++
40 1 file changed, 18 insertions(+)
41
42--- a/drivers/usb/host/xhci.c
43+++ b/drivers/usb/host/xhci.c
44@@ -1284,6 +1284,15 @@ static int xhci_configure_endpoint(struc
45 cmd_completion = command->completion;
46 cmd_status = &command->status;
47 command->command_trb = xhci->cmd_ring->enqueue;
48+
49+ /* Enqueue pointer can be left pointing to the link TRB,
50+ * we must handle that
51+ */
52+ if ((command->command_trb->link.control & TRB_TYPE_BITMASK)
53+ == TRB_TYPE(TRB_LINK))
54+ command->command_trb =
55+ xhci->cmd_ring->enq_seg->next->trbs;
56+
57 list_add_tail(&command->cmd_list, &virt_dev->cmd_list);
58 } else {
59 in_ctx = virt_dev->in_ctx;
60@@ -1993,6 +2002,15 @@ int xhci_reset_device(struct usb_hcd *hc
61 /* Attempt to submit the Reset Device command to the command ring */
62 spin_lock_irqsave(&xhci->lock, flags);
63 reset_device_cmd->command_trb = xhci->cmd_ring->enqueue;
64+
65+ /* Enqueue pointer can be left pointing to the link TRB,
66+ * we must handle that
67+ */
68+ if ((reset_device_cmd->command_trb->link.control & TRB_TYPE_BITMASK)
69+ == TRB_TYPE(TRB_LINK))
70+ reset_device_cmd->command_trb =
71+ xhci->cmd_ring->enq_seg->next->trbs;
72+
73 list_add_tail(&reset_device_cmd->cmd_list, &virt_dev->cmd_list);
74 ret = xhci_queue_reset_device(xhci, slot_id);
75 if (ret) {