Patch "xhci: workaround for hosts missing CAS bit" has been added to the 4.4-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
xhci: workaround for hosts missing CAS bit
to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
xhci-workaround-for-hosts-missing-cas-bit.patch
and it can be found in the queue-4.4 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
346e99736c3ce328fd42d678343b70243aca5f36Mon Sep 17 00:00:00 2001
From: Mathias Nyman <[email protected]>
Date: Thu, 20 Oct 2016 18:09:19 +0300
Subject: xhci: workaround for hosts missing CAS bit
From: Mathias Nyman <[email protected]>
commit 346e99736c3ce328fd42d678343b70243aca5f36 upstream.
If a device is unplugged and replugged during Sx system suspend some Intel xHC hosts will overwrite the CAS (Cold attach status) flag and no device connection is noticed in resume.
A device in this state can be identified in resume if its link state is in polling or compliance mode, and the current connect status is 0. A device in this state needs to be warm reset.
Intel 100/c230 series PCH specification update Doc #332692-006 Errata #8
Observed on Cherryview and Apollolake as they go into compliance mode if LFPS times out during polling, and re-plugged devices are not discovered at resume.
--- drivers/usb/host/xhci-hub.c | 37 +++++++++++++++++++++++++++++++++++++ drivers/usb/host/xhci-pci.c | 6 ++++++ drivers/usb/host/xhci.h | 3 +++ 3 files changed, 46 insertions(+)
drivers/usb/host/xhci-hub.c +37 -0
@@ -1346,6 +1346,35 @@ int xhci_bus_suspend(struct usb_hcd *hcdreturn 0 ; } +/* +* Workaround for missing Cold Attach Status (CAS) if device re-plugged in S3. +* warm reset a USB3 device stuck in polling or compliance mode after resume. +* See Intel 100/c230 series PCH specification update Doc #332692-006 Errata #8 +*/ +static bool xhci_port_missing_cas_quirk (int port_index, +__le32 __iomem **port_array) +{ +u32 portsc; + + portsc =readl (port_array[port_index]); + +/* if any of these are set we are not stuck */ +if (portsc & (PORT_CONNECT |PORT_CAS )) +return false; + +if (((portsc &PORT_PLS_MASK ) !=XDEV_POLLING ) && + ((portsc &PORT_PLS_MASK ) !=XDEV_COMP_MODE )) +return false; + +/* clear wakeup/change bits, and do a warm port reset */ + portsc &= ~(PORT_RWC_BITS |PORT_CEC |PORT_WAKE_BITS ); + portsc |=PORT_WR ; +writel (portsc, port_array[port_index]); +/* flush write */ +readl (port_array[port_index]); +return true; +} +int xhci_bus_resume (struct usb_hcd *hcd) {struct xhci_hcd *xhci =hcd_to_xhci (hcd);
@@ -1383,6 +1412,14 @@ int xhci_bus_resume(struct usb_hcd *hcd)u32 temp; temp =readl (port_array[port_index]); + +/* warm reset CAS limited ports stuck in polling/compliance */ +if ((xhci->quirks &XHCI_MISSING_CAS ) && + (hcd->speed >=HCD_USB3 ) && +xhci_port_missing_cas_quirk (port_index, port_array)) { +xhci_dbg (xhci,"reset stuck port %d\n" , port_index); +continue ; + }if (DEV_SUPERSPEED_ANY (temp)) temp &= ~(PORT_RWC_BITS |PORT_CEC |PORT_WAKE_BITS );else
drivers/usb/host/xhci-pci.c +6 -0
@@ -51,6 +51,7 @@#define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_XHCI 0x9d2f#define PCI_DEVICE_ID_INTEL_BROXTON_M_XHCI 0x0aa8#define PCI_DEVICE_ID_INTEL_BROXTON_B_XHCI 0x1aa8 +#define PCI_DEVICE_ID_INTEL_APL_XHCI 0x5aa8static const char hcd_name[] ="xhci_hcd" ;
@@ -168,6 +169,11 @@ static void xhci_pci_quirks(struct devic pdev->device == PCI_DEVICE_ID_INTEL_BROXTON_B_XHCI)) { xhci->quirks |=XHCI_PME_STUCK_QUIRK ; } +if (pdev->vendor ==PCI_VENDOR_ID_INTEL && + (pdev->device ==PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI || + pdev->device ==PCI_DEVICE_ID_INTEL_APL_XHCI )) + xhci->quirks |=XHCI_MISSING_CAS ; +if (pdev->vendor ==PCI_VENDOR_ID_ETRON && pdev->device ==PCI_DEVICE_ID_EJ168 ) { xhci->quirks |=XHCI_RESET_ON_RESUME ;
drivers/usb/host/xhci.h +3 -0
@@ -312,6 +312,8 @@ struct xhci_op_regs {#define XDEV_U2 (0x2 << 5)#define XDEV_U3 (0x3 << 5)#define XDEV_INACTIVE (0x6 << 5) +#define XDEV_POLLING (0x7 << 5) +#define XDEV_COMP_MODE (0xa << 5)#define XDEV_RESUME (0xf << 5)/* true: port has power (see HCC_PPC) */ #define PORT_POWER (1 << 9)
@@ -1631,6 +1633,7 @@ struct xhci_hcd {/* For controllers with a broken beyond repair streams implementation */ #define XHCI_BROKEN_STREAMS (1 << 19)#define XHCI_PME_STUCK_QUIRK (1 << 20) +#define XHCI_MISSING_CAS (1 << 24)unsigned int num_active_eps;unsigned int limit_active_eps;/* There are two roothubs to keep track of bus suspend info for */
Patches currently in stable-queue which might be from [email protected] are
queue-4.4/usb-host-xhci-fix-possible-wild-pointer-when-handling-abort-command.patch queue-4.4/xhci-workaround-for-hosts-missing-cas-bit.patch queue-4.4/xhci-handle-command-completion-and-timeout-race.patch queue-4.4/usb-xhci-fix-possible-wild-pointer.patch queue-4.4/xhci-free-xhci-virtual-devices-with-leaf-nodes-first.patch queue-4.4/usb-xhci-fix-return-value-of-xhci_setup_device.patch queue-4.4/usb-xhci-apply-xhci_pme_stuck_quirk-to-intel-apollo-lake.patch queue-4.4/usb-xhci-hold-lock-over-xhci_abort_cmd_ring.patch