diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2010-08-30 20:42:55 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2010-08-30 20:42:55 +0000 |
commit | 0dc5c529ac587885468d2b11474fa9705127d678 (patch) | |
tree | d66e42d3da13fd1a3e5308e9aae264da44674133 /sys/dev | |
parent | bbb36a164f00f5b8538f7487aef1dc973a857c29 (diff) |
ioctl versus resume-workq exclusion; cloned from iwn
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/ic/if_wi.c | 29 | ||||
-rw-r--r-- | sys/dev/ic/if_wivar.h | 3 | ||||
-rw-r--r-- | sys/dev/pci/if_wi_pci.c | 13 |
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 |