Module Name: src
Committed By: jmcneill
Date: Mon Sep 25 00:03:11 UTC 2017
Modified Files:
src/sys/dev/usb: xhci.c xhcivar.h
Log Message:
If the bus glue calls xhci_init with interrupts enabled, there is a window
between when xhci interrupts are enabled and the usb bus driver is
attached. If an irq occurs in this window, xhci will attempt to schedule
a softint with an invalid softint handle.
Add a quirk flag, XHCI_DEFERRED_START, that when set skips starting the
controller at the end of xhci_init. Bus glue that sets this is responsible
to call xhci_start after attaching the child usb devices.
To generate a diff of this commit:
cvs rdiff -u -r1.73 -r1.74 src/sys/dev/usb/xhci.c
cvs rdiff -u -r1.7 -r1.8 src/sys/dev/usb/xhcivar.h
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/xhci.c
diff -u src/sys/dev/usb/xhci.c:1.73 src/sys/dev/usb/xhci.c:1.74
--- src/sys/dev/usb/xhci.c:1.73 Tue Aug 22 16:57:00 2017
+++ src/sys/dev/usb/xhci.c Mon Sep 25 00:03:10 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: xhci.c,v 1.73 2017/08/22 16:57:00 skrll Exp $ */
+/* $NetBSD: xhci.c,v 1.74 2017/09/25 00:03:10 jmcneill Exp $ */
/*
* Copyright (c) 2013 Jonathan A. Kollasch
@@ -34,7 +34,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xhci.c,v 1.73 2017/08/22 16:57:00 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xhci.c,v 1.74 2017/09/25 00:03:10 jmcneill Exp $");
#ifdef _KERNEL_OPT
#include "opt_usb.h"
@@ -891,6 +891,23 @@ xhci_ecp(struct xhci_softc *sc, uint32_t
"b\0AC64\0" \
"\0"
+void
+xhci_start(struct xhci_softc *sc)
+{
+ xhci_rt_write_4(sc, XHCI_IMAN(0), XHCI_IMAN_INTR_ENA);
+ if ((sc->sc_quirks & XHCI_QUIRK_INTEL) != 0)
+ /* Intel xhci needs interrupt rate moderated. */
+ xhci_rt_write_4(sc, XHCI_IMOD(0), XHCI_IMOD_DEFAULT_LP);
+ else
+ xhci_rt_write_4(sc, XHCI_IMOD(0), 0);
+ aprint_debug_dev(sc->sc_dev, "current IMOD %u\n",
+ xhci_rt_read_4(sc, XHCI_IMOD(0)));
+
+ xhci_op_write_4(sc, XHCI_USBCMD, XHCI_CMD_INTE|XHCI_CMD_RS); /* Go! */
+ aprint_debug_dev(sc->sc_dev, "USBCMD %08"PRIx32"\n",
+ xhci_op_read_4(sc, XHCI_USBCMD));
+}
+
int
xhci_init(struct xhci_softc *sc)
{
@@ -1168,18 +1185,8 @@ xhci_init(struct xhci_softc *sc)
XHCI_ERSTE_SIZE * XHCI_EVENT_RING_SEGMENTS);
#endif
- xhci_rt_write_4(sc, XHCI_IMAN(0), XHCI_IMAN_INTR_ENA);
- if ((sc->sc_quirks & XHCI_QUIRK_INTEL) != 0)
- /* Intel xhci needs interrupt rate moderated. */
- xhci_rt_write_4(sc, XHCI_IMOD(0), XHCI_IMOD_DEFAULT_LP);
- else
- xhci_rt_write_4(sc, XHCI_IMOD(0), 0);
- aprint_debug_dev(sc->sc_dev, "current IMOD %u\n",
- xhci_rt_read_4(sc, XHCI_IMOD(0)));
-
- xhci_op_write_4(sc, XHCI_USBCMD, XHCI_CMD_INTE|XHCI_CMD_RS); /* Go! */
- aprint_debug_dev(sc->sc_dev, "USBCMD %08"PRIx32"\n",
- xhci_op_read_4(sc, XHCI_USBCMD));
+ if ((sc->sc_quirks & XHCI_DEFERRED_START) == 0)
+ xhci_start(sc);
return 0;
Index: src/sys/dev/usb/xhcivar.h
diff -u src/sys/dev/usb/xhcivar.h:1.7 src/sys/dev/usb/xhcivar.h:1.8
--- src/sys/dev/usb/xhcivar.h:1.7 Thu Jan 19 16:05:00 2017
+++ src/sys/dev/usb/xhcivar.h Mon Sep 25 00:03:11 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: xhcivar.h,v 1.7 2017/01/19 16:05:00 skrll Exp $ */
+/* $NetBSD: xhcivar.h,v 1.8 2017/09/25 00:03:11 jmcneill Exp $ */
/*
* Copyright (c) 2013 Jonathan A. Kollasch
@@ -135,9 +135,11 @@ struct xhci_softc {
int sc_quirks;
#define XHCI_QUIRK_INTEL __BIT(0) /* Intel xhci chip */
+#define XHCI_DEFERRED_START __BIT(1)
};
int xhci_init(struct xhci_softc *);
+void xhci_start(struct xhci_softc *);
int xhci_intr(void *);
int xhci_detach(struct xhci_softc *, int);
int xhci_activate(device_t, enum devact);