summaryrefslogtreecommitdiffstats
path: root/sys/pci/if_ti.c
diff options
context:
space:
mode:
authornjl <njl@FreeBSD.org>2003-04-17 20:32:06 +0000
committernjl <njl@FreeBSD.org>2003-04-17 20:32:06 +0000
commitfe07eb9dfb67dec3b9867ee376a889a70b355179 (patch)
tree3cf87a7e7fce73f14cb753a6554ec38575d14502 /sys/pci/if_ti.c
parent9aba79052e570949849c1985ff95ff264ff272ec (diff)
downloadFreeBSD-src-fe07eb9dfb67dec3b9867ee376a889a70b355179.zip
FreeBSD-src-fe07eb9dfb67dec3b9867ee376a889a70b355179.tar.gz
Revise attach/detach resource cleanup
- Unconditionally call *_stop() if device is in the tree. This is to prevent callouts from happening after the device is gone. Checks for bus_child_present() should be added in the future to keep from touching potentially non-existent hardware in *_detach(). Found by iedowse@. - Always check for and free miibus children, even if the device is not in the tree since some failure cases could have gotten here. - Call ether_ifdetach() in the irq setup failure case - ti(4), xl(4): move ifmedia_init() calls to the beginning of attach so that ifmedia_removeall() can be unconditionally called on detach. There is no way to detect whether ifmedia has been initialized without using a separate variable (as tl(4) does). - Add comments to indicate assumptions of code path
Diffstat (limited to 'sys/pci/if_ti.c')
-rw-r--r--sys/pci/if_ti.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/sys/pci/if_ti.c b/sys/pci/if_ti.c
index c1b5796..5046685 100644
--- a/sys/pci/if_ti.c
+++ b/sys/pci/if_ti.c
@@ -2115,6 +2115,7 @@ ti_attach(dev)
mtx_init(&sc->ti_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
MTX_DEF | MTX_RECURSE);
+ ifmedia_init(&sc->ifmedia, IFM_IMASK, ti_ifmedia_upd, ti_ifmedia_sts);
sc->arpcom.ac_if.if_capabilities = IFCAP_HWCSUM | IFCAP_VLAN_HWTAGGING;
sc->arpcom.ac_if.if_capenable = sc->arpcom.ac_if.if_capabilities;
@@ -2259,7 +2260,6 @@ ti_attach(dev)
ifp->if_snd.ifq_maxlen = TI_TX_RING_CNT - 1;
/* Set up ifmedia support. */
- ifmedia_init(&sc->ifmedia, IFM_IMASK, ti_ifmedia_upd, ti_ifmedia_sts);
if (sc->ti_copper) {
/*
* Copper cards allow manual 10/100 mode selection,
@@ -2310,11 +2310,13 @@ ti_attach(dev)
*/
ether_ifattach(ifp, sc->arpcom.ac_enaddr);
+ /* Hook interrupt last to avoid having to lock softc */
error = bus_setup_intr(dev, sc->ti_irq, INTR_TYPE_NET,
ti_intr, sc, &sc->ti_intrhand);
if (error) {
printf("ti%d: couldn't set up irq\n", unit);
+ ether_ifdetach(ifp);
goto fail;
}
@@ -2352,7 +2354,13 @@ ti_unref_special(device_t dev)
return(0);
}
-
+/*
+ * Shutdown hardware and free up resources. This can be called any
+ * time after the mutex has been initialized. It is called in both
+ * the error case in attach and the normal detach case so it needs
+ * to be careful about only freeing resources that have actually been
+ * allocated.
+ */
static int
ti_detach(dev)
device_t dev;
@@ -2368,13 +2376,13 @@ ti_detach(dev)
TI_LOCK(sc);
ifp = &sc->arpcom.ac_if;
+ /* These should only be active if attach succeeded */
if (device_is_alive(dev)) {
- if (bus_child_present(dev))
- ti_stop(sc);
+ ti_stop(sc);
ether_ifdetach(ifp);
bus_generic_detach(dev);
- ifmedia_removeall(&sc->ifmedia);
}
+ ifmedia_removeall(&sc->ifmedia);
if (sc->ti_intrhand)
bus_teardown_intr(dev, sc->ti_irq, sc->ti_intrhand);
OpenPOWER on IntegriCloud