diff options
author | imp <imp@FreeBSD.org> | 2005-09-19 03:10:21 +0000 |
---|---|---|
committer | imp <imp@FreeBSD.org> | 2005-09-19 03:10:21 +0000 |
commit | 4e70215e6bf590140205774753c8b0a1f1fe9a36 (patch) | |
tree | c3358cebc77043ea8b2a3a5036b02dad6a674b7e | |
parent | 37a0bbb7e543c6b2a2f055d676d5a94f781d7738 (diff) | |
download | FreeBSD-src-4e70215e6bf590140205774753c8b0a1f1fe9a36.zip FreeBSD-src-4e70215e6bf590140205774753c8b0a1f1fe9a36.tar.gz |
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.
31 files changed, 55 insertions, 62 deletions
diff --git a/sys/dev/an/if_an.c b/sys/dev/an/if_an.c index f10f30e..23f94ed 100644 --- a/sys/dev/an/if_an.c +++ b/sys/dev/an/if_an.c @@ -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); diff --git a/sys/dev/arl/if_arl_isa.c b/sys/dev/arl/if_arl_isa.c index e318adf..fa84396 100644 --- a/sys/dev/arl/if_arl_isa.c +++ b/sys/dev/arl/if_arl_isa.c @@ -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); diff --git a/sys/dev/awi/if_awi_pccard.c b/sys/dev/awi/if_awi_pccard.c index bc8bb32..0e4958c 100644 --- a/sys/dev/awi/if_awi_pccard.c +++ b/sys/dev/awi/if_awi_pccard.c @@ -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 diff --git a/sys/dev/cm/if_cm_isa.c b/sys/dev/cm/if_cm_isa.c index 1baa687..0eb070c 100644 --- a/sys/dev/cm/if_cm_isa.c +++ b/sys/dev/cm/if_cm_isa.c @@ -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); diff --git a/sys/dev/cnw/if_cnw.c b/sys/dev/cnw/if_cnw.c index 5db732d..b2b99c1 100644 --- a/sys/dev/cnw/if_cnw.c +++ b/sys/dev/cnw/if_cnw.c @@ -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 diff --git a/sys/dev/cp/if_cp.c b/sys/dev/cp/if_cp.c index ab24f6f..f6ecd74 100644 --- a/sys/dev/cp/if_cp.c +++ b/sys/dev/cp/if_cp.c @@ -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); diff --git a/sys/dev/cs/if_cs.c b/sys/dev/cs/if_cs.c index afa3fb7..a55c4eb 100644 --- a/sys/dev/cs/if_cs.c +++ b/sys/dev/cs/if_cs.c @@ -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); } diff --git a/sys/dev/ed/if_ed.c b/sys/dev/ed/if_ed.c index e76c0c8..0cbe2b3 100644 --- a/sys/dev/ed/if_ed.c +++ b/sys/dev/ed/if_ed.c @@ -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); } diff --git a/sys/dev/em/if_em.c b/sys/dev/em/if_em.c index 9d98158..3fa1180 100644 --- a/sys/dev/em/if_em.c +++ b/sys/dev/em/if_em.c @@ -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) { diff --git a/sys/dev/en/if_en_pci.c b/sys/dev/en/if_en_pci.c index bfff233..c17e24d 100644 --- a/sys/dev/en/if_en_pci.c +++ b/sys/dev/en/if_en_pci.c @@ -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); } diff --git a/sys/dev/ep/if_ep.c b/sys/dev/ep/if_ep.c index 3cf9623..1cb8c81 100644 --- a/sys/dev/ep/if_ep.c +++ b/sys/dev/ep/if_ep.c @@ -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); diff --git a/sys/dev/fe/if_fe_pccard.c b/sys/dev/fe/if_fe_pccard.c index a143e63..064e246 100644 --- a/sys/dev/fe/if_fe_pccard.c +++ b/sys/dev/fe/if_fe_pccard.c @@ -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; diff --git a/sys/dev/if_ndis/if_ndis.c b/sys/dev/if_ndis/if_ndis.c index 616887d..f22068e 100644 --- a/sys/dev/if_ndis/if_ndis.c +++ b/sys/dev/if_ndis/if_ndis.c @@ -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); diff --git a/sys/dev/ipw/if_ipw.c b/sys/dev/ipw/if_ipw.c index 4a33fa6..1f9fd07 100644 --- a/sys/dev/ipw/if_ipw.c +++ b/sys/dev/ipw/if_ipw.c @@ -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); diff --git a/sys/dev/iwi/if_iwi.c b/sys/dev/iwi/if_iwi.c index 420d2ae..d353a03 100644 --- a/sys/dev/iwi/if_iwi.c +++ b/sys/dev/iwi/if_iwi.c @@ -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; diff --git a/sys/dev/ixgb/if_ixgb.c b/sys/dev/ixgb/if_ixgb.c index 6453262..4cb9caa 100644 --- a/sys/dev/ixgb/if_ixgb.c +++ b/sys/dev/ixgb/if_ixgb.c @@ -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) { diff --git a/sys/dev/lge/if_lge.c b/sys/dev/lge/if_lge.c index f1d73d4..9ba8542 100644 --- a/sys/dev/lge/if_lge.c +++ b/sys/dev/lge/if_lge.c @@ -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); diff --git a/sys/dev/nge/if_nge.c b/sys/dev/nge/if_nge.c index 88ded49..a14d4ef 100644 --- a/sys/dev/nge/if_nge.c +++ b/sys/dev/nge/if_nge.c @@ -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); diff --git a/sys/dev/nve/if_nve.c b/sys/dev/nve/if_nve.c index 0d8267a..6ffecbd 100644 --- a/sys/dev/nve/if_nve.c +++ b/sys/dev/nve/if_nve.c @@ -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); diff --git a/sys/dev/ral/if_ral.c b/sys/dev/ral/if_ral.c index b7b7316..acc7daf 100644 --- a/sys/dev/ral/if_ral.c +++ b/sys/dev/ral/if_ral.c @@ -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); diff --git a/sys/dev/ray/if_ray.c b/sys/dev/ray/if_ray.c index 9ea6680..adc48beb 100644 --- a/sys/dev/ray/if_ray.c +++ b/sys/dev/ray/if_ray.c @@ -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); diff --git a/sys/dev/re/if_re.c b/sys/dev/re/if_re.c index 7a9aec1..81e26cb 100644 --- a/sys/dev/re/if_re.c +++ b/sys/dev/re/if_re.c @@ -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) diff --git a/sys/dev/sbsh/if_sbsh.c b/sys/dev/sbsh/if_sbsh.c index 03cff46..32b15aa 100644 --- a/sys/dev/sbsh/if_sbsh.c +++ b/sys/dev/sbsh/if_sbsh.c @@ -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); } diff --git a/sys/dev/sio/sio_pccard.c b/sys/dev/sio/sio_pccard.c index b715828..5c2ba77 100644 --- a/sys/dev/sio/sio_pccard.c +++ b/sys/dev/sio/sio_pccard.c @@ -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); + return (ENXIO); } static int -sio_pccard_probe(dev) +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 */ - return (sioprobe(dev, 0, 0UL, 1)); -} - -static int -sio_pccard_attach(dev) - device_t dev; -{ + if ((err = sioprobe(dev, 0, 0UL, 1)) != 0) + return (err); return (sioattach(dev, 0, 0UL)); } diff --git a/sys/dev/sn/if_sn.c b/sys/dev/sn/if_sn.c index b4dbd2e..bb3fc5e 100644 --- a/sys/dev/sn/if_sn.c +++ b/sys/dev/sn/if_sn.c @@ -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; } diff --git a/sys/dev/tx/if_tx.c b/sys/dev/tx/if_tx.c index 34b26ec..ce2da96 100644 --- a/sys/dev/tx/if_tx.c +++ b/sys/dev/tx/if_tx.c @@ -446,7 +446,6 @@ fail: static void epic_release(epic_softc_t *sc) { - if (sc->ifp != NULL) if_free(sc->ifp); if (sc->irq) diff --git a/sys/dev/txp/if_txp.c b/sys/dev/txp/if_txp.c index 0a35070..03bd0b4 100644 --- a/sys/dev/txp/if_txp.c +++ b/sys/dev/txp/if_txp.c @@ -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; } diff --git a/sys/dev/vge/if_vge.c b/sys/dev/vge/if_vge.c index 60d8cdc..0780bc5 100644 --- a/sys/dev/vge/if_vge.c +++ b/sys/dev/vge/if_vge.c @@ -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 */ diff --git a/sys/dev/wi/if_wi.c b/sys/dev/wi/if_wi.c index 21e7e50..a55bfb6 100644 --- a/sys/dev/wi/if_wi.c +++ b/sys/dev/wi/if_wi.c @@ -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); diff --git a/sys/dev/wl/if_wl.c b/sys/dev/wl/if_wl.c index f34915f..0df46ca 100644 --- a/sys/dev/wl/if_wl.c +++ b/sys/dev/wl/if_wl.c @@ -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); } diff --git a/sys/dev/xe/if_xe_pccard.c b/sys/dev/xe/if_xe_pccard.c index 4e6b2a4..48f1180 100644 --- a/sys/dev/xe/if_xe_pccard.c +++ b/sys/dev/xe/if_xe_pccard.c @@ -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); } |