Add detach, shutdown, suspend and resume methods. The latter two are

not really tested, but are derived from the original NetBSD version.
This commit is contained in:
Thomas Moestl 2003-01-08 20:12:45 +00:00
parent 9a032278bd
commit cbbdf2367e
3 changed files with 97 additions and 42 deletions

View File

@ -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

View File

@ -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);
}

View File

@ -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 *);