Module Name:    src
Committed By:   riastradh
Date:           Sun Dec  5 11:05:37 UTC 2021

Modified Files:
        src/sys/dev/usb: ehci.c

Log Message:
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.


To generate a diff of this commit:
cvs rdiff -u -r1.286 -r1.287 src/sys/dev/usb/ehci.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/usb/ehci.c
diff -u src/sys/dev/usb/ehci.c:1.286 src/sys/dev/usb/ehci.c:1.287
--- src/sys/dev/usb/ehci.c:1.286	Tue Aug 31 08:22:28 2021
+++ src/sys/dev/usb/ehci.c	Sun Dec  5 11:05:37 2021
@@ -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
 /*
  * 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
 
 	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
 	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_
 
 	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_
 	if (hcr == EHCI_STS_HCH)
 		printf("%s: config timeout\n", device_xname(dv));
 
+	mutex_exit(&sc->sc_lock);
+
 	return true;
 }
 

Reply via email to