summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/dev/pcmcia/cfxga.c10
-rw-r--r--sys/dev/pcmcia/com_pcmcia.c22
-rw-r--r--sys/dev/pcmcia/gpr.c8
-rw-r--r--sys/dev/pcmcia/if_an_pcmcia.c13
-rw-r--r--sys/dev/pcmcia/if_cnw.c10
-rw-r--r--sys/dev/pcmcia/if_ep_pcmcia.c34
-rw-r--r--sys/dev/pcmcia/if_malo.c78
-rw-r--r--sys/dev/pcmcia/if_malovar.h5
-rw-r--r--sys/dev/pcmcia/if_ne_pcmcia.c36
-rw-r--r--sys/dev/pcmcia/if_ray.c13
-rw-r--r--sys/dev/pcmcia/if_sm_pcmcia.c10
-rw-r--r--sys/dev/pcmcia/if_wi_pcmcia.c48
-rw-r--r--sys/dev/pcmcia/if_xe.c39
-rw-r--r--sys/dev/pcmcia/pcmcia.c67
-rw-r--r--sys/dev/pcmcia/wdc_pcmcia.c96
15 files changed, 284 insertions, 205 deletions
diff --git a/sys/dev/pcmcia/cfxga.c b/sys/dev/pcmcia/cfxga.c
index 32b84d6e648..ac7949ca9e4 100644
--- a/sys/dev/pcmcia/cfxga.c
+++ b/sys/dev/pcmcia/cfxga.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cfxga.c,v 1.19 2009/10/13 19:33:16 pirofti Exp $ */
+/* $OpenBSD: cfxga.c,v 1.20 2010/08/30 20:33:18 deraadt Exp $ */
/*
* Copyright (c) 2005, 2006, Matthieu Herrb and Miodrag Vallat
@@ -319,12 +319,8 @@ cfxga_activate(struct device *dev, int act)
switch (act) {
case DVACT_ACTIVATE:
- if (pcmcia_function_enable(sc->sc_pf) != 0) {
- printf("%s: function enable failed\n",
- sc->sc_dev.dv_xname);
- } else {
- cfxga_reset_and_repaint(sc);
- }
+ pcmcia_function_enable(sc->sc_pf);
+ cfxga_reset_and_repaint(sc);
break;
case DVACT_DEACTIVATE:
pcmcia_function_disable(sc->sc_pf);
diff --git a/sys/dev/pcmcia/com_pcmcia.c b/sys/dev/pcmcia/com_pcmcia.c
index 58ebfb4556f..daaae7816ba 100644
--- a/sys/dev/pcmcia/com_pcmcia.c
+++ b/sys/dev/pcmcia/com_pcmcia.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: com_pcmcia.c,v 1.50 2010/06/26 23:24:45 guenther Exp $ */
+/* $OpenBSD: com_pcmcia.c,v 1.51 2010/08/30 20:33:18 deraadt Exp $ */
/* $NetBSD: com_pcmcia.c,v 1.15 1998/08/22 17:47:58 msaitoh Exp $ */
/*
@@ -210,22 +210,32 @@ com_pcmcia_activate(dev, act)
int act;
{
struct com_pcmcia_softc *sc = (void *) dev;
- int s;
- s = spltty();
switch (act) {
case DVACT_ACTIVATE:
pcmcia_function_enable(sc->sc_pf);
sc->sc_ih = pcmcia_intr_establish(sc->sc_pf, IPL_TTY,
comintr, sc, sc->sc_com.sc_dev.dv_xname);
break;
-
+ case DVACT_SUSPEND:
+ if (sc->sc_ih)
+ pcmcia_intr_disestablish(sc->sc_pf, sc->sc_ih);
+ sc->sc_ih = NULL;
+ pcmcia_function_disable(sc->sc_pf);
+ break;
+ case DVACT_RESUME:
+ pcmcia_function_enable(sc->sc_pf);
+ sc->sc_ih = pcmcia_intr_establish(sc->sc_pf, IPL_TTY,
+ comintr, sc, sc->sc_com.sc_dev.dv_xname);
+ com_resume(&sc->sc_com);
+ break;
case DVACT_DEACTIVATE:
- pcmcia_intr_disestablish(sc->sc_pf, sc->sc_ih);
+ if (sc->sc_ih)
+ pcmcia_intr_disestablish(sc->sc_pf, sc->sc_ih);
+ sc->sc_ih = NULL;
pcmcia_function_disable(sc->sc_pf);
break;
}
- splx(s);
return (0);
}
diff --git a/sys/dev/pcmcia/gpr.c b/sys/dev/pcmcia/gpr.c
index 2a708216614..767b680ae79 100644
--- a/sys/dev/pcmcia/gpr.c
+++ b/sys/dev/pcmcia/gpr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: gpr.c,v 1.14 2009/10/29 08:03:16 fgsch Exp $ */
+/* $OpenBSD: gpr.c,v 1.15 2010/08/30 20:33:18 deraadt Exp $ */
/*
* Copyright (c) 2002, Federico G. Schwindt
@@ -247,13 +247,13 @@ gpr_activate(struct device *dev, int act)
sc->sc_ih = pcmcia_intr_establish(sc->sc_pf, IPL_TTY,
gpr_intr, sc, sc->sc_dev.dv_xname);
break;
-
case DVACT_DEACTIVATE:
- pcmcia_intr_disestablish(sc->sc_pf, sc->sc_ih);
+ if (sc->sc_ih)
+ pcmcia_intr_disestablish(sc->sc_pf, sc->sc_ih);
+ sc->sc_ih = NULL;
pcmcia_function_disable(sc->sc_pf);
break;
}
-
return (0);
}
diff --git a/sys/dev/pcmcia/if_an_pcmcia.c b/sys/dev/pcmcia/if_an_pcmcia.c
index d5208d9f3d3..5acbddd40cc 100644
--- a/sys/dev/pcmcia/if_an_pcmcia.c
+++ b/sys/dev/pcmcia/if_an_pcmcia.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_an_pcmcia.c,v 1.20 2009/10/13 19:33:16 pirofti Exp $ */
+/* $OpenBSD: if_an_pcmcia.c,v 1.21 2010/08/30 20:33:18 deraadt Exp $ */
/*
* Copyright (c) 1999 Michael Shalayeff
@@ -130,7 +130,6 @@ an_pcmcia_attach(struct device *parent, struct device *self, void *aux)
sc->sc_iot = psc->sc_pcioh.iot;
sc->sc_ioh = psc->sc_pcioh.ioh;
- sc->sc_enabled = 1;
sc->sc_ih = pcmcia_intr_establish(psc->sc_pf, IPL_NET, an_intr, sc,
sc->sc_dev.dv_xname);
@@ -146,7 +145,6 @@ an_pcmcia_attach(struct device *parent, struct device *self, void *aux)
return;
}
- sc->sc_enabled = 0;
psc->sc_state = AN_PCMCIA_ATTACHED;
}
@@ -176,9 +174,7 @@ an_pcmcia_activate(struct device *dev, int act)
struct an_softc *sc = &psc->sc_an;
struct ieee80211com *ic = &sc->sc_ic;
struct ifnet *ifp = &ic->ic_if;
- int s;
- s = splnet();
switch (act) {
case DVACT_ACTIVATE:
pcmcia_function_enable(psc->sc_pf);
@@ -186,16 +182,15 @@ an_pcmcia_activate(struct device *dev, int act)
an_intr, sc, sc->sc_dev.dv_xname);
an_init(ifp);
break;
-
case DVACT_DEACTIVATE:
ifp->if_timer = 0;
if (ifp->if_flags & IFF_RUNNING)
an_stop(ifp, 1);
- pcmcia_intr_disestablish(psc->sc_pf, sc->sc_ih);
+ if (sc->sc_ih)
+ pcmcia_intr_disestablish(psc->sc_pf, sc->sc_ih);
+ sc->sc_ih = NULL;
pcmcia_function_disable(psc->sc_pf);
break;
}
-
- splx(s);
return (0);
}
diff --git a/sys/dev/pcmcia/if_cnw.c b/sys/dev/pcmcia/if_cnw.c
index ea8d72cf14a..cf34c4e8ef7 100644
--- a/sys/dev/pcmcia/if_cnw.c
+++ b/sys/dev/pcmcia/if_cnw.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_cnw.c,v 1.20 2009/10/13 19:33:16 pirofti Exp $ */
+/* $OpenBSD: if_cnw.c,v 1.21 2010/08/30 20:33:18 deraadt Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -860,9 +860,7 @@ cnw_activate(dev, act)
{
struct cnw_softc *sc = (struct cnw_softc *)dev;
struct ifnet *ifp = &sc->sc_arpcom.ac_if;
- int s;
- s = splnet();
switch (act) {
case DVACT_ACTIVATE:
pcmcia_function_enable(sc->sc_pf);
@@ -870,14 +868,14 @@ cnw_activate(dev, act)
cnw_intr, sc, sc->sc_dev.dv_xname);
cnw_init(sc);
break;
-
case DVACT_DEACTIVATE:
ifp->if_timer = 0;
ifp->if_flags &= ~IFF_RUNNING; /* XXX no cnw_stop() ? */
- pcmcia_intr_disestablish(sc->sc_pf, sc->sc_ih);
+ if (sc->sc_ih)
+ pcmcia_intr_disestablish(sc->sc_pf, sc->sc_ih);
+ sc->sc_ih = NULL;
pcmcia_function_disable(sc->sc_pf);
break;
}
- splx(s);
return (0);
}
diff --git a/sys/dev/pcmcia/if_ep_pcmcia.c b/sys/dev/pcmcia/if_ep_pcmcia.c
index fa14d7b539b..1b9f3222b4e 100644
--- a/sys/dev/pcmcia/if_ep_pcmcia.c
+++ b/sys/dev/pcmcia/if_ep_pcmcia.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_ep_pcmcia.c,v 1.38 2009/10/13 19:33:16 pirofti Exp $ */
+/* $OpenBSD: if_ep_pcmcia.c,v 1.39 2010/08/30 20:33:18 deraadt Exp $ */
/* $NetBSD: if_ep_pcmcia.c,v 1.16 1998/08/17 23:20:40 thorpej Exp $ */
/*-
@@ -408,26 +408,40 @@ ep_pcmcia_activate(dev, act)
struct ep_pcmcia_softc *sc = (struct ep_pcmcia_softc *)dev;
struct ep_softc *esc = &sc->sc_ep;
struct ifnet *ifp = &esc->sc_arpcom.ac_if;
- int s;
- s = splnet();
switch (act) {
case DVACT_ACTIVATE:
+ if (sc->sc_ep.sc_ih == NULL) {
+ pcmcia_function_enable(sc->sc_pf);
+ sc->sc_ep.sc_ih = pcmcia_intr_establish(sc->sc_pf, IPL_NET,
+ epintr, sc, esc->sc_dev.dv_xname);
+ }
+ if (ifp->if_flags & IFF_UP)
+ epinit(esc);
+ break;
+ case DVACT_SUSPEND:
+ ifp->if_timer = 0;
+ if (ifp->if_flags & IFF_RUNNING)
+ epstop(esc);
+ if (sc->sc_ep.sc_ih)
+ pcmcia_intr_disestablish(sc->sc_pf, sc->sc_ep.sc_ih);
+ sc->sc_ep.sc_ih = NULL;
+ pcmcia_function_disable(sc->sc_pf);
+ break;
+ case DVACT_RESUME:
pcmcia_function_enable(sc->sc_pf);
sc->sc_ep.sc_ih = pcmcia_intr_establish(sc->sc_pf, IPL_NET,
epintr, sc, esc->sc_dev.dv_xname);
- epinit(esc);
+ if (ifp->if_flags & IFF_UP)
+ epinit(esc);
break;
-
case DVACT_DEACTIVATE:
- ifp->if_timer = 0;
- if (ifp->if_flags & IFF_RUNNING)
- epstop(esc);
- pcmcia_intr_disestablish(sc->sc_pf, sc->sc_ep.sc_ih);
+ if (sc->sc_ep.sc_ih)
+ pcmcia_intr_disestablish(sc->sc_pf, sc->sc_ep.sc_ih);
+ sc->sc_ep.sc_ih = NULL;
pcmcia_function_disable(sc->sc_pf);
break;
}
- splx(s);
return (0);
}
diff --git a/sys/dev/pcmcia/if_malo.c b/sys/dev/pcmcia/if_malo.c
index f97141ab59f..b4d4c400aa8 100644
--- a/sys/dev/pcmcia/if_malo.c
+++ b/sys/dev/pcmcia/if_malo.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_malo.c,v 1.70 2010/08/27 17:08:00 jsg Exp $ */
+/* $OpenBSD: if_malo.c,v 1.71 2010/08/30 20:33:18 deraadt Exp $ */
/*
* Copyright (c) 2007 Marcus Glocker <mglocker@openbsd.org>
@@ -29,6 +29,7 @@
#include <sys/malloc.h>
#include <sys/sockio.h>
#include <sys/mbuf.h>
+#include <sys/workq.h>
#if NBPFILTER > 0
#include <net/bpf.h>
@@ -71,6 +72,7 @@ int malo_pcmcia_match(struct device *, void *, void *);
void malo_pcmcia_attach(struct device *, struct device *, void *);
int malo_pcmcia_detach(struct device *, int);
int malo_pcmcia_activate(struct device *, int);
+void malo_pcmcia_resume(void *, void *);
void cmalo_attach(void *);
int cmalo_ioctl(struct ifnet *, u_long, caddr_t);
@@ -236,30 +238,64 @@ malo_pcmcia_activate(struct device *dev, int act)
struct malo_softc *sc = &psc->sc_malo;
struct ieee80211com *ic = &sc->sc_ic;
struct ifnet *ifp = &ic->ic_if;
- int s;
- s = splnet();
switch (act) {
case DVACT_ACTIVATE:
pcmcia_function_enable(psc->sc_pf);
psc->sc_ih = pcmcia_intr_establish(psc->sc_pf, IPL_NET,
cmalo_intr, sc, sc->sc_dev.dv_xname);
- cmalo_init(ifp);
+ workq_queue_task(NULL, &sc->sc_resume_wqt, 0,
+ malo_pcmcia_resume, sc, NULL);
break;
- case DVACT_DEACTIVATE:
- ifp->if_timer = 0;
- if (ifp->if_flags & IFF_RUNNING)
+ case DVACT_SUSPEND:
+ if ((sc->sc_flags & MALO_DEVICE_ATTACHED) &&
+ (ifp->if_flags & IFF_RUNNING))
cmalo_stop(sc);
- if (psc->sc_ih != NULL)
+ if (psc->sc_ih)
pcmcia_intr_disestablish(psc->sc_pf, psc->sc_ih);
+ psc->sc_ih = NULL;
+ pcmcia_function_disable(psc->sc_pf);
+ break;
+ case DVACT_RESUME:
+ pcmcia_function_enable(psc->sc_pf);
+ psc->sc_ih = pcmcia_intr_establish(psc->sc_pf, IPL_NET,
+ cmalo_intr, sc, sc->sc_dev.dv_xname);
+ workq_queue_task(NULL, &sc->sc_resume_wqt, 0,
+ malo_pcmcia_resume, sc, NULL);
+ break;
+ case DVACT_DEACTIVATE:
+ if ((sc->sc_flags & MALO_DEVICE_ATTACHED) &&
+ (ifp->if_flags & IFF_RUNNING))
+ cmalo_stop(sc); /* XXX tries to touch regs */
+ if (psc->sc_ih)
+ pcmcia_intr_disestablish(psc->sc_pf, psc->sc_ih);
+ psc->sc_ih = NULL;
pcmcia_function_disable(psc->sc_pf);
break;
}
- splx(s);
-
return (0);
}
+void
+malo_pcmcia_resume(void *arg1, void *arg2)
+{
+ struct malo_softc *sc = arg1;
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct ifnet *ifp = &ic->ic_if;
+ int s;
+
+ s = splnet();
+ while (sc->sc_flags & MALO_BUSY)
+ tsleep(&sc->sc_flags, 0, "malopwr", 0);
+ sc->sc_flags |= MALO_BUSY;
+
+ cmalo_init(ifp);
+
+ sc->sc_flags &= ~MALO_BUSY;
+ wakeup(&sc->sc_flags);
+ splx(s);
+}
+
/*
* Driver.
*/
@@ -350,6 +386,17 @@ cmalo_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
int i, j, s, error = 0;
s = splnet();
+ /*
+ * Prevent processes from entering this function while another
+ * process is tsleep'ing in it.
+ */
+ while ((sc->sc_flags & MALO_BUSY) && error == 0)
+ error = tsleep(&sc->sc_flags, PCATCH, "maloioc", 0);
+ if (error != 0) {
+ splx(s);
+ return error;
+ }
+ sc->sc_flags |= MALO_BUSY;
switch (cmd) {
case SIOCSIFADDR:
@@ -430,6 +477,8 @@ cmalo_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
error = 0;
}
+ sc->sc_flags &= ~MALO_BUSY;
+ wakeup(&sc->sc_flags);
splx(s);
return (error);
@@ -587,7 +636,7 @@ cmalo_fw_load_main(struct malo_softc *sc)
for (i = 0; i < bsize / 2; i++)
MALO_WRITE_2(sc, MALO_REG_CMD_WRITE, htole16(uc[i]));
MALO_WRITE_1(sc, MALO_REG_HOST_STATUS, MALO_VAL_CMD_DL_OVER);
- MALO_WRITE_2(sc, MALO_REG_CARD_INTR_CAUSE,
+ MALO_WRITE_2(sc, MALO_REG_CARD_INTR_CAUSE,
MALO_VAL_CMD_DL_OVER);
/* poll for an acknowledgement */
@@ -648,8 +697,8 @@ cmalo_init(struct ifnet *ifp)
sc->sc_flags &= ~MALO_ASSOC_FAILED;
/* get current channel */
- ic->ic_bss->ni_chan = ic->ic_ibss_chan;
- sc->sc_curchan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan);
+ ic->ic_bss->ni_chan = ic->ic_ibss_chan;
+ sc->sc_curchan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan);
DPRINTF(1, "%s: current channel is %d\n",
sc->sc_dev.dv_xname, sc->sc_curchan);
@@ -704,7 +753,7 @@ void
cmalo_stop(struct malo_softc *sc)
{
struct ieee80211com *ic = &sc->sc_ic;
- struct ifnet *ifp = &ic->ic_if;
+ struct ifnet *ifp = &ic->ic_if;
/* device down */
ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
@@ -715,6 +764,7 @@ cmalo_stop(struct malo_softc *sc)
/* reset device */
cmalo_cmd_set_reset(sc);
sc->sc_flags &= ~MALO_FW_LOADED;
+ ifp->if_timer = 0;
DPRINTF(1, "%s: device down\n", sc->sc_dev.dv_xname);
}
diff --git a/sys/dev/pcmcia/if_malovar.h b/sys/dev/pcmcia/if_malovar.h
index 4ffbf7d65be..e98a19177f0 100644
--- a/sys/dev/pcmcia/if_malovar.h
+++ b/sys/dev/pcmcia/if_malovar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_malovar.h,v 1.27 2007/10/09 20:37:32 mglocker Exp $ */
+/* $OpenBSD: if_malovar.h,v 1.28 2010/08/30 20:33:18 deraadt Exp $ */
/*
* Copyright (c) 2007 Marcus Glocker <mglocker@openbsd.org>
@@ -42,7 +42,7 @@
#define MALO_DEVICE_ATTACHED (1 << 0)
#define MALO_FW_LOADED (1 << 1)
#define MALO_ASSOC_FAILED (1 << 2)
-
+#define MALO_BUSY (1 << 3)
/*
* FW command structures
*/
@@ -365,4 +365,5 @@ struct malo_softc {
int sc_net_cur;
struct malo_networks sc_net[12];
struct timeout sc_scan_to;
+ struct workq_task sc_resume_wqt;
};
diff --git a/sys/dev/pcmcia/if_ne_pcmcia.c b/sys/dev/pcmcia/if_ne_pcmcia.c
index 0f15416c425..f96a14da897 100644
--- a/sys/dev/pcmcia/if_ne_pcmcia.c
+++ b/sys/dev/pcmcia/if_ne_pcmcia.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_ne_pcmcia.c,v 1.93 2009/10/13 19:33:16 pirofti Exp $ */
+/* $OpenBSD: if_ne_pcmcia.c,v 1.94 2010/08/30 20:33:18 deraadt Exp $ */
/* $NetBSD: if_ne_pcmcia.c,v 1.17 1998/08/15 19:00:04 thorpej Exp $ */
/*
@@ -865,29 +865,47 @@ ne_pcmcia_activate(dev, act)
struct ne_pcmcia_softc *sc = (struct ne_pcmcia_softc *)dev;
struct dp8390_softc *esc = &sc->sc_ne2000.sc_dp8390;
struct ifnet *ifp = &esc->sc_arpcom.ac_if;
- int s;
- s = splnet();
switch (act) {
case DVACT_ACTIVATE:
pcmcia_function_enable(sc->sc_pf);
sc->sc_ih = pcmcia_intr_establish(sc->sc_pf, IPL_NET,
dp8390_intr, sc, esc->sc_dev.dv_xname);
+ /* XXX this is ridiculous */
dp8390_init(esc);
+ dp8390_stop(esc);
break;
-
- case DVACT_DEACTIVATE:
+ case DVACT_SUSPEND:
ifp->if_timer = 0;
- if (ifp->if_flags & IFF_RUNNING)
+ if (ifp->if_flags & IFF_RUNNING) {
dp8390_stop(esc);
- if (sc->sc_ih != NULL) {
+ ifp->if_flags &= ~IFF_RUNNING;
+ }
+ if (sc->sc_ih != NULL)
pcmcia_intr_disestablish(sc->sc_pf, sc->sc_ih);
- sc->sc_ih = NULL;
+ sc->sc_ih = NULL;
+ pcmcia_function_disable(sc->sc_pf);
+ break;
+ case DVACT_RESUME:
+ pcmcia_function_enable(sc->sc_pf);
+ sc->sc_ih = pcmcia_intr_establish(sc->sc_pf, IPL_NET,
+ dp8390_intr, sc, esc->sc_dev.dv_xname);
+ dp8390_enable(esc);
+ if (ifp->if_flags & IFF_UP)
+ dp8390_init(esc);
+ break;
+ case DVACT_DEACTIVATE:
+ ifp->if_timer = 0;
+ if (ifp->if_flags & IFF_RUNNING) {
+ dp8390_stop(esc);
+ ifp->if_flags &= ~IFF_RUNNING;
}
+ if (sc->sc_ih != NULL)
+ pcmcia_intr_disestablish(sc->sc_pf, sc->sc_ih);
+ sc->sc_ih = NULL;
pcmcia_function_disable(sc->sc_pf);
break;
}
- splx(s);
return (0);
}
diff --git a/sys/dev/pcmcia/if_ray.c b/sys/dev/pcmcia/if_ray.c
index 595d481f261..c6eefbfa63c 100644
--- a/sys/dev/pcmcia/if_ray.c
+++ b/sys/dev/pcmcia/if_ray.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_ray.c,v 1.42 2010/08/27 05:04:12 deraadt Exp $ */
+/* $OpenBSD: if_ray.c,v 1.43 2010/08/30 20:33:18 deraadt Exp $ */
/* $NetBSD: if_ray.c,v 1.21 2000/07/05 02:35:54 onoe Exp $ */
/*
@@ -654,11 +654,7 @@ ray_activate(struct device *dev, int act)
{
struct ray_softc *sc = (struct ray_softc *)dev;
struct ifnet *ifp = &sc->sc_if;
- int s;
-
- RAY_DPRINTF(("%s: activate\n", sc->sc_xname));
- s = splnet();
switch (act) {
case DVACT_ACTIVATE:
pcmcia_function_enable(sc->sc_pf);
@@ -666,18 +662,15 @@ ray_activate(struct device *dev, int act)
ray_enable(sc);
printf("\n");
break;
-
case DVACT_DEACTIVATE:
if (ifp->if_flags & IFF_RUNNING)
ray_disable(sc);
- if (sc->sc_ih) {
+ if (sc->sc_ih)
pcmcia_intr_disestablish(sc->sc_pf, sc->sc_ih);
- sc->sc_ih = NULL;
- }
+ sc->sc_ih = NULL;
pcmcia_function_disable(sc->sc_pf);
break;
}
- splx(s);
return (0);
}
diff --git a/sys/dev/pcmcia/if_sm_pcmcia.c b/sys/dev/pcmcia/if_sm_pcmcia.c
index 21c35cf064d..a6327cd7204 100644
--- a/sys/dev/pcmcia/if_sm_pcmcia.c
+++ b/sys/dev/pcmcia/if_sm_pcmcia.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_sm_pcmcia.c,v 1.29 2009/10/13 19:33:16 pirofti Exp $ */
+/* $OpenBSD: if_sm_pcmcia.c,v 1.30 2010/08/30 20:33:18 deraadt Exp $ */
/* $NetBSD: if_sm_pcmcia.c,v 1.11 1998/08/15 20:47:32 thorpej Exp $ */
/*-
@@ -252,9 +252,7 @@ sm_pcmcia_activate(dev, act)
{
struct sm_pcmcia_softc *sc = (struct sm_pcmcia_softc *)dev;
struct ifnet *ifp = &sc->sc_smc.sc_arpcom.ac_if;
- int s;
- s = splnet();
switch (act) {
case DVACT_ACTIVATE:
pcmcia_function_enable(sc->sc_pf);
@@ -262,16 +260,16 @@ sm_pcmcia_activate(dev, act)
smc91cxx_intr, sc, sc->sc_smc.sc_dev.dv_xname);
smc91cxx_init(&sc->sc_smc);
break;
-
case DVACT_DEACTIVATE:
ifp->if_timer = 0;
if (ifp->if_flags & IFF_RUNNING)
smc91cxx_stop(&sc->sc_smc);
- pcmcia_intr_disestablish(sc->sc_pf, sc->sc_ih);
+ if (sc->sc_ih)
+ pcmcia_intr_disestablish(sc->sc_pf, sc->sc_ih);
+ sc->sc_ih = NULL;
pcmcia_function_disable(sc->sc_pf);
break;
}
- splx(s);
return (0);
}
diff --git a/sys/dev/pcmcia/if_wi_pcmcia.c b/sys/dev/pcmcia/if_wi_pcmcia.c
index 3a3ad263808..3c45273fec2 100644
--- a/sys/dev/pcmcia/if_wi_pcmcia.c
+++ b/sys/dev/pcmcia/if_wi_pcmcia.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_wi_pcmcia.c,v 1.68 2009/10/13 19:33:16 pirofti Exp $ */
+/* $OpenBSD: if_wi_pcmcia.c,v 1.69 2010/08/30 20:33:18 deraadt Exp $ */
/* $NetBSD: if_wi_pcmcia.c,v 1.14 2001/11/26 04:34:56 ichiro Exp $ */
/*
@@ -49,6 +49,7 @@
#include <sys/socket.h>
#include <sys/device.h>
#include <sys/tree.h>
+#include <sys/workq.h>
#include <net/if.h>
#include <net/if_dl.h>
@@ -76,6 +77,7 @@ int wi_pcmcia_match(struct device *, void *, void *);
void wi_pcmcia_attach(struct device *, struct device *, void *);
int wi_pcmcia_detach(struct device *, int);
int wi_pcmcia_activate(struct device *, int);
+void wi_pcmcia_resume(void *, void *);
struct wi_pcmcia_softc {
struct wi_softc sc_wi;
@@ -83,6 +85,7 @@ struct wi_pcmcia_softc {
struct pcmcia_io_handle sc_pcioh;
int sc_io_window;
struct pcmcia_function *sc_pf;
+ struct workq_task sc_resume_wqt;
};
struct cfattach wi_pcmcia_ca = {
@@ -472,28 +475,57 @@ wi_pcmcia_activate(struct device *dev, int act)
struct wi_pcmcia_softc *psc = (struct wi_pcmcia_softc *)dev;
struct wi_softc *sc = &psc->sc_wi;
struct ifnet *ifp = &sc->sc_ic.ic_if;
- int s;
- s = splnet();
switch (act) {
case DVACT_ACTIVATE:
pcmcia_function_enable(psc->sc_pf);
sc->sc_ih = pcmcia_intr_establish(psc->sc_pf, IPL_NET,
wi_intr, sc, sc->sc_dev.dv_xname);
- wi_cor_reset(sc);
- wi_init(sc);
+ workq_queue_task(NULL, &psc->sc_resume_wqt, 0,
+ wi_pcmcia_resume, sc, NULL);
break;
-
- case DVACT_DEACTIVATE:
+ case DVACT_SUSPEND:
ifp->if_timer = 0;
if (ifp->if_flags & IFF_RUNNING)
wi_stop(sc);
sc->wi_flags &= ~WI_FLAGS_INITIALIZED;
if (sc->sc_ih != NULL)
pcmcia_intr_disestablish(psc->sc_pf, sc->sc_ih);
+ sc->sc_ih = NULL;
+ pcmcia_function_disable(psc->sc_pf);
+ break;
+ case DVACT_RESUME:
+ pcmcia_function_enable(psc->sc_pf);
+ sc->sc_ih = pcmcia_intr_establish(psc->sc_pf, IPL_NET,
+ wi_intr, sc, sc->sc_dev.dv_xname);
+ workq_queue_task(NULL, &psc->sc_resume_wqt, 0,
+ wi_pcmcia_resume, sc, NULL);
+ break;
+ case DVACT_DEACTIVATE:
+ if (sc->sc_ih != NULL)
+ pcmcia_intr_disestablish(psc->sc_pf, sc->sc_ih);
+ sc->sc_ih = NULL;
pcmcia_function_disable(psc->sc_pf);
break;
}
- splx(s);
return (0);
}
+
+void
+wi_pcmcia_resume(void *arg1, void *arg2)
+{
+ struct wi_softc *sc = (struct wi_softc *)arg1;
+ int s;
+
+ s = splnet();
+ while (sc->wi_flags & WI_FLAGS_BUSY)
+ tsleep(&sc->wi_flags, 0, "wipwr", 0);
+ sc->wi_flags |= WI_FLAGS_BUSY;
+
+ wi_cor_reset(sc);
+ wi_init(sc);
+
+ sc->wi_flags &= ~WI_FLAGS_BUSY;
+ wakeup(&sc->wi_flags);
+ splx(s);
+}
diff --git a/sys/dev/pcmcia/if_xe.c b/sys/dev/pcmcia/if_xe.c
index 778ae416423..e73631c0098 100644
--- a/sys/dev/pcmcia/if_xe.c
+++ b/sys/dev/pcmcia/if_xe.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_xe.c,v 1.38 2009/10/13 19:33:16 pirofti Exp $ */
+/* $OpenBSD: if_xe.c,v 1.39 2010/08/30 20:33:18 deraadt Exp $ */
/*
* Copyright (c) 1999 Niklas Hallqvist, Brandon Creighton, Job de Haas
@@ -420,11 +420,6 @@ xe_pcmcia_attach(parent, self, aux)
ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER | IFM_NONE);
xe_stop(sc);
}
-
-#ifdef notyet
- pcmcia_function_disable(pa->pf);
-#endif /* notyet */
-
return;
bad:
@@ -466,26 +461,42 @@ xe_pcmcia_activate(dev, act)
{
struct xe_pcmcia_softc *sc = (struct xe_pcmcia_softc *)dev;
struct ifnet *ifp = &sc->sc_xe.sc_arpcom.ac_if;
- int s;
- s = splnet();
switch (act) {
case DVACT_ACTIVATE:
+ if (sc->sc_xe.sc_ih == NULL) {
+ pcmcia_function_enable(sc->sc_pf);
+ sc->sc_xe.sc_ih = pcmcia_intr_establish(sc->sc_pf, IPL_NET,
+ xe_intr, sc, sc->sc_xe.sc_dev.dv_xname);
+ }
+ break;
+ case DVACT_SUSPEND:
+ if (ifp->if_flags & IFF_RUNNING)
+ xe_stop(&sc->sc_xe);
+ ifp->if_flags &= ~IFF_RUNNING;
+ if (sc->sc_xe.sc_ih)
+ pcmcia_intr_disestablish(sc->sc_pf, sc->sc_xe.sc_ih);
+ sc->sc_xe.sc_ih = NULL;
+ pcmcia_function_disable(sc->sc_pf);
+ break;
+ case DVACT_RESUME:
pcmcia_function_enable(sc->sc_pf);
sc->sc_xe.sc_ih = pcmcia_intr_establish(sc->sc_pf, IPL_NET,
xe_intr, sc, sc->sc_xe.sc_dev.dv_xname);
- xe_init(&sc->sc_xe);
+ /* XXX this is a ridiculous */
+ xe_reset(&sc->sc_xe);
+ if ((ifp->if_flags & IFF_UP) == 0)
+ xe_stop(&sc->sc_xe);
break;
-
case DVACT_DEACTIVATE:
ifp->if_timer = 0;
- if (ifp->if_flags & IFF_RUNNING)
- xe_stop(&sc->sc_xe);
- pcmcia_intr_disestablish(sc->sc_pf, sc->sc_xe.sc_ih);
+ ifp->if_flags &= ~IFF_RUNNING;
+ if (sc->sc_xe.sc_ih)
+ pcmcia_intr_disestablish(sc->sc_pf, sc->sc_xe.sc_ih);
+ sc->sc_xe.sc_ih = NULL;
pcmcia_function_disable(sc->sc_pf);
break;
}
- splx(s);
return (0);
}
diff --git a/sys/dev/pcmcia/pcmcia.c b/sys/dev/pcmcia/pcmcia.c
index 6659f0538c7..08dc0476296 100644
--- a/sys/dev/pcmcia/pcmcia.c
+++ b/sys/dev/pcmcia/pcmcia.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pcmcia.c,v 1.39 2007/09/11 13:39:34 gilles Exp $ */
+/* $OpenBSD: pcmcia.c,v 1.40 2010/08/30 20:33:18 deraadt Exp $ */
/* $NetBSD: pcmcia.c,v 1.9 1998/08/13 02:10:55 eeh Exp $ */
/*
@@ -55,9 +55,10 @@ int pcmcia_verbose = 0;
int pcmcia_match(struct device *, void *, void *);
int pcmcia_submatch(struct device *, void *, void *);
void pcmcia_attach(struct device *, struct device *, void *);
+int pcmcia_activate(struct device *, int);
int pcmcia_print(void *, const char *);
void pcmcia_card_detach_notify(struct device *, void *);
-void pcmcia_power(int why, void *arg);
+void pcmcia_powerhook(int why, void *arg);
static inline void pcmcia_socket_enable(pcmcia_chipset_tag_t,
pcmcia_chipset_handle_t *);
@@ -71,7 +72,8 @@ struct cfdriver pcmcia_cd = {
};
struct cfattach pcmcia_ca = {
- sizeof(struct pcmcia_softc), pcmcia_match, pcmcia_attach
+ sizeof(struct pcmcia_softc), pcmcia_match, pcmcia_attach, NULL,
+ pcmcia_activate
};
int
@@ -128,34 +130,46 @@ pcmcia_attach(parent, self, aux)
sc->iosize = paa->iosize;
sc->ih = NULL;
- powerhook_establish(pcmcia_power, sc);
+ powerhook_establish(pcmcia_powerhook, sc);
}
-void
-pcmcia_power(why, arg)
- int why;
- void *arg;
+int
+pcmcia_activate(struct device *self, int act)
{
- struct pcmcia_softc *sc = (struct pcmcia_softc *) arg;
+ struct pcmcia_softc *sc = (struct pcmcia_softc *)self;
struct pcmcia_function *pf;
- struct device *d;
- int act = DVACT_ACTIVATE;
- if (why != PWR_RESUME)
- act = DVACT_DEACTIVATE;
-
- for (pf = SIMPLEQ_FIRST(&sc->card.pf_head); pf != NULL;
- pf = SIMPLEQ_NEXT(pf, pf_list)) {
- if (SIMPLEQ_FIRST(&pf->cfe_head) == NULL)
- continue;
- d = pf->child;
- if (d == NULL)
- continue;
- if (act == DVACT_ACTIVATE)
- config_activate(pf->child);
- else
+ switch (act) {
+ case DVACT_ACTIVATE:
+ /* No children yet */
+ break;
+ case DVACT_DEACTIVATE:
+ for (pf = SIMPLEQ_FIRST(&sc->card.pf_head); pf != NULL;
+ pf = SIMPLEQ_NEXT(pf, pf_list)) {
+ if (SIMPLEQ_FIRST(&pf->cfe_head) == NULL ||
+ pf->child == NULL)
+ continue;
config_deactivate(pf->child);
+ }
+ break;
+ case DVACT_SUSPEND:
+ case DVACT_RESUME:
+ for (pf = SIMPLEQ_FIRST(&sc->card.pf_head); pf != NULL;
+ pf = SIMPLEQ_NEXT(pf, pf_list)) {
+ if (SIMPLEQ_FIRST(&pf->cfe_head) == NULL ||
+ pf->child == NULL)
+ continue;
+ config_suspend(pf->child, act);
+ }
+ break;
}
+ return 0;
+}
+
+void
+pcmcia_powerhook(int why, void *arg)
+{
+ pcmcia_activate(arg, why);
}
int
@@ -296,9 +310,8 @@ pcmcia_card_deactivate(dev)
*/
for (pf = SIMPLEQ_FIRST(&sc->card.pf_head); pf != NULL;
pf = SIMPLEQ_NEXT(pf, pf_list)) {
- if (SIMPLEQ_FIRST(&pf->cfe_head) == NULL)
- continue;
- if (pf->child == NULL)
+ if (SIMPLEQ_FIRST(&pf->cfe_head) == NULL ||
+ pf->child == NULL)
continue;
DPRINTF(("%s: deactivating %s (function %d)\n",
sc->dev.dv_xname, pf->child->dv_xname, pf->number));
diff --git a/sys/dev/pcmcia/wdc_pcmcia.c b/sys/dev/pcmcia/wdc_pcmcia.c
index bed15e261e3..97d29d4ed10 100644
--- a/sys/dev/pcmcia/wdc_pcmcia.c
+++ b/sys/dev/pcmcia/wdc_pcmcia.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: wdc_pcmcia.c,v 1.22 2010/08/29 18:41:24 deraadt Exp $ */
+/* $OpenBSD: wdc_pcmcia.c,v 1.23 2010/08/30 20:33:18 deraadt Exp $ */
/* $NetBSD: wdc_pcmcia.c,v 1.19 1999/02/19 21:49:43 abs Exp $ */
/*-
@@ -138,8 +138,6 @@ int wdc_pcmcia_disk_device_interface(struct pcmcia_function *);
struct wdc_pcmcia_product *
wdc_pcmcia_lookup(struct pcmcia_attach_args *);
-int wdc_pcmcia_enable(void *, int);
-
int
wdc_pcmcia_disk_device_interface_callback(tuple, arg)
struct pcmcia_tuple *tuple;
@@ -354,23 +352,12 @@ wdc_pcmcia_attach(parent, self, aux)
if (quirks & WDC_PCMCIA_NO_EXTRA_RESETS)
sc->sc_wdcdev.cap |= WDC_CAPABILITY_NO_EXTRA_RESETS;
-#ifdef notyet
- /* We can enable and disable the controller. */
- sc->sc_wdcdev.sc_atapi_adapter.scsipi_enable = wdc_pcmcia_enable;
-
- /*
- * Disable the pcmcia function now; wdcattach() will enable
- * us again as it adds references to probe for children.
- */
- pcmcia_function_disable(pa->pf);
-#else
/* Establish the interrupt handler. */
sc->sc_ih = pcmcia_intr_establish(sc->sc_pf, IPL_BIO, wdcintr,
&sc->wdc_channel, sc->sc_wdcdev.sc_dev.dv_xname);
intrstr = pcmcia_intr_string(sc->sc_pf, sc->sc_ih);
if (*intrstr)
printf(": %s", intrstr);
-#endif
printf("\n");
@@ -438,81 +425,44 @@ wdc_pcmcia_activate(self, act)
int act;
{
struct wdc_pcmcia_softc *sc = (struct wdc_pcmcia_softc *)self;
- int rv = 0, s;
+ int rv = 0;
if (sc->sc_iowindow == -1)
/* Nothing to activate/deactivate. */
return (0);
- s = splbio();
switch (act) {
case DVACT_ACTIVATE:
- if (pcmcia_function_enable(sc->sc_pf)) {
- printf("%s: couldn't enable PCMCIA function\n",
- sc->sc_wdcdev.sc_dev.dv_xname);
- rv = EIO;
- break;
+ if (sc->sc_ih == NULL) {
+ /* XXX attach function already did the work */
+ pcmcia_function_enable(sc->sc_pf);
+ sc->sc_ih = pcmcia_intr_establish(sc->sc_pf, IPL_BIO,
+ wdcintr, &sc->wdc_channel, sc->sc_wdcdev.sc_dev.dv_xname);
+ wdcreset(&sc->wdc_channel, VERBOSE);
}
-
+ rv = config_activate_children(self, act);
+ break;
+ case DVACT_SUSPEND:
+ rv = config_activate_children(self, act);
+ if (sc->sc_ih)
+ pcmcia_intr_disestablish(sc->sc_pf, sc->sc_ih);
+ sc->sc_ih = NULL;
+ pcmcia_function_disable(sc->sc_pf);
+ break;
+ case DVACT_RESUME:
+ pcmcia_function_enable(sc->sc_pf);
sc->sc_ih = pcmcia_intr_establish(sc->sc_pf, IPL_BIO,
wdcintr, &sc->wdc_channel, sc->sc_wdcdev.sc_dev.dv_xname);
- if (sc->sc_ih == NULL) {
- printf("%s: "
- "couldn't establish interrupt handler\n",
- sc->sc_wdcdev.sc_dev.dv_xname);
- pcmcia_function_disable(sc->sc_pf);
- rv = EIO;
- break;
- }
-
wdcreset(&sc->wdc_channel, VERBOSE);
rv = config_activate_children(self, act);
break;
-
case DVACT_DEACTIVATE:
- pcmcia_intr_disestablish(sc->sc_pf, sc->sc_ih);
- pcmcia_function_disable(sc->sc_pf);
rv = config_activate_children(self, act);
- break;
- }
- splx(s);
- return (rv);
-}
-
-#if 0
-int
-wdc_pcmcia_enable(arg, onoff)
- void *arg;
- int onoff;
-{
- struct wdc_pcmcia_softc *sc = arg;
-
- if (onoff) {
- if ((sc->sc_flags & WDC_PCMCIA_ATTACH) == 0) {
- if (pcmcia_function_enable(sc->sc_pf)) {
- printf("%s: couldn't enable PCMCIA function\n",
- sc->sc_wdcdev.sc_dev.dv_xname);
- return (EIO);
- }
-
- sc->sc_ih = pcmcia_intr_establish(sc->sc_pf, IPL_BIO,
- wdcintr, &sc->wdc_channel, sc->sc_dev.dv_xname);
- if (sc->sc_ih == NULL) {
- printf("%s: "
- "couldn't establish interrupt handler\n",
- sc->sc_wdcdev.sc_dev.dv_xname);
- pcmcia_function_disable(sc->sc_pf);
- return (EIO);
- }
-
- wdcreset(&sc->wdc_channel, VERBOSE);
- }
- } else {
- if ((sc->sc_flags & WDC_PCMCIA_ATTACH) == 0)
+ if (sc->sc_ih)
pcmcia_intr_disestablish(sc->sc_pf, sc->sc_ih);
+ sc->sc_ih = NULL;
pcmcia_function_disable(sc->sc_pf);
+ break;
}
-
- return (0);
+ return (rv);
}
-#endif