On 19/05/17(Fri) 15:28, Bryan Steele wrote: > Still noticing this, kind of disappears when X is running.. *hand wavey* > > May 19th amd64 snap
Could you try the diff below? Index: ohci.c =================================================================== RCS file: /cvs/src/sys/dev/usb/ohci.c,v retrieving revision 1.150 diff -u -p -r1.150 ohci.c --- ohci.c 15 May 2017 10:52:08 -0000 1.150 +++ ohci.c 23 May 2017 11:00:55 -0000 @@ -3,12 +3,14 @@ /* $FreeBSD: src/sys/dev/usb/ohci.c,v 1.22 1999/11/17 22:33:40 n_hibma Exp $ */ /* - * Copyright (c) 1998 The NetBSD Foundation, Inc. + * Copyright (c) 1998, 2005 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation * by Lennart Augustsson ([email protected]) at * Carlstedt Research & Technology. + * This code is derived from software contributed to The NetBSD Foundation + * by Charles M. Hannum. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -90,7 +92,6 @@ usbd_status ohci_open(struct usbd_pipe * int ohci_setaddr(struct usbd_device *, int); void ohci_poll(struct usbd_bus *); void ohci_softintr(void *); -void ohci_add_done(struct ohci_softc *, ohci_physaddr_t); void ohci_rhsc(struct ohci_softc *, struct usbd_xfer *); usbd_status ohci_device_request(struct usbd_xfer *xfer); @@ -149,7 +150,6 @@ usbd_status ohci_device_setintr(struct o void ohci_timeout(void *); void ohci_timeout_task(void *); -void ohci_rhsc_able(struct ohci_softc *, int); void ohci_rhsc_enable(void *); void ohci_close_pipe(struct usbd_pipe *, struct ohci_soft_ed *); @@ -1016,7 +1016,6 @@ int ohci_intr1(struct ohci_softc *sc) { u_int32_t intrs, eintrs; - ohci_physaddr_t done; DPRINTFN(14,("ohci_intr1: enter\n")); @@ -1028,28 +1027,11 @@ ohci_intr1(struct ohci_softc *sc) return (0); } - intrs = 0; - done = letoh32(sc->sc_hcca->hcca_done_head); - if (done != 0) { - if (done & ~OHCI_DONE_INTRS) - intrs = OHCI_WDH; - if (done & OHCI_DONE_INTRS) - intrs |= OREAD4(sc, OHCI_INTERRUPT_STATUS); - sc->sc_hcca->hcca_done_head = 0; - } else { - intrs = OREAD4(sc, OHCI_INTERRUPT_STATUS); - /* If we've flushed out a WDH then reread */ - if (intrs & OHCI_WDH) { - done = letoh32(sc->sc_hcca->hcca_done_head); - sc->sc_hcca->hcca_done_head = 0; - } - } - + intrs = OREAD4(sc, OHCI_INTERRUPT_STATUS); if (intrs == 0xffffffff) { sc->sc_bus.dying = 1; return (0); } - if (!intrs) return (0); @@ -1059,11 +1041,7 @@ ohci_intr1(struct ohci_softc *sc) if (!eintrs) return (0); - sc->sc_bus.intr_context++; sc->sc_bus.no_intrs++; - DPRINTFN(7, ("ohci_intr: sc=%p intrs=0x%x(0x%x) eintrs=0x%x\n", - sc, (u_int)intrs, OREAD4(sc, OHCI_INTERRUPT_STATUS), - (u_int)eintrs)); if (eintrs & OHCI_SO) { sc->sc_overrun_cnt++; @@ -1076,7 +1054,6 @@ ohci_intr1(struct ohci_softc *sc) eintrs &= ~OHCI_SO; } if (eintrs & OHCI_WDH) { - ohci_add_done(sc, done &~ OHCI_DONE_INTRS); usb_schedsoftintr(&sc->sc_bus); eintrs &= ~OHCI_WDH; } @@ -1091,47 +1068,24 @@ ohci_intr1(struct ohci_softc *sc) /* XXX what else */ } if (eintrs & OHCI_RHSC) { - ohci_rhsc(sc, sc->sc_intrxfer); - /* - * Disable RHSC interrupt for now, because it will be - * on until the port has been reset. - */ - ohci_rhsc_able(sc, 0); - DPRINTFN(2, ("%s: rhsc interrupt disabled\n", - sc->sc_bus.bdev.dv_xname)); - + atomic_setbits_int(&sc->sc_flags, OHCIF_RHSC_INTR); + usb_schedsoftintr(&sc->sc_bus); /* Do not allow RHSC interrupts > 1 per second */ timeout_add_sec(&sc->sc_tmo_rhsc, 1); - eintrs &= ~OHCI_RHSC; } - sc->sc_bus.intr_context--; - if (eintrs != 0) { - /* Block unprocessed interrupts. XXX */ + /* Block unprocessed interrupts. */ OWRITE4(sc, OHCI_INTERRUPT_DISABLE, eintrs); sc->sc_eintrs &= ~eintrs; - printf("%s: blocking intrs 0x%x\n", - sc->sc_bus.bdev.dv_xname, eintrs); + DPRINTFN(1, ("%s: blocking intrs 0x%x\n", + sc->sc_bus.bdev.dv_xname, eintrs)); } return (1); } void -ohci_rhsc_able(struct ohci_softc *sc, int on) -{ - DPRINTFN(4, ("ohci_rhsc_able: on=%d\n", on)); - if (on) { - sc->sc_eintrs |= OHCI_RHSC; - OWRITE4(sc, OHCI_INTERRUPT_ENABLE, OHCI_RHSC); - } else { - sc->sc_eintrs &= ~OHCI_RHSC; - OWRITE4(sc, OHCI_INTERRUPT_DISABLE, OHCI_RHSC); - } -} - -void ohci_rhsc_enable(void *v_sc) { struct ohci_softc *sc = v_sc; @@ -1141,11 +1095,8 @@ ohci_rhsc_enable(void *v_sc) return; s = splhardusb(); - ohci_rhsc(sc, sc->sc_intrxfer); - DPRINTFN(2, ("%s: rhsc interrupt enabled\n", - sc->sc_bus.bdev.dv_xname)); - - ohci_rhsc_able(sc, 1); + sc->sc_eintrs |= OHCI_RHSC; + OWRITE4(sc, OHCI_INTERRUPT_ENABLE, OHCI_RHSC); splx(s); } @@ -1171,10 +1122,39 @@ char *ohci_cc_strs[] = { #endif void -ohci_add_done(struct ohci_softc *sc, ohci_physaddr_t done) +ohci_softintr(void *v) { - struct ohci_soft_itd *sitd, *sidone, **ip; - struct ohci_soft_td *std, *sdone, **p; + struct ohci_softc *sc = v; + struct ohci_soft_itd *sitd, *sidone, *sitdnext; + struct ohci_soft_td *std, *sdone, *stdnext; + struct usbd_xfer *xfer; + struct ohci_pipe *opipe; + int len, cc, s; + int i, j, actlen, iframes, uedir; + ohci_physaddr_t done = 0; + + DPRINTFN(10,("ohci_softintr: enter\n")); + + if (sc->sc_bus.dying) + return; + + sc->sc_bus.intr_context++; + + if (sc->sc_flags & OHCIF_RHSC_INTR) { + atomic_clearbits_int(&sc->sc_flags, OHCIF_RHSC_INTR); + ohci_rhsc(sc, sc->sc_intrxfer); + } + + s = splhardusb(); + usb_syncmem(&sc->sc_hccadma, offsetof(struct ohci_hcca, hcca_done_head), + sizeof(sc->sc_hcca->hcca_done_head), + BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); + done = le32toh(sc->sc_hcca->hcca_done_head) & ~OHCI_DONE_INTRS; + sc->sc_hcca->hcca_done_head = 0; + usb_syncmem(&sc->sc_hccadma, offsetof(struct ohci_hcca, hcca_done_head), + sizeof(sc->sc_hcca->hcca_done_head), + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); + splx(s); /* Reverse the done list. */ for (sdone = NULL, sidone = NULL; done != 0; ) { @@ -1194,44 +1174,9 @@ ohci_add_done(struct ohci_softc *sc, ohc DPRINTFN(5,("add ITD %p\n", sitd)); continue; } - panic("ohci_add_done: addr 0x%08lx not found", (u_long)done); + panic("addr 0x%08lx not found", (u_long)done); } - /* sdone & sidone now hold the done lists. */ - /* Put them on the already processed lists. */ - for (p = &sc->sc_sdone; *p != NULL; p = &(*p)->dnext) - ; - *p = sdone; - for (ip = &sc->sc_sidone; *ip != NULL; ip = &(*ip)->dnext) - ; - *ip = sidone; -} - -void -ohci_softintr(void *v) -{ - struct ohci_softc *sc = v; - struct ohci_soft_itd *sitd, *sidone, *sitdnext; - struct ohci_soft_td *std, *sdone, *stdnext; - struct usbd_xfer *xfer; - struct ohci_pipe *opipe; - int len, cc, s; - int i, j, actlen, iframes, uedir; - - DPRINTFN(10,("ohci_softintr: enter\n")); - - if (sc->sc_bus.dying) - return; - - sc->sc_bus.intr_context++; - - s = splhardusb(); - sdone = sc->sc_sdone; - sc->sc_sdone = NULL; - sidone = sc->sc_sidone; - sc->sc_sidone = NULL; - splx(s); - DPRINTFN(10,("ohci_softintr: sdone=%p sidone=%p\n", sdone, sidone)); #ifdef OHCI_DEBUG @@ -2435,7 +2380,7 @@ ohci_root_ctrl_start(struct usbd_xfer *x case UHF_C_PORT_RESET: /* Enable RHSC interrupt if condition is cleared. */ if ((OREAD4(sc, port) >> 16) == 0) - ohci_rhsc_able(sc, 1); + ohci_rhsc_enable(sc); break; default: break; Index: ohcivar.h =================================================================== RCS file: /cvs/src/sys/dev/usb/ohcivar.h,v retrieving revision 1.37 diff -u -p -r1.37 ohcivar.h --- ohcivar.h 16 May 2014 18:17:03 -0000 1.37 +++ ohcivar.h 23 May 2017 10:31:49 -0000 @@ -82,6 +82,8 @@ struct ohci_softc { bus_space_tag_t iot; bus_space_handle_t ioh; bus_size_t sc_size; + int sc_flags; /* misc flags */ +#define OHCIF_RHSC_INTR 0x01 struct usb_dma sc_hccadma; struct ohci_hcca *sc_hcca; @@ -106,9 +108,6 @@ struct ohci_softc { struct ohci_soft_itd *sc_freeitds; struct usbd_xfer *sc_intrxfer; - - struct ohci_soft_itd *sc_sidone; - struct ohci_soft_td *sc_sdone; char sc_vendor[16]; int sc_id_vendor;
