Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/pci Make nfe(4) detachable.



details:   https://anonhg.NetBSD.org/src/rev/6b926feabfe5
branches:  trunk
changeset: 758363:6b926feabfe5
user:      jakllsch <jakllsch%NetBSD.org@localhost>
date:      Wed Nov 03 14:03:40 2010 +0000

description:
Make nfe(4) detachable.

diffstat:

 sys/dev/pci/if_nfe.c    |  69 +++++++++++++++++++++++++++++++++++++++++++-----
 sys/dev/pci/if_nfevar.h |   4 ++-
 2 files changed, 64 insertions(+), 9 deletions(-)

diffs (161 lines):

diff -r 49b84806aa0f -r 6b926feabfe5 sys/dev/pci/if_nfe.c
--- a/sys/dev/pci/if_nfe.c      Wed Nov 03 12:21:50 2010 +0000
+++ b/sys/dev/pci/if_nfe.c      Wed Nov 03 14:03:40 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_nfe.c,v 1.52 2010/11/02 16:56:47 jakllsch Exp $     */
+/*     $NetBSD: if_nfe.c,v 1.53 2010/11/03 14:03:40 jakllsch Exp $     */
 /*     $OpenBSD: if_nfe.c,v 1.77 2008/02/05 16:52:50 brad Exp $        */
 
 /*-
@@ -21,7 +21,7 @@
 /* Driver for NVIDIA nForce MCP Fast Ethernet and Gigabit Ethernet */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_nfe.c,v 1.52 2010/11/02 16:56:47 jakllsch Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_nfe.c,v 1.53 2010/11/03 14:03:40 jakllsch Exp $");
 
 #include "opt_inet.h"
 #include "vlan.h"
@@ -75,6 +75,7 @@
 
 int    nfe_match(device_t, cfdata_t, void *);
 void   nfe_attach(device_t, device_t, void *);
+int    nfe_detach(device_t, int);
 void   nfe_power(int, void *);
 void   nfe_miibus_statchg(device_t);
 int    nfe_miibus_readreg(device_t, int, int);
@@ -111,8 +112,8 @@
 void   nfe_poweron(device_t);
 bool   nfe_resume(device_t, const pmf_qual_t *);
 
-CFATTACH_DECL_NEW(nfe, sizeof(struct nfe_softc), nfe_match, nfe_attach,
-    NULL, NULL);
+CFATTACH_DECL_NEW(nfe, sizeof(struct nfe_softc),
+    nfe_match, nfe_attach, nfe_detach, NULL);
 
 /* #define NFE_NO_JUMBO */
 
@@ -218,12 +219,12 @@
        pci_intr_handle_t ih;
        const char *intrstr;
        struct ifnet *ifp;
-       bus_size_t memsize;
        pcireg_t memtype, csr;
        char devinfo[256];
        int mii_flags = 0;
 
        sc->sc_dev = self;
+       sc->sc_pc = pa->pa_pc;
        pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo));
        aprint_normal(": %s (rev. 0x%02x)\n", devinfo, PCI_REVISION(pa->pa_class));
 
@@ -232,7 +233,7 @@
        case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT:
        case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT:
                if (pci_mapreg_map(pa, NFE_PCI_BA, memtype, 0, &sc->sc_memt,
-                   &sc->sc_memh, NULL, &memsize) == 0)
+                   &sc->sc_memh, NULL, &sc->sc_mems) == 0)
                        break;
                /* FALLTHROUGH */
        default:
@@ -425,8 +426,56 @@
                pci_intr_disestablish(pc, sc->sc_ih);
                sc->sc_ih = NULL;
        }
-       if (memsize)
-               bus_space_unmap(sc->sc_memt, sc->sc_memh, memsize);
+       if (sc->sc_mems != 0) {
+               bus_space_unmap(sc->sc_memt, sc->sc_memh, sc->sc_mems);
+               sc->sc_mems = 0;
+       }
+}
+
+int
+nfe_detach(device_t self, int flags)
+{
+       struct nfe_softc *sc = device_private(self);
+       struct ifnet *ifp = &sc->sc_ethercom.ec_if;
+       int s;
+
+       s = splnet();
+
+       nfe_stop(ifp, 1);
+
+       pmf_device_deregister(self);
+       callout_destroy(&sc->sc_tick_ch);
+       ether_ifdetach(ifp);
+       if_detach(ifp);
+       mii_detach(&sc->sc_mii, MII_PHY_ANY, MII_OFFSET_ANY);
+
+       nfe_free_rx_ring(sc, &sc->rxq);
+       mutex_destroy(&sc->rxq.mtx);
+       nfe_free_tx_ring(sc, &sc->txq);
+
+       if (sc->sc_ih != NULL) {
+               pci_intr_disestablish(sc->sc_pc, sc->sc_ih);
+               sc->sc_ih = NULL;
+       }
+
+       if ((sc->sc_flags & NFE_CORRECT_MACADDR) != 0) {
+               nfe_set_macaddr(sc, sc->sc_enaddr);
+       } else {
+               NFE_WRITE(sc, NFE_MACADDR_LO,
+                   sc->sc_enaddr[0] <<  8 | sc->sc_enaddr[1]);
+               NFE_WRITE(sc, NFE_MACADDR_HI,
+                   sc->sc_enaddr[2] << 24 | sc->sc_enaddr[3] << 16 |
+                   sc->sc_enaddr[4] <<  8 | sc->sc_enaddr[5]);
+       }
+
+       if (sc->sc_mems != 0) {
+               bus_space_unmap(sc->sc_memt, sc->sc_memh, sc->sc_mems);
+               sc->sc_mems = 0;
+       }
+
+       splx(s);
+
+       return 0;
 }
 
 void
@@ -1540,6 +1589,8 @@
                if (data->m != NULL)
                        m_freem(data->m);
        }
+
+       nfe_jpool_free(sc);
 }
 
 struct nfe_jbuf *
@@ -1667,10 +1718,12 @@
                    ring->jmap->dm_mapsize, BUS_DMASYNC_POSTWRITE);
                bus_dmamap_unload(sc->sc_dmat, ring->jmap);
                bus_dmamap_destroy(sc->sc_dmat, ring->jmap);
+               ring->jmap = NULL;
        }
        if (ring->jpool != NULL) {
                bus_dmamem_unmap(sc->sc_dmat, ring->jpool, NFE_JPOOL_SIZE);
                bus_dmamem_free(sc->sc_dmat, &ring->jseg, 1);
+               ring->jpool = NULL;
        }
 }
 
diff -r 49b84806aa0f -r 6b926feabfe5 sys/dev/pci/if_nfevar.h
--- a/sys/dev/pci/if_nfevar.h   Wed Nov 03 12:21:50 2010 +0000
+++ b/sys/dev/pci/if_nfevar.h   Wed Nov 03 14:03:40 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_nfevar.h,v 1.9 2008/04/20 08:57:37 cube Exp $       */
+/*     $NetBSD: if_nfevar.h,v 1.10 2010/11/03 14:03:40 jakllsch Exp $  */
 /*     $OpenBSD: if_nfevar.h,v 1.13 2007/12/05 08:30:33 jsg Exp $      */
 
 /*-
@@ -71,8 +71,10 @@
        device_t                sc_dev;
        struct ethercom         sc_ethercom;
        uint8_t                 sc_enaddr[ETHER_ADDR_LEN];
+       pci_chipset_tag_t       sc_pc;
        bus_space_handle_t      sc_memh;
        bus_space_tag_t         sc_memt;
+       bus_size_t              sc_mems;
        void                    *sc_ih;
        bus_dma_tag_t           sc_dmat;
        struct mii_data         sc_mii;



Home | Main Index | Thread Index | Old Index