diff options
-rw-r--r-- | sys/dev/pcmcia/cfxga.c | 10 | ||||
-rw-r--r-- | sys/dev/pcmcia/com_pcmcia.c | 22 | ||||
-rw-r--r-- | sys/dev/pcmcia/gpr.c | 8 | ||||
-rw-r--r-- | sys/dev/pcmcia/if_an_pcmcia.c | 13 | ||||
-rw-r--r-- | sys/dev/pcmcia/if_cnw.c | 10 | ||||
-rw-r--r-- | sys/dev/pcmcia/if_ep_pcmcia.c | 34 | ||||
-rw-r--r-- | sys/dev/pcmcia/if_malo.c | 78 | ||||
-rw-r--r-- | sys/dev/pcmcia/if_malovar.h | 5 | ||||
-rw-r--r-- | sys/dev/pcmcia/if_ne_pcmcia.c | 36 | ||||
-rw-r--r-- | sys/dev/pcmcia/if_ray.c | 13 | ||||
-rw-r--r-- | sys/dev/pcmcia/if_sm_pcmcia.c | 10 | ||||
-rw-r--r-- | sys/dev/pcmcia/if_wi_pcmcia.c | 48 | ||||
-rw-r--r-- | sys/dev/pcmcia/if_xe.c | 39 | ||||
-rw-r--r-- | sys/dev/pcmcia/pcmcia.c | 67 | ||||
-rw-r--r-- | sys/dev/pcmcia/wdc_pcmcia.c | 96 |
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 |