diff options
author | joerg <joerg@FreeBSD.org> | 2001-06-14 15:08:40 +0000 |
---|---|---|
committer | joerg <joerg@FreeBSD.org> | 2001-06-14 15:08:40 +0000 |
commit | ad173225baec589e8442cfc1d75b32843b41bdcc (patch) | |
tree | 95132fd0a117455920b0ed84ad389bd6fe0cc2c8 /sys/contrib | |
parent | 95c8aa86caf18813f7c1c2d30d529d754d8c93cc (diff) | |
download | FreeBSD-src-ad173225baec589e8442cfc1d75b32843b41bdcc.zip FreeBSD-src-ad173225baec589e8442cfc1d75b32843b41bdcc.tar.gz |
Do only call oltr_stop() if we are not already in OL_STOPPED state.
This avoids a null pointer deref panic in TRlldClose() inside the
vendor-supplied object code. It's now possible to unload the driver
at all.
Implement deallocation of malloc()ed memory regions.
MFC after: 2 months
Diffstat (limited to 'sys/contrib')
-rw-r--r-- | sys/contrib/dev/oltr/if_oltr.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/sys/contrib/dev/oltr/if_oltr.c b/sys/contrib/dev/oltr/if_oltr.c index 4df1268..21c36e1 100644 --- a/sys/contrib/dev/oltr/if_oltr.c +++ b/sys/contrib/dev/oltr/if_oltr.c @@ -439,14 +439,15 @@ oltr_pci_detach(device_t dev) { struct oltr_softc *sc = device_get_softc(dev); struct ifnet *ifp = &sc->arpcom.ac_if; - int s; + int s, i; device_printf(dev, "driver unloading\n"); s = splimp(); if_detach(ifp); - oltr_stop(sc); + if (sc->state > OL_CLOSED) + oltr_stop(sc); untimeout(oltr_poll, (void *)sc, sc->oltr_poll_ch); /*untimeout(oltr_stat, (void *)sc, sc->oltr_stat_ch);*/ @@ -454,6 +455,15 @@ oltr_pci_detach(device_t dev) bus_teardown_intr(dev, sc->oltr_irq, sc->oltr_intrhand); bus_release_resource(dev, SYS_RES_IRQ, 0, sc->oltr_irq); + /* Deallocate all dynamic memory regions */ + for (i = 0; i < RING_BUFFER_LEN; i++) { + free(sc->rx_ring[i].data, M_DEVBUF); + free(sc->tx_ring[i].data, M_DEVBUF); + } + if (sc->work_memory) + free(sc->work_memory, M_DEVBUF); + free(sc->TRlldAdapter, M_DEVBUF); + (void)splx(s); return(0); @@ -466,7 +476,8 @@ oltr_pci_shutdown(device_t dev) device_printf(dev, "oltr_pci_shutdown called\n"); - oltr_stop(sc); + if (sc->state > OL_CLOSED) + oltr_stop(sc); return; } |