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);

Reply via email to