diff --git a/sys/dev/firewire/firewire.c b/sys/dev/firewire/firewire.c index a7af161bd9d7..7985743e2d03 100644 --- a/sys/dev/firewire/firewire.c +++ b/sys/dev/firewire/firewire.c @@ -395,6 +395,7 @@ firewire_attach( device_t dev ) fc = (struct firewire_comm *)device_get_softc(pa); sc->fc = fc; + fc->status = -1; unitmask = UNIT2MIN(device_get_unit(dev)); @@ -475,6 +476,7 @@ static int firewire_detach( device_t dev ) { struct firewire_softc *sc; + struct csrdir *csrd, *next; sc = (struct firewire_softc *)device_get_softc(dev); @@ -488,6 +490,10 @@ firewire_detach( device_t dev ) } #endif /* XXX xfree_free and untimeout on all xfers */ + for (csrd = SLIST_FIRST(&sc->fc->csrfree); csrd != NULL; csrd = next) { + next = SLIST_NEXT(csrd, link); + free(csrd, M_FW); + } callout_stop(&sc->fc->timeout_callout); callout_stop(&sc->fc->bmr_callout); callout_stop(&sc->fc->retry_probe_callout); diff --git a/sys/dev/firewire/fwohci.c b/sys/dev/firewire/fwohci.c index 3e48b377cb71..6a6addb4c06e 100644 --- a/sys/dev/firewire/fwohci.c +++ b/sys/dev/firewire/fwohci.c @@ -1765,6 +1765,11 @@ fwohci_intr_body(struct fwohci_softc *sc, u_int32_t stat, int count) #endif /* Bus reset */ if(stat & OHCI_INT_PHY_BUS_R ){ + if (fc->status == FWBUSRESET) + goto busresetout; + /* Disable bus reset interrupt until sid recv. */ + OWRITE(sc, FWOHCI_INTMASKCLR, OHCI_INT_PHY_BUS_R); + device_printf(fc->dev, "BUS reset\n"); OWRITE(sc, FWOHCI_INTMASKCLR, OHCI_INT_CYC_LOST); OWRITE(sc, OHCI_LNKCTLCLR, OHCI_CNTL_CYCSRC); @@ -1786,6 +1791,7 @@ fwohci_intr_body(struct fwohci_softc *sc, u_int32_t stat, int count) OWRITE(sc, OHCI_PREQUPPER, 0x10000); } +busresetout: if((stat & OHCI_INT_DMA_IR )){ #ifndef ACK_ALL OWRITE(sc, FWOHCI_INTSTATCLR, OHCI_INT_DMA_IR); @@ -1849,6 +1855,8 @@ fwohci_intr_body(struct fwohci_softc *sc, u_int32_t stat, int count) #ifndef ACK_ALL OWRITE(sc, FWOHCI_INTSTATCLR, OHCI_INT_PHY_SID); #endif + /* Enable bus reset interrupt */ + OWRITE(sc, FWOHCI_INTMASK, OHCI_INT_PHY_BUS_R); /* ** Checking whether the node is root or not. If root, turn on ** cycle master. @@ -1928,7 +1936,7 @@ void fwohci_intr(void *arg) { struct fwohci_softc *sc = (struct fwohci_softc *)arg; - u_int32_t stat; + u_int32_t stat, bus_reset = 0; if (!(sc->intmask & OHCI_INT_EN)) { /* polling mode */ @@ -1944,6 +1952,10 @@ fwohci_intr(void *arg) #ifdef ACK_ALL OWRITE(sc, FWOHCI_INTSTATCLR, stat); #endif + /* We cannot clear bus reset event during bus reset phase */ + if ((stat & ~bus_reset) == 0) + return; + bus_reset = stat & OHCI_INT_PHY_BUS_R; fwohci_intr_body(sc, stat, -1); } }