Module Name: src Committed By: jakllsch Date: Wed Nov 3 14:03:40 UTC 2010
Modified Files: src/sys/dev/pci: if_nfe.c if_nfevar.h Log Message: Make nfe(4) detachable. To generate a diff of this commit: cvs rdiff -u -r1.52 -r1.53 src/sys/dev/pci/if_nfe.c cvs rdiff -u -r1.9 -r1.10 src/sys/dev/pci/if_nfevar.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/pci/if_nfe.c diff -u src/sys/dev/pci/if_nfe.c:1.52 src/sys/dev/pci/if_nfe.c:1.53 --- src/sys/dev/pci/if_nfe.c:1.52 Tue Nov 2 16:56:47 2010 +++ src/sys/dev/pci/if_nfe.c Wed Nov 3 14:03:40 2010 @@ -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; } } Index: src/sys/dev/pci/if_nfevar.h diff -u src/sys/dev/pci/if_nfevar.h:1.9 src/sys/dev/pci/if_nfevar.h:1.10 --- src/sys/dev/pci/if_nfevar.h:1.9 Sun Apr 20 08:57:37 2008 +++ src/sys/dev/pci/if_nfevar.h Wed Nov 3 14:03:40 2010 @@ -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;