Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

xhci: Reserve one command for USB3 LPM disable.

We want to do everything we can to ensure that USB 3.0 Link Power
Management (LPM) can be disabled when it is enabled. If LPM can't be
disabled, we can't suspend USB 3.0 devices, or reset them. To make sure
we can submit the command to disable LPM, allocate a command in the
xhci_hcd structure, and reserve one TRB on the command ring.

We only need one command per xHCI driver instance, because LPM is only
disabled or enabled while the USB core is holding the bandwidth_mutex
that is shared between the xHCI USB 2.0 and USB 3.0 roothubs. The
bandwidth_mutex will be held until the command completes, or times out.

Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>

+14
+12
drivers/usb/host/xhci-mem.c
··· 1815 1815 xhci->event_ring = NULL; 1816 1816 xhci_dbg(xhci, "Freed event ring\n"); 1817 1817 1818 + if (xhci->lpm_command) 1819 + xhci_free_command(xhci, xhci->lpm_command); 1818 1820 xhci->cmd_ring_reserved_trbs = 0; 1819 1821 if (xhci->cmd_ring) 1820 1822 xhci_ring_free(xhci, xhci->cmd_ring); ··· 2378 2376 xhci_dbg(xhci, "// Setting command ring address to 0x%x\n", val); 2379 2377 xhci_write_64(xhci, val_64, &xhci->op_regs->cmd_ring); 2380 2378 xhci_dbg_cmd_ptrs(xhci); 2379 + 2380 + xhci->lpm_command = xhci_alloc_command(xhci, true, true, flags); 2381 + if (!xhci->lpm_command) 2382 + goto fail; 2383 + 2384 + /* Reserve one command ring TRB for disabling LPM. 2385 + * Since the USB core grabs the shared usb_bus bandwidth mutex before 2386 + * disabling LPM, we only need to reserve one TRB for all devices. 2387 + */ 2388 + xhci->cmd_ring_reserved_trbs++; 2381 2389 2382 2390 val = xhci_readl(xhci, &xhci->cap_regs->db_off); 2383 2391 val &= DBOFF_MASK;
+2
drivers/usb/host/xhci.h
··· 1426 1426 /* slot enabling and address device helpers */ 1427 1427 struct completion addr_dev; 1428 1428 int slot_id; 1429 + /* For USB 3.0 LPM enable/disable. */ 1430 + struct xhci_command *lpm_command; 1429 1431 /* Internal mirror of the HW's dcbaa */ 1430 1432 struct xhci_virt_device *devs[MAX_HC_SLOTS]; 1431 1433 /* For keeping track of bandwidth domains per roothub. */