NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: port-amd64/59180: System reboots instead of shutting down
- To: swagg boi <swaggboi@gangstalking.agency>
- Subject: Re: port-amd64/59180: System reboots instead of shutting down
- From: Taylor R Campbell <riastradh%NetBSD.org@localhost>
- Date: Sun, 30 Mar 2025 20:34:57 +0000
> Date: Mon, 17 Mar 2025 18:13:31 -0400
> From: swagg boi <swaggboi@gangstalking.agency>
>
> Hello, sorry for the delay but I have my little 'build environment'
> setup with the handy build.sh so I can build kernels nice and easy now.
>
> I gave the patch a try and still get the reboot but when I set
> ddb.onpanic=1 the output looks different: [...]
Thanks, can you revert the patch I gave you before and try this one
instead?
diff -r 63a5958e843d -r e419e0cd0295 sys/arch/arm/xscale/pxa2x0_ohci.c
--- a/sys/arch/arm/xscale/pxa2x0_ohci.c Sun Mar 30 16:22:37 2025 +0000
+++ b/sys/arch/arm/xscale/pxa2x0_ohci.c Sun Mar 30 20:18:14 2025 +0000
@@ -123,11 +123,7 @@ pxaohci_attach(device_t parent, device_t
}
#if 0
- sc->sc.sc_powerhook = powerhook_establish(device_xname(sc->sc.sc_bus.bdev),
- pxaohci_power, sc);
- if (sc->sc.sc_powerhook == NULL) {
- aprint_error_dev(sc->sc.sc_dev->sc_bus.bdev, "cannot establish powerhook\n");
- }
+ pmf_device_register1(self, ohci_suspend, ohci_resume, ohci_shutdown);
#endif
sc->sc.sc_child = config_found(self, &sc->sc.sc_bus, usbctlprint,
@@ -151,27 +147,57 @@ pxaohci_detach(device_t self, int flags)
struct pxaohci_softc *sc = device_private(self);
int error;
- error = ohci_detach(&sc->sc, flags);
+ /*
+ * Detach the USB child first. Disconnects all USB devices and
+ * prevents connecting new ones.
+ */
+ error = config_detach_children(self, flags);
if (error)
return error;
+ /*
+ * Shut down the controller and block interrupts at the device
+ * level. Once we have shut down the controller, the shutdown
+ * handler no longer needed -- deregister it from PMF.
+ * (Harmless to call ohci_shutdown more than once, so no
+ * synchronization needed.)
+ */
+ ohci_shutdown(self, 0);
#if 0
- if (sc->sc.sc_powerhook) {
- powerhook_disestablish(sc->sc.sc_powerhook);
- sc->sc.sc_powerhook = NULL;
- }
+ pmf_device_deregister(self);
#endif
+ /*
+ * Interrupts are blocked at the device level by ohci_shutdown.
+ * Disestablish the interrupt handler. This waits for it to
+ * complete on all CPUs.
+ */
if (sc->sc_ih) {
pxa2x0_intr_disestablish(sc->sc_ih);
sc->sc_ih = NULL;
}
+ /*
+ * Free the bus-independent ohci(4) state now that the
+ * interrupt handler has ceased to run on all CPUs.
+ */
+ ohci_detach(&sc->sc);
+
+ /*
+ * Issue a Full Host Reset to disable the host controller
+ * interface.
+ *
+ * XXX Is this necessary or is it redundant with ohci_shutdown?
+ * Should it be done in ohci_shutdown as well?
+ */
pxaohci_disable(sc);
/* stop clock */
pxa2x0_clkman_config(CKEN_USBHC, 0);
+ /*
+ * Unmap the registers now that we're all done with them.
+ */
if (sc->sc.sc_size) {
bus_space_unmap(sc->sc.iot, sc->sc.ioh, sc->sc.sc_size);
sc->sc.sc_size = 0;
diff -r 63a5958e843d -r e419e0cd0295 sys/arch/mips/ralink/ralink_ehci.c
--- a/sys/arch/mips/ralink/ralink_ehci.c Sun Mar 30 16:22:37 2025 +0000
+++ b/sys/arch/mips/ralink/ralink_ehci.c Sun Mar 30 20:18:14 2025 +0000
@@ -57,15 +57,11 @@ static void ralink_ehci_attach(device_t,
static int ralink_ehci_detach(device_t, int);
CFATTACH_DECL2_NEW(ralink_ehci, sizeof(struct ralink_ehci_softc),
- ralink_ehci_match, ralink_ehci_attach, ralink_ehci_detach,
- ehci_activate, NULL, ehci_childdet);
+ ralink_ehci_match, ralink_ehci_attach, ralink_ehci_detach,
+ ehci_activate, NULL, ehci_childdet);
static TAILQ_HEAD(, ralink_usb_hc) ralink_usb_alldevs =
- TAILQ_HEAD_INITIALIZER(ralink_usb_alldevs);
-
-#if 0
-struct usb_hc_alldevs ralink_usb_alldevs = TAILQ_HEAD_INITIALIZER(ralink_usb_alldevs);
-#endif
+ TAILQ_HEAD_INITIALIZER(ralink_usb_alldevs);
/*
* ralink_ehci_match
@@ -144,6 +140,7 @@ ralink_ehci_attach(device_t parent, devi
* have lower function numbers so they should be enumerated already.
*/
int ncomp = 0;
+ KASSERT(KERNEL_LOCKED_P()); /* XXXSMP ralink_usb_alldevs */
TAILQ_FOREACH(ruh, &ralink_usb_alldevs, next) {
aprint_normal_dev(self, "companion %s\n",
device_xname(ruh->usb));
@@ -207,6 +204,9 @@ ralink_ehci_detach(device_t self, int fl
void
ralink_usb_hc_add(struct ralink_usb_hc *ruh, device_t usbp)
{
+
+ KASSERT(KERNEL_LOCKED_P()); /* XXXSMP ralink_usb_alldevs */
+
TAILQ_INSERT_TAIL(&ralink_usb_alldevs, ruh, next);
ruh->usb = usbp;
}
@@ -214,5 +214,9 @@ ralink_usb_hc_add(struct ralink_usb_hc *
void
ralink_usb_hc_rem(struct ralink_usb_hc *ruh)
{
- TAILQ_REMOVE(&ralink_usb_alldevs, ruh, next);
+
+ KASSERT(KERNEL_LOCKED_P()); /* XXXSMP ralink_usb_alldevs */
+
+ if (ruh->usb)
+ TAILQ_REMOVE(&ralink_usb_alldevs, ruh, next);
}
diff -r 63a5958e843d -r e419e0cd0295 sys/arch/mips/ralink/ralink_ohci.c
--- a/sys/arch/mips/ralink/ralink_ohci.c Sun Mar 30 16:22:37 2025 +0000
+++ b/sys/arch/mips/ralink/ralink_ohci.c Sun Mar 30 20:18:14 2025 +0000
@@ -162,28 +162,58 @@ static int
ralink_ohci_detach(device_t self, int flags)
{
struct ralink_ohci_softc *sc = device_private(self);
- int rv;
+ int error;
+
+ /*
+ * Detach the USB child first. Disconnects all USB devices and
+ * prevents connecting new ones.
+ */
+ error = config_detach_children(self, flags);
+ if (error)
+ return error;
+ /*
+ * Stop listing this as a possible companion controller for
+ * ehci(4).
+ */
+#if NEHCI > 0
+ ralink_usb_hc_rem(&sc->sc_hc);
+#endif
+
+ /*
+ * Shut down the controller and block interrupts at the device
+ * level. Once we have shut down the controller, the shutdown
+ * handler no longer needed -- deregister it from PMF.
+ * (Harmless to call ohci_shutdown more than once, so no
+ * synchronization needed.)
+ */
+ ohci_shutdown(self, 0);
pmf_device_deregister(self);
- rv = ohci_detach(&sc->sc_ohci, flags);
- if (rv != 0)
- return rv;
-
+ /*
+ * Interrupts are blocked at the device level by ohci_shutdown.
+ * Disestablish the interrupt handler. This waits for it to
+ * complete on all CPUs.
+ */
if (sc->sc_ih != NULL) {
ra_intr_disestablish(sc->sc_ih);
sc->sc_ih = NULL;
}
- if (sc->sc_ohci.sc_size == 0) {
+ /*
+ * Free the bus-independent ohci(4) state now that the
+ * interrupt handler has ceased to run on all CPUs.
+ */
+ ohci_detach(&sc->sc_ohci);
+
+ /*
+ * Unmap the registers now that we're all done with them.
+ */
+ if (sc->sc_ohci.sc_size) {
bus_space_unmap(sc->sc_ohci.iot, sc->sc_ohci.ioh,
- sc->sc_ohci.sc_size);
+ sc->sc_ohci.sc_size);
sc->sc_ohci.sc_size = 0;
}
-#if NEHCI > 0
- ralink_usb_hc_rem(&sc->sc_hc);
-#endif
-
return 0;
}
diff -r 63a5958e843d -r e419e0cd0295 sys/dev/cardbus/ehci_cardbus.c
--- a/sys/dev/cardbus/ehci_cardbus.c Sun Mar 30 16:22:37 2025 +0000
+++ b/sys/dev/cardbus/ehci_cardbus.c Sun Mar 30 20:18:14 2025 +0000
@@ -82,7 +82,7 @@ CFATTACH_DECL_NEW(ehci_cardbus, sizeof(s
ehci_activate);
static TAILQ_HEAD(, usb_cardbus) ehci_cardbus_alldevs =
- TAILQ_HEAD_INITIALIZER(ehci_cardbus_alldevs);
+ TAILQ_HEAD_INITIALIZER(ehci_cardbus_alldevs);
int
ehci_cardbus_match(device_t parent, cfdata_t match, void *aux)
@@ -175,6 +175,7 @@ ehci_cardbus_attach(device_t parent, dev
* have lower function numbers so they should be enumerated already.
*/
ncomp = 0;
+ KASSERT(KERNEL_LOCKED_P()); /* XXXSMP ehci_cardbus_alldevs */
TAILQ_FOREACH(up, &ehci_cardbus_alldevs, next) {
if (up->bus == ca->ca_bus) {
DPRINTF(("ehci_cardbus_attach: companion %s\n",
@@ -232,6 +233,9 @@ void
usb_cardbus_add(struct usb_cardbus *up, struct cardbus_attach_args *ca,
device_t bu)
{
+
+ KASSERT(KERNEL_LOCKED_P()); /* XXXSMP ehci_cardbus_alldevs */
+
TAILQ_INSERT_TAIL(&ehci_cardbus_alldevs, up, next);
up->bus = ca->ca_bus;
up->function = ca->ca_function;
@@ -241,5 +245,9 @@ usb_cardbus_add(struct usb_cardbus *up,
void
usb_cardbus_rem(struct usb_cardbus *up)
{
- TAILQ_REMOVE(&ehci_cardbus_alldevs, up, next);
+
+ KASSERT(KERNEL_LOCKED_P()); /* XXXSMP ehci_cardbus_alldevs */
+
+ if (up->usb)
+ TAILQ_REMOVE(&ehci_cardbus_alldevs, up, next);
}
diff -r 63a5958e843d -r e419e0cd0295 sys/dev/cardbus/ohci_cardbus.c
--- a/sys/dev/cardbus/ohci_cardbus.c Sun Mar 30 16:22:37 2025 +0000
+++ b/sys/dev/cardbus/ohci_cardbus.c Sun Mar 30 20:18:14 2025 +0000
@@ -175,22 +175,58 @@ ohci_cardbus_detach(device_t self, int f
{
struct ohci_cardbus_softc *sc = device_private(self);
struct cardbus_devfunc *ct = sc->sc_ct;
- int rv;
+ int error;
+
+ /*
+ * Detach the USB child first. Disconnects all USB devices and
+ * prevents connecting new ones.
+ */
+ error = config_detach_children(self, flags);
+ if (error)
+ return error;
- rv = ohci_detach(&sc->sc, flags);
- if (rv)
- return rv;
+ /*
+ * Stop listing this as a possible companion controller for
+ * ehci(4).
+ */
+#if NEHCI_CARDBUS > 0
+ usb_cardbus_rem(&sc->sc_cardbus);
+#endif
+
+ /*
+ * Shut down the controller and block interrupts at the device
+ * level. Once we have shut down the controller, the shutdown
+ * handler no longer needed -- deregister it from PMF.
+ * (Harmless to call ohci_shutdown more than once, so no
+ * synchronization needed.)
+ */
+ ohci_shutdown(self, 0);
+ pmf_device_deregister(self);
+
+ /*
+ * Interrupts are blocked at the device level by ohci_shutdown.
+ * Disestablish the interrupt handler. This waits for it to
+ * complete on all CPUs.
+ */
if (sc->sc_ih != NULL) {
Cardbus_intr_disestablish(ct, sc->sc_ih);
sc->sc_ih = NULL;
}
+
+ /*
+ * Free the bus-independent ohci(4) state now that the
+ * interrupt handler has ceased to run on all CPUs.
+ */
+ ohci_detach(&sc->sc);
+
+ /*
+ * Unmap the registers now that we're all done with them.
+ */
if (sc->sc.sc_size) {
Cardbus_mapreg_unmap(ct, PCI_CBMEM, sc->sc.iot,
sc->sc.ioh, sc->sc.sc_size);
sc->sc.sc_size = 0;
}
-#if NEHCI_CARDBUS > 0
- usb_cardbus_rem(&sc->sc_cardbus);
-#endif
+
return 0;
}
diff -r 63a5958e843d -r e419e0cd0295 sys/dev/pci/ehci_pci.c
--- a/sys/dev/pci/ehci_pci.c Sun Mar 30 16:22:37 2025 +0000
+++ b/sys/dev/pci/ehci_pci.c Sun Mar 30 20:18:14 2025 +0000
@@ -243,6 +243,7 @@ ehci_pci_attach(device_t parent, device_
const u_int maxncomp = EHCI_HCS_N_CC(EREAD4(&sc->sc, EHCI_HCSPARAMS));
KASSERT(maxncomp <= EHCI_COMPANION_MAX);
ncomp = 0;
+ KASSERT(KERNEL_LOCKED_P()); /* XXXSMP ehci_pci_alldevs */
TAILQ_FOREACH(up, &ehci_pci_alldevs, next) {
if (up->bus == pa->pa_bus && up->device == pa->pa_device &&
!up->claimed) {
diff -r 63a5958e843d -r e419e0cd0295 sys/dev/pci/ohci_pci.c
--- a/sys/dev/pci/ohci_pci.c Sun Mar 30 16:22:37 2025 +0000
+++ b/sys/dev/pci/ohci_pci.c Sun Mar 30 20:18:14 2025 +0000
@@ -187,33 +187,58 @@ static int
ohci_pci_detach(device_t self, int flags)
{
struct ohci_pci_softc *sc = device_private(self);
- int rv;
+ int error;
+
+ /*
+ * Detach the USB child first. Disconnects all USB devices and
+ * prevents connecting new ones.
+ */
+ error = config_detach_children(self, flags);
+ if (error)
+ return error;
- rv = ohci_detach(&sc->sc, flags);
- if (rv)
- return rv;
+ /*
+ * Stop listing this as a possible companion controller for
+ * ehci(4).
+ */
+#if NEHCI > 0
+ usb_pci_rem(&sc->sc_pci);
+#endif
+ /*
+ * Shut down the controller and block interrupts at the device
+ * level. Once we have shut down the controller, the shutdown
+ * handler no longer needed -- deregister it from PMF.
+ * (Harmless to call ohci_shutdown more than once, so no
+ * synchronization needed.)
+ */
+ ohci_shutdown(self, 0);
pmf_device_deregister(self);
- ohci_shutdown(self, flags);
-
- if (sc->sc.sc_size) {
- /* Disable interrupts, so we don't get any spurious ones. */
- bus_space_write_4(sc->sc.iot, sc->sc.ioh,
- OHCI_INTERRUPT_DISABLE, OHCI_ALL_INTRS);
- }
-
+ /*
+ * Interrupts are blocked at the device level by ohci_shutdown.
+ * Disestablish the interrupt handler. This waits for it to
+ * complete on all CPUs.
+ */
if (sc->sc_ih != NULL) {
pci_intr_disestablish(sc->sc_pc, sc->sc_ih);
sc->sc_ih = NULL;
}
+
+ /*
+ * Free the bus-independent ohci(4) state now that the
+ * interrupt handler has ceased to run on all CPUs.
+ */
+ ohci_detach(&sc->sc);
+
+ /*
+ * Unmap the registers now that we're all done with them.
+ */
if (sc->sc.sc_size) {
bus_space_unmap(sc->sc.iot, sc->sc.ioh, sc->sc.sc_size);
sc->sc.sc_size = 0;
}
-#if NEHCI > 0
- usb_pci_rem(&sc->sc_pci);
-#endif
+
return 0;
}
diff -r 63a5958e843d -r e419e0cd0295 sys/dev/pci/usb_pci.c
--- a/sys/dev/pci/usb_pci.c Sun Mar 30 16:22:37 2025 +0000
+++ b/sys/dev/pci/usb_pci.c Sun Mar 30 20:18:14 2025 +0000
@@ -33,28 +33,31 @@
__KERNEL_RCSID(0, "$NetBSD: usb_pci.c,v 1.7 2008/04/28 20:23:55 martin Exp $");
#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/proc.h>
+#include <sys/queue.h>
#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/queue.h>
-#include <sys/proc.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/usb_pci.h>
#include <dev/usb/usb.h>
+#include <dev/usb/usb_mem.h>
#include <dev/usb/usbdi.h>
#include <dev/usb/usbdivar.h>
-#include <dev/usb/usb_mem.h>
#include <dev/usb/ehcireg.h>
#include <dev/usb/ehcivar.h>
struct usb_pci_alldevs ehci_pci_alldevs =
- TAILQ_HEAD_INITIALIZER(ehci_pci_alldevs);
+ TAILQ_HEAD_INITIALIZER(ehci_pci_alldevs);
void
usb_pci_add(struct usb_pci *up, struct pci_attach_args *pa, device_t bu)
{
+
+ KASSERT(KERNEL_LOCKED_P()); /* XXXSMP ehci_pci_alldevs */
+
TAILQ_INSERT_TAIL(&ehci_pci_alldevs, up, next);
up->bus = pa->pa_bus;
up->device = pa->pa_device;
@@ -65,5 +68,9 @@ usb_pci_add(struct usb_pci *up, struct p
void
usb_pci_rem(struct usb_pci *up)
{
- TAILQ_REMOVE(&ehci_pci_alldevs, up, next);
+
+ KASSERT(KERNEL_LOCKED_P()); /* XXXSMP ehci_pci_alldevs */
+
+ if (up->usb)
+ TAILQ_REMOVE(&ehci_pci_alldevs, up, next);
}
diff -r 63a5958e843d -r e419e0cd0295 sys/dev/usb/ohci.c
--- a/sys/dev/usb/ohci.c Sun Mar 30 16:22:37 2025 +0000
+++ b/sys/dev/usb/ohci.c Sun Mar 30 20:18:14 2025 +0000
@@ -368,16 +368,14 @@ ohci_childdet(device_t self, device_t ch
sc->sc_child = NULL;
}
-int
-ohci_detach(struct ohci_softc *sc, int flags)
+void
+ohci_detach(struct ohci_softc *sc)
{
- int rv = 0;
-
- if (sc->sc_child != NULL)
- rv = config_detach(sc->sc_child, flags);
-
- if (rv != 0)
- return rv;
+
+ KASSERT(sc->sc_child == NULL);
+
+ if (!sc->sc_attached)
+ return;
softint_disestablish(sc->sc_rhsc_si);
@@ -391,8 +389,6 @@ ohci_detach(struct ohci_softc *sc, int f
usb_freemem(&sc->sc_hccadma);
pool_cache_destroy(sc->sc_xferpool);
cv_destroy(&sc->sc_abort_cv);
-
- return rv;
}
ohci_soft_ed_t *
@@ -1092,6 +1088,7 @@ ohci_init(ohci_softc_t *sc)
DPRINTF("enabling %#jx", sc->sc_eintrs | OHCI_MIE, 0, 0, 0);
OWRITE4(sc, OHCI_INTERRUPT_ENABLE, sc->sc_eintrs | OHCI_MIE);
+ sc->sc_attached = true;
return 0;
bad5:
@@ -1166,6 +1163,9 @@ ohci_shutdown(device_t self, int flags)
OHCIHIST_FUNC(); OHCIHIST_CALLED();
+ if (!sc->sc_attached)
+ return true;
+
DPRINTF("stopping the HC", 0, 0, 0, 0);
OWRITE4(sc, OHCI_INTERRUPT_DISABLE, OHCI_ALL_INTRS);
OWRITE4(sc, OHCI_CONTROL, OHCI_SET_HCFS(OHCI_HCFS_RESET));
diff -r 63a5958e843d -r e419e0cd0295 sys/dev/usb/ohcivar.h
--- a/sys/dev/usb/ohcivar.h Sun Mar 30 16:22:37 2025 +0000
+++ b/sys/dev/usb/ohcivar.h Sun Mar 30 20:18:14 2025 +0000
@@ -90,6 +90,7 @@ typedef struct ohci_softc {
bus_space_tag_t iot;
bus_space_handle_t ioh;
bus_size_t sc_size;
+ bool sc_attached;
kmutex_t sc_lock;
kmutex_t sc_intr_lock;
@@ -172,7 +173,7 @@ struct ohci_xfer {
int ohci_init(ohci_softc_t *);
int ohci_intr(void *);
-int ohci_detach(ohci_softc_t *, int);
+void ohci_detach(ohci_softc_t *);
bool ohci_shutdown(device_t, int);
void ohci_childdet(device_t, device_t);
int ohci_activate(device_t, enum devact);
diff -r 63a5958e843d -r e419e0cd0295 sys/dev/usb/usbdivar.h
--- a/sys/dev/usb/usbdivar.h Sun Mar 30 16:22:37 2025 +0000
+++ b/sys/dev/usb/usbdivar.h Sun Mar 30 20:18:14 2025 +0000
@@ -74,9 +74,11 @@
*
*/
+#include <sys/bus.h>
#include <sys/callout.h>
#include <sys/mutex.h>
-#include <sys/bus.h>
+
+#include <dev/usb/usbdi.h>
/* From usb_mem.h */
struct usb_dma_block;
Home |
Main Index |
Thread Index |
Old Index