summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorPatrick Wildt <patrick@cvs.openbsd.org>2020-06-24 09:43:21 +0000
committerPatrick Wildt <patrick@cvs.openbsd.org>2020-06-24 09:43:21 +0000
commit4a99c7d6a2415d86cc59c35a970e5edcbb310ea1 (patch)
treede9485f1865d9aa8352d44b51411c5121f87675d /sys/dev
parent86060a6db12ecf94f4bbdedf24365ff10f74e44c (diff)
Acknowledge xhci(4) interrupts before calling usb_schedsoftintr().
On powerdown (halt -p), sd(4)'s suspend function tries to powerdown a USB mass storage using a STOP command. In that case we are already cold and splhigh(), so that the xhci is supposed to run in polling- mode. usb_schedsoftintr() behaves differently when running in polling-mode. Instead of scheduling a soft interrupt, it immediately dequeues from the event queue. But dequeueing means touching the xhci registers. Apparently we need to acknowledge the interrupts before touching those registers, the hardware doesn't like it otherwise and we will never get an interrupt status for the second transfer. ok gerhard@
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/usb/xhci.c10
1 files changed, 5 insertions, 5 deletions
diff --git a/sys/dev/usb/xhci.c b/sys/dev/usb/xhci.c
index 2d65208f3db..903e57039a0 100644
--- a/sys/dev/usb/xhci.c
+++ b/sys/dev/usb/xhci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: xhci.c,v 1.114 2020/04/03 20:11:47 patrick Exp $ */
+/* $OpenBSD: xhci.c,v 1.115 2020/06/24 09:43:20 patrick Exp $ */
/*
* Copyright (c) 2014-2015 Martin Pieuchot
@@ -624,13 +624,13 @@ xhci_intr1(struct xhci_softc *sc)
return (1);
}
- XOWRITE4(sc, XHCI_USBSTS, intrs); /* Acknowledge */
- usb_schedsoftintr(&sc->sc_bus);
-
- /* Acknowledge PCI interrupt */
+ /* Acknowledge interrupts */
+ XOWRITE4(sc, XHCI_USBSTS, intrs);
intrs = XRREAD4(sc, XHCI_IMAN(0));
XRWRITE4(sc, XHCI_IMAN(0), intrs | XHCI_IMAN_INTR_PEND);
+ usb_schedsoftintr(&sc->sc_bus);
+
return (1);
}