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