ACPI suspend/resume for bwi(4). Initial diff from todd@, finished and
authormglocker <mglocker@openbsd.org>
Fri, 6 Aug 2010 05:26:24 +0000 (05:26 +0000)
committermglocker <mglocker@openbsd.org>
Fri, 6 Aug 2010 05:26:24 +0000 (05:26 +0000)
tested by me on X40 with a BCM4306.

OK deraadt@

sys/dev/cardbus/if_bwi_cardbus.c
sys/dev/ic/bwi.c
sys/dev/ic/bwivar.h
sys/dev/pci/if_bwi_pci.c

index 902aef1..e4e5b3c 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if_bwi_cardbus.c,v 1.12 2010/03/27 21:40:13 jsg Exp $ */
+/*     $OpenBSD: if_bwi_cardbus.c,v 1.13 2010/08/06 05:26:24 mglocker Exp $ */
 
 /*
  * Copyright (c) 2007 Marcus Glocker <mglocker@openbsd.org>
@@ -24,6 +24,7 @@
 #include "bpfilter.h"
 
 #include <sys/param.h>
+#include <sys/workq.h>
 #include <sys/mbuf.h>
 #include <sys/socket.h>
 #include <sys/systm.h>
index 171546c..d4e994b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: bwi.c,v 1.92 2010/05/19 15:27:35 oga Exp $    */
+/*     $OpenBSD: bwi.c,v 1.93 2010/08/06 05:26:24 mglocker Exp $       */
 
 /*
  * Copyright (c) 2007 The DragonFly Project.  All rights reserved.
@@ -45,6 +45,7 @@
 #include <sys/device.h>
 #include <sys/kernel.h>
 #include <sys/malloc.h>
+#include <sys/workq.h>
 #include <sys/mbuf.h>
 #include <sys/proc.h>
 #include <sys/socket.h>
@@ -288,13 +289,11 @@ void               bwi_get_clock_freq(struct bwi_softc *,
                     struct bwi_clock_freq *);
 int             bwi_set_clock_mode(struct bwi_softc *, enum bwi_clock_mode);
 int             bwi_set_clock_delay(struct bwi_softc *);
-int             bwi_init(struct ifnet *);
 int             bwi_ioctl(struct ifnet *, u_long, caddr_t);
 void            bwi_start(struct ifnet *);
 void            bwi_watchdog(struct ifnet *);
 void            bwi_newstate_begin(struct bwi_softc *, enum ieee80211_state);
 void            bwi_init_statechg(struct bwi_softc *, int);
-int             bwi_stop(struct bwi_softc *, int);
 int             bwi_newstate(struct ieee80211com *, enum ieee80211_state, int);
 int             bwi_media_change(struct ifnet *);
 void            bwi_iter_func(void *, struct ieee80211_node *);
index 0f7b17c..e7f4283 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: bwivar.h,v 1.25 2009/01/07 01:01:41 jsg Exp $ */
+/*     $OpenBSD: bwivar.h,v 1.26 2010/08/06 05:26:24 mglocker Exp $    */
 
 /*
  * Copyright (c) 2007 The DragonFly Project.  All rights reserved.
@@ -620,6 +620,7 @@ struct bwi_softc {
 #define sc_txtap                 sc_txtapu.th
         int                      sc_txtap_len;
 #endif
+       struct workq_task        sc_resume_wqt;
 };
 
 #define BWI_F_BUS_INITED       0x1
@@ -738,3 +739,5 @@ bwi_rf_lo_update(struct bwi_mac *_mac)
 int            bwi_intr(void *);
 int            bwi_attach(struct bwi_softc *);
 int            bwi_detach(void *);
+int            bwi_init(struct ifnet *);
+int            bwi_stop(struct bwi_softc *, int);
index 55d59cc..051caac 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if_bwi_pci.c,v 1.10 2009/03/29 21:53:52 sthen Exp $ */
+/*     $OpenBSD: if_bwi_pci.c,v 1.11 2010/08/06 05:26:24 mglocker Exp $ */
 
 /*
  * Copyright (c) 2007 Marcus Glocker <mglocker@openbsd.org>
@@ -24,6 +24,7 @@
 
 #include <sys/param.h>
 #include <sys/sockio.h>
+#include <sys/workq.h>
 #include <sys/mbuf.h>
 #include <sys/kernel.h>
 #include <sys/socket.h>
@@ -60,6 +61,8 @@ void          bwi_pci_attach(struct device *, struct device *, void *);
 int            bwi_pci_detach(struct device *, int);
 void           bwi_pci_conf_write(void *, uint32_t, uint32_t);
 uint32_t       bwi_pci_conf_read(void *, uint32_t);
+int            bwi_pci_activate(struct device *, int);
+void           bwi_resume(void *, void *);
 
 struct bwi_pci_softc {
        struct bwi_softc         psc_bwi;
@@ -73,7 +76,7 @@ struct bwi_pci_softc {
 
 struct cfattach bwi_pci_ca = {
        sizeof(struct bwi_pci_softc), bwi_pci_match, bwi_pci_attach,
-       bwi_pci_detach
+       bwi_pci_detach, bwi_pci_activate
 };
 
 const struct pci_matchid bwi_pci_devices[] = {
@@ -175,6 +178,37 @@ bwi_pci_detach(struct device *self, int flags)
        return (0);
 }
 
+int
+bwi_pci_activate(struct device *self, int act)
+{
+       struct bwi_pci_softc *psc = (struct bwi_pci_softc *)self;
+       struct bwi_softc *sc = &psc->psc_bwi;
+       struct ifnet *ifp = &sc->sc_ic.ic_if;
+
+       switch (act) {
+       case DVACT_SUSPEND:
+               if (ifp->if_flags & IFF_RUNNING)
+                       bwi_stop(sc, 1);
+               break;
+       case DVACT_RESUME:
+               workq_queue_task(NULL, &sc->sc_resume_wqt, 0,
+                   bwi_resume, sc, NULL);
+               break;
+       }
+
+       return (0);
+}
+
+void
+bwi_resume(void *arg1, void *arg2)
+{
+       struct bwi_softc *sc = arg1;
+       struct ifnet *ifp = &sc->sc_ic.ic_if;
+
+       if (ifp->if_flags & IFF_UP)
+               bwi_init(ifp);
+}
+
 void
 bwi_pci_conf_write(void *self, uint32_t reg, uint32_t val)
 {