From: Greg Kroah-Hartman Date: Thu, 25 Oct 2012 23:49:02 +0000 (-0700) Subject: 3.0-stable patches X-Git-Tag: v3.0.49~25 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b9369ae0e95ec747dc46478cfc6c268ddc069ec3;p=thirdparty%2Fkernel%2Fstable-queue.git 3.0-stable patches added patches: xhci-add-aborting-command-ring-function.patch xhci-add-cmd_ring_state.patch xhci-cancel-command-after-command-timeout.patch xhci-handle-command-after-aborting-the-command-ring.patch --- diff --git a/queue-3.0/series b/queue-3.0/series index d5568adc37a..0dc88cad85b 100644 --- a/queue-3.0/series +++ b/queue-3.0/series @@ -25,3 +25,7 @@ sparc64-like-x86-we-should-check-current-mm-during-perf-backtrace-generation.pat sparc64-fix-bit-twiddling-in-sparc_pmu_enable_event.patch sparc64-do-not-clobber-personality-flags-in-sys_sparc64_personality.patch sparc64-be-less-verbose-during-vmemmap-population.patch +xhci-add-cmd_ring_state.patch +xhci-add-aborting-command-ring-function.patch +xhci-cancel-command-after-command-timeout.patch +xhci-handle-command-after-aborting-the-command-ring.patch diff --git a/queue-3.0/xhci-add-aborting-command-ring-function.patch b/queue-3.0/xhci-add-aborting-command-ring-function.patch new file mode 100644 index 00000000000..44415986dee --- /dev/null +++ b/queue-3.0/xhci-add-aborting-command-ring-function.patch @@ -0,0 +1,241 @@ +From b92cc66c047ff7cf587b318fe377061a353c120f Mon Sep 17 00:00:00 2001 +From: Elric Fu +Date: Wed, 27 Jun 2012 16:31:12 +0800 +Subject: xHCI: add aborting command ring function + +From: Elric Fu + +commit b92cc66c047ff7cf587b318fe377061a353c120f upstream. + +Software have to abort command ring and cancel command +when a command is failed or hang. Otherwise, the command +ring will hang up and can't handle the others. An example +of a command that may hang is the Address Device Command, +because waiting for a SET_ADDRESS request to be acknowledged +by a USB device is outside of the xHC's ability to control. + +To cancel a command, software will initialize a command +descriptor for the cancel command, and add it into a +cancel_cmd_list of xhci. + +Sarah: Fixed missing newline on "Have the command ring been stopped?" +debugging statement. + +This patch should be backported to kernels as old as 3.0, that contain +the commit 7ed603ecf8b68ab81f4c83097d3063d43ec73bb8 "xhci: Add an +assertion to check for virt_dev=0 bug." That commit papers over a NULL +pointer dereference, and this patch fixes the underlying issue that +caused the NULL pointer dereference. + +Signed-off-by: Elric Fu +Signed-off-by: Sarah Sharp +Tested-by: Miroslav Sabljic +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci-mem.c | 7 ++ + drivers/usb/host/xhci-ring.c | 108 +++++++++++++++++++++++++++++++++++++++++++ + drivers/usb/host/xhci.c | 2 + drivers/usb/host/xhci.h | 12 ++++ + 4 files changed, 128 insertions(+), 1 deletion(-) + +--- a/drivers/usb/host/xhci-mem.c ++++ b/drivers/usb/host/xhci-mem.c +@@ -1505,6 +1505,7 @@ void xhci_free_command(struct xhci_hcd * + void xhci_mem_cleanup(struct xhci_hcd *xhci) + { + struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller); ++ struct xhci_cd *cur_cd, *next_cd; + int size; + int i; + +@@ -1525,6 +1526,11 @@ void xhci_mem_cleanup(struct xhci_hcd *x + xhci_ring_free(xhci, xhci->cmd_ring); + xhci->cmd_ring = NULL; + xhci_dbg(xhci, "Freed command ring\n"); ++ list_for_each_entry_safe(cur_cd, next_cd, ++ &xhci->cancel_cmd_list, cancel_cmd_list) { ++ list_del(&cur_cd->cancel_cmd_list); ++ kfree(cur_cd); ++ } + + for (i = 1; i < MAX_HC_SLOTS; ++i) + xhci_free_virt_device(xhci, i); +@@ -2014,6 +2020,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, + xhci->cmd_ring = xhci_ring_alloc(xhci, 1, true, false, flags); + if (!xhci->cmd_ring) + goto fail; ++ INIT_LIST_HEAD(&xhci->cancel_cmd_list); + xhci_dbg(xhci, "Allocated command ring at %p\n", xhci->cmd_ring); + xhci_dbg(xhci, "First segment DMA is 0x%llx\n", + (unsigned long long)xhci->cmd_ring->first_seg->dma); +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -320,6 +320,114 @@ void xhci_ring_cmd_db(struct xhci_hcd *x + xhci_readl(xhci, &xhci->dba->doorbell[0]); + } + ++static int xhci_abort_cmd_ring(struct xhci_hcd *xhci) ++{ ++ u64 temp_64; ++ int ret; ++ ++ xhci_dbg(xhci, "Abort command ring\n"); ++ ++ if (!(xhci->cmd_ring_state & CMD_RING_STATE_RUNNING)) { ++ xhci_dbg(xhci, "The command ring isn't running, " ++ "Have the command ring been stopped?\n"); ++ return 0; ++ } ++ ++ temp_64 = xhci_read_64(xhci, &xhci->op_regs->cmd_ring); ++ if (!(temp_64 & CMD_RING_RUNNING)) { ++ xhci_dbg(xhci, "Command ring had been stopped\n"); ++ return 0; ++ } ++ xhci->cmd_ring_state = CMD_RING_STATE_ABORTED; ++ xhci_write_64(xhci, temp_64 | CMD_RING_ABORT, ++ &xhci->op_regs->cmd_ring); ++ ++ /* Section 4.6.1.2 of xHCI 1.0 spec says software should ++ * time the completion od all xHCI commands, including ++ * the Command Abort operation. If software doesn't see ++ * CRR negated in a timely manner (e.g. longer than 5 ++ * seconds), then it should assume that the there are ++ * larger problems with the xHC and assert HCRST. ++ */ ++ ret = handshake(xhci, &xhci->op_regs->cmd_ring, ++ CMD_RING_RUNNING, 0, 5 * 1000 * 1000); ++ if (ret < 0) { ++ xhci_err(xhci, "Stopped the command ring failed, " ++ "maybe the host is dead\n"); ++ xhci->xhc_state |= XHCI_STATE_DYING; ++ xhci_quiesce(xhci); ++ xhci_halt(xhci); ++ return -ESHUTDOWN; ++ } ++ ++ return 0; ++} ++ ++static int xhci_queue_cd(struct xhci_hcd *xhci, ++ struct xhci_command *command, ++ union xhci_trb *cmd_trb) ++{ ++ struct xhci_cd *cd; ++ cd = kzalloc(sizeof(struct xhci_cd), GFP_ATOMIC); ++ if (!cd) ++ return -ENOMEM; ++ INIT_LIST_HEAD(&cd->cancel_cmd_list); ++ ++ cd->command = command; ++ cd->cmd_trb = cmd_trb; ++ list_add_tail(&cd->cancel_cmd_list, &xhci->cancel_cmd_list); ++ ++ return 0; ++} ++ ++/* ++ * Cancel the command which has issue. ++ * ++ * Some commands may hang due to waiting for acknowledgement from ++ * usb device. It is outside of the xHC's ability to control and ++ * will cause the command ring is blocked. When it occurs software ++ * should intervene to recover the command ring. ++ * See Section 4.6.1.1 and 4.6.1.2 ++ */ ++int xhci_cancel_cmd(struct xhci_hcd *xhci, struct xhci_command *command, ++ union xhci_trb *cmd_trb) ++{ ++ int retval = 0; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&xhci->lock, flags); ++ ++ if (xhci->xhc_state & XHCI_STATE_DYING) { ++ xhci_warn(xhci, "Abort the command ring," ++ " but the xHCI is dead.\n"); ++ retval = -ESHUTDOWN; ++ goto fail; ++ } ++ ++ /* queue the cmd desriptor to cancel_cmd_list */ ++ retval = xhci_queue_cd(xhci, command, cmd_trb); ++ if (retval) { ++ xhci_warn(xhci, "Queuing command descriptor failed.\n"); ++ goto fail; ++ } ++ ++ /* abort command ring */ ++ retval = xhci_abort_cmd_ring(xhci); ++ if (retval) { ++ xhci_err(xhci, "Abort command ring failed\n"); ++ if (unlikely(retval == -ESHUTDOWN)) { ++ spin_unlock_irqrestore(&xhci->lock, flags); ++ usb_hc_died(xhci_to_hcd(xhci)->primary_hcd); ++ xhci_dbg(xhci, "xHCI host controller is dead.\n"); ++ return retval; ++ } ++ } ++ ++fail: ++ spin_unlock_irqrestore(&xhci->lock, flags); ++ return retval; ++} ++ + void xhci_ring_ep_doorbell(struct xhci_hcd *xhci, + unsigned int slot_id, + unsigned int ep_index, +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -51,7 +51,7 @@ MODULE_PARM_DESC(link_quirk, "Don't clea + * handshake done). There are two failure modes: "usec" have passed (major + * hardware flakeout), or the register reads as all-ones (hardware removed). + */ +-static int handshake(struct xhci_hcd *xhci, void __iomem *ptr, ++int handshake(struct xhci_hcd *xhci, void __iomem *ptr, + u32 mask, u32 done, int usec) + { + u32 result; +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -1111,6 +1111,13 @@ struct xhci_td { + union xhci_trb *last_trb; + }; + ++/* command descriptor */ ++struct xhci_cd { ++ struct list_head cancel_cmd_list; ++ struct xhci_command *command; ++ union xhci_trb *cmd_trb; ++}; ++ + struct xhci_dequeue_state { + struct xhci_segment *new_deq_seg; + union xhci_trb *new_deq_ptr; +@@ -1256,6 +1263,7 @@ struct xhci_hcd { + #define CMD_RING_STATE_RUNNING (1 << 0) + #define CMD_RING_STATE_ABORTED (1 << 1) + #define CMD_RING_STATE_STOPPED (1 << 2) ++ struct list_head cancel_cmd_list; + unsigned int cmd_ring_reserved_trbs; + struct xhci_ring *event_ring; + struct xhci_erst erst; +@@ -1490,6 +1498,8 @@ void xhci_unregister_pci(void); + #endif + + /* xHCI host controller glue */ ++int handshake(struct xhci_hcd *xhci, void __iomem *ptr, ++ u32 mask, u32 done, int usec); + void xhci_quiesce(struct xhci_hcd *xhci); + int xhci_halt(struct xhci_hcd *xhci); + int xhci_reset(struct xhci_hcd *xhci); +@@ -1572,6 +1582,8 @@ void xhci_queue_config_ep_quirk(struct x + unsigned int slot_id, unsigned int ep_index, + struct xhci_dequeue_state *deq_state); + void xhci_stop_endpoint_command_watchdog(unsigned long arg); ++int xhci_cancel_cmd(struct xhci_hcd *xhci, struct xhci_command *command, ++ union xhci_trb *cmd_trb); + void xhci_ring_ep_doorbell(struct xhci_hcd *xhci, unsigned int slot_id, + unsigned int ep_index, unsigned int stream_id); + diff --git a/queue-3.0/xhci-add-cmd_ring_state.patch b/queue-3.0/xhci-add-cmd_ring_state.patch new file mode 100644 index 00000000000..e13cec4da67 --- /dev/null +++ b/queue-3.0/xhci-add-cmd_ring_state.patch @@ -0,0 +1,79 @@ +From c181bc5b5d5c79b71203cd10cef97f802fb6f9c1 Mon Sep 17 00:00:00 2001 +From: Elric Fu +Date: Wed, 27 Jun 2012 16:30:57 +0800 +Subject: xHCI: add cmd_ring_state + +From: Elric Fu + +commit c181bc5b5d5c79b71203cd10cef97f802fb6f9c1 upstream. + +Adding cmd_ring_state for command ring. It helps to verify +the current command ring state for controlling the command +ring operations. + +This patch should be backported to kernels as old as 3.0. The commit +7ed603ecf8b68ab81f4c83097d3063d43ec73bb8 "xhci: Add an assertion to +check for virt_dev=0 bug." papers over the NULL pointer dereference that +I now believe is related to a timed out Set Address command. This (and +the four patches that follow it) contain the real fix that also allows +VIA USB 3.0 hubs to consistently re-enumerate during the plug/unplug +stress tests. + +Signed-off-by: Elric Fu +Signed-off-by: Sarah Sharp +Tested-by: Miroslav Sabljic +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci-ring.c | 3 +++ + drivers/usb/host/xhci.c | 5 ++++- + drivers/usb/host/xhci.h | 4 ++++ + 3 files changed, 11 insertions(+), 1 deletion(-) + +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -311,6 +311,9 @@ static int room_on_ring(struct xhci_hcd + /* Ring the host controller doorbell after placing a command on the ring */ + void xhci_ring_cmd_db(struct xhci_hcd *xhci) + { ++ if (!(xhci->cmd_ring_state & CMD_RING_STATE_RUNNING)) ++ return; ++ + xhci_dbg(xhci, "// Ding dong!\n"); + xhci_writel(xhci, DB_VALUE_HOST, &xhci->dba->doorbell[0]); + /* Flush PCI posted writes */ +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -104,8 +104,10 @@ int xhci_halt(struct xhci_hcd *xhci) + + ret = handshake(xhci, &xhci->op_regs->status, + STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC); +- if (!ret) ++ if (!ret) { + xhci->xhc_state |= XHCI_STATE_HALTED; ++ xhci->cmd_ring_state = CMD_RING_STATE_STOPPED; ++ } + return ret; + } + +@@ -390,6 +392,7 @@ static int xhci_run_finished(struct xhci + return -ENODEV; + } + xhci->shared_hcd->state = HC_STATE_RUNNING; ++ xhci->cmd_ring_state = CMD_RING_STATE_RUNNING; + + if (xhci->quirks & XHCI_NEC_HOST) + xhci_ring_cmd_db(xhci); +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -1252,6 +1252,10 @@ struct xhci_hcd { + /* data structures */ + struct xhci_device_context_array *dcbaa; + struct xhci_ring *cmd_ring; ++ unsigned int cmd_ring_state; ++#define CMD_RING_STATE_RUNNING (1 << 0) ++#define CMD_RING_STATE_ABORTED (1 << 1) ++#define CMD_RING_STATE_STOPPED (1 << 2) + unsigned int cmd_ring_reserved_trbs; + struct xhci_ring *event_ring; + struct xhci_erst erst; diff --git a/queue-3.0/xhci-cancel-command-after-command-timeout.patch b/queue-3.0/xhci-cancel-command-after-command-timeout.patch new file mode 100644 index 00000000000..e024bc7973b --- /dev/null +++ b/queue-3.0/xhci-cancel-command-after-command-timeout.patch @@ -0,0 +1,142 @@ +From 6e4468b9a0793dfb53eb80d9fe52c739b13b27fd Mon Sep 17 00:00:00 2001 +From: Elric Fu +Date: Wed, 27 Jun 2012 16:31:52 +0800 +Subject: xHCI: cancel command after command timeout + +From: Elric Fu + +commit 6e4468b9a0793dfb53eb80d9fe52c739b13b27fd upstream. + +The patch is used to cancel command when the command isn't +acknowledged and a timeout occurs. + +This patch should be backported to kernels as old as 3.0, that contain +the commit 7ed603ecf8b68ab81f4c83097d3063d43ec73bb8 "xhci: Add an +assertion to check for virt_dev=0 bug." That commit papers over a NULL +pointer dereference, and this patch fixes the underlying issue that +caused the NULL pointer dereference. + +Signed-off-by: Elric Fu +Signed-off-by: Sarah Sharp +Tested-by: Miroslav Sabljic +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci.c | 26 +++++++++++++++++++------- + drivers/usb/host/xhci.h | 3 +++ + 2 files changed, 22 insertions(+), 7 deletions(-) + +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -1778,6 +1778,7 @@ static int xhci_configure_endpoint(struc + struct completion *cmd_completion; + u32 *cmd_status; + struct xhci_virt_device *virt_dev; ++ union xhci_trb *cmd_trb; + + spin_lock_irqsave(&xhci->lock, flags); + virt_dev = xhci->devs[udev->slot_id]; +@@ -1820,6 +1821,7 @@ static int xhci_configure_endpoint(struc + } + init_completion(cmd_completion); + ++ cmd_trb = xhci->cmd_ring->dequeue; + if (!ctx_change) + ret = xhci_queue_configure_endpoint(xhci, in_ctx->dma, + udev->slot_id, must_succeed); +@@ -1841,14 +1843,17 @@ static int xhci_configure_endpoint(struc + /* Wait for the configure endpoint command to complete */ + timeleft = wait_for_completion_interruptible_timeout( + cmd_completion, +- USB_CTRL_SET_TIMEOUT); ++ XHCI_CMD_DEFAULT_TIMEOUT); + if (timeleft <= 0) { + xhci_warn(xhci, "%s while waiting for %s command\n", + timeleft == 0 ? "Timeout" : "Signal", + ctx_change == 0 ? + "configure endpoint" : + "evaluate context"); +- /* FIXME cancel the configure endpoint command */ ++ /* cancel the configure endpoint command */ ++ ret = xhci_cancel_cmd(xhci, command, cmd_trb); ++ if (ret < 0) ++ return ret; + return -ETIME; + } + +@@ -2781,8 +2786,10 @@ int xhci_alloc_dev(struct usb_hcd *hcd, + unsigned long flags; + int timeleft; + int ret; ++ union xhci_trb *cmd_trb; + + spin_lock_irqsave(&xhci->lock, flags); ++ cmd_trb = xhci->cmd_ring->dequeue; + ret = xhci_queue_slot_control(xhci, TRB_ENABLE_SLOT, 0); + if (ret) { + spin_unlock_irqrestore(&xhci->lock, flags); +@@ -2794,12 +2801,12 @@ int xhci_alloc_dev(struct usb_hcd *hcd, + + /* XXX: how much time for xHC slot assignment? */ + timeleft = wait_for_completion_interruptible_timeout(&xhci->addr_dev, +- USB_CTRL_SET_TIMEOUT); ++ XHCI_CMD_DEFAULT_TIMEOUT); + if (timeleft <= 0) { + xhci_warn(xhci, "%s while waiting for a slot\n", + timeleft == 0 ? "Timeout" : "Signal"); +- /* FIXME cancel the enable slot request */ +- return 0; ++ /* cancel the enable slot request */ ++ return xhci_cancel_cmd(xhci, NULL, cmd_trb); + } + + if (!xhci->slot_id) { +@@ -2860,6 +2867,7 @@ int xhci_address_device(struct usb_hcd * + struct xhci_slot_ctx *slot_ctx; + struct xhci_input_control_ctx *ctrl_ctx; + u64 temp_64; ++ union xhci_trb *cmd_trb; + + if (!udev->slot_id) { + xhci_dbg(xhci, "Bad Slot ID %d\n", udev->slot_id); +@@ -2898,6 +2906,7 @@ int xhci_address_device(struct usb_hcd * + xhci_dbg_ctx(xhci, virt_dev->in_ctx, 2); + + spin_lock_irqsave(&xhci->lock, flags); ++ cmd_trb = xhci->cmd_ring->dequeue; + ret = xhci_queue_address_device(xhci, virt_dev->in_ctx->dma, + udev->slot_id); + if (ret) { +@@ -2910,7 +2919,7 @@ int xhci_address_device(struct usb_hcd * + + /* ctrl tx can take up to 5 sec; XXX: need more time for xHC? */ + timeleft = wait_for_completion_interruptible_timeout(&xhci->addr_dev, +- USB_CTRL_SET_TIMEOUT); ++ XHCI_CMD_DEFAULT_TIMEOUT); + /* FIXME: From section 4.3.4: "Software shall be responsible for timing + * the SetAddress() "recovery interval" required by USB and aborting the + * command on a timeout. +@@ -2918,7 +2927,10 @@ int xhci_address_device(struct usb_hcd * + if (timeleft <= 0) { + xhci_warn(xhci, "%s while waiting for a slot\n", + timeleft == 0 ? "Timeout" : "Signal"); +- /* FIXME cancel the address device command */ ++ /* cancel the address device command */ ++ ret = xhci_cancel_cmd(xhci, NULL, cmd_trb); ++ if (ret < 0) ++ return ret; + return -ETIME; + } + +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -1111,6 +1111,9 @@ struct xhci_td { + union xhci_trb *last_trb; + }; + ++/* xHCI command default timeout value */ ++#define XHCI_CMD_DEFAULT_TIMEOUT (5 * HZ) ++ + /* command descriptor */ + struct xhci_cd { + struct list_head cancel_cmd_list; diff --git a/queue-3.0/xhci-handle-command-after-aborting-the-command-ring.patch b/queue-3.0/xhci-handle-command-after-aborting-the-command-ring.patch new file mode 100644 index 00000000000..20017566c8f --- /dev/null +++ b/queue-3.0/xhci-handle-command-after-aborting-the-command-ring.patch @@ -0,0 +1,255 @@ +From b63f4053cc8aa22a98e3f9a97845afe6c15d0a0d Mon Sep 17 00:00:00 2001 +From: Elric Fu +Date: Wed, 27 Jun 2012 16:55:43 +0800 +Subject: xHCI: handle command after aborting the command ring + +From: Elric Fu + +commit b63f4053cc8aa22a98e3f9a97845afe6c15d0a0d upstream. + +According to xHCI spec section 4.6.1.1 and section 4.6.1.2, +after aborting a command on the command ring, xHC will +generate a command completion event with its completion +code set to Command Ring Stopped at least. If a command is +currently executing at the time of aborting a command, xHC +also generate a command completion event with its completion +code set to Command Abort. When the command ring is stopped, +software may remove, add, or rearrage Command Descriptors. + +To cancel a command, software will initialize a command +descriptor for the cancel command, and add it into a +cancel_cmd_list of xhci. When the command ring is stopped, +software will find the command trbs described by command +descriptors in cancel_cmd_list and modify it to No Op +command. If software can't find the matched trbs, we can +think it had been finished. + +This patch should be backported to kernels as old as 3.0, that contain +the commit 7ed603ecf8b68ab81f4c83097d3063d43ec73bb8 "xhci: Add an +assertion to check for virt_dev=0 bug." That commit papers over a NULL +pointer dereference, and this patch fixes the underlying issue that +caused the NULL pointer dereference. + +Note from Sarah: The TRB_TYPE_LINK_LE32 macro is not in the 3.0 stable +kernel, so I added it to this patch. + +Signed-off-by: Elric Fu +Signed-off-by: Sarah Sharp +Tested-by: Miroslav Sabljic +Signed-off-by: Greg Kroah-Hartman + + +--- + drivers/usb/host/xhci-ring.c | 171 +++++++++++++++++++++++++++++++++++++++++-- + drivers/usb/host/xhci.h | 3 + 2 files changed, 168 insertions(+), 6 deletions(-) + +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -1157,6 +1157,20 @@ static void handle_reset_ep_completion(s + } + } + ++/* Complete the command and detele it from the devcie's command queue. ++ */ ++static void xhci_complete_cmd_in_cmd_wait_list(struct xhci_hcd *xhci, ++ struct xhci_command *command, u32 status) ++{ ++ command->status = status; ++ list_del(&command->cmd_list); ++ if (command->completion) ++ complete(command->completion); ++ else ++ xhci_free_command(xhci, command); ++} ++ ++ + /* Check to see if a command in the device's command queue matches this one. + * Signal the completion or free the command, and return 1. Return 0 if the + * completed command isn't at the head of the command list. +@@ -1175,15 +1189,144 @@ static int handle_cmd_in_cmd_wait_list(s + if (xhci->cmd_ring->dequeue != command->command_trb) + return 0; + +- command->status = GET_COMP_CODE(le32_to_cpu(event->status)); +- list_del(&command->cmd_list); +- if (command->completion) +- complete(command->completion); +- else +- xhci_free_command(xhci, command); ++ xhci_complete_cmd_in_cmd_wait_list(xhci, command, ++ GET_COMP_CODE(le32_to_cpu(event->status))); + return 1; + } + ++/* ++ * Finding the command trb need to be cancelled and modifying it to ++ * NO OP command. And if the command is in device's command wait ++ * list, finishing and freeing it. ++ * ++ * If we can't find the command trb, we think it had already been ++ * executed. ++ */ ++static void xhci_cmd_to_noop(struct xhci_hcd *xhci, struct xhci_cd *cur_cd) ++{ ++ struct xhci_segment *cur_seg; ++ union xhci_trb *cmd_trb; ++ u32 cycle_state; ++ ++ if (xhci->cmd_ring->dequeue == xhci->cmd_ring->enqueue) ++ return; ++ ++ /* find the current segment of command ring */ ++ cur_seg = find_trb_seg(xhci->cmd_ring->first_seg, ++ xhci->cmd_ring->dequeue, &cycle_state); ++ ++ /* find the command trb matched by cd from command ring */ ++ for (cmd_trb = xhci->cmd_ring->dequeue; ++ cmd_trb != xhci->cmd_ring->enqueue; ++ next_trb(xhci, xhci->cmd_ring, &cur_seg, &cmd_trb)) { ++ /* If the trb is link trb, continue */ ++ if (TRB_TYPE_LINK_LE32(cmd_trb->generic.field[3])) ++ continue; ++ ++ if (cur_cd->cmd_trb == cmd_trb) { ++ ++ /* If the command in device's command list, we should ++ * finish it and free the command structure. ++ */ ++ if (cur_cd->command) ++ xhci_complete_cmd_in_cmd_wait_list(xhci, ++ cur_cd->command, COMP_CMD_STOP); ++ ++ /* get cycle state from the origin command trb */ ++ cycle_state = le32_to_cpu(cmd_trb->generic.field[3]) ++ & TRB_CYCLE; ++ ++ /* modify the command trb to NO OP command */ ++ cmd_trb->generic.field[0] = 0; ++ cmd_trb->generic.field[1] = 0; ++ cmd_trb->generic.field[2] = 0; ++ cmd_trb->generic.field[3] = cpu_to_le32( ++ TRB_TYPE(TRB_CMD_NOOP) | cycle_state); ++ break; ++ } ++ } ++} ++ ++static void xhci_cancel_cmd_in_cd_list(struct xhci_hcd *xhci) ++{ ++ struct xhci_cd *cur_cd, *next_cd; ++ ++ if (list_empty(&xhci->cancel_cmd_list)) ++ return; ++ ++ list_for_each_entry_safe(cur_cd, next_cd, ++ &xhci->cancel_cmd_list, cancel_cmd_list) { ++ xhci_cmd_to_noop(xhci, cur_cd); ++ list_del(&cur_cd->cancel_cmd_list); ++ kfree(cur_cd); ++ } ++} ++ ++/* ++ * traversing the cancel_cmd_list. If the command descriptor according ++ * to cmd_trb is found, the function free it and return 1, otherwise ++ * return 0. ++ */ ++static int xhci_search_cmd_trb_in_cd_list(struct xhci_hcd *xhci, ++ union xhci_trb *cmd_trb) ++{ ++ struct xhci_cd *cur_cd, *next_cd; ++ ++ if (list_empty(&xhci->cancel_cmd_list)) ++ return 0; ++ ++ list_for_each_entry_safe(cur_cd, next_cd, ++ &xhci->cancel_cmd_list, cancel_cmd_list) { ++ if (cur_cd->cmd_trb == cmd_trb) { ++ if (cur_cd->command) ++ xhci_complete_cmd_in_cmd_wait_list(xhci, ++ cur_cd->command, COMP_CMD_STOP); ++ list_del(&cur_cd->cancel_cmd_list); ++ kfree(cur_cd); ++ return 1; ++ } ++ } ++ ++ return 0; ++} ++ ++/* ++ * If the cmd_trb_comp_code is COMP_CMD_ABORT, we just check whether the ++ * trb pointed by the command ring dequeue pointer is the trb we want to ++ * cancel or not. And if the cmd_trb_comp_code is COMP_CMD_STOP, we will ++ * traverse the cancel_cmd_list to trun the all of the commands according ++ * to command descriptor to NO-OP trb. ++ */ ++static int handle_stopped_cmd_ring(struct xhci_hcd *xhci, ++ int cmd_trb_comp_code) ++{ ++ int cur_trb_is_good = 0; ++ ++ /* Searching the cmd trb pointed by the command ring dequeue ++ * pointer in command descriptor list. If it is found, free it. ++ */ ++ cur_trb_is_good = xhci_search_cmd_trb_in_cd_list(xhci, ++ xhci->cmd_ring->dequeue); ++ ++ if (cmd_trb_comp_code == COMP_CMD_ABORT) ++ xhci->cmd_ring_state = CMD_RING_STATE_STOPPED; ++ else if (cmd_trb_comp_code == COMP_CMD_STOP) { ++ /* traversing the cancel_cmd_list and canceling ++ * the command according to command descriptor ++ */ ++ xhci_cancel_cmd_in_cd_list(xhci); ++ ++ xhci->cmd_ring_state = CMD_RING_STATE_RUNNING; ++ /* ++ * ring command ring doorbell again to restart the ++ * command ring ++ */ ++ if (xhci->cmd_ring->dequeue != xhci->cmd_ring->enqueue) ++ xhci_ring_cmd_db(xhci); ++ } ++ return cur_trb_is_good; ++} ++ + static void handle_cmd_completion(struct xhci_hcd *xhci, + struct xhci_event_cmd *event) + { +@@ -1209,6 +1352,22 @@ static void handle_cmd_completion(struct + xhci->error_bitmask |= 1 << 5; + return; + } ++ ++ if ((GET_COMP_CODE(le32_to_cpu(event->status)) == COMP_CMD_ABORT) || ++ (GET_COMP_CODE(le32_to_cpu(event->status)) == COMP_CMD_STOP)) { ++ /* If the return value is 0, we think the trb pointed by ++ * command ring dequeue pointer is a good trb. The good ++ * trb means we don't want to cancel the trb, but it have ++ * been stopped by host. So we should handle it normally. ++ * Otherwise, driver should invoke inc_deq() and return. ++ */ ++ if (handle_stopped_cmd_ring(xhci, ++ GET_COMP_CODE(le32_to_cpu(event->status)))) { ++ inc_deq(xhci, xhci->cmd_ring, false); ++ return; ++ } ++ } ++ + switch (le32_to_cpu(xhci->cmd_ring->dequeue->generic.field[3]) + & TRB_TYPE_BITMASK) { + case TRB_TYPE(TRB_ENABLE_SLOT): +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -1070,6 +1070,9 @@ union xhci_trb { + #define TRB_MFINDEX_WRAP 39 + /* TRB IDs 40-47 reserved, 48-63 is vendor-defined */ + ++#define TRB_TYPE_LINK_LE32(x) (((x) & cpu_to_le32(TRB_TYPE_BITMASK)) == \ ++ cpu_to_le32(TRB_TYPE(TRB_LINK))) ++ + /* Nec vendor-specific command completion event. */ + #define TRB_NEC_CMD_COMP 48 + /* Get NEC firmware revision. */