From 230e01aee54aa2f006d7d2feab2d103001d88dc7 Mon Sep 17 00:00:00 2001 From: kettenis Date: Thu, 22 Jul 2010 14:42:43 +0000 Subject: [PATCH] Add suspend/resume logic. As discussed with phessler@, incorporating suggestions by damien@. --- sys/dev/pci/if_wpi.c | 38 ++++++++++++++++++++++++++++++++++++-- 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 #include #include +#include #include #include @@ -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; -- 2.20.1