summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2010-08-30 20:42:55 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2010-08-30 20:42:55 +0000
commit0dc5c529ac587885468d2b11474fa9705127d678 (patch)
treed66e42d3da13fd1a3e5308e9aae264da44674133 /sys/dev
parentbbb36a164f00f5b8538f7487aef1dc973a857c29 (diff)
ioctl versus resume-workq exclusion; cloned from iwn
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/ic/if_wi.c29
-rw-r--r--sys/dev/ic/if_wivar.h3
-rw-r--r--sys/dev/pci/if_wi_pci.c13
3 files changed, 34 insertions, 11 deletions
diff --git a/sys/dev/ic/if_wi.c b/sys/dev/ic/if_wi.c
index 3911135ed5f..2f24cb973fd 100644
--- a/sys/dev/ic/if_wi.c
+++ b/sys/dev/ic/if_wi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_wi.c,v 1.148 2010/07/02 02:40:15 blambert Exp $ */
+/* $OpenBSD: if_wi.c,v 1.149 2010/08/30 20:42:27 deraadt Exp $ */
/*
* Copyright (c) 1997, 1998, 1999
@@ -1544,28 +1544,36 @@ STATIC int
wi_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
{
int s, error = 0, i, j, len;
- struct wi_softc *sc;
- struct ifreq *ifr;
+ struct wi_softc *sc = ifp->if_softc;
+ struct ifreq *ifr = (struct ifreq *)data;
struct proc *p = curproc;
struct ifaddr *ifa = (struct ifaddr *)data;
struct wi_scan_res *res;
struct wi_scan_p2_hdr *p2;
struct wi_req *wreq = NULL;
u_int32_t flags;
-
struct ieee80211_nwid *nwidp = NULL;
struct ieee80211_nodereq_all *na;
struct ieee80211_bssid *bssid;
s = splnet();
-
- sc = ifp->if_softc;
- ifr = (struct ifreq *)data;
-
if (!(sc->wi_flags & WI_FLAGS_ATTACHED)) {
+ error = ENODEV;
+ goto fail;
+ }
+
+ /*
+ * Prevent processes from entering this function while another
+ * process is tsleep'ing in it.
+ */
+ while ((sc->wi_flags & WI_FLAGS_BUSY) && error == 0)
+ error = tsleep(&sc->wi_flags, PCATCH, "wiioc", 0);
+ if (error != 0) {
splx(s);
- return(ENODEV);
+ return error;
}
+ sc->wi_flags |= WI_FLAGS_BUSY;
+
DPRINTF (WID_IOCTL, ("wi_ioctl: command %lu data %p\n",
command, data));
@@ -2032,6 +2040,9 @@ wi_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
if (nwidp)
free(nwidp, M_DEVBUF);
+fail:
+ sc->wi_flags &= ~WI_FLAGS_BUSY;
+ wakeup(&sc->wi_flags);
splx(s);
return(error);
}
diff --git a/sys/dev/ic/if_wivar.h b/sys/dev/ic/if_wivar.h
index 6a316e9bba6..cb400dadb2d 100644
--- a/sys/dev/ic/if_wivar.h
+++ b/sys/dev/ic/if_wivar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_wivar.h,v 1.29 2009/08/10 20:29:54 deraadt Exp $ */
+/* $OpenBSD: if_wivar.h,v 1.30 2010/08/30 20:42:27 deraadt Exp $ */
/*
* Copyright (c) 1997, 1998, 1999
@@ -139,6 +139,7 @@ struct wi_softc {
#define WI_FLAGS_BUS_USB 0x0400
#define WI_FLAGS_HAS_ENH_SECURITY 0x0800
#define WI_FLAGS_TXPOWER 0x1000
+#define WI_FLAGS_BUSY 0x2000
#define WI_PRT_FMT "%s"
#define WI_PRT_ARG(sc) (sc)->sc_dev.dv_xname
diff --git a/sys/dev/pci/if_wi_pci.c b/sys/dev/pci/if_wi_pci.c
index d763582c442..9a6fdfe6c3f 100644
--- a/sys/dev/pci/if_wi_pci.c
+++ b/sys/dev/pci/if_wi_pci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_wi_pci.c,v 1.46 2010/08/27 18:29:44 deraadt Exp $ */
+/* $OpenBSD: if_wi_pci.c,v 1.47 2010/08/30 20:42:54 deraadt Exp $ */
/*
* Copyright (c) 2001-2003 Todd C. Miller <Todd.Miller@courtesan.com>
@@ -187,7 +187,18 @@ wi_pci_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_init(sc);
+
+ sc->wi_flags &= ~WI_FLAGS_BUSY;
+ wakeup(&sc->wi_flags);
+ splx(s);
}
void