From dbac012ecf692e7185e279afc76cd9b3ff46fe30 Mon Sep 17 00:00:00 2001 From: bouyer Date: Fri, 6 Mar 2009 23:40:50 +0000 Subject: [PATCH] Make it safe to call uhci_init() from a kernel thread with interrupts enabled: - don't enable interrupts before calling uhci_run() - check if the controller's interrupt is enabled in uhci_intr() The issue is that uhci_run() may tsleep(), uhci_intr1() may be called before uhci_run() is complete and disable it because it found it halted. Now a uhci controller can be successfully exported to a NetBSD Xen domU :) --- sys/dev/usb/uhci.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/sys/dev/usb/uhci.c b/sys/dev/usb/uhci.c index 9c654179edd1..df48c59fe5ce 100644 --- a/sys/dev/usb/uhci.c +++ b/sys/dev/usb/uhci.c @@ -1,4 +1,4 @@ -/* $NetBSD: uhci.c,v 1.224 2008/12/16 22:35:36 christos Exp $ */ +/* $NetBSD: uhci.c,v 1.225 2009/03/06 23:40:50 bouyer Exp $ */ /* $FreeBSD: src/sys/dev/usb/uhci.c,v 1.33 1999/11/17 22:33:41 n_hibma Exp $ */ /* @@ -42,7 +42,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: uhci.c,v 1.224 2008/12/16 22:35:36 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uhci.c,v 1.225 2009/03/06 23:40:50 bouyer Exp $"); #include #include @@ -563,10 +563,11 @@ uhci_init(uhci_softc_t *sc) UHCICMD(sc, UHCI_CMD_MAXP); /* Assume 64 byte packets at frame end */ DPRINTFN(1,("uhci_init: enabling\n")); + + err = uhci_run(sc, 1); /* and here we go... */ UWRITE2(sc, UHCI_INTR, UHCI_INTR_TOCRCIE | UHCI_INTR_RIE | UHCI_INTR_IOCE | UHCI_INTR_SPIE); /* enable interrupts */ - - return (uhci_run(sc, 1)); /* and here we go... */ + return err; } #if defined(__NetBSD__) || defined(__OpenBSD__) @@ -1309,7 +1310,7 @@ uhci_intr(void *arg) if (sc->sc_dying || !device_has_power(sc->sc_dev)) return (0); - if (sc->sc_bus.use_polling) { + if (sc->sc_bus.use_polling || UREAD2(sc, UHCI_INTR) == 0) { #ifdef DIAGNOSTIC DPRINTFN(16, ("uhci_intr: ignored interrupt while polling\n")); #endif