summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorriastradh <riastradh@NetBSD.org>2021-12-05 11:05:37 +0000
committerriastradh <riastradh@NetBSD.org>2021-12-05 11:05:37 +0000
commit8f9af57686ef575d5e66c6bceef479b1d6058f2d (patch)
tree0e23b29221c37df649efeada6b9aaa04e78589ba /sys/dev
parente079b70128e7653b1964b0ca9ba578786a3f4dc2 (diff)
ehci: Replace bogus polling during suspend by taking bus lock.
The system is not at high IPL or limited to a single CPU at this point; it is running essentially normally, just with some devices suspended. Other threads might be trying to touch EHCI registers, which might have bad outcomes while we're suspending stuff. Enabling polling only makes sense if there is a single thread and single CPU running, such as when we enter ddb on crash.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/usb/ehci.c20
1 files changed, 8 insertions, 12 deletions
diff --git a/sys/dev/usb/ehci.c b/sys/dev/usb/ehci.c
index ee146245f05..ec38d6e6b62 100644
--- a/sys/dev/usb/ehci.c
+++ b/sys/dev/usb/ehci.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ehci.c,v 1.286 2021/08/31 08:22:28 mrg Exp $ */
+/* $NetBSD: ehci.c,v 1.287 2021/12/05 11:05:37 riastradh Exp $ */
/*
* Copyright (c) 2004-2012,2016,2020 The NetBSD Foundation, Inc.
@@ -54,7 +54,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.286 2021/08/31 08:22:28 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.287 2021/12/05 11:05:37 riastradh Exp $");
#include "ohci.h"
#include "uhci.h"
@@ -1385,10 +1385,6 @@ ehci_activate(device_t self, enum devact act)
/*
* Handle suspend/resume.
*
- * We need to switch to polling mode here, because this routine is
- * called from an interrupt context. This is all right since we
- * are almost suspended anyway.
- *
* Note that this power handler isn't to be registered directly; the
* bus glue needs to call out to it.
*/
@@ -1401,9 +1397,7 @@ ehci_suspend(device_t dv, const pmf_qual_t *qual)
EHCIHIST_FUNC(); EHCIHIST_CALLED();
- mutex_spin_enter(&sc->sc_intr_lock);
- sc->sc_bus.ub_usepolling++;
- mutex_spin_exit(&sc->sc_intr_lock);
+ mutex_enter(&sc->sc_lock);
for (i = 1; i <= sc->sc_noport; i++) {
cmd = EOREAD4(sc, EHCI_PORTSC(i)) & ~EHCI_PS_CLEAR;
@@ -1439,9 +1433,7 @@ ehci_suspend(device_t dv, const pmf_qual_t *qual)
if (hcr != EHCI_STS_HCH)
printf("%s: config timeout\n", device_xname(dv));
- mutex_spin_enter(&sc->sc_intr_lock);
- sc->sc_bus.ub_usepolling--;
- mutex_spin_exit(&sc->sc_intr_lock);
+ mutex_exit(&sc->sc_lock);
return true;
}
@@ -1455,6 +1447,8 @@ ehci_resume(device_t dv, const pmf_qual_t *qual)
EHCIHIST_FUNC(); EHCIHIST_CALLED();
+ mutex_enter(&sc->sc_lock);
+
/* restore things in case the bios sucks */
EOWRITE4(sc, EHCI_CTRLDSSEGMENT, 0);
EOWRITE4(sc, EHCI_PERIODICLISTBASE, DMAADDR(&sc->sc_fldma, 0));
@@ -1500,6 +1494,8 @@ ehci_resume(device_t dv, const pmf_qual_t *qual)
if (hcr == EHCI_STS_HCH)
printf("%s: config timeout\n", device_xname(dv));
+ mutex_exit(&sc->sc_lock);
+
return true;
}