diff options
author | Aaron Campbell <aaron@cvs.openbsd.org> | 2000-09-05 18:18:51 +0000 |
---|---|---|
committer | Aaron Campbell <aaron@cvs.openbsd.org> | 2000-09-05 18:18:51 +0000 |
commit | 26f2c634cf644276cd544c193b2a8a6a7b2674fe (patch) | |
tree | 0a19a2cfd7a3db06e608932dbd7caeccba822e8d | |
parent | 92c05d8b674beb0766817a5189e46d13bb3b0b4d (diff) |
Support detach of xl(4) devices, mainly to allow the ejection and insertion of
3Com575-based CardBus PC Cards; from nate@
-rw-r--r-- | sys/dev/cardbus/if_xl_cardbus.c | 4 | ||||
-rw-r--r-- | sys/dev/ic/xl.c | 91 | ||||
-rw-r--r-- | sys/dev/ic/xlreg.h | 4 |
3 files changed, 70 insertions, 29 deletions
diff --git a/sys/dev/cardbus/if_xl_cardbus.c b/sys/dev/cardbus/if_xl_cardbus.c index debb014b67d..1f8bc5db0d8 100644 --- a/sys/dev/cardbus/if_xl_cardbus.c +++ b/sys/dev/cardbus/if_xl_cardbus.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_xl_cardbus.c,v 1.5 2000/07/06 21:17:44 aaron Exp $ */ +/* $OpenBSD: if_xl_cardbus.c,v 1.6 2000/09/05 18:18:50 aaron Exp $ */ /* $NetBSD: if_xl_cardbus.c,v 1.13 2000/03/07 00:32:52 mycroft Exp $ */ /* @@ -339,9 +339,7 @@ xl_cardbus_detach(self, arg) } #endif -#if 0 rv = xl_detach(sc); -#endif if (rv == 0) { /* * Unhook the interrupt handler. diff --git a/sys/dev/ic/xl.c b/sys/dev/ic/xl.c index f34c7783a46..8ef84f3d7d9 100644 --- a/sys/dev/ic/xl.c +++ b/sys/dev/ic/xl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: xl.c,v 1.5 2000/07/01 03:19:14 aaron Exp $ */ +/* $OpenBSD: xl.c,v 1.6 2000/09/05 18:18:49 aaron Exp $ */ /* * Copyright (c) 1997, 1998, 1999 @@ -160,6 +160,7 @@ void xl_start_90xB __P((struct ifnet *)); int xl_ioctl __P((struct ifnet *, u_long, caddr_t)); void xl_init __P((void *)); void xl_stop __P((struct xl_softc *)); +void xl_freetxrx __P((struct xl_softc *)); void xl_watchdog __P((struct ifnet *)); void xl_shutdown __P((void *)); int xl_ifmedia_upd __P((struct ifnet *)); @@ -2292,6 +2293,36 @@ void xl_watchdog(ifp) return; } +void +xl_freetxrx(sc) + struct xl_softc *sc; +{ + int i; + + /* + * Free data in the RX lists. + */ + for (i = 0; i < XL_RX_LIST_CNT; i++) { + if (sc->xl_cdata.xl_rx_chain[i].xl_mbuf != NULL) { + m_freem(sc->xl_cdata.xl_rx_chain[i].xl_mbuf); + sc->xl_cdata.xl_rx_chain[i].xl_mbuf = NULL; + } + } + bzero((char *)&sc->xl_ldata->xl_rx_list, + sizeof(sc->xl_ldata->xl_rx_list)); + /* + * Free the TX list buffers. + */ + for (i = 0; i < XL_TX_LIST_CNT; i++) { + if (sc->xl_cdata.xl_tx_chain[i].xl_mbuf != NULL) { + m_freem(sc->xl_cdata.xl_tx_chain[i].xl_mbuf); + sc->xl_cdata.xl_tx_chain[i].xl_mbuf = NULL; + } + } + bzero((char *)&sc->xl_ldata->xl_tx_list, + sizeof(sc->xl_ldata->xl_tx_list)); +} + /* * Stop the adapter and free any mbufs allocated to the * RX and TX lists. @@ -2299,7 +2330,6 @@ void xl_watchdog(ifp) void xl_stop(sc) struct xl_softc *sc; { - int i; struct ifnet *ifp; ifp = &sc->arpcom.ac_if; @@ -2332,28 +2362,7 @@ void xl_stop(sc) /* Stop the stats updater. */ untimeout(xl_stats_update, sc); - /* - * Free data in the RX lists. - */ - for (i = 0; i < XL_RX_LIST_CNT; i++) { - if (sc->xl_cdata.xl_rx_chain[i].xl_mbuf != NULL) { - m_freem(sc->xl_cdata.xl_rx_chain[i].xl_mbuf); - sc->xl_cdata.xl_rx_chain[i].xl_mbuf = NULL; - } - } - bzero((char *)&sc->xl_ldata->xl_rx_list, - sizeof(sc->xl_ldata->xl_rx_list)); - /* - * Free the TX list buffers. - */ - for (i = 0; i < XL_TX_LIST_CNT; i++) { - if (sc->xl_cdata.xl_tx_chain[i].xl_mbuf != NULL) { - m_freem(sc->xl_cdata.xl_tx_chain[i].xl_mbuf); - sc->xl_cdata.xl_tx_chain[i].xl_mbuf = NULL; - } - } - bzero((char *)&sc->xl_ldata->xl_tx_list, - sizeof(sc->xl_ldata->xl_tx_list)); + xl_freetxrx(sc); ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); @@ -2595,7 +2604,39 @@ xl_attach(sc) bpfattach(&sc->arpcom.ac_if.if_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header)); #endif - shutdownhook_establish(xl_shutdown, sc); + sc->sc_sdhook = shutdownhook_establish(xl_shutdown, sc); +} + +int +xl_detach(sc) + struct xl_softc *sc; +{ + struct ifnet *ifp = &sc->arpcom.ac_if; + + /* Unhook our tick handler. */ + untimeout(xl_stats_update, sc); + + xl_freetxrx(sc); + + /* Detach all PHYs */ + if (sc->xl_hasmii) + mii_detach(&sc->sc_mii, MII_PHY_ANY, MII_OFFSET_ANY); + + /* Delete all remaining media. */ + ifmedia_delete_instance(&sc->sc_mii.mii_media, IFM_INST_ANY); + +#if NRND > 0 + rnd_detach_source(&sc->rnd_source); +#endif +#if NBPFILTER > 0 + bpfdetach(ifp); +#endif + ether_ifdetach(ifp); + if_detach(ifp); + + shutdownhook_disestablish(sc->sc_sdhook); + + return (0); } void diff --git a/sys/dev/ic/xlreg.h b/sys/dev/ic/xlreg.h index 708038260d2..b10a7b6ad21 100644 --- a/sys/dev/ic/xlreg.h +++ b/sys/dev/ic/xlreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: xlreg.h,v 1.3 2000/07/01 03:19:14 aaron Exp $ */ +/* $OpenBSD: xlreg.h,v 1.4 2000/09/05 18:18:50 aaron Exp $ */ /* * Copyright (c) 1997, 1998 @@ -579,6 +579,7 @@ struct xl_softc { struct xl_list_data *xl_ldata; struct xl_chain_data xl_cdata; void (*intr_ack) __P((struct xl_softc *)); + void * sc_sdhook; }; #define xl_rx_goodframes(x) \ @@ -720,3 +721,4 @@ struct xl_stats { extern int xl_intr __P((void *)); extern void xl_attach __P((struct xl_softc *)); +extern int xl_detach __P((struct xl_softc *)); |