summaryrefslogtreecommitdiff
path: root/sys/dev/pci
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2010-07-28 21:21:39 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2010-07-28 21:21:39 +0000
commit8e9f06982f62b3c888466e7be07aef39397657df (patch)
treec4cb46b51d4d08b185147d0fccb0d4a9ada57329 /sys/dev/pci
parente3d2d3e6e203081f26c8422b05f95b04468c8e20 (diff)
Make legacy xxpower() functions call xxstop() on suspend, and simplify their
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
Diffstat (limited to 'sys/dev/pci')
-rw-r--r--sys/dev/pci/if_ipw.c47
-rw-r--r--sys/dev/pci/if_ipwvar.h3
-rw-r--r--sys/dev/pci/if_iwi.c48
-rw-r--r--sys/dev/pci/if_iwivar.h3
-rw-r--r--sys/dev/pci/if_iwn.c18
-rw-r--r--sys/dev/pci/if_wpi.c11
6 files changed, 93 insertions, 37 deletions
diff --git a/sys/dev/pci/if_ipw.c b/sys/dev/pci/if_ipw.c
index fa131e7d59a..d7f90e163bc 100644
--- a/sys/dev/pci/if_ipw.c
+++ b/sys/dev/pci/if_ipw.c
@@ -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
diff --git a/sys/dev/pci/if_ipwvar.h b/sys/dev/pci/if_ipwvar.h
index 7d46e38dddc..77029a5c904 100644
--- a/sys/dev/pci/if_ipwvar.h
+++ b/sys/dev/pci/if_ipwvar.h
@@ -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;
diff --git a/sys/dev/pci/if_iwi.c b/sys/dev/pci/if_iwi.c
index 50abb89e7d5..8c307a6dff4 100644
--- a/sys/dev/pci/if_iwi.c
+++ b/sys/dev/pci/if_iwi.c
@@ -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);
}
diff --git a/sys/dev/pci/if_iwivar.h b/sys/dev/pci/if_iwivar.h
index c98d3ebc0ab..b0c51fae01d 100644
--- a/sys/dev/pci/if_iwivar.h
+++ b/sys/dev/pci/if_iwivar.h
@@ -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;
diff --git a/sys/dev/pci/if_iwn.c b/sys/dev/pci/if_iwn.c
index 958b7c5deb6..b1374e0abab 100644
--- a/sys/dev/pci/if_iwn.c
+++ b/sys/dev/pci/if_iwn.c
@@ -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);
diff --git a/sys/dev/pci/if_wpi.c b/sys/dev/pci/if_wpi.c
index d3df5abe025..46cb8514d1c 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.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)