[PATCH] The ioctl wext etc, seems to be broken because they don't take any lock during shutdown. If the user do an echo to the state variabile of the rfkill during the network scanning the system can go in panic. It introduces a semaphore variable to the ar priv data.
michael
michael at panicking.kicks-ass.org
Tue Mar 31 12:44:32 CEST 2009
Signed-off-by: Michael Trimarch <michael at panicking.kicks-ass.org>
---
drivers/ar6000/ar6000/ar6000_drv.c | 7 ++-
drivers/ar6000/ar6000/ar6000_drv.h | 14 ++++
drivers/ar6000/ar6000/wireless_ext.c | 136 ++++++++++++++++++++++++----------
3 files changed, 116 insertions(+), 41 deletions(-)
diff --git a/drivers/ar6000/ar6000/ar6000_drv.c b/drivers/ar6000/ar6000/ar6000_drv.c
index 21504f2..a1ebdf0 100644
--- a/drivers/ar6000/ar6000/ar6000_drv.c
+++ b/drivers/ar6000/ar6000/ar6000_drv.c
@@ -902,6 +902,9 @@ ar6000_avail_ev(HTC_HANDLE HTCHandle)
AR_DEBUG_PRINTF("ar6000_avail: name=%s htcTarget=0x%x, dev=0x%x (%d), ar=0x%x\n",
dev->name, (A_UINT32)HTCHandle, (A_UINT32)dev, device_index,
(A_UINT32)ar);
+
+ init_rwsem(&ar->arHwAvail);
+ up_write(&ar->arHwAvail);
}
static void ar6000_target_failure(void *Instance, A_STATUS Status)
@@ -942,7 +945,9 @@ static void
ar6000_unavail_ev(void *Instance)
{
AR_SOFTC_T *ar = (AR_SOFTC_T *)Instance;
- /* NULL out it's entry in the global list */
+ /* NULL out it's entry in the global list */
+
+ down_write(&ar->arHwAvail);
ar6000_devices[ar->arDeviceIndex] = NULL;
ar6000_destroy(ar->arNetDev, 1);
}
diff --git a/drivers/ar6000/ar6000/ar6000_drv.h b/drivers/ar6000/ar6000/ar6000_drv.h
index 784f158..f380f39 100644
--- a/drivers/ar6000/ar6000/ar6000_drv.h
+++ b/drivers/ar6000/ar6000/ar6000_drv.h
@@ -205,6 +205,7 @@ typedef struct ar6_softc {
HTC_HANDLE arHtcTarget;
void *arHifDevice;
spinlock_t arLock;
+ struct rw_semaphore arHwAvail;
struct semaphore arSem;
int arRxBuffers[WMI_PRI_MAX_COUNT];
int arSsidLen;
@@ -312,6 +313,19 @@ struct ar_giwscan_param {
#define AR6000_STAT_INC(ar, stat) (ar->arNetStats.stat++)
+static inline int ar6000_hw_avail_lock(struct ar6_softc* ar)
+{
+ if (!down_read_trylock(&ar->arHwAvail))
+ return -EAGAIN;
+ return 0;
+}
+
+static inline int ar6000_hw_avail_unlock(struct ar6_softc* ar)
+{
+ up_read(&ar->arHwAvail);
+ return 0;
+}
+
#define AR6000_SPIN_LOCK(lock, param) do { \
if (irqs_disabled()) { \
AR_DEBUG_PRINTF("IRQs disabled:AR6000_LOCK\n"); \
diff --git a/drivers/ar6000/ar6000/wireless_ext.c b/drivers/ar6000/ar6000/wireless_ext.c
index d9a5920..b0958c7 100644
--- a/drivers/ar6000/ar6000/wireless_ext.c
+++ b/drivers/ar6000/ar6000/wireless_ext.c
@@ -25,6 +25,20 @@ extern unsigned int wmitimeout;
extern A_WAITQUEUE_HEAD arEvent;
extern wait_queue_head_t ar6000_scan_queue;
+#define DECLARE_LOCKED_VERSION(_name) \
+int LOCK_##_name(struct net_device *dev, struct iw_request_info *info, \
+ void *p, char *data) \
+{ \
+ AR_SOFTC_T *ar = (AR_SOFTC_T *)netdev_priv(dev); \
+ int ret; \
+ ret = ar6000_hw_avail_lock(ar); \
+ if (ret) \
+ return ret; \
+ ret = _name(dev, info, p, data); \
+ ret = ar6000_hw_avail_unlock(ar); \
+ return ret; \
+}
+
/*
* Encode a WPA or RSN information element as a custom
* element using the hostap format.
@@ -1849,21 +1863,63 @@ ar6000_set_quality(struct iw_quality *iq, A_INT8 rssi)
iq->updated = 7;
}
+DECLARE_LOCKED_VERSION(ar6000_ioctl_giwname)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_siwfreq)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_siwmode)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_giwfreq)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_giwmode)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_siwsens)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_giwsens)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_giwrange)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_siwap)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_giwap)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_iwaplist)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_siwscan)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_giwscan)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_siwessid)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_giwessid)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_siwrate)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_giwrate)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_siwtxpow)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_giwtxpow)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_siwretry)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_giwretry)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_siwencode)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_giwencode)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_siwpower)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_giwpower)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_siwgenie)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_giwgenie)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_siwauth)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_giwauth)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_siwencodeext)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_giwencodeext)
+
+/* private handler */
+DECLARE_LOCKED_VERSION(ar6000_ioctl_setparam)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_getparam)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_setkey)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_setwmmparams)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_delkey)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_getwmmparams)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_setoptie)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_setmlme)
+DECLARE_LOCKED_VERSION(ar6000_ioctl_addpmkid)
/* Structures to export the Wireless Handlers */
static const iw_handler ath_handlers[] = {
(iw_handler) NULL, /* SIOCSIWCOMMIT */
- (iw_handler) ar6000_ioctl_giwname, /* SIOCGIWNAME */
+ (iw_handler) LOCK_ar6000_ioctl_giwname, /* SIOCGIWNAME */
(iw_handler) NULL, /* SIOCSIWNWID */
(iw_handler) NULL, /* SIOCGIWNWID */
- (iw_handler) ar6000_ioctl_siwfreq, /* SIOCSIWFREQ */
- (iw_handler) ar6000_ioctl_giwfreq, /* SIOCGIWFREQ */
- (iw_handler) ar6000_ioctl_siwmode, /* SIOCSIWMODE */
- (iw_handler) ar6000_ioctl_giwmode, /* SIOCGIWMODE */
- (iw_handler) ar6000_ioctl_siwsens, /* SIOCSIWSENS */
- (iw_handler) ar6000_ioctl_giwsens, /* SIOCGIWSENS */
+ (iw_handler) LOCK_ar6000_ioctl_siwfreq, /* SIOCSIWFREQ */
+ (iw_handler) LOCK_ar6000_ioctl_giwfreq, /* SIOCGIWFREQ */
+ (iw_handler) LOCK_ar6000_ioctl_siwmode, /* SIOCSIWMODE */
+ (iw_handler) LOCK_ar6000_ioctl_giwmode, /* SIOCGIWMODE */
+ (iw_handler) LOCK_ar6000_ioctl_siwsens, /* SIOCSIWSENS */
+ (iw_handler) LOCK_ar6000_ioctl_giwsens, /* SIOCGIWSENS */
(iw_handler) NULL /* not _used */, /* SIOCSIWRANGE */
- (iw_handler) ar6000_ioctl_giwrange, /* SIOCGIWRANGE */
+ (iw_handler) LOCK_ar6000_ioctl_giwrange, /* SIOCGIWRANGE */
(iw_handler) NULL /* not used */, /* SIOCSIWPRIV */
(iw_handler) NULL /* kernel code */, /* SIOCGIWPRIV */
(iw_handler) NULL /* not used */, /* SIOCSIWSTATS */
@@ -1872,53 +1928,53 @@ static const iw_handler ath_handlers[] = {
(iw_handler) NULL, /* SIOCGIWSPY */
(iw_handler) NULL, /* SIOCSIWTHRSPY */
(iw_handler) NULL, /* SIOCGIWTHRSPY */
- (iw_handler) ar6000_ioctl_siwap, /* SIOCSIWAP */
- (iw_handler) ar6000_ioctl_giwap, /* SIOCGIWAP */
+ (iw_handler) LOCK_ar6000_ioctl_siwap, /* SIOCSIWAP */
+ (iw_handler) LOCK_ar6000_ioctl_giwap, /* SIOCGIWAP */
(iw_handler) NULL, /* -- hole -- */
- (iw_handler) ar6000_ioctl_iwaplist, /* SIOCGIWAPLIST */
- (iw_handler) ar6000_ioctl_siwscan, /* SIOCSIWSCAN */
- (iw_handler) ar6000_ioctl_giwscan, /* SIOCGIWSCAN */
- (iw_handler) ar6000_ioctl_siwessid, /* SIOCSIWESSID */
- (iw_handler) ar6000_ioctl_giwessid, /* SIOCGIWESSID */
+ (iw_handler) LOCK_ar6000_ioctl_iwaplist, /* SIOCGIWAPLIST */
+ (iw_handler) LOCK_ar6000_ioctl_siwscan, /* SIOCSIWSCAN */
+ (iw_handler) LOCK_ar6000_ioctl_giwscan, /* SIOCGIWSCAN */
+ (iw_handler) LOCK_ar6000_ioctl_siwessid, /* SIOCSIWESSID */
+ (iw_handler) LOCK_ar6000_ioctl_giwessid, /* SIOCGIWESSID */
(iw_handler) NULL, /* SIOCSIWNICKN */
(iw_handler) NULL, /* SIOCGIWNICKN */
(iw_handler) NULL, /* -- hole -- */
(iw_handler) NULL, /* -- hole -- */
- (iw_handler) ar6000_ioctl_siwrate, /* SIOCSIWRATE */
- (iw_handler) ar6000_ioctl_giwrate, /* SIOCGIWRATE */
+ (iw_handler) LOCK_ar6000_ioctl_siwrate, /* SIOCSIWRATE */
+ (iw_handler) LOCK_ar6000_ioctl_giwrate, /* SIOCGIWRATE */
(iw_handler) NULL, /* SIOCSIWRTS */
(iw_handler) NULL, /* SIOCGIWRTS */
(iw_handler) NULL, /* SIOCSIWFRAG */
(iw_handler) NULL, /* SIOCGIWFRAG */
- (iw_handler) ar6000_ioctl_siwtxpow, /* SIOCSIWTXPOW */
- (iw_handler) ar6000_ioctl_giwtxpow, /* SIOCGIWTXPOW */
- (iw_handler) ar6000_ioctl_siwretry, /* SIOCSIWRETRY */
- (iw_handler) ar6000_ioctl_giwretry, /* SIOCGIWRETRY */
- (iw_handler) ar6000_ioctl_siwencode, /* SIOCSIWENCODE */
- (iw_handler) ar6000_ioctl_giwencode, /* SIOCGIWENCODE */
- (iw_handler) ar6000_ioctl_siwpower, /* SIOCSIWPOWER */
- (iw_handler) ar6000_ioctl_giwpower, /* SIOCGIWPOWER */
+ (iw_handler) LOCK_ar6000_ioctl_siwtxpow, /* SIOCSIWTXPOW */
+ (iw_handler) LOCK_ar6000_ioctl_giwtxpow, /* SIOCGIWTXPOW */
+ (iw_handler) LOCK_ar6000_ioctl_siwretry, /* SIOCSIWRETRY */
+ (iw_handler) LOCK_ar6000_ioctl_giwretry, /* SIOCGIWRETRY */
+ (iw_handler) LOCK_ar6000_ioctl_siwencode, /* SIOCSIWENCODE */
+ (iw_handler) LOCK_ar6000_ioctl_giwencode, /* SIOCGIWENCODE */
+ (iw_handler) LOCK_ar6000_ioctl_siwpower, /* SIOCSIWPOWER */
+ (iw_handler) LOCK_ar6000_ioctl_giwpower, /* SIOCGIWPOWER */
(iw_handler) NULL, /* -- hole -- */
(iw_handler) NULL, /* -- hole -- */
- (iw_handler) ar6000_ioctl_siwgenie, /* SIOCSIWGENIE */
- (iw_handler) ar6000_ioctl_giwgenie, /* SIOCGIWGENIE */
- (iw_handler) ar6000_ioctl_siwauth, /* SIOCSIWAUTH */
- (iw_handler) ar6000_ioctl_giwauth, /* SIOCGIWAUTH */
- (iw_handler) ar6000_ioctl_siwencodeext,/* SIOCSIWENCODEEXT */
- (iw_handler) ar6000_ioctl_giwencodeext,/* SIOCGIWENCODEEXT */
+ (iw_handler) LOCK_ar6000_ioctl_siwgenie, /* SIOCSIWGENIE */
+ (iw_handler) LOCK_ar6000_ioctl_giwgenie, /* SIOCGIWGENIE */
+ (iw_handler) LOCK_ar6000_ioctl_siwauth, /* SIOCSIWAUTH */
+ (iw_handler) LOCK_ar6000_ioctl_giwauth, /* SIOCGIWAUTH */
+ (iw_handler) LOCK_ar6000_ioctl_siwencodeext,/* SIOCSIWENCODEEXT */
+ (iw_handler) LOCK_ar6000_ioctl_giwencodeext,/* SIOCGIWENCODEEXT */
(iw_handler) NULL, /* SIOCSIWPMKSA */
};
static const iw_handler ath_priv_handlers[] = {
- (iw_handler) ar6000_ioctl_setparam, /* SIOCWFIRSTPRIV+0 */
- (iw_handler) ar6000_ioctl_getparam, /* SIOCWFIRSTPRIV+1 */
- (iw_handler) ar6000_ioctl_setkey, /* SIOCWFIRSTPRIV+2 */
- (iw_handler) ar6000_ioctl_setwmmparams, /* SIOCWFIRSTPRIV+3 */
- (iw_handler) ar6000_ioctl_delkey, /* SIOCWFIRSTPRIV+4 */
- (iw_handler) ar6000_ioctl_getwmmparams, /* SIOCWFIRSTPRIV+5 */
- (iw_handler) ar6000_ioctl_setoptie, /* SIOCWFIRSTPRIV+6 */
- (iw_handler) ar6000_ioctl_setmlme, /* SIOCWFIRSTPRIV+7 */
- (iw_handler) ar6000_ioctl_addpmkid, /* SIOCWFIRSTPRIV+8 */
+ (iw_handler) LOCK_ar6000_ioctl_setparam, /* SIOCWFIRSTPRIV+0 */
+ (iw_handler) LOCK_ar6000_ioctl_getparam, /* SIOCWFIRSTPRIV+1 */
+ (iw_handler) LOCK_ar6000_ioctl_setkey, /* SIOCWFIRSTPRIV+2 */
+ (iw_handler) LOCK_ar6000_ioctl_setwmmparams, /* SIOCWFIRSTPRIV+3 */
+ (iw_handler) LOCK_ar6000_ioctl_delkey, /* SIOCWFIRSTPRIV+4 */
+ (iw_handler) LOCK_ar6000_ioctl_getwmmparams, /* SIOCWFIRSTPRIV+5 */
+ (iw_handler) LOCK_ar6000_ioctl_setoptie, /* SIOCWFIRSTPRIV+6 */
+ (iw_handler) LOCK_ar6000_ioctl_setmlme, /* SIOCWFIRSTPRIV+7 */
+ (iw_handler) LOCK_ar6000_ioctl_addpmkid, /* SIOCWFIRSTPRIV+8 */
};
#define IW_PRIV_TYPE_KEY \
--
1.5.6.5
More information about the openmoko-kernel
mailing list