提交 f0d70eec 编写于 作者: L leoliuoc

Fix mouse enumeration issue after wakeup from s4

zhaoxin inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I62V77
CVE: NA

----------------------------------------------------------------

There is a mouse attached in the xHCI port. Then plug out this mouse and
plug to UHCI port after system go into hibernation. This mouse will
random be identified after system wakeup from hibernation.

During s4 wakeup, xHCI driver will cleanup this disconnect mouse (not
connect to xHCI port). This will delay s4 wakeup process and UHCI root hub
will goto auto suspend. Usb hub threads will be called to handle usb
controller root hub's event after S4 wakeup completed. However, this are
too many usb controllers to ensure EHCI and UHCI hub threads execute
order. Once, EHCI giveback port to UHCI before UHCI hub event check. UHCI
will try to enumerate this mouse with UHCI run bit not set. Which will
cause control transfer fail during enumeration phase.

In order to fix this issues, set UHCI root hub auto suspend delay value
larger. UHCI run bit will be set after wakeup from S4 and mouse will be
identified.
Signed-off-by: Nleoliuoc <leoliu-oc@zhaoxin.com>
上级 ace4dc02
......@@ -432,6 +432,7 @@ struct uhci_hcd {
unsigned int big_endian_mmio:1; /* Big endian registers */
unsigned int big_endian_desc:1; /* Big endian descriptors */
unsigned int is_aspeed:1; /* Aspeed impl. workarounds */
unsigned int auto_suspend_delay:1; /* delay root hub autosuspend*/
/* Support for port suspend/resume/reset */
unsigned long port_c_suspend; /* Bit-arrays of ports */
......
......@@ -217,7 +217,10 @@ static int uhci_hub_status_data(struct usb_hcd *hcd, char *buf)
/* are any devices attached? */
if (!any_ports_active(uhci)) {
uhci->rh_state = UHCI_RH_RUNNING_NODEVS;
uhci->auto_stop_time = jiffies + HZ;
if (!uhci->auto_suspend_delay)
uhci->auto_stop_time = jiffies + HZ;
else
uhci->auto_stop_time = jiffies + 3 * HZ;
}
break;
......
......@@ -134,8 +134,10 @@ static int uhci_pci_init(struct usb_hcd *hcd)
if (to_pci_dev(uhci_dev(uhci))->vendor == PCI_VENDOR_ID_INTEL)
device_set_wakeup_capable(uhci_dev(uhci), true);
if (to_pci_dev(uhci_dev(uhci))->vendor == PCI_VENDOR_ID_ZHAOXIN)
if (to_pci_dev(uhci_dev(uhci))->vendor == PCI_VENDOR_ID_ZHAOXIN) {
uhci->oc_low = 1;
uhci->auto_suspend_delay = 1;
}
/* Set up pointers to PCI-specific functions */
uhci->reset_hc = uhci_pci_reset_hc;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册