diff options
author | simokawa <simokawa@FreeBSD.org> | 2003-02-18 09:39:48 +0000 |
---|---|---|
committer | simokawa <simokawa@FreeBSD.org> | 2003-02-18 09:39:48 +0000 |
commit | 3b267173bf6438c7ad203678578c32ad2fad0baa (patch) | |
tree | b97b6c4a011401c09db3ae103bc57c575c8462b6 /sys | |
parent | f0bd4843819bd45fd7808e5238f3f85a0c4658dc (diff) | |
download | FreeBSD-src-3b267173bf6438c7ad203678578c32ad2fad0baa.zip FreeBSD-src-3b267173bf6438c7ad203678578c32ad2fad0baa.tar.gz |
* firewire.c
- Fix memory leak in detaching.
- Initialize fc->status to other than FWBUSREST.
* fwohci.c
- Ignore BUS reset events while BUS reset phase. We can't clear that flag
during bus reset phase.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/firewire/firewire.c | 6 | ||||
-rw-r--r-- | sys/dev/firewire/fwohci.c | 14 |
2 files changed, 19 insertions, 1 deletions
diff --git a/sys/dev/firewire/firewire.c b/sys/dev/firewire/firewire.c index a7af161..7985743 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 3e48b37..6a6addb 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); } } |