summaryrefslogtreecommitdiffstats
path: root/sys/dev/pci/if_ipw.c
diff options
context:
space:
mode:
authoroga <oga@openbsd.org>2010-08-12 15:03:59 +0000
committeroga <oga@openbsd.org>2010-08-12 15:03:59 +0000
commit0d2a695a79bf321d8bd7eecdcc88e038af56d503 (patch)
tree75a5f8ebe202a366d2c5a743137c169deecec01e /sys/dev/pci/if_ipw.c
parentNuke extra (typoed) extern declaration and a spare newline from the last (diff)
downloadwireguard-openbsd-0d2a695a79bf321d8bd7eecdcc88e038af56d503.tar.xz
wireguard-openbsd-0d2a695a79bf321d8bd7eecdcc88e038af56d503.zip
Instead of returning EBUSY when the busy flag is set in the ioctl, sleep
until whoever has it is done with it. This is kept as flag/sleep condvars instead of a rwlock because later we may want to quiesce the handler before suspend to make sure nothing is sleeping on a chip that is about to be whacked (doing so will change the proc so rwlocks won't work). ok damien@
Diffstat (limited to 'sys/dev/pci/if_ipw.c')
-rw-r--r--sys/dev/pci/if_ipw.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/sys/dev/pci/if_ipw.c b/sys/dev/pci/if_ipw.c
index 2bd64440f5d..e2d28eab276 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.88 2010/08/03 18:26:25 kettenis Exp $ */
+/* $OpenBSD: if_ipw.c,v 1.89 2010/08/12 15:03:59 oga Exp $ */
/*-
* Copyright (c) 2004-2008
@@ -339,12 +339,15 @@ ipw_power(int why, void *arg)
pci_conf_write(sc->sc_pct, sc->sc_pcitag, 0x40, data);
s = splnet();
+ while (sc->sc_flags & IPW_FLAG_BUSY)
+ tsleep(&sc->sc_flags, PZERO, "ipwpwr", 0);
sc->sc_flags |= IPW_FLAG_BUSY;
if (ifp->if_flags & IFF_UP)
ipw_init(ifp);
sc->sc_flags &= ~IPW_FLAG_BUSY;
+ wakeup(&sc->sc_flags);
splx(s);
}
@@ -1399,9 +1402,11 @@ ipw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
* Prevent processes from entering this function while another
* process is tsleep'ing in it.
*/
- if (sc->sc_flags & IPW_FLAG_BUSY) {
+ while (sc->sc_flags & IPW_FLAG_BUSY && error == 0)
+ error = tsleep(&sc->sc_flags, PCATCH, "ipwioc", 0);
+ if (error) {
splx(s);
- return EBUSY;
+ return error;
}
sc->sc_flags |= IPW_FLAG_BUSY;
@@ -1458,6 +1463,7 @@ ipw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
}
sc->sc_flags &= ~IPW_FLAG_BUSY;
+ wakeup(&sc->sc_flags);
splx(s);
return error;
}