diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2010-07-22 14:42:44 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2010-07-22 14:42:44 +0000 |
commit | 469cd4460afec9fd9ea621a290d6a5d34e7bad1c (patch) | |
tree | 3f456f3cd6f209b77bc92c067214b70b8085d74e /sys | |
parent | e2d76dea27904cbab76eea70f63b71106344667e (diff) |
Add suspend/resume logic. As discussed with phessler@, incorporating
suggestions by damien@.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/pci/if_wpi.c | 38 | ||||
-rw-r--r-- | sys/dev/pci/if_wpivar.h | 3 |
2 files changed, 38 insertions, 3 deletions
diff --git a/sys/dev/pci/if_wpi.c b/sys/dev/pci/if_wpi.c index 87f13e0e775..d3df5abe025 100644 --- a/sys/dev/pci/if_wpi.c +++ b/sys/dev/pci/if_wpi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_wpi.c,v 1.101 2010/07/22 10:22:37 kettenis Exp $ */ +/* $OpenBSD: if_wpi.c,v 1.102 2010/07/22 14:42:43 kettenis Exp $ */ /*- * Copyright (c) 2006-2008 @@ -32,6 +32,7 @@ #include <sys/malloc.h> #include <sys/conf.h> #include <sys/device.h> +#include <sys/workq.h> #include <machine/bus.h> #include <machine/endian.h> @@ -74,6 +75,8 @@ void wpi_attach(struct device *, struct device *, void *); void wpi_radiotap_attach(struct wpi_softc *); #endif int wpi_detach(struct device *, int); +int wpi_activate(struct device *, int); +void wpi_resume(void *, void *); void wpi_power(int, void *); int wpi_nic_lock(struct wpi_softc *); int wpi_read_prom_data(struct wpi_softc *, uint32_t, void *, int); @@ -161,7 +164,8 @@ struct cfdriver wpi_cd = { }; struct cfattach wpi_ca = { - sizeof (struct wpi_softc), wpi_match, wpi_attach, wpi_detach + sizeof (struct wpi_softc), wpi_match, wpi_attach, wpi_detach, + wpi_activate }; int @@ -387,6 +391,32 @@ wpi_detach(struct device *self, int flags) return 0; } +int +wpi_activate(struct device *self, int act) +{ + struct wpi_softc *sc = (struct wpi_softc *)self; + struct ifnet *ifp = &sc->sc_ic.ic_if; + + switch (act) { + case DVACT_SUSPEND: + if (ifp->if_flags & IFF_RUNNING) + wpi_stop(ifp, 1); + break; + case DVACT_RESUME: + workq_queue_task(NULL, &sc->sc_resume_wqt, 0, + wpi_resume, sc, NULL); + break; + } + + return (0); +} + +void +wpi_resume(void *arg1, void *arg2) +{ + wpi_power(PWR_RESUME, arg1); +} + void wpi_power(int why, void *arg) { @@ -404,12 +434,16 @@ wpi_power(int why, void *arg) pci_conf_write(sc->sc_pct, sc->sc_pcitag, 0x40, reg); s = splnet(); + sc->sc_flags |= WPI_FLAG_BUSY; + ifp = &sc->sc_ic.ic_if; if (ifp->if_flags & IFF_UP) { ifp->if_init(ifp); if (ifp->if_flags & IFF_RUNNING) ifp->if_start(ifp); } + + sc->sc_flags &= ~WPI_FLAG_BUSY; splx(s); } diff --git a/sys/dev/pci/if_wpivar.h b/sys/dev/pci/if_wpivar.h index 300de136bca..0c981701cc1 100644 --- a/sys/dev/pci/if_wpivar.h +++ b/sys/dev/pci/if_wpivar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_wpivar.h,v 1.21 2010/07/22 10:22:37 kettenis Exp $ */ +/* $OpenBSD: if_wpivar.h,v 1.22 2010/07/22 14:42:43 kettenis Exp $ */ /*- * Copyright (c) 2006-2008 @@ -181,6 +181,7 @@ struct wpi_softc { int sc_tx_timer; void *powerhook; + struct workq_task sc_resume_wqt; #if NBPFILTER > 0 caddr_t sc_drvbpf; |