Make legacy xxpower() functions call xxstop() on suspend, and simplify their
authorderaadt <deraadt@openbsd.org>
Wed, 28 Jul 2010 21:21:38 +0000 (21:21 +0000)
committerderaadt <deraadt@openbsd.org>
Wed, 28 Jul 2010 21:21:38 +0000 (21:21 +0000)
resume paths.  For new-style suspend/resume, add a ca_activate function where
it is missing, and use a workq to resume because these drivers like to sleep.
ok damien

sys/dev/pci/if_ipw.c
sys/dev/pci/if_ipwvar.h
sys/dev/pci/if_iwi.c
sys/dev/pci/if_iwivar.h
sys/dev/pci/if_iwn.c
sys/dev/pci/if_wpi.c

index fa131e7..d7f90e1 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if_ipw.c,v 1.86 2010/04/20 22:05:43 tedu Exp $        */
+/*     $OpenBSD: if_ipw.c,v 1.87 2010/07/28 21:21:38 deraadt Exp $     */
 
 /*-
  * Copyright (c) 2004-2008
@@ -64,6 +64,8 @@
 
 int            ipw_match(struct device *, void *, void *);
 void           ipw_attach(struct device *, struct device *, void *);
+int            ipw_activate(struct device *, int);
+void           ipw_resume(void *, void *);
 void           ipw_power(int, void *);
 int            ipw_dma_alloc(struct ipw_softc *);
 void           ipw_release(struct ipw_softc *);
@@ -132,7 +134,8 @@ int ipw_debug = 0;
 #endif
 
 struct cfattach ipw_ca = {
-       sizeof (struct ipw_softc), ipw_match, ipw_attach
+       sizeof (struct ipw_softc), ipw_match, ipw_attach, NULL,
+       ipw_activate
 };
 
 int
@@ -291,27 +294,51 @@ ipw_attach(struct device *parent, struct device *self, void *aux)
 #endif
 }
 
+int
+ipw_activate(struct device *self, int act)
+{
+       struct ipw_softc *sc = (struct ipw_softc *)self;
+       struct ifnet *ifp = &sc->sc_ic.ic_if;
+
+       switch (act) {
+       case DVACT_SUSPEND:
+               if (ifp->if_flags & IFF_RUNNING)
+                       ipw_stop(ifp, 0);
+               break;
+       case DVACT_RESUME:
+               workq_queue_task(NULL, &sc->sc_resume_wqt, 0,
+                   ipw_resume, sc, NULL);
+               break;
+       }
+
+       return (0);
+}
+
+void
+ipw_resume(void *arg1, void *arg2)
+{
+       ipw_power(PWR_RESUME, arg1);
+}
+
 void
 ipw_power(int why, void *arg)
 {
        struct ipw_softc *sc = arg;
-       struct ifnet *ifp;
+       struct ifnet *ifp = &sc->sc_ic.ic_if;
        pcireg_t data;
 
-       if (why != PWR_RESUME)
+       if (why != PWR_RESUME) {
+               ipw_stop(ifp, 0);
                return;
+       }
 
        /* clear device specific PCI configuration register 0x41 */
        data = pci_conf_read(sc->sc_pct, sc->sc_pcitag, 0x40);
        data &= ~0x0000ff00;
        pci_conf_write(sc->sc_pct, sc->sc_pcitag, 0x40, data);
 
-       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);
-       }
+       if (ifp->if_flags & IFF_UP)
+               ipw_init(ifp);
 }
 
 int
index 7d46e38..77029a5 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if_ipwvar.h,v 1.18 2008/08/28 15:08:38 damien Exp $   */
+/*     $OpenBSD: if_ipwvar.h,v 1.19 2010/07/28 21:21:38 deraadt Exp $  */
 
 /*-
  * Copyright (c) 2004-2006
@@ -128,6 +128,7 @@ struct ipw_softc {
        int                             txfree;
 
        void                            *powerhook;
+       struct workq_task               sc_resume_wqt;
 
 #if NBPFILTER > 0
        caddr_t                         sc_drvbpf;
index 50abb89..8c307a6 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if_iwi.c,v 1.103 2010/05/19 15:27:35 oga Exp $        */
+/*     $OpenBSD: if_iwi.c,v 1.104 2010/07/28 21:21:38 deraadt Exp $    */
 
 /*-
  * Copyright (c) 2004-2008
@@ -31,6 +31,7 @@
 #include <sys/systm.h>
 #include <sys/conf.h>
 #include <sys/device.h>
+#include <sys/workq.h>
 
 #include <machine/bus.h>
 #include <machine/endian.h>
@@ -73,6 +74,8 @@ const struct pci_matchid iwi_devices[] = {
 
 int            iwi_match(struct device *, void *, void *);
 void           iwi_attach(struct device *, struct device *, void *);
+int            iwi_activate(struct device *, int);
+void           iwi_resume(void *, void *);
 void           iwi_power(int, void *);
 int            iwi_alloc_cmd_ring(struct iwi_softc *, struct iwi_cmd_ring *);
 void           iwi_reset_cmd_ring(struct iwi_softc *, struct iwi_cmd_ring *);
@@ -141,7 +144,8 @@ int iwi_debug = 0;
 #endif
 
 struct cfattach iwi_ca = {
-       sizeof (struct iwi_softc), iwi_match, iwi_attach
+       sizeof (struct iwi_softc), iwi_match, iwi_attach, NULL,
+       iwi_activate
 };
 
 int
@@ -332,16 +336,44 @@ fail:     while (--ac >= 0)
        iwi_free_cmd_ring(sc, &sc->cmdq);
 }
 
+int
+iwi_activate(struct device *self, int act)
+{
+       struct iwi_softc *sc = (struct iwi_softc *)self;
+       struct ifnet *ifp = &sc->sc_ic.ic_if;
+
+       switch (act) {
+       case DVACT_SUSPEND:
+               if (ifp->if_flags & IFF_RUNNING)
+                       iwi_stop(ifp, 0);
+               break;
+       case DVACT_RESUME:
+               workq_queue_task(NULL, &sc->sc_resume_wqt, 0,
+                   iwi_resume, sc, NULL);
+               break;
+       }
+
+       return (0);
+}
+
+void
+iwi_resume(void *arg1, void *arg2)
+{
+       iwi_power(PWR_RESUME, arg1);
+}
+
 void
 iwi_power(int why, void *arg)
 {
        struct iwi_softc *sc = arg;
-       struct ifnet *ifp;
+       struct ifnet *ifp = &sc->sc_ic.ic_if;
        pcireg_t data;
        int s;
 
-       if (why != PWR_RESUME)
+       if (why != PWR_RESUME) {
+               iwi_stop(ifp, 0);
                return;
+       }
 
        /* clear device specific PCI configuration register 0x41 */
        data = pci_conf_read(sc->sc_pct, sc->sc_pcitag, 0x40);
@@ -349,12 +381,8 @@ iwi_power(int why, void *arg)
        pci_conf_write(sc->sc_pct, sc->sc_pcitag, 0x40, data);
 
        s = splnet();
-       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);
-       }
+       if (ifp->if_flags & IFF_UP)
+               iwi_init(ifp);
        splx(s);
 }
 
index c98d3eb..b0c51fa 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if_iwivar.h,v 1.20 2009/06/05 22:40:31 deraadt Exp $  */
+/*     $OpenBSD: if_iwivar.h,v 1.21 2010/07/28 21:21:38 deraadt Exp $  */
 
 /*-
  * Copyright (c) 2004-2006
@@ -114,6 +114,7 @@ struct iwi_softc {
        int                     sc_tx_timer;
 
        void                    *powerhook;
+       struct workq_task       sc_resume_wqt;
 
 #if NBPFILTER > 0
        caddr_t                 sc_drvbpf;
index 958b7c5..b1374e0 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if_iwn.c,v 1.99 2010/07/23 06:43:00 phessler Exp $    */
+/*     $OpenBSD: if_iwn.c,v 1.100 2010/07/28 21:21:38 deraadt Exp $    */
 
 /*-
  * Copyright (c) 2007-2010 Damien Bergamini <damien.bergamini@free.fr>
@@ -750,7 +750,7 @@ iwn_activate(struct device *self, int act)
        switch (act) {
        case DVACT_SUSPEND:
                if (ifp->if_flags & IFF_RUNNING)
-                       iwn_stop(ifp, 1);
+                       iwn_stop(ifp, 0);
                break;
        case DVACT_RESUME:
                workq_queue_task(NULL, &sc->sc_resume_wqt, 0,
@@ -771,12 +771,14 @@ void
 iwn_power(int why, void *arg)
 {
        struct iwn_softc *sc = arg;
-       struct ifnet *ifp;
+       struct ifnet *ifp = &sc->sc_ic.ic_if;
        pcireg_t reg;
        int s;
 
-       if (why != PWR_RESUME)
+       if (why != PWR_RESUME) {
+               iwn_stop(ifp, 0);
                return;
+       }
 
        /* Clear device-specific "PCI retry timeout" register (41h). */
        reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag, 0x40);
@@ -786,12 +788,8 @@ iwn_power(int why, void *arg)
        s = splnet();
        sc->sc_flags |= IWN_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);
-       }
+       if (ifp->if_flags & IFF_UP)
+               iwn_init(ifp);
 
        sc->sc_flags &= ~IWN_FLAG_BUSY;
        splx(s);
index d3df5ab..46cb851 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if_wpi.c,v 1.102 2010/07/22 14:42:43 kettenis Exp $   */
+/*     $OpenBSD: if_wpi.c,v 1.103 2010/07/28 21:21:38 deraadt Exp $    */
 
 /*-
  * Copyright (c) 2006-2008
@@ -400,7 +400,7 @@ wpi_activate(struct device *self, int act)
        switch (act) {
        case DVACT_SUSPEND:
                if (ifp->if_flags & IFF_RUNNING)
-                       wpi_stop(ifp, 1);
+                       wpi_stop(ifp, 0);
                break;
        case DVACT_RESUME:
                workq_queue_task(NULL, &sc->sc_resume_wqt, 0,
@@ -421,12 +421,14 @@ void
 wpi_power(int why, void *arg)
 {
        struct wpi_softc *sc = arg;
-       struct ifnet *ifp;
+       struct ifnet *ifp = &sc->sc_ic.ic_if;
        pcireg_t reg;
        int s;
 
-       if (why != PWR_RESUME)
+       if (why != PWR_RESUME) {
+               wpi_stop(ifp, 0);
                return;
+       }
 
        /* Clear device-specific "PCI retry timeout" register (41h). */
        reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag, 0x40);
@@ -436,7 +438,6 @@ wpi_power(int why, void *arg)
        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)