summaryrefslogtreecommitdiffstats
path: root/sys/dev/gem
diff options
context:
space:
mode:
authortmm <tmm@FreeBSD.org>2003-01-08 20:12:45 +0000
committertmm <tmm@FreeBSD.org>2003-01-08 20:12:45 +0000
commit9544452611e2a3828dacd20186fc3c21e3f1527e (patch)
tree7f1bdfd08a76f7c21692493db199849d0d80874f /sys/dev/gem
parent03f7564d9e62f81ebe5702c3294d62c1ef3a644f (diff)
downloadFreeBSD-src-9544452611e2a3828dacd20186fc3c21e3f1527e.zip
FreeBSD-src-9544452611e2a3828dacd20186fc3c21e3f1527e.tar.gz
Add detach, shutdown, suspend and resume methods. The latter two are
not really tested, but are derived from the original NetBSD version.
Diffstat (limited to 'sys/dev/gem')
-rw-r--r--sys/dev/gem/if_gem.c89
-rw-r--r--sys/dev/gem/if_gem_pci.c46
-rw-r--r--sys/dev/gem/if_gemvar.h4
3 files changed, 97 insertions, 42 deletions
diff --git a/sys/dev/gem/if_gem.c b/sys/dev/gem/if_gem.c
index 12550cc..635bd27 100644
--- a/sys/dev/gem/if_gem.c
+++ b/sys/dev/gem/if_gem.c
@@ -350,6 +350,55 @@ fail_ptag:
return (error);
}
+void
+gem_detach(sc)
+ struct gem_softc *sc;
+{
+ struct ifnet *ifp = &sc->sc_arpcom.ac_if;
+ int i;
+
+ ether_ifdetach(ifp);
+ gem_stop(ifp, 1);
+ device_delete_child(sc->sc_dev, sc->sc_miibus);
+
+ for (i = 0; i < GEM_NRXDESC; i++) {
+ if (sc->sc_rxsoft[i].rxs_dmamap != NULL)
+ bus_dmamap_destroy(sc->sc_rdmatag,
+ sc->sc_rxsoft[i].rxs_dmamap);
+ }
+ for (i = 0; i < GEM_TXQUEUELEN; i++) {
+ if (sc->sc_txsoft[i].txs_dmamap != NULL)
+ bus_dmamap_destroy(sc->sc_tdmatag,
+ sc->sc_txsoft[i].txs_dmamap);
+ }
+ bus_dmamap_unload(sc->sc_cdmatag, sc->sc_cddmamap);
+ bus_dmamem_free(sc->sc_cdmatag, sc->sc_control_data,
+ sc->sc_cddmamap);
+ bus_dma_tag_destroy(sc->sc_cdmatag);
+ bus_dma_tag_destroy(sc->sc_tdmatag);
+ bus_dma_tag_destroy(sc->sc_rdmatag);
+ bus_dma_tag_destroy(sc->sc_pdmatag);
+}
+
+void
+gem_suspend(sc)
+ struct gem_softc *sc;
+{
+ struct ifnet *ifp = &sc->sc_arpcom.ac_if;
+
+ gem_stop(ifp, 0);
+}
+
+void
+gem_resume(sc)
+ struct gem_softc *sc;
+{
+ struct ifnet *ifp = &sc->sc_arpcom.ac_if;
+
+ if (ifp->if_flags & IFF_UP)
+ gem_init(ifp);
+}
+
static void
gem_cddma_callback(xsc, segs, nsegs, error)
void *xsc;
@@ -1833,43 +1882,3 @@ gem_setladrf(sc)
chipit:
bus_space_write_4(t, h, GEM_MAC_RX_CONFIG, v);
}
-
-#if notyet
-
-/*
- * gem_power:
- *
- * Power management (suspend/resume) hook.
- */
-void
-static gem_power(why, arg)
- int why;
- void *arg;
-{
- struct gem_softc *sc = arg;
- struct ifnet *ifp = &sc->sc_arpcom.ac_if;
- int s;
-
- s = splnet();
- switch (why) {
- case PWR_SUSPEND:
- case PWR_STANDBY:
- gem_stop(ifp, 1);
- if (sc->sc_power != NULL)
- (*sc->sc_power)(sc, why);
- break;
- case PWR_RESUME:
- if (ifp->if_flags & IFF_UP) {
- if (sc->sc_power != NULL)
- (*sc->sc_power)(sc, why);
- gem_init(ifp);
- }
- break;
- case PWR_SOFTSUSPEND:
- case PWR_SOFTSTANDBY:
- case PWR_SOFTRESUME:
- break;
- }
- splx(s);
-}
-#endif
diff --git a/sys/dev/gem/if_gem_pci.c b/sys/dev/gem/if_gem_pci.c
index a2b5e27..5948183 100644
--- a/sys/dev/gem/if_gem_pci.c
+++ b/sys/dev/gem/if_gem_pci.c
@@ -77,12 +77,19 @@ struct gem_pci_softc {
static int gem_pci_probe(device_t);
static int gem_pci_attach(device_t);
-
+static int gem_pci_detach(device_t);
+static int gem_pci_suspend(device_t);
+static int gem_pci_resume(device_t);
static device_method_t gem_pci_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, gem_pci_probe),
DEVMETHOD(device_attach, gem_pci_attach),
+ DEVMETHOD(device_detach, gem_pci_detach),
+ DEVMETHOD(device_suspend, gem_pci_suspend),
+ DEVMETHOD(device_resume, gem_pci_resume),
+ /* Use the suspend handler here, it is all that is required. */
+ DEVMETHOD(device_shutdown, gem_pci_suspend),
/* bus interface */
DEVMETHOD(bus_print_child, bus_generic_print_child),
@@ -202,3 +209,40 @@ fail_sres:
bus_release_resource(dev, SYS_RES_MEMORY, gsc->gsc_srid, gsc->gsc_sres);
return (ENXIO);
}
+
+static int
+gem_pci_detach(dev)
+ device_t dev;
+{
+ struct gem_pci_softc *gsc = device_get_softc(dev);
+ struct gem_softc *sc = &gsc->gsc_gem;
+
+ gem_detach(sc);
+
+ bus_teardown_intr(dev, gsc->gsc_ires, gsc->gsc_ih);
+ bus_release_resource(dev, SYS_RES_IRQ, gsc->gsc_irid, gsc->gsc_ires);
+ bus_release_resource(dev, SYS_RES_MEMORY, gsc->gsc_srid, gsc->gsc_sres);
+ return (0);
+}
+
+static int
+gem_pci_suspend(dev)
+ device_t dev;
+{
+ struct gem_pci_softc *gsc = device_get_softc(dev);
+ struct gem_softc *sc = &gsc->gsc_gem;
+
+ gem_suspend(sc);
+ return (0);
+}
+
+static int
+gem_pci_resume(dev)
+ device_t dev;
+{
+ struct gem_pci_softc *gsc = device_get_softc(dev);
+ struct gem_softc *sc = &gsc->gsc_gem;
+
+ gem_resume(sc);
+ return (0);
+}
diff --git a/sys/dev/gem/if_gemvar.h b/sys/dev/gem/if_gemvar.h
index 5da15fe..62e0b18 100644
--- a/sys/dev/gem/if_gemvar.h
+++ b/sys/dev/gem/if_gemvar.h
@@ -219,7 +219,9 @@ do { \
extern devclass_t gem_devclass;
int gem_attach(struct gem_softc *);
-int gem_detach(struct gem_softc *);
+void gem_detach(struct gem_softc *);
+void gem_suspend(struct gem_softc *);
+void gem_resume(struct gem_softc *);
void gem_intr(void *);
int gem_mediachange(struct ifnet *);
OpenPOWER on IntegriCloud