From 2cdab2ffeaf8fd89d2591b8d96f21b8d00509dbc Mon Sep 17 00:00:00 2001 From: leoliu-oc Date: Tue, 4 Jun 2024 11:13:11 +0800 Subject: [PATCH 1/9] Revert "xhci: fix issue with resume from system Sx state" zhaoxin inclusion category: other bugzilla: https://gitee.com/openeuler/kernel/issues/I9USMU CVE: NA -------------------------------------------- This reverts commit 2fdfd5b8eea6f5ffe961a75cf868e51b3432f4df. Revoke this version first before updating to the upstream mainline version: f927728186f0 ("xhci: Fix resume issue of some ZHAOXIN hosts") Signed-off-by: leoliu-oc --- drivers/usb/host/xhci-pci.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 4c2376a4c1d6..d31666a331e0 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -250,9 +250,6 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) if (pdev->vendor == PCI_VENDOR_ID_TI && pdev->device == 0x8241) xhci->quirks |= XHCI_LIMIT_ENDPOINT_INTERVAL_7; - if (pdev->vendor == PCI_VENDOR_ID_ZHAOXIN && pdev->device == 0x9202) - xhci->quirks |= XHCI_RESET_ON_RESUME; - if ((pdev->vendor == PCI_VENDOR_ID_BROADCOM || pdev->vendor == PCI_VENDOR_ID_CAVIUM) && pdev->device == 0x9026) -- Gitee From dad7bee707f54011bf70d55254a49be4c3b18a19 Mon Sep 17 00:00:00 2001 From: Weitao Wang Date: Fri, 2 Jun 2023 17:40:06 +0300 Subject: [PATCH 2/9] xhci: Fix resume issue of some ZHAOXIN hosts mainline inclusion from mainline-v6.4-rc5 commit f927728186f0de1167262d6a632f9f7e96433d1a category: other bugzilla: https://gitee.com/openeuler/kernel/issues/I9USMU CVE: NA ------------------- On ZHAOXIN ZX-100 project, xHCI can't work normally after resume from system Sx state. To fix this issue, when resume from system Sx state, reinitialize xHCI instead of restore. So, Add XHCI_RESET_ON_RESUME quirk for ZX-100 to fix issue of resuming from system Sx state. Cc: stable@vger.kernel.org Signed-off-by: Weitao Wang Signed-off-by: Mathias Nyman Message-ID: <20230602144009.1225632-9-mathias.nyman@linux.intel.com> Signed-off-by: Greg Kroah-Hartman Signed-off-by: leoliu-oc --- drivers/usb/host/xhci-pci.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index d31666a331e0..b1a036e0f22b 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -255,6 +255,11 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) pdev->device == 0x9026) xhci->quirks |= XHCI_RESET_PLL_ON_DISCONNECT; + if (pdev->vendor == PCI_VENDOR_ID_ZHAOXIN) { + if (pdev->device == 0x9202) + xhci->quirks |= XHCI_RESET_ON_RESUME; + } + if (xhci->quirks & XHCI_RESET_ON_RESUME) xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, "QUIRK: Resetting on resume"); -- Gitee From 16eab1c236a2793ab68c004b1506602e95a599b9 Mon Sep 17 00:00:00 2001 From: leoliu-oc Date: Tue, 4 Jun 2024 14:15:34 +0800 Subject: [PATCH 3/9] Revert "xhci: fix issue of cross page boundary in TRB prefetch" zhaoxin inclusion category: other bugzilla: https://gitee.com/openeuler/kernel/issues/I9USMU CVE: NA -------------------------------------------- This reverts commit 46bbb3dc9e53cde9e5fcf63820f97834558b1467. Revoke this version first before updating to the upstream mainline version: 2a865a652299 ("xhci: Fix TRB prefetch issue of ZHAOXIN hosts") Signed-off-by: leoliu-oc --- drivers/usb/host/xhci-mem.c | 11 ++--------- drivers/usb/host/xhci-pci.c | 5 ----- drivers/usb/host/xhci.h | 1 - 3 files changed, 2 insertions(+), 15 deletions(-) diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index a6101f095db8..9e87c282a743 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -2450,15 +2450,8 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) * and our use of dma addresses in the trb_address_map radix tree needs * TRB_SEGMENT_SIZE alignment, so we pick the greater alignment need. */ - /* With xHCI TRB prefetch patch:To fix cross page boundry access issue - * in IOV environment */ - if (xhci->quirks & XHCI_ZHAOXIN_TRB_FETCH) { - xhci->segment_pool = dma_pool_create("xHCI ring segments", dev, - TRB_SEGMENT_SIZE*2, TRB_SEGMENT_SIZE*2, xhci->page_size*2); - } else { - xhci->segment_pool = dma_pool_create("xHCI ring segments", dev, - TRB_SEGMENT_SIZE, TRB_SEGMENT_SIZE, xhci->page_size); - } + xhci->segment_pool = dma_pool_create("xHCI ring segments", dev, + TRB_SEGMENT_SIZE, TRB_SEGMENT_SIZE, xhci->page_size); /* See Table 46 and Note on Figure 55 */ xhci->device_pool = dma_pool_create("xHCI input/output contexts", dev, diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index b1a036e0f22b..b74349540f23 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -231,11 +231,6 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) pdev->device == 0x3432) xhci->quirks |= XHCI_BROKEN_STREAMS; - if (pdev->vendor == PCI_VENDOR_ID_ZHAOXIN && - (pdev->device == 0x9202 || - pdev->device == 0x9203)) - xhci->quirks |= XHCI_ZHAOXIN_TRB_FETCH; - if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA && pdev->device == 0x1042) xhci->quirks |= XHCI_BROKEN_STREAMS; diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 485ba36b566c..b02911887d20 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1873,7 +1873,6 @@ struct xhci_hcd { #define XHCI_RESET_PLL_ON_DISCONNECT BIT_ULL(34) #define XHCI_SNPS_BROKEN_SUSPEND BIT_ULL(35) #define XHCI_ZHAOXIN_HOST BIT_ULL(36) -#define XHCI_ZHAOXIN_TRB_FETCH BIT_ULL(39) unsigned int num_active_eps; unsigned int limit_active_eps; -- Gitee From 234b2a8463d58ba7e4772a215e288b13dfa633c7 Mon Sep 17 00:00:00 2001 From: Weitao Wang Date: Fri, 2 Jun 2023 17:40:07 +0300 Subject: [PATCH 4/9] xhci: Fix TRB prefetch issue of ZHAOXIN hosts mainline inclusion from mainline-v6.4-rc5 commit 2a865a652299f5666f3b785cbe758c5f57453036 category: other bugzilla: https://gitee.com/openeuler/kernel/issues/I9USMU CVE: NA ------------------- On some ZHAOXIN hosts, xHCI will prefetch TRB for performance improvement. However this TRB prefetch mechanism may cross page boundary, which may access memory not allocated by xHCI driver. In order to fix this issue, two pages was allocated for a segment and only the first page will be used. And add a quirk XHCI_ZHAOXIN_TRB_FETCH for this issue. Cc: stable@vger.kernel.org Signed-off-by: Weitao Wang Signed-off-by: Mathias Nyman Message-ID: <20230602144009.1225632-10-mathias.nyman@linux.intel.com> Signed-off-by: Greg Kroah-Hartman Signed-off-by: leoliu-oc --- drivers/usb/host/xhci-mem.c | 8 ++++++-- drivers/usb/host/xhci-pci.c | 7 ++++++- drivers/usb/host/xhci.h | 1 + 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 9e87c282a743..dadfb56e6cb4 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -2450,8 +2450,12 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) * and our use of dma addresses in the trb_address_map radix tree needs * TRB_SEGMENT_SIZE alignment, so we pick the greater alignment need. */ - xhci->segment_pool = dma_pool_create("xHCI ring segments", dev, - TRB_SEGMENT_SIZE, TRB_SEGMENT_SIZE, xhci->page_size); + if (xhci->quirks & XHCI_ZHAOXIN_TRB_FETCH) + xhci->segment_pool = dma_pool_create("xHCI ring segments", dev, + TRB_SEGMENT_SIZE * 2, TRB_SEGMENT_SIZE * 2, xhci->page_size * 2); + else + xhci->segment_pool = dma_pool_create("xHCI ring segments", dev, + TRB_SEGMENT_SIZE, TRB_SEGMENT_SIZE, xhci->page_size); /* See Table 46 and Note on Figure 55 */ xhci->device_pool = dma_pool_create("xHCI input/output contexts", dev, diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index b74349540f23..9ea90183bb82 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -251,8 +251,13 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) xhci->quirks |= XHCI_RESET_PLL_ON_DISCONNECT; if (pdev->vendor == PCI_VENDOR_ID_ZHAOXIN) { - if (pdev->device == 0x9202) + if (pdev->device == 0x9202) { xhci->quirks |= XHCI_RESET_ON_RESUME; + xhci->quirks |= XHCI_ZHAOXIN_TRB_FETCH; + } + + if (pdev->device == 0x9203) + xhci->quirks |= XHCI_ZHAOXIN_TRB_FETCH; } if (xhci->quirks & XHCI_RESET_ON_RESUME) diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index b02911887d20..0bcba904839b 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1873,6 +1873,7 @@ struct xhci_hcd { #define XHCI_RESET_PLL_ON_DISCONNECT BIT_ULL(34) #define XHCI_SNPS_BROKEN_SUSPEND BIT_ULL(35) #define XHCI_ZHAOXIN_HOST BIT_ULL(36) +#define XHCI_ZHAOXIN_TRB_FETCH BIT_ULL(45) unsigned int num_active_eps; unsigned int limit_active_eps; -- Gitee From dee26a1d450a0a6754f40bca8d840e87948b5275 Mon Sep 17 00:00:00 2001 From: leoliu-oc Date: Tue, 4 Jun 2024 14:54:38 +0800 Subject: [PATCH 5/9] Revert "xhci: Fix a logic issue when display Zhaoxin XHCI root hub speed" zhaoxin inclusion category: other bugzilla: https://gitee.com/openeuler/kernel/issues/I9USMU CVE: NA -------------------------------------------- This reverts commit 38c318614bc42d029357679f411341e79313d4e5. Revoke this version first before updating to the upstream mainline version: d9b0328d0b8b ("xhci: Show ZHAOXIN xHCI root hub speed correctly") Signed-off-by: leoliu-oc --- drivers/usb/host/xhci.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 1cb66cbe6487..e8108139d680 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -5145,10 +5145,10 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks) if (XHCI_EXT_PORT_PSIV(xhci->port_caps[j].psi[i]) >= 5) minor_rev = 1; } - } - if (minor_rev != 1) { - hcd->speed = HCD_USB3; - hcd->self.root_hub->speed = USB_SPEED_SUPER; + if (minor_rev != 1) { + hcd->speed = HCD_USB3; + hcd->self.root_hub->speed = USB_SPEED_SUPER; + } } } -- Gitee From 2d3cb38decd30775f090fc941fdded88a0586c4b Mon Sep 17 00:00:00 2001 From: leoliu-oc Date: Tue, 4 Jun 2024 15:19:03 +0800 Subject: [PATCH 6/9] Revert "xhci: Show Zhaoxin XHCI root hub speed correctly" zhaoxin inclusion category: other bugzilla: https://gitee.com/openeuler/kernel/issues/I9USMU CVE: NA -------------------------------------------- This reverts commit b782348986c6d9ce1e8f55cc2c5c2b077de07e73. Revoke this version first before updating to the upstream mainline version: d9b0328d0b8b ("xhci: Show ZHAOXIN xHCI root hub speed correctly") Signed-off-by: leoliu-oc --- drivers/usb/host/xhci.c | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index e8108139d680..41f3cf0d0737 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -5079,7 +5079,6 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks) */ struct device *dev = hcd->self.sysdev; unsigned int minor_rev; - u8 i, j; int retval; /* Accept arbitrarily long scatter-gather lists */ @@ -5134,24 +5133,6 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks) hcd->self.root_hub->speed = USB_SPEED_SUPER_PLUS; break; } - - /* usb3.1 has gen1 and gen2, Some zx's xHCI controller that follow usb3.1 spec - * but only support gen1 - */ - if (xhci->quirks & XHCI_ZHAOXIN_HOST) { - minor_rev = 0; - for (j = 0; j < xhci->num_port_caps; j++) { - for (i = 0; i < xhci->port_caps[j].psi_count; i++) { - if (XHCI_EXT_PORT_PSIV(xhci->port_caps[j].psi[i]) >= 5) - minor_rev = 1; - } - if (minor_rev != 1) { - hcd->speed = HCD_USB3; - hcd->self.root_hub->speed = USB_SPEED_SUPER; - } - } - } - xhci_info(xhci, "Host supports USB 3.%x %sSuperSpeed\n", minor_rev, minor_rev ? "Enhanced " : ""); -- Gitee From 8a64dc868d76ad19b65c65fd8168f46b4cb662cb Mon Sep 17 00:00:00 2001 From: Weitao Wang Date: Fri, 2 Jun 2023 17:40:08 +0300 Subject: [PATCH 7/9] xhci: Show ZHAOXIN xHCI root hub speed correctly mainline inclusion from mainline-v6.4-rc5 commit d9b0328d0b8b8298dfdc97cd8e0e2371d4bcc97b category: other bugzilla: https://gitee.com/openeuler/kernel/issues/I9USMU CVE: NA ------------------- Some ZHAOXIN xHCI controllers follow usb3.1 spec, but only support gen1 speed 5Gbps. While in Linux kernel, if xHCI suspport usb3.1, root hub speed will show on 10Gbps. To fix this issue of ZHAOXIN xHCI platforms, read usb speed ID supported by xHCI to determine root hub speed. And add a quirk XHCI_ZHAOXIN_HOST for this issue. [fix warning about uninitialized symbol -Mathias] Suggested-by: Mathias Nyman Cc: stable@vger.kernel.org Signed-off-by: Weitao Wang Signed-off-by: Mathias Nyman Message-ID: <20230602144009.1225632-11-mathias.nyman@linux.intel.com> Signed-off-by: Greg Kroah-Hartman Signed-off-by: leoliu-oc --- drivers/usb/host/xhci-mem.c | 30 +++++++++++++++++++++++------- drivers/usb/host/xhci-pci.c | 2 ++ drivers/usb/host/xhci.h | 1 + 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index dadfb56e6cb4..b7ed214b757c 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -2123,7 +2123,7 @@ static void xhci_add_in_port(struct xhci_hcd *xhci, unsigned int num_ports, { u32 temp, port_offset, port_count; int i; - u8 major_revision, minor_revision; + u8 major_revision, minor_revision, tmp_minor_revision; struct xhci_hub *rhub; struct device *dev = xhci_to_hcd(xhci)->self.sysdev; struct xhci_port_cap *port_cap; @@ -2134,6 +2134,14 @@ static void xhci_add_in_port(struct xhci_hcd *xhci, unsigned int num_ports, if (major_revision == 0x03) { rhub = &xhci->usb3_rhub; + /* + * Some zhaoxin's xHCI controller that follow usb3.1 spec + * but only support Gen1. + */ + if (xhci->quirks & XHCI_ZHAOXIN_HOST) { + tmp_minor_revision = minor_revision; + minor_revision = 0; + } } else if (major_revision <= 0x02) { rhub = &xhci->usb2_rhub; } else { @@ -2143,10 +2151,6 @@ static void xhci_add_in_port(struct xhci_hcd *xhci, unsigned int num_ports, /* Ignoring port protocol we can't understand. FIXME */ return; } - rhub->maj_rev = XHCI_EXT_PORT_MAJOR(temp); - - if (rhub->min_rev < minor_revision) - rhub->min_rev = minor_revision; /* Port offset and count in the third dword, see section 7.2 */ temp = readl(addr + 2); @@ -2165,8 +2169,6 @@ static void xhci_add_in_port(struct xhci_hcd *xhci, unsigned int num_ports, if (xhci->num_port_caps > max_caps) return; - port_cap->maj_rev = major_revision; - port_cap->min_rev = minor_revision; port_cap->psi_count = XHCI_EXT_PORT_PSIC(temp); if (port_cap->psi_count) { @@ -2187,6 +2189,11 @@ static void xhci_add_in_port(struct xhci_hcd *xhci, unsigned int num_ports, XHCI_EXT_PORT_PSIV(port_cap->psi[i - 1]))) port_cap->psi_uid_count++; + if (xhci->quirks & XHCI_ZHAOXIN_HOST && + major_revision == 0x03 && + XHCI_EXT_PORT_PSIV(port_cap->psi[i]) >= 5) + minor_revision = tmp_minor_revision; + xhci_dbg(xhci, "PSIV:%d PSIE:%d PLT:%d PFD:%d LP:%d PSIM:%d\n", XHCI_EXT_PORT_PSIV(port_cap->psi[i]), XHCI_EXT_PORT_PSIE(port_cap->psi[i]), @@ -2196,6 +2203,15 @@ static void xhci_add_in_port(struct xhci_hcd *xhci, unsigned int num_ports, XHCI_EXT_PORT_PSIM(port_cap->psi[i])); } } + + rhub->maj_rev = major_revision; + + if (rhub->min_rev < minor_revision) + rhub->min_rev = minor_revision; + + port_cap->maj_rev = major_revision; + port_cap->min_rev = minor_revision; + /* cache usb2 port capabilities */ if (major_revision < 0x03 && xhci->num_ext_caps < max_caps) xhci->ext_caps[xhci->num_ext_caps++] = temp; diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 9ea90183bb82..79c60eb98c15 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -251,6 +251,8 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) xhci->quirks |= XHCI_RESET_PLL_ON_DISCONNECT; if (pdev->vendor == PCI_VENDOR_ID_ZHAOXIN) { + xhci->quirks |= XHCI_ZHAOXIN_HOST; + if (pdev->device == 0x9202) { xhci->quirks |= XHCI_RESET_ON_RESUME; xhci->quirks |= XHCI_ZHAOXIN_TRB_FETCH; diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 0bcba904839b..4f91bd3194c7 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1874,6 +1874,7 @@ struct xhci_hcd { #define XHCI_SNPS_BROKEN_SUSPEND BIT_ULL(35) #define XHCI_ZHAOXIN_HOST BIT_ULL(36) #define XHCI_ZHAOXIN_TRB_FETCH BIT_ULL(45) +#define XHCI_ZHAOXIN_HOST BIT_ULL(46) unsigned int num_active_eps; unsigned int limit_active_eps; -- Gitee From 787bbf071c9311e04f73122319798e1b00ff883c Mon Sep 17 00:00:00 2001 From: leoliu-oc Date: Tue, 4 Jun 2024 15:42:17 +0800 Subject: [PATCH 8/9] Revert "xhci: Add Zhaoxin xHCI LPM U1/U2 feature support" zhaoxin inclusion category: other bugzilla: https://gitee.com/openeuler/kernel/issues/I9USMU CVE: NA -------------------------------------------- This reverts commit 51b0b45623fa098c7427f34fd936bc31a384ee45. Revoke this version first before updating to the upstream mainline version: d5e234ff08a4 ("xhci: Add ZHAOXIN xHCI host U1/U2 feature support") Signed-off-by: leoliu-oc --- drivers/usb/host/xhci-pci.c | 4 ---- drivers/usb/host/xhci.c | 34 ++-------------------------------- 2 files changed, 2 insertions(+), 36 deletions(-) diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 79c60eb98c15..3e0db75ca7ea 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -218,10 +218,6 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) } if (pdev->vendor == PCI_VENDOR_ID_VIA) xhci->quirks |= XHCI_RESET_ON_RESUME; - if (pdev->vendor == PCI_VENDOR_ID_ZHAOXIN) { - xhci->quirks |= XHCI_LPM_SUPPORT; - xhci->quirks |= XHCI_ZHAOXIN_HOST; - } if (pdev->vendor == PCI_VENDOR_ID_ZHAOXIN) xhci->quirks |= XHCI_SUSPEND_DELAY; diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 41f3cf0d0737..304b354ff083 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -4567,7 +4567,7 @@ static u16 xhci_calculate_u1_timeout(struct xhci_hcd *xhci, } } - if (xhci->quirks & (XHCI_INTEL_HOST | XHCI_ZHAOXIN_HOST)) + if (xhci->quirks & (XHCI_INTEL_HOST)) timeout_ns = xhci_calculate_intel_u1_timeout(udev, desc); else timeout_ns = udev->u1_params.sel; @@ -4631,7 +4631,7 @@ static u16 xhci_calculate_u2_timeout(struct xhci_hcd *xhci, } } - if (xhci->quirks & (XHCI_INTEL_HOST | XHCI_ZHAOXIN_HOST)) + if (xhci->quirks & (XHCI_INTEL_HOST)) timeout_ns = xhci_calculate_intel_u2_timeout(udev, desc); else timeout_ns = udev->u2_params.sel; @@ -4728,42 +4728,12 @@ static int xhci_check_intel_tier_policy(struct usb_device *udev, return -E2BIG; } -static int xhci_check_zhaoxin_tier_policy(struct usb_device *udev, - enum usb3_link_state state) -{ - struct usb_device *parent; - unsigned int num_hubs; - char *state_name; - - if (state == USB3_LPM_U1) - state_name = "U1"; - else if (state == USB3_LPM_U2) - state_name = "U2"; - else - state_name = "Unknown"; - /* Don't enable U1/U2 if the device is on an external hub*/ - for (parent = udev->parent, num_hubs = 0; parent->parent; - parent = parent->parent) - num_hubs++; - - if (num_hubs < 1) - return 0; - - dev_dbg(&udev->dev, "Disabling %s link state for device" \ - " below external hub.\n", state_name); - dev_dbg(&udev->dev, "Plug device into root port " \ - "to decrease power consumption.\n"); - return -E2BIG; -} - static int xhci_check_tier_policy(struct xhci_hcd *xhci, struct usb_device *udev, enum usb3_link_state state) { if (xhci->quirks & XHCI_INTEL_HOST) return xhci_check_intel_tier_policy(udev, state); - else if (xhci->quirks & XHCI_ZHAOXIN_HOST) - return xhci_check_zhaoxin_tier_policy(udev, state); else return 0; } -- Gitee From d25d7511a90d4550a695e629ee0b277dff1c4526 Mon Sep 17 00:00:00 2001 From: Weitao Wang Date: Fri, 2 Jun 2023 17:40:09 +0300 Subject: [PATCH 9/9] xhci: Add ZHAOXIN xHCI host U1/U2 feature support mainline inclusion from mainline-v6.4-rc5 commit d5e234ff08a45a7a08a52173ed793b3c125ab88d category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I9USMU CVE: NA ------------------- Add U1/U2 feature support of xHCI for ZHAOXIN. Since both INTEL and ZHAOXIN need to check the tier where the device is located to determine whether to enabled U1/U2, remove the previous INTEL U1/U2 tier policy and add common policy in xhci_check_tier_policy. If vendor has specific U1/U2 enable policy,quirks can be add to declare. Suggested-by: Mathias Nyman Signed-off-by: Weitao Wang Signed-off-by: Mathias Nyman Message-ID: <20230602144009.1225632-12-mathias.nyman@linux.intel.com> Signed-off-by: Greg Kroah-Hartman Signed-off-by: leoliu-oc --- drivers/usb/host/xhci-pci.c | 1 + drivers/usb/host/xhci.c | 43 ++++++++++++++++--------------------- 2 files changed, 19 insertions(+), 25 deletions(-) diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 3e0db75ca7ea..8eb049c4e65c 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -248,6 +248,7 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) if (pdev->vendor == PCI_VENDOR_ID_ZHAOXIN) { xhci->quirks |= XHCI_ZHAOXIN_HOST; + xhci->quirks |= XHCI_LPM_SUPPORT; if (pdev->device == 0x9202) { xhci->quirks |= XHCI_RESET_ON_RESUME; diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 304b354ff083..d4b86aa2a5eb 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -4567,7 +4567,7 @@ static u16 xhci_calculate_u1_timeout(struct xhci_hcd *xhci, } } - if (xhci->quirks & (XHCI_INTEL_HOST)) + if (xhci->quirks & (XHCI_INTEL_HOST | XHCI_ZHAOXIN_HOST)) timeout_ns = xhci_calculate_intel_u1_timeout(udev, desc); else timeout_ns = udev->u1_params.sel; @@ -4631,7 +4631,7 @@ static u16 xhci_calculate_u2_timeout(struct xhci_hcd *xhci, } } - if (xhci->quirks & (XHCI_INTEL_HOST)) + if (xhci->quirks & (XHCI_INTEL_HOST | XHCI_ZHAOXIN_HOST)) timeout_ns = xhci_calculate_intel_u2_timeout(udev, desc); else timeout_ns = udev->u2_params.sel; @@ -4704,40 +4704,33 @@ static int xhci_update_timeout_for_interface(struct xhci_hcd *xhci, return 0; } -static int xhci_check_intel_tier_policy(struct usb_device *udev, +static int xhci_check_tier_policy(struct xhci_hcd *xhci, + struct usb_device *udev, enum usb3_link_state state) { - struct usb_device *parent; - unsigned int num_hubs; + struct usb_device *parent = udev->parent; + int tier = 1; /* roothub is tier1 */ if (state == USB3_LPM_U2) return 0; - /* Don't enable U1 if the device is on a 2nd tier hub or lower. */ - for (parent = udev->parent, num_hubs = 0; parent->parent; - parent = parent->parent) - num_hubs++; + while (parent) { + parent = parent->parent; + tier++; + } - if (num_hubs < 2) - return 0; + if (xhci->quirks & XHCI_INTEL_HOST && tier > 3) + goto fail; + if (xhci->quirks & XHCI_ZHAOXIN_HOST && tier > 2) + goto fail; - dev_dbg(&udev->dev, "Disabling U1 link state for device" - " below second-tier hub.\n"); - dev_dbg(&udev->dev, "Plug device into first-tier hub " - "to decrease power consumption.\n"); + return 0; +fail: + dev_dbg(&udev->dev, "Tier policy prevents U1/U2 LPM states for devices at tier %d\n", + tier); return -E2BIG; } -static int xhci_check_tier_policy(struct xhci_hcd *xhci, - struct usb_device *udev, - enum usb3_link_state state) -{ - if (xhci->quirks & XHCI_INTEL_HOST) - return xhci_check_intel_tier_policy(udev, state); - else - return 0; -} - /* Returns the U1 or U2 timeout that should be enabled. * If the tier check or timeout setting functions return with a non-zero exit * code, that means the timeout value has been finalized and we shouldn't look -- Gitee