From 581cc054804359b7b7c67d5723dfb3a2f3657957 Mon Sep 17 00:00:00 2001 From: jsg Date: Sat, 17 Aug 2024 01:55:03 +0000 Subject: [PATCH] skip Controller Save State (CSS) and Controller Restore State (CRS) on AMD 17h/1xh xHCI avoids problem with resume after CRS was introduced in xhci.c rev 1.133 uhub0: device problem, disabling port 2 uhub1: device problem, disabling port 1 reported by brynet@ and reproduced on t495, ok kettenis@ --- sys/dev/pci/xhci_pci.c | 7 ++++++- sys/dev/usb/xhci.c | 31 ++++++++++++++++--------------- sys/dev/usb/xhcivar.h | 5 ++++- 3 files changed, 26 insertions(+), 17 deletions(-) diff --git a/sys/dev/pci/xhci_pci.c b/sys/dev/pci/xhci_pci.c index 5409588f39c..e906f16c88e 100644 --- a/sys/dev/pci/xhci_pci.c +++ b/sys/dev/pci/xhci_pci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: xhci_pci.c,v 1.13 2024/05/24 06:02:58 jsg Exp $ */ +/* $OpenBSD: xhci_pci.c,v 1.14 2024/08/17 01:55:03 jsg Exp $ */ /* * Copyright (c) 2001, 2002 The NetBSD Foundation, Inc. @@ -151,6 +151,11 @@ xhci_pci_attach(struct device *parent, struct device *self, void *aux) PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_FRESCO_FL1400) pa->pa_flags &= ~PCI_FLAGS_MSI_ENABLED; break; + case PCI_VENDOR_AMD: + if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_AMD_17_1X_XHCI_1 || + PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_AMD_17_1X_XHCI_2) + psc->sc.sc_flags |= XHCI_NOCSS; + break; } /* Map and establish the interrupt. */ diff --git a/sys/dev/usb/xhci.c b/sys/dev/usb/xhci.c index 75792693b70..d7a1fc0c9f1 100644 --- a/sys/dev/usb/xhci.c +++ b/sys/dev/usb/xhci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: xhci.c,v 1.133 2024/08/15 17:17:05 kettenis Exp $ */ +/* $OpenBSD: xhci.c,v 1.134 2024/08/17 01:55:03 jsg Exp $ */ /* * Copyright (c) 2014-2015 Martin Pieuchot @@ -626,24 +626,25 @@ xhci_suspend(struct xhci_softc *sc) * will prevent the SoC from reaching its lowest idle state. * So save the state here. */ + if ((sc->sc_flags & XHCI_NOCSS) == 0) { + XOWRITE4(sc, XHCI_USBCMD, XHCI_CMD_CSS); /* Save state */ + hcr = XOREAD4(sc, XHCI_USBSTS); + for (i = 0; i < 100; i++) { + usb_delay_ms(&sc->sc_bus, 1); + hcr = XOREAD4(sc, XHCI_USBSTS) & XHCI_STS_SSS; + if (!hcr) + break; + } - XOWRITE4(sc, XHCI_USBCMD, XHCI_CMD_CSS); /* Save state */ - hcr = XOREAD4(sc, XHCI_USBSTS); - for (i = 0; i < 100; i++) { - usb_delay_ms(&sc->sc_bus, 1); - hcr = XOREAD4(sc, XHCI_USBSTS) & XHCI_STS_SSS; - if (!hcr) - break; - } + if (hcr) { + printf("%s: save state timeout\n", DEVNAME(sc)); + xhci_reset(sc); + return; + } - if (hcr) { - printf("%s: save state timeout\n", DEVNAME(sc)); - xhci_reset(sc); - return; + sc->sc_saved_state = 1; } - sc->sc_saved_state = 1; - /* Disable interrupts. */ XRWRITE4(sc, XHCI_IMOD(0), 0); XRWRITE4(sc, XHCI_IMAN(0), 0); diff --git a/sys/dev/usb/xhcivar.h b/sys/dev/usb/xhcivar.h index cf1e86feb56..884cd5b732e 100644 --- a/sys/dev/usb/xhcivar.h +++ b/sys/dev/usb/xhcivar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: xhcivar.h,v 1.15 2024/08/15 17:17:05 kettenis Exp $ */ +/* $OpenBSD: xhcivar.h,v 1.16 2024/08/17 01:55:03 jsg Exp $ */ /* * Copyright (c) 2014 Martin Pieuchot @@ -121,6 +121,9 @@ struct xhci_softc { char sc_vendor[16]; /* Vendor string for root hub */ int sc_id_vendor; /* Vendor ID for root hub */ + + int sc_flags; +#define XHCI_NOCSS 0x01 }; int xhci_init(struct xhci_softc *); -- 2.20.1