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 :)
This commit is contained in:
bouyer 2009-03-06 23:40:50 +00:00
parent 84c870d611
commit dbac012ecf
1 changed files with 6 additions and 5 deletions

View File

@ -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 <sys/cdefs.h>
__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 <sys/param.h>
#include <sys/systm.h>
@ -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