On Fri, Aug 16, 2024 at 01:30:18PM +0200, Mark Kettenis wrote: > > Date: Fri, 16 Aug 2024 21:08:08 +1000 > > From: Jonathan Gray <j...@jsg.id.au> > > > > On Fri, Aug 16, 2024 at 11:59:08AM +0200, Mark Kettenis wrote: > > > > Date: Fri, 16 Aug 2024 15:21:17 +1000 > > > > From: Jonathan Gray <j...@jsg.id.au> > > > > > > > > On Thu, Aug 15, 2024 at 11:04:32PM -0600, Theo de Raadt wrote: > > > > > I'm no sure we should call it "BROKEN SUSPEND". > > > > > It suspends, in our way. It just has a bug in CRS for RESUME. > > > > > > > > > > So maybe BROKEN_CRS? > > > > > > > > NOCRS? > > > > > > I wonder if we should also skip saving the state in that case. The > > > Linux code also has seem workarounds for that. In that case the name > > > of the flag should probably be XHCI_NOCSS. > > > > we can also skip restore by not setting sc_saved_state > > Right. I think I'd prefer an if () block instead of goto though.
Index: sys/dev/usb/xhci.c =================================================================== RCS file: /cvs/src/sys/dev/usb/xhci.c,v diff -u -p -r1.133 xhci.c --- sys/dev/usb/xhci.c 15 Aug 2024 17:17:05 -0000 1.133 +++ sys/dev/usb/xhci.c 16 Aug 2024 11:40:16 -0000 @@ -626,23 +626,24 @@ 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_NOCCS) == 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); Index: sys/dev/usb/xhcivar.h =================================================================== RCS file: /cvs/src/sys/dev/usb/xhcivar.h,v diff -u -p -r1.15 xhcivar.h --- sys/dev/usb/xhcivar.h 15 Aug 2024 17:17:05 -0000 1.15 +++ sys/dev/usb/xhcivar.h 16 Aug 2024 10:52:11 -0000 @@ -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_NOCCS 0x01 }; int xhci_init(struct xhci_softc *); Index: sys/dev/pci/xhci_pci.c =================================================================== RCS file: /cvs/src/sys/dev/pci/xhci_pci.c,v diff -u -p -r1.13 xhci_pci.c --- sys/dev/pci/xhci_pci.c 24 May 2024 06:02:58 -0000 1.13 +++ sys/dev/pci/xhci_pci.c 16 Aug 2024 10:53:39 -0000 @@ -150,6 +164,11 @@ xhci_pci_attach(struct device *parent, s if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_FRESCO_FL1000 || 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_NOCCS; break; }