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