diff options
author | Owain Ainsworth <oga@cvs.openbsd.org> | 2010-08-12 15:04:01 +0000 |
---|---|---|
committer | Owain Ainsworth <oga@cvs.openbsd.org> | 2010-08-12 15:04:01 +0000 |
commit | 40ad5e5f1bda27bfeb7bfdad8f6678d2a3dac781 (patch) | |
tree | 7ec7e7372217fa6522f526fee7d6f3d957525274 /sys/dev/pci/if_iwn.c | |
parent | efcc9540fb5c0cb70f9a83b72d2a388401581f71 (diff) |
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_iwn.c')
-rw-r--r-- | sys/dev/pci/if_iwn.c | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/sys/dev/pci/if_iwn.c b/sys/dev/pci/if_iwn.c index b1374e0abab..29b11456b29 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.100 2010/07/28 21:21:38 deraadt Exp $ */ +/* $OpenBSD: if_iwn.c,v 1.101 2010/08/12 15:04:00 oga Exp $ */ /*- * Copyright (c) 2007-2010 Damien Bergamini <damien.bergamini@free.fr> @@ -786,12 +786,15 @@ iwn_power(int why, void *arg) pci_conf_write(sc->sc_pct, sc->sc_pcitag, 0x40, reg); s = splnet(); + while (sc->sc_flags & IWN_FLAG_BUSY) + tsleep(&sc->sc_flags, 0, "iwnpwr", 0); sc->sc_flags |= IWN_FLAG_BUSY; if (ifp->if_flags & IFF_UP) iwn_init(ifp); sc->sc_flags &= ~IWN_FLAG_BUSY; + wakeup(&sc->sc_flags); splx(s); } @@ -3111,9 +3114,11 @@ iwn_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 & IWN_FLAG_BUSY) { + while (sc->sc_flags & IWN_FLAG_BUSY && error == 0) + error = tsleep(&sc->sc_flags, PCATCH, "iwnioc", 0); + if (error) { splx(s); - return EBUSY; + return error; } sc->sc_flags |= IWN_FLAG_BUSY; @@ -3177,6 +3182,7 @@ iwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) } sc->sc_flags &= ~IWN_FLAG_BUSY; + wakeup(&sc->sc_flags); splx(s); return error; } |