diff options
author | Elric Fu <elricfu1@gmail.com> | 2012-06-27 04:31:12 -0400 |
---|---|---|
committer | Sarah Sharp <sarah.a.sharp@linux.intel.com> | 2012-09-13 18:49:28 -0400 |
commit | b92cc66c047ff7cf587b318fe377061a353c120f (patch) | |
tree | c4c7e2f695ed5c796b2b7fcb88ddaaa5480f1d59 /drivers/usb/host | |
parent | c181bc5b5d5c79b71203cd10cef97f802fb6f9c1 (diff) |
xHCI: add aborting command ring function
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 <elricfu1@gmail.com>
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Tested-by: Miroslav Sabljic <miroslav.sabljic@avl.com>
Cc: stable@vger.kernel.org
Diffstat (limited to 'drivers/usb/host')
-rw-r--r-- | drivers/usb/host/xhci-mem.c | 7 | ||||
-rw-r--r-- | drivers/usb/host/xhci-ring.c | 108 | ||||
-rw-r--r-- | drivers/usb/host/xhci.c | 2 | ||||
-rw-r--r-- | drivers/usb/host/xhci.h | 12 |
4 files changed, 128 insertions, 1 deletions
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 77689bd64cac..487bc083dead 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c | |||
@@ -1772,6 +1772,7 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) | |||
1772 | { | 1772 | { |
1773 | struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller); | 1773 | struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller); |
1774 | struct dev_info *dev_info, *next; | 1774 | struct dev_info *dev_info, *next; |
1775 | struct xhci_cd *cur_cd, *next_cd; | ||
1775 | unsigned long flags; | 1776 | unsigned long flags; |
1776 | int size; | 1777 | int size; |
1777 | int i, j, num_ports; | 1778 | int i, j, num_ports; |
@@ -1795,6 +1796,11 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) | |||
1795 | xhci_ring_free(xhci, xhci->cmd_ring); | 1796 | xhci_ring_free(xhci, xhci->cmd_ring); |
1796 | xhci->cmd_ring = NULL; | 1797 | xhci->cmd_ring = NULL; |
1797 | xhci_dbg(xhci, "Freed command ring\n"); | 1798 | xhci_dbg(xhci, "Freed command ring\n"); |
1799 | list_for_each_entry_safe(cur_cd, next_cd, | ||
1800 | &xhci->cancel_cmd_list, cancel_cmd_list) { | ||
1801 | list_del(&cur_cd->cancel_cmd_list); | ||
1802 | kfree(cur_cd); | ||
1803 | } | ||
1798 | 1804 | ||
1799 | for (i = 1; i < MAX_HC_SLOTS; ++i) | 1805 | for (i = 1; i < MAX_HC_SLOTS; ++i) |
1800 | xhci_free_virt_device(xhci, i); | 1806 | xhci_free_virt_device(xhci, i); |
@@ -2340,6 +2346,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) | |||
2340 | xhci->cmd_ring = xhci_ring_alloc(xhci, 1, 1, TYPE_COMMAND, flags); | 2346 | xhci->cmd_ring = xhci_ring_alloc(xhci, 1, 1, TYPE_COMMAND, flags); |
2341 | if (!xhci->cmd_ring) | 2347 | if (!xhci->cmd_ring) |
2342 | goto fail; | 2348 | goto fail; |
2349 | INIT_LIST_HEAD(&xhci->cancel_cmd_list); | ||
2343 | xhci_dbg(xhci, "Allocated command ring at %p\n", xhci->cmd_ring); | 2350 | xhci_dbg(xhci, "Allocated command ring at %p\n", xhci->cmd_ring); |
2344 | xhci_dbg(xhci, "First segment DMA is 0x%llx\n", | 2351 | xhci_dbg(xhci, "First segment DMA is 0x%llx\n", |
2345 | (unsigned long long)xhci->cmd_ring->first_seg->dma); | 2352 | (unsigned long long)xhci->cmd_ring->first_seg->dma); |
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 75c857ec55b9..0b0e720521f8 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
@@ -289,6 +289,114 @@ void xhci_ring_cmd_db(struct xhci_hcd *xhci) | |||
289 | xhci_readl(xhci, &xhci->dba->doorbell[0]); | 289 | xhci_readl(xhci, &xhci->dba->doorbell[0]); |
290 | } | 290 | } |
291 | 291 | ||
292 | static int xhci_abort_cmd_ring(struct xhci_hcd *xhci) | ||
293 | { | ||
294 | u64 temp_64; | ||
295 | int ret; | ||
296 | |||
297 | xhci_dbg(xhci, "Abort command ring\n"); | ||
298 | |||
299 | if (!(xhci->cmd_ring_state & CMD_RING_STATE_RUNNING)) { | ||
300 | xhci_dbg(xhci, "The command ring isn't running, " | ||
301 | "Have the command ring been stopped?\n"); | ||
302 | return 0; | ||
303 | } | ||
304 | |||
305 | temp_64 = xhci_read_64(xhci, &xhci->op_regs->cmd_ring); | ||
306 | if (!(temp_64 & CMD_RING_RUNNING)) { | ||
307 | xhci_dbg(xhci, "Command ring had been stopped\n"); | ||
308 | return 0; | ||
309 | } | ||
310 | xhci->cmd_ring_state = CMD_RING_STATE_ABORTED; | ||
311 | xhci_write_64(xhci, temp_64 | CMD_RING_ABORT, | ||
312 | &xhci->op_regs->cmd_ring); | ||
313 | |||
314 | /* Section 4.6.1.2 of xHCI 1.0 spec says software should | ||
315 | * time the completion od all xHCI commands, including | ||
316 | * the Command Abort operation. If software doesn't see | ||
317 | * CRR negated in a timely manner (e.g. longer than 5 | ||
318 | * seconds), then it should assume that the there are | ||
319 | * larger problems with the xHC and assert HCRST. | ||
320 | */ | ||
321 | ret = handshake(xhci, &xhci->op_regs->cmd_ring, | ||
322 | CMD_RING_RUNNING, 0, 5 * 1000 * 1000); | ||
323 | if (ret < 0) { | ||
324 | xhci_err(xhci, "Stopped the command ring failed, " | ||
325 | "maybe the host is dead\n"); | ||
326 | xhci->xhc_state |= XHCI_STATE_DYING; | ||
327 | xhci_quiesce(xhci); | ||
328 | xhci_halt(xhci); | ||
329 | return -ESHUTDOWN; | ||
330 | } | ||
331 | |||
332 | return 0; | ||
333 | } | ||
334 | |||
335 | static int xhci_queue_cd(struct xhci_hcd *xhci, | ||
336 | struct xhci_command *command, | ||
337 | union xhci_trb *cmd_trb) | ||
338 | { | ||
339 | struct xhci_cd *cd; | ||
340 | cd = kzalloc(sizeof(struct xhci_cd), GFP_ATOMIC); | ||
341 | if (!cd) | ||
342 | return -ENOMEM; | ||
343 | INIT_LIST_HEAD(&cd->cancel_cmd_list); | ||
344 | |||
345 | cd->command = command; | ||
346 | cd->cmd_trb = cmd_trb; | ||
347 | list_add_tail(&cd->cancel_cmd_list, &xhci->cancel_cmd_list); | ||
348 | |||
349 | return 0; | ||
350 | } | ||
351 | |||
352 | /* | ||
353 | * Cancel the command which has issue. | ||
354 | * | ||
355 | * Some commands may hang due to waiting for acknowledgement from | ||
356 | * usb device. It is outside of the xHC's ability to control and | ||
357 | * will cause the command ring is blocked. When it occurs software | ||
358 | * should intervene to recover the command ring. | ||
359 | * See Section 4.6.1.1 and 4.6.1.2 | ||
360 | */ | ||
361 | int xhci_cancel_cmd(struct xhci_hcd *xhci, struct xhci_command *command, | ||
362 | union xhci_trb *cmd_trb) | ||
363 | { | ||
364 | int retval = 0; | ||
365 | unsigned long flags; | ||
366 | |||
367 | spin_lock_irqsave(&xhci->lock, flags); | ||
368 | |||
369 | if (xhci->xhc_state & XHCI_STATE_DYING) { | ||
370 | xhci_warn(xhci, "Abort the command ring," | ||
371 | " but the xHCI is dead.\n"); | ||
372 | retval = -ESHUTDOWN; | ||
373 | goto fail; | ||
374 | } | ||
375 | |||
376 | /* queue the cmd desriptor to cancel_cmd_list */ | ||
377 | retval = xhci_queue_cd(xhci, command, cmd_trb); | ||
378 | if (retval) { | ||
379 | xhci_warn(xhci, "Queuing command descriptor failed.\n"); | ||
380 | goto fail; | ||
381 | } | ||
382 | |||
383 | /* abort command ring */ | ||
384 | retval = xhci_abort_cmd_ring(xhci); | ||
385 | if (retval) { | ||
386 | xhci_err(xhci, "Abort command ring failed\n"); | ||
387 | if (unlikely(retval == -ESHUTDOWN)) { | ||
388 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
389 | usb_hc_died(xhci_to_hcd(xhci)->primary_hcd); | ||
390 | xhci_dbg(xhci, "xHCI host controller is dead.\n"); | ||
391 | return retval; | ||
392 | } | ||
393 | } | ||
394 | |||
395 | fail: | ||
396 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
397 | return retval; | ||
398 | } | ||
399 | |||
292 | void xhci_ring_ep_doorbell(struct xhci_hcd *xhci, | 400 | void xhci_ring_ep_doorbell(struct xhci_hcd *xhci, |
293 | unsigned int slot_id, | 401 | unsigned int slot_id, |
294 | unsigned int ep_index, | 402 | unsigned int ep_index, |
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index f425356e71f2..3f0763d63598 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c | |||
@@ -51,7 +51,7 @@ MODULE_PARM_DESC(link_quirk, "Don't clear the chain bit on a link TRB"); | |||
51 | * handshake done). There are two failure modes: "usec" have passed (major | 51 | * handshake done). There are two failure modes: "usec" have passed (major |
52 | * hardware flakeout), or the register reads as all-ones (hardware removed). | 52 | * hardware flakeout), or the register reads as all-ones (hardware removed). |
53 | */ | 53 | */ |
54 | static int handshake(struct xhci_hcd *xhci, void __iomem *ptr, | 54 | int handshake(struct xhci_hcd *xhci, void __iomem *ptr, |
55 | u32 mask, u32 done, int usec) | 55 | u32 mask, u32 done, int usec) |
56 | { | 56 | { |
57 | u32 result; | 57 | u32 result; |
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 33f24e9fa766..fdfcebf342e8 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h | |||
@@ -1256,6 +1256,13 @@ struct xhci_td { | |||
1256 | union xhci_trb *last_trb; | 1256 | union xhci_trb *last_trb; |
1257 | }; | 1257 | }; |
1258 | 1258 | ||
1259 | /* command descriptor */ | ||
1260 | struct xhci_cd { | ||
1261 | struct list_head cancel_cmd_list; | ||
1262 | struct xhci_command *command; | ||
1263 | union xhci_trb *cmd_trb; | ||
1264 | }; | ||
1265 | |||
1259 | struct xhci_dequeue_state { | 1266 | struct xhci_dequeue_state { |
1260 | struct xhci_segment *new_deq_seg; | 1267 | struct xhci_segment *new_deq_seg; |
1261 | union xhci_trb *new_deq_ptr; | 1268 | union xhci_trb *new_deq_ptr; |
@@ -1425,6 +1432,7 @@ struct xhci_hcd { | |||
1425 | #define CMD_RING_STATE_RUNNING (1 << 0) | 1432 | #define CMD_RING_STATE_RUNNING (1 << 0) |
1426 | #define CMD_RING_STATE_ABORTED (1 << 1) | 1433 | #define CMD_RING_STATE_ABORTED (1 << 1) |
1427 | #define CMD_RING_STATE_STOPPED (1 << 2) | 1434 | #define CMD_RING_STATE_STOPPED (1 << 2) |
1435 | struct list_head cancel_cmd_list; | ||
1428 | unsigned int cmd_ring_reserved_trbs; | 1436 | unsigned int cmd_ring_reserved_trbs; |
1429 | struct xhci_ring *event_ring; | 1437 | struct xhci_ring *event_ring; |
1430 | struct xhci_erst erst; | 1438 | struct xhci_erst erst; |
@@ -1702,6 +1710,8 @@ static inline void xhci_unregister_plat(void) | |||
1702 | 1710 | ||
1703 | /* xHCI host controller glue */ | 1711 | /* xHCI host controller glue */ |
1704 | typedef void (*xhci_get_quirks_t)(struct device *, struct xhci_hcd *); | 1712 | typedef void (*xhci_get_quirks_t)(struct device *, struct xhci_hcd *); |
1713 | int handshake(struct xhci_hcd *xhci, void __iomem *ptr, | ||
1714 | u32 mask, u32 done, int usec); | ||
1705 | void xhci_quiesce(struct xhci_hcd *xhci); | 1715 | void xhci_quiesce(struct xhci_hcd *xhci); |
1706 | int xhci_halt(struct xhci_hcd *xhci); | 1716 | int xhci_halt(struct xhci_hcd *xhci); |
1707 | int xhci_reset(struct xhci_hcd *xhci); | 1717 | int xhci_reset(struct xhci_hcd *xhci); |
@@ -1792,6 +1802,8 @@ void xhci_queue_config_ep_quirk(struct xhci_hcd *xhci, | |||
1792 | unsigned int slot_id, unsigned int ep_index, | 1802 | unsigned int slot_id, unsigned int ep_index, |
1793 | struct xhci_dequeue_state *deq_state); | 1803 | struct xhci_dequeue_state *deq_state); |
1794 | void xhci_stop_endpoint_command_watchdog(unsigned long arg); | 1804 | void xhci_stop_endpoint_command_watchdog(unsigned long arg); |
1805 | int xhci_cancel_cmd(struct xhci_hcd *xhci, struct xhci_command *command, | ||
1806 | union xhci_trb *cmd_trb); | ||
1795 | void xhci_ring_ep_doorbell(struct xhci_hcd *xhci, unsigned int slot_id, | 1807 | void xhci_ring_ep_doorbell(struct xhci_hcd *xhci, unsigned int slot_id, |
1796 | unsigned int ep_index, unsigned int stream_id); | 1808 | unsigned int ep_index, unsigned int stream_id); |
1797 | 1809 | ||