Make sure that we call if_free(ifp) after bus_teardown_intr. Since we

could get an interrupt after we free the ifp, and the interrupt
handler depended on the ifp being still alive, this could, in theory,
cause a crash.  Eliminate this possibility by moving the if_free to
after the bus_teardown_intr() call.
This commit is contained in:
Warner Losh 2005-09-19 03:10:21 +00:00
parent 6763e7c1ed
commit ad4f426ef6
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=150306
31 changed files with 60 additions and 67 deletions

View file

@ -837,8 +837,8 @@ an_detach(device_t dev)
ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
AN_UNLOCK(sc);
ether_ifdetach(ifp);
if_free(ifp);
bus_teardown_intr(dev, sc->irq_res, sc->irq_handle);
if_free(ifp);
an_release_resources(dev);
mtx_destroy(&sc->an_mtx);
return (0);

View file

@ -324,13 +324,13 @@ arl_isa_detach(device_t dev)
arl_stop(sc);
ifmedia_removeall(&sc->arl_ifmedia);
bus_teardown_intr(dev, sc->irq_res, sc->irq_handle);
#if __FreeBSD_version < 500100
ether_ifdetach(sc->arl_ifp, ETHER_BPF_SUPPORTED);
#else
ether_ifdetach(sc->arl_ifp);
if_free(sc->arl_ifp);
#endif
bus_teardown_intr(dev, sc->irq_res, sc->irq_handle);
arl_release_resources(dev);
return (0);

View file

@ -153,8 +153,7 @@ awi_pccard_attach(device_t dev)
psc->sc_port_rid = 0;
psc->sc_port_res = bus_alloc_resource(dev, SYS_RES_IOPORT,
&psc->sc_port_rid, 0, ~0, 16,
rman_make_alignment_flags(64) | RF_ACTIVE);
&psc->sc_port_rid, 0, ~0, 16, RF_ACTIVE);
if (!psc->sc_port_res) {
device_printf(dev, "awi_pccard_attach: port alloc failed\n");
goto fail;
@ -176,7 +175,6 @@ awi_pccard_attach(device_t dev)
* XXX: awi needs to access memory with 8bit,
* but pccardd apparently maps memory with MDF_16BITS flag.
* So memory mapped access is disabled and use IO port instead.
* Also, memory mapping is not yet supported on pccard.
*/
psc->sc_mem_res = 0;
#else

View file

@ -111,10 +111,10 @@ cm_isa_detach(device_t dev)
s = splimp();
arc_ifdetach(ifp);
if_free(ifp);
splx(s);
bus_teardown_intr(dev, sc->irq_res, sc->irq_handle);
if_free(ifp);
cm_release_resources(dev);
return (0);

View file

@ -1599,8 +1599,8 @@ static int cnw_pccard_detach(dev)
cnw_stop(sc);
ether_ifdetach(ifp);
if_free(ifp);
cnw_free(dev);
if_free(ifp);
sc->cnw_gone = 1;
#if 0

View file

@ -1438,6 +1438,9 @@ static int cp_detach (device_t dev)
cp_reset (b, 0 ,0);
callout_stop (&led_timo[b->num]);
/* Disable the interrupt request. */
bus_teardown_intr (dev, bd->cp_irq, bd->cp_intrhand);
for (c=b->chan; c<b->chan+NCHAN; ++c) {
drv_t *d = (drv_t*) c->sys;
@ -1470,8 +1473,6 @@ static int cp_detach (device_t dev)
b->sys = NULL;
CP_UNLOCK (bd);
/* Disable the interrupt request. */
bus_teardown_intr (dev, bd->cp_irq, bd->cp_intrhand);
bus_deactivate_resource (dev, SYS_RES_IRQ, 0, bd->cp_irq);
bus_release_resource (dev, SYS_RES_IRQ, 0, bd->cp_irq);
bus_release_resource (dev, SYS_RES_MEMORY, PCIR_BAR(0), bd->cp_res);

View file

@ -696,8 +696,8 @@ cs_detach(device_t dev)
cs_stop(sc);
ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
ether_ifdetach(ifp);
if_free(ifp);
cs_release_resources(dev);
if_free(ifp);
return (0);
}

View file

@ -369,8 +369,8 @@ ed_detach(device_t dev)
callout_drain(&sc->tick_ch);
ether_ifdetach(ifp);
bus_teardown_intr(dev, sc->irq_res, sc->irq_handle);
if_free(ifp);
ed_release_resources(dev);
if_free(ifp);
ED_LOCK_DESTROY(sc);
return (0);
}

View file

@ -535,10 +535,12 @@ em_detach(device_t dev)
ether_ifdetach(adapter->ifp, ETHER_BPF_SUPPORTED);
#else
ether_ifdetach(adapter->ifp);
if_free(ifp);
#endif
em_free_pci_resources(adapter);
bus_generic_detach(dev);
#if __FreeBSD_version >= 500000
if_free(ifp);
#endif
/* Free Transmit Descriptor ring */
if (adapter->tx_desc_base) {

View file

@ -321,7 +321,6 @@ en_pci_detach(device_t dev)
*/
en_reset(sc);
atm_ifdetach(sc->ifp);
if_free(sc->ifp);
/*
* Deallocate resources.
@ -334,6 +333,7 @@ en_pci_detach(device_t dev)
* Free all the driver internal resources
*/
en_destroy(sc);
if_free(sc->ifp);
return (0);
}

View file

@ -360,10 +360,10 @@ ep_detach(device_t dev)
ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
ether_ifdetach(ifp);
if_free(ifp);
sc->gone = 1;
ep_free(dev);
if_free(ifp);
EP_LOCK_DESTROY(sc);
return (0);

View file

@ -187,8 +187,8 @@ fe_pccard_detach(device_t dev)
fe_stop(sc);
ether_ifdetach(ifp);
if_free(ifp);
bus_teardown_intr(dev, sc->irq_res, sc->irq_handle);
if_free(ifp);
fe_release_resource(dev);
return 0;

View file

@ -885,8 +885,6 @@ ndis_detach(dev)
ether_ifdetach(ifp);
} else
NDIS_UNLOCK(sc);
if (ifp != NULL)
if_free(ifp);
bus_generic_detach(dev);
@ -904,6 +902,9 @@ ndis_detach(dev)
bus_release_resource(dev, SYS_RES_MEMORY,
sc->ndis_altmem_rid, sc->ndis_res_altmem);
if (ifp != NULL)
if_free(ifp);
if (sc->ndis_iftype == PCMCIABus)
ndis_free_amem(sc);

View file

@ -391,7 +391,6 @@ ipw_detach(device_t dev)
if (ifp != NULL) {
bpfdetach(ifp);
ieee80211_ifdetach(ic);
if_free(ifp);
}
ipw_release(sc);
@ -403,6 +402,8 @@ ipw_detach(device_t dev)
if (sc->mem != NULL)
bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, sc->mem);
if (ifp != NULL)
if_free(ifp);
mtx_destroy(&sc->sc_mtx);

View file

@ -467,7 +467,6 @@ iwi_detach(device_t dev)
if (ifp != NULL) {
bpfdetach(ifp);
ieee80211_ifdetach(ic);
if_free(ifp);
}
iwi_free_cmd_ring(sc, &sc->cmdq);
@ -485,6 +484,8 @@ iwi_detach(device_t dev)
if (sc->mem != NULL)
bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, sc->mem);
if (ifp != NULL)
if_free(ifp);
mtx_destroy(&sc->sc_mtx);
return 0;

View file

@ -378,10 +378,11 @@ ixgb_detach(device_t dev)
ether_ifdetach(adapter->ifp, ETHER_BPF_SUPPORTED);
#else
ether_ifdetach(adapter->ifp);
if_free(adapter->ifp);
#endif
ixgb_free_pci_resources(adapter);
#if __FreeBSD_version >= 500000
if_free(adapter->ifp);
#endif
/* Free Transmit Descriptor ring */
if (adapter->tx_desc_base) {

View file

@ -627,7 +627,6 @@ lge_detach(dev)
lge_reset(sc);
lge_stop(sc);
ether_ifdetach(ifp);
if_free(ifp);
bus_generic_detach(dev);
device_delete_child(dev, sc->lge_miibus);
@ -637,6 +636,7 @@ lge_detach(dev)
bus_release_resource(dev, LGE_RES, LGE_RID, sc->lge_res);
contigfree(sc->lge_ldata, sizeof(struct lge_list_data), M_DEVBUF);
if_free(ifp);
lge_free_jumbo_mem(sc);
splx(s);

View file

@ -963,7 +963,6 @@ nge_detach(dev)
nge_stop(sc);
NGE_UNLOCK(sc);
ether_ifdetach(ifp);
if_free(ifp);
bus_generic_detach(dev);
if (!sc->nge_tbi) {
@ -974,6 +973,7 @@ nge_detach(dev)
bus_release_resource(dev, NGE_RES, NGE_RID, sc->nge_res);
contigfree(sc->nge_ldata, sizeof(struct nge_list_data), M_DEVBUF);
if_free(ifp);
NGE_LOCK_DESTROY(sc);

View file

@ -559,12 +559,10 @@ nve_detach(device_t dev)
if (device_is_attached(dev)) {
nve_stop(sc);
/* XXX shouldn't hold lock over call to ether_ifdetch */
ether_ifdetach(ifp);
}
if (ifp)
if_free(ifp);
if (sc->miibus)
device_delete_child(dev, sc->miibus);
bus_generic_detach(dev);
@ -601,6 +599,8 @@ nve_detach(device_t dev)
bus_dma_tag_destroy(sc->rtag);
NVE_UNLOCK(sc);
if (ifp)
if_free(ifp);
mtx_destroy(&sc->mtx);
mtx_destroy(&sc->osmtx);

View file

@ -531,7 +531,6 @@ ral_detach(device_t dev)
bpfdetach(ifp);
ieee80211_ifdetach(ic);
if_free(ifp);
ral_free_tx_ring(sc, &sc->txq);
ral_free_tx_ring(sc, &sc->atimq);
@ -540,6 +539,7 @@ ral_detach(device_t dev)
ral_free_rx_ring(sc, &sc->rxq);
bus_teardown_intr(dev, sc->irq, sc->sc_ih);
if_free(ifp);
ral_free(dev);
mtx_destroy(&sc->sc_mtx);

View file

@ -604,7 +604,6 @@ ray_detach(device_t dev)
sc->sc_c.np_havenet = 0;
ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
ether_ifdetach(ifp);
if_free(ifp);
/*
* Stop the runq and wake up anyone sleeping for us.
@ -627,6 +626,7 @@ ray_detach(device_t dev)
* Release resources
*/
ray_res_release(sc);
if_free(ifp);
RAY_DPRINTF(sc, RAY_DBG_STOP, "unloading complete");
splx(s);

View file

@ -1303,10 +1303,10 @@ re_detach(dev)
* stopped here.
*/
if (ifp != NULL)
if_free(ifp);
if (sc->rl_intrhand)
bus_teardown_intr(dev, sc->rl_irq, sc->rl_intrhand);
if (ifp != NULL)
if_free(ifp);
if (sc->rl_irq)
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->rl_irq);
if (sc->rl_res)

View file

@ -311,12 +311,13 @@ sbsh_detach(device_t dev)
sbsh_stop(sc);
ether_ifdetach(ifp);
if_free(ifp);
bus_teardown_intr(dev, sc->irq_res, sc->intr_hand);
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq_res);
bus_release_resource(dev, SYS_RES_MEMORY, PCIR_BAR(1), sc->mem_res);
if_free(ifp);
splx(s);
return (0);
}

View file

@ -44,23 +44,15 @@ __FBSDID("$FreeBSD$");
#include <dev/sio/siovar.h>
#include "pccarddevs.h"
static int sio_pccard_attach(device_t dev);
static int sio_pccard_match(device_t self);
static int sio_pccard_probe(device_t dev);
static device_method_t sio_pccard_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, pccard_compat_probe),
DEVMETHOD(device_attach, pccard_compat_attach),
DEVMETHOD(device_probe, sio_pccard_probe),
DEVMETHOD(device_attach, sio_pccard_attach),
DEVMETHOD(device_detach, siodetach),
/* Card interface */
DEVMETHOD(card_compat_match, sio_pccard_match),
DEVMETHOD(card_compat_probe, sio_pccard_probe),
DEVMETHOD(card_compat_attach, sio_pccard_attach),
{ 0, 0 }
};
@ -71,7 +63,7 @@ static driver_t sio_pccard_driver = {
};
static int
sio_pccard_match(device_t dev)
sio_pccard_probe(device_t dev)
{
int error = 0;
u_int32_t fcn = PCCARD_FUNCTION_UNSPEC;
@ -79,6 +71,7 @@ sio_pccard_match(device_t dev)
error = pccard_get_function(dev, &fcn);
if (error != 0)
return (error);
/*
* If a serial card, we are likely the right driver. However,
* some serial cards are better servered by other drivers, so
@ -86,27 +79,22 @@ sio_pccard_match(device_t dev)
*/
if (fcn == PCCARD_FUNCTION_SERIAL)
return (-100);
return(ENXIO);
}
static int
sio_pccard_probe(dev)
device_t dev;
{
#ifdef PC98
SET_FLAG(dev, SET_IFTYPE(COM_IF_MODEM_CARD));
#endif
/* Do not probe IRQ - pccard doesn't turn on the interrupt line */
/* until bus_setup_intr */
return (sioprobe(dev, 0, 0UL, 1));
return (ENXIO);
}
static int
sio_pccard_attach(dev)
device_t dev;
{
int err;
#ifdef PC98
SET_FLAG(dev, SET_IFTYPE(COM_IF_MODEM_CARD));
#endif
/* Do not probe IRQ - pccard doesn't turn on the interrupt line */
/* until bus_setup_intr */
if ((err = sioprobe(dev, 0, 0UL, 1)) != 0)
return (err);
return (sioattach(dev, 0, 0UL));
}

View file

@ -233,8 +233,8 @@ sn_detach(device_t dev)
snstop(sc);
ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
ether_ifdetach(ifp);
if_free(ifp);
sn_deactivate(dev);
if_free(ifp);
SN_LOCK_DESTROY(sc);
return 0;
}

View file

@ -446,7 +446,6 @@ epic_attach(dev)
static void
epic_release(epic_softc_t *sc)
{
if (sc->ifp != NULL)
if_free(sc->ifp);
if (sc->irq)

View file

@ -392,9 +392,6 @@ txp_release_resources(sc)
dev = sc->sc_dev;
if (sc->sc_ifp)
if_free(sc->sc_ifp);
if (sc->sc_intrhand != NULL)
bus_teardown_intr(dev, sc->sc_irq, sc->sc_intrhand);
@ -407,6 +404,9 @@ txp_release_resources(sc)
if (sc->sc_ldata != NULL)
contigfree(sc->sc_ldata, sizeof(struct txp_ldata), M_DEVBUF);
if (sc->sc_ifp)
if_free(sc->sc_ifp);
return;
}

View file

@ -1123,8 +1123,6 @@ vge_detach(dev)
ifp->if_flags &= ~IFF_UP;
ether_ifdetach(ifp);
}
if (ifp)
if_free(ifp);
if (sc->vge_miibus)
device_delete_child(dev, sc->vge_miibus);
bus_generic_detach(dev);
@ -1136,6 +1134,8 @@ vge_detach(dev)
if (sc->vge_res)
bus_release_resource(dev, SYS_RES_MEMORY,
VGE_PCI_LOMEM, sc->vge_res);
if (ifp)
if_free(ifp);
/* Unload and free the RX DMA ring memory and map */

View file

@ -534,9 +534,9 @@ wi_detach(device_t dev)
bpfdetach(ifp);
#endif
ieee80211_ifdetach(&sc->sc_ic);
if_free(sc->sc_ifp);
WI_UNLOCK(sc);
bus_teardown_intr(dev, sc->irq, sc->wi_intrhand);
if_free(sc->sc_ifp);
wi_free(dev);
#if __FreeBSD_version >= 500000
mtx_destroy(&sc->sc_mtx);

View file

@ -589,7 +589,6 @@ wldetach(device_t device)
ifp = sc->ifp;
ether_ifdetach(ifp);
if_free(ifp);
WL_LOCK(sc);
@ -607,6 +606,7 @@ wldetach(device_t device)
bus_generic_detach(device);
wl_deallocate_resources(device);
WL_UNLOCK(sc);
if_free(ifp);
mtx_destroy(&sc->wl_mtx);
return (0);
}

View file

@ -328,8 +328,8 @@ xe_pccard_detach(device_t dev)
sc->ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
ether_ifdetach(sc->ifp);
if_free(sc->ifp);
xe_deactivate(dev);
if_free(sc->ifp);
return (0);
}