Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev First cut at detach support; doens't fully work yet.



details:   https://anonhg.NetBSD.org/src/rev/dc9bbf988361
branches:  trunk
changeset: 481551:dc9bbf988361
user:      thorpej <thorpej%NetBSD.org@localhost>
date:      Tue Feb 01 22:54:47 2000 +0000

description:
First cut at detach support; doens't fully work yet.

diffstat:

 sys/dev/cardbus/if_tlp_cardbus.c |   24 +++++++-
 sys/dev/ic/tulip.c               |  114 ++++++++++++++++++++++++++++++++++++--
 sys/dev/ic/tulipvar.h            |    6 +-
 3 files changed, 134 insertions(+), 10 deletions(-)

diffs (249 lines):

diff -r 3fd05e7e74a6 -r dc9bbf988361 sys/dev/cardbus/if_tlp_cardbus.c
--- a/sys/dev/cardbus/if_tlp_cardbus.c  Tue Feb 01 22:53:14 2000 +0000
+++ b/sys/dev/cardbus/if_tlp_cardbus.c  Tue Feb 01 22:54:47 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_tlp_cardbus.c,v 1.10 2000/01/25 21:50:30 thorpej Exp $      */
+/*     $NetBSD: if_tlp_cardbus.c,v 1.11 2000/02/01 22:54:47 thorpej Exp $      */
 
 /*-
  * Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
@@ -122,10 +122,12 @@
 
 int    tlp_cardbus_match __P((struct device *, struct cfdata *, void *));
 void   tlp_cardbus_attach __P((struct device *, struct device *, void *));
+int    tlp_cardbus_detach __P((struct device *, int));
 
 struct cfattach tlp_cardbus_ca = {
        sizeof(struct tulip_cardbus_softc),
            tlp_cardbus_match, tlp_cardbus_attach,
+               tlp_cardbus_detach, tlp_activate,
 };
 
 const struct tulip_cardbus_product {
@@ -429,6 +431,26 @@
        tlp_attach(sc, enaddr);
 }
 
+int
+tlp_cardbus_detach(self, flags)
+       struct device *self;
+       int flags;
+{
+       struct tulip_cardbus_softc *csc = (void *) self;
+       struct tulip_softc *sc = &csc->sc_tulip;
+       int rv;
+
+       rv = tlp_detach(sc);
+       if (rv == 0) {
+               /*
+                * Unhook the interrupt handler.
+                */
+               cardbus_intr_disestablish(csc->sc_ct->ct_cc,
+                   csc->sc_ct->ct_cf, csc->sc_ih);
+       }
+       return (rv);
+}
+
 void
 tlp_cardbus_x3201_reset(sc)
        struct tulip_softc *sc;
diff -r 3fd05e7e74a6 -r dc9bbf988361 sys/dev/ic/tulip.c
--- a/sys/dev/ic/tulip.c        Tue Feb 01 22:53:14 2000 +0000
+++ b/sys/dev/ic/tulip.c        Tue Feb 01 22:54:47 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: tulip.c,v 1.41 2000/01/28 23:23:49 thorpej Exp $       */
+/*     $NetBSD: tulip.c,v 1.42 2000/02/01 22:54:47 thorpej Exp $       */
 
 /*-
  * Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc.
@@ -227,8 +227,7 @@
        const u_int8_t *enaddr;
 {
        struct ifnet *ifp = &sc->sc_ethercom.ec_if;
-       int i, rseg, error;
-       bus_dma_segment_t seg;
+       int i, error;
 
        /*
         * NOTE: WE EXPECT THE FRONT-END TO INITIALIZE sc_regshift!
@@ -369,14 +368,14 @@
         * DMA map for it.
         */
        if ((error = bus_dmamem_alloc(sc->sc_dmat,
-           sizeof(struct tulip_control_data), PAGE_SIZE, 0, &seg, 1, &rseg,
-           0)) != 0) {
+           sizeof(struct tulip_control_data), PAGE_SIZE, 0, &sc->sc_cdseg,
+           1, &sc->sc_cdnseg, 0)) != 0) {
                printf("%s: unable to allocate control data, error = %d\n",
                    sc->sc_dev.dv_xname, error);
                goto fail_0;
        }
 
-       if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg,
+       if ((error = bus_dmamem_map(sc->sc_dmat, &sc->sc_cdseg, sc->sc_cdnseg,
            sizeof(struct tulip_control_data), (caddr_t *)&sc->sc_control_data,
            BUS_DMA_COHERENT)) != 0) {
                printf("%s: unable to map control data, error = %d\n",
@@ -506,12 +505,104 @@
        bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_control_data,
            sizeof(struct tulip_control_data));
  fail_1:
-       bus_dmamem_free(sc->sc_dmat, &seg, rseg);
+       bus_dmamem_free(sc->sc_dmat, &sc->sc_cdseg, sc->sc_cdnseg);
  fail_0:
        return;
 }
 
 /*
+ * tlp_activate:
+ *
+ *     Handle device activation/deactivation requests.
+ */
+int
+tlp_activate(self, act)
+       struct device *self;
+       enum devact act;
+{
+       struct tulip_softc *sc = (void *) self;
+       int s, error = 0;
+
+       s = splnet();
+       switch (act) {
+       case DVACT_ACTIVATE:
+               error = EOPNOTSUPP;
+               break;
+
+       case DVACT_DEACTIVATE:
+               if (sc->sc_flags & TULIPF_HAS_MII)
+                       mii_phy_activate(&sc->sc_mii, act, MII_PHY_ANY,
+                           MII_OFFSET_ANY);
+               if_deactivate(&sc->sc_ethercom.ec_if);
+               break;
+       }
+       splx(s);
+
+       return (error);
+}
+
+/*
+ * tlp_detach:
+ *
+ *     Detach a Tulip interface.
+ */
+int
+tlp_detach(sc)
+       struct tulip_softc *sc;
+{
+       struct ifnet *ifp = &sc->sc_ethercom.ec_if;
+       struct tulip_rxsoft *rxs;
+       struct tulip_txsoft *txs;
+       int i;
+
+       /* Unhook our tick handler. */
+       if (sc->sc_tick)
+               untimeout(sc->sc_tick, sc);
+
+       if (sc->sc_flags & TULIPF_HAS_MII) {
+               /* Detach all PHYs */
+               mii_phy_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 NBPFILTER > 0
+       bpfdetach(ifp);
+#endif
+       ether_ifdetach(ifp);
+       if_detach(ifp);
+
+       for (i = 0; i < TULIP_NRXDESC; i++) {
+               rxs = &sc->sc_rxsoft[i];
+               if (rxs->rxs_mbuf != NULL) {
+                       bus_dmamap_unload(sc->sc_dmat, rxs->rxs_dmamap);
+                       m_freem(rxs->rxs_mbuf);
+                       rxs->rxs_mbuf = NULL;
+               }
+               bus_dmamap_destroy(sc->sc_dmat, rxs->rxs_dmamap);
+       }
+       for (i = 0; i < TULIP_TXQUEUELEN; i++) {
+               txs = &sc->sc_txsoft[i];
+               if (txs->txs_mbuf != NULL) {
+                       bus_dmamap_unload(sc->sc_dmat, txs->txs_dmamap);
+                       m_freem(txs->txs_mbuf);
+                       txs->txs_mbuf = NULL;
+               }
+               bus_dmamap_destroy(sc->sc_dmat, txs->txs_dmamap);
+       }
+       bus_dmamap_unload(sc->sc_dmat, sc->sc_cddmamap);
+       bus_dmamap_destroy(sc->sc_dmat, sc->sc_cddmamap);
+       bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_control_data,
+           sizeof(struct tulip_control_data));
+       bus_dmamem_free(sc->sc_dmat, &sc->sc_cdseg, sc->sc_cdnseg);
+
+       shutdownhook_disestablish(sc->sc_sdhook);
+
+       return (0);
+}
+
+/*
  * tlp_shutdown:
  *
  *     Make sure the interface is stopped at reboot time.
@@ -952,7 +1043,8 @@
         * If the interface isn't running, the interrupt couldn't
         * possibly have come from us.
         */
-       if ((ifp->if_flags & IFF_RUNNING) == 0)
+       if ((ifp->if_flags & IFF_RUNNING) == 0 ||
+           (sc->sc_dev.dv_flags & DVF_ACTIVE) == 0)
                return (0);
 
        for (;;) {
@@ -2700,6 +2792,9 @@
        struct tulip_softc *sc = arg;
        int s;
 
+       if ((sc->sc_dev.dv_flags & DVF_ACTIVE) == 0)
+               return;
+
        s = splnet();
        mii_tick(&sc->sc_mii);
        splx(s);
@@ -4772,6 +4867,9 @@
        struct tulip_softc *sc = arg;
        int s;
 
+       if ((sc->sc_dev.dv_flags & DVF_ACTIVE) == 0)
+               return;
+
        s = splnet();
        tlp_pnic_nway_service(sc, MII_TICK);
        splx(s);
diff -r 3fd05e7e74a6 -r dc9bbf988361 sys/dev/ic/tulipvar.h
--- a/sys/dev/ic/tulipvar.h     Tue Feb 01 22:53:14 2000 +0000
+++ b/sys/dev/ic/tulipvar.h     Tue Feb 01 22:54:47 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: tulipvar.h,v 1.27 2000/01/28 23:23:50 thorpej Exp $    */
+/*     $NetBSD: tulipvar.h,v 1.28 2000/02/01 22:54:48 thorpej Exp $    */
 
 /*-
  * Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc.
@@ -338,6 +338,8 @@
 
        u_int32_t       sc_filtmode;    /* filter mode we're using */
 
+       bus_dma_segment_t sc_cdseg;     /* control data memory */
+       int             sc_cdnseg;      /* number of segments */
        bus_dmamap_t sc_cddmamap;       /* control data DMA map */
 #define        sc_cddma        sc_cddmamap->dm_segs[0].ds_addr
 
@@ -497,6 +499,8 @@
 extern const struct tulip_mediasw tlp_al981_mediasw;
 
 void   tlp_attach __P((struct tulip_softc *, const u_int8_t *));
+int    tlp_activate __P((struct device *, enum devact));
+int    tlp_detach __P((struct tulip_softc *));
 int    tlp_intr __P((void *));
 void   tlp_read_srom __P((struct tulip_softc *, int, int, u_int8_t *));
 int    tlp_srom_crcok __P((const u_int8_t *));



Home | Main Index | Thread Index | Old Index