On Thu, Feb 12, 2015 at 09:36:52AM +0100, Joerg Sonnenberger wrote: > Well, let's try the first hack of keep uhci interrupts off and just poll > via timeout.
Let's not forget the second part in the header ;) Joerg
Index: uhci.c =================================================================== RCS file: /home/joerg/repo/netbsd/src/sys/dev/usb/uhci.c,v retrieving revision 1.264 diff -u -p -r1.264 uhci.c --- uhci.c 5 Aug 2014 06:35:24 -0000 1.264 +++ uhci.c 12 Feb 2015 08:35:26 -0000 @@ -72,6 +72,11 @@ __KERNEL_RCSID(0, "$NetBSD: uhci.c,v 1.2 /*#define UHCI_CTL_LOOP */ +Static int uhci_intr1(uhci_softc_t *); +static void uhci_intr1_wrap(void *sc) +{ + uhci_intr1(sc); +} #ifdef UHCI_DEBUG uhci_softc_t *thesc; @@ -542,8 +547,11 @@ uhci_init(uhci_softc_t *sc) DPRINTFN(1,("uhci_init: enabling\n")); err = uhci_run(sc, 1, 0); /* and here we go... */ - UWRITE2(sc, UHCI_INTR, UHCI_INTR_TOCRCIE | UHCI_INTR_RIE | - UHCI_INTR_IOCE | UHCI_INTR_SPIE); /* enable interrupts */ + + callout_init(&sc->sc_simulated_interrupt, CALLOUT_MPSAFE); + callout_setfunc(&sc->sc_simulated_interrupt, uhci_intr1_wrap, sc); + callout_schedule(&sc->sc_simulated_interrupt, 1); + return err; } @@ -720,8 +728,6 @@ uhci_resume(device_t dv, const pmf_qual_ UHCICMD(sc, cmd | UHCI_CMD_FGR); /* force resume */ usb_delay_ms_locked(&sc->sc_bus, USB_RESUME_DELAY, &sc->sc_intr_lock); UHCICMD(sc, cmd & ~UHCI_CMD_EGSM); /* back to normal */ - UWRITE2(sc, UHCI_INTR, UHCI_INTR_TOCRCIE | - UHCI_INTR_RIE | UHCI_INTR_IOCE | UHCI_INTR_SPIE); UHCICMD(sc, UHCI_CMD_MAXP); uhci_run(sc, 1, 1); /* and start traffic again */ usb_delay_ms_locked(&sc->sc_bus, USB_RESUME_RECOVERY, &sc->sc_intr_lock); @@ -735,6 +741,7 @@ uhci_resume(device_t dv, const pmf_qual_ #endif sc->sc_suspend = PWR_RESUME; + callout_schedule(&sc->sc_simulated_interrupt, 1); mutex_spin_exit(&sc->sc_intr_lock); return true; @@ -1270,8 +1277,6 @@ uhci_remove_bulk(uhci_softc_t *sc, uhci_ sc->sc_bulk_end = pqh; } -Static int uhci_intr1(uhci_softc_t *); - int uhci_intr(void *arg) { @@ -1290,8 +1295,6 @@ uhci_intr(void *arg) goto done; } - ret = uhci_intr1(sc); - done: mutex_spin_exit(&sc->sc_intr_lock); return ret; @@ -1313,8 +1316,10 @@ uhci_intr1(uhci_softc_t *sc) KASSERT(mutex_owned(&sc->sc_intr_lock)); status = UREAD2(sc, UHCI_STS) & UHCI_STS_ALLINTRS; - if (status == 0) /* The interrupt was not for us. */ + if (status == 0) { /* The interrupt was not for us. */ + callout_schedule(&sc->sc_simulated_interrupt, 1); return (0); + } if (sc->sc_suspend != PWR_RESUME) { #ifdef DIAGNOSTIC @@ -1322,6 +1327,7 @@ uhci_intr1(uhci_softc_t *sc) device_xname(sc->sc_dev)); #endif UWRITE2(sc, UHCI_STS, status); /* acknowledge the ints */ + callout_schedule(&sc->sc_simulated_interrupt, 1); return (0); } @@ -1368,6 +1374,7 @@ uhci_intr1(uhci_softc_t *sc) DPRINTFN(15, ("%s: uhci_intr: exit\n", device_xname(sc->sc_dev))); + callout_schedule(&sc->sc_simulated_interrupt, 1); return (1); } Index: uhcivar.h =================================================================== RCS file: /home/joerg/repo/netbsd/src/sys/dev/usb/uhcivar.h,v retrieving revision 1.52 diff -u -p -r1.52 uhcivar.h --- uhcivar.h 29 Jan 2013 00:00:15 -0000 1.52 +++ uhcivar.h 12 Feb 2015 07:06:37 -0000 @@ -136,6 +136,7 @@ typedef struct uhci_softc { bus_space_tag_t iot; bus_space_handle_t ioh; bus_size_t sc_size; + struct callout sc_simulated_interrupt; kmutex_t sc_lock; kmutex_t sc_intr_lock;