summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorsimokawa <simokawa@FreeBSD.org>2003-02-18 09:39:48 +0000
committersimokawa <simokawa@FreeBSD.org>2003-02-18 09:39:48 +0000
commit3b267173bf6438c7ad203678578c32ad2fad0baa (patch)
treeb97b6c4a011401c09db3ae103bc57c575c8462b6 /sys
parentf0bd4843819bd45fd7808e5238f3f85a0c4658dc (diff)
downloadFreeBSD-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.c6
-rw-r--r--sys/dev/firewire/fwohci.c14
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);
}
}
OpenPOWER on IntegriCloud