summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Shmidt <dimitrysh@google.com>2011-06-13 17:33:26 -0700
committerColin Cross <ccross@android.com>2011-06-15 17:20:58 -0700
commita70ab7beb436f1448445c1609e71fb9a4d4d68b3 (patch)
treec650b5f8ea109398fae44182a6d449b84cca9e42
parentd530ae0780726ce0dd198afc151ebb893bc9319e (diff)
net: wireless: bcmdhd: Fix race conditions for sysioc_thread
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
-rw-r--r--drivers/net/wireless/bcmdhd/dhd_linux.c14
-rw-r--r--drivers/net/wireless/bcmdhd/wl_iw.c29
2 files changed, 32 insertions, 11 deletions
diff --git a/drivers/net/wireless/bcmdhd/dhd_linux.c b/drivers/net/wireless/bcmdhd/dhd_linux.c
index 854da51d257..7d78bae0df0 100644
--- a/drivers/net/wireless/bcmdhd/dhd_linux.c
+++ b/drivers/net/wireless/bcmdhd/dhd_linux.c
@@ -407,7 +407,7 @@ typedef struct dhd_info {
struct wake_lock wl_rxwake; /* Wifi rx wakelock */
#endif
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25))
struct mutex wl_start_lock; /* mutex when START called to prevent any other Linux calls */
#endif
spinlock_t wakelock_spinlock;
@@ -1205,6 +1205,7 @@ _dhd_sysioc_thread(void *data)
break;
}
+ dhd_os_start_lock(&dhd->pub);
for (i = 0; i < DHD_MAX_IFS; i++) {
if (dhd->iflist[i]) {
@@ -1249,6 +1250,8 @@ _dhd_sysioc_thread(void *data)
}
DHD_OS_WAKE_UNLOCK(&dhd->pub);
+ dhd_os_start_unlock(&dhd->pub);
+
}
DHD_TRACE(("%s: stopped\n", __FUNCTION__));
complete_and_exit(&tsk->completed, 0);
@@ -2563,6 +2566,9 @@ dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen)
wake_lock_init(&dhd->wl_wifi, WAKE_LOCK_SUSPEND, "wlan_wake");
wake_lock_init(&dhd->wl_rxwake, WAKE_LOCK_SUSPEND, "wlan_rx_wake");
#endif
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25))
+ mutex_init(&dhd->wl_start_lock);
+#endif
dhd_state |= DHD_ATTACH_STATE_WAKELOCKS_INIT;
/* Attach and link in the protocol */
@@ -3961,24 +3967,26 @@ void dhd_bus_country_set(struct net_device *dev, wl_country_t *cspec)
}
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1
void dhd_os_start_lock(dhd_pub_t *pub)
{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25))
dhd_info_t *dhd = (dhd_info_t *)(pub->info);
if (dhd)
mutex_lock(&dhd->wl_start_lock);
+#endif
}
void dhd_os_start_unlock(dhd_pub_t *pub)
{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25))
dhd_info_t *dhd = (dhd_info_t *)(pub->info);
if (dhd)
mutex_unlock(&dhd->wl_start_lock);
+#endif
}
-#endif
#ifdef SOFTAP
unsigned long dhd_os_spin_lock(dhd_pub_t *pub)
diff --git a/drivers/net/wireless/bcmdhd/wl_iw.c b/drivers/net/wireless/bcmdhd/wl_iw.c
index ef713eea425..0af60732dca 100644
--- a/drivers/net/wireless/bcmdhd/wl_iw.c
+++ b/drivers/net/wireless/bcmdhd/wl_iw.c
@@ -130,7 +130,6 @@ wl_iw_extra_params_t g_wl_iw_params;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && 1
-static struct mutex wl_start_lock;
static struct mutex wl_cache_lock;
static struct mutex wl_softap_lock;
@@ -1633,6 +1632,7 @@ int
wl_control_wl_start(struct net_device *dev)
{
int ret = 0;
+ wl_iw_t *iw;
WL_TRACE(("Enter %s \n", __FUNCTION__));
@@ -1640,8 +1640,15 @@ wl_control_wl_start(struct net_device *dev)
WL_ERROR(("%s: dev is null\n", __FUNCTION__));
return -1;
}
-
- DHD_OS_MUTEX_LOCK(&wl_start_lock);
+
+ iw = *(wl_iw_t **)netdev_priv(dev);
+
+ if (!iw) {
+ WL_ERROR(("%s: wl is null\n", __FUNCTION__));
+ return -1;
+ }
+
+ dhd_os_start_lock(iw->pub);
if (g_onoff == G_WLAN_SET_OFF) {
dhd_customer_gpio_wlan_ctrl(WLAN_RESET_ON);
@@ -1662,7 +1669,7 @@ wl_control_wl_start(struct net_device *dev)
}
WL_TRACE(("Exited %s\n", __FUNCTION__));
- DHD_OS_MUTEX_UNLOCK(&wl_start_lock);
+ dhd_os_start_unlock(iw->pub);
return ret;
}
@@ -1674,6 +1681,7 @@ wl_iw_control_wl_off(
)
{
int ret = 0;
+ wl_iw_t *iw;
WL_TRACE(("Enter %s\n", __FUNCTION__));
@@ -1682,7 +1690,14 @@ wl_iw_control_wl_off(
return -1;
}
- DHD_OS_MUTEX_LOCK(&wl_start_lock);
+ iw = *(wl_iw_t **)netdev_priv(dev);
+
+ if (!iw) {
+ WL_ERROR(("%s: wl is null\n", __FUNCTION__));
+ return -1;
+ }
+
+ dhd_os_start_lock(iw->pub);
#ifdef SOFTAP
ap_cfg_running = FALSE;
@@ -1718,7 +1733,6 @@ wl_iw_control_wl_off(
sdioh_stop(NULL);
#endif
-
net_os_set_dtim_skip(dev, 0);
dhd_customer_gpio_wlan_ctrl(WLAN_RESET_OFF);
@@ -1726,7 +1740,7 @@ wl_iw_control_wl_off(
wl_iw_send_priv_event(dev, "STOP");
}
- DHD_OS_MUTEX_UNLOCK(&wl_start_lock);
+ dhd_os_start_unlock(iw->pub);
WL_TRACE(("Exited %s\n", __FUNCTION__));
@@ -8475,7 +8489,6 @@ wl_iw_attach(struct net_device *dev, void * dhdp)
#endif
DHD_OS_MUTEX_INIT(&wl_cache_lock);
- DHD_OS_MUTEX_INIT(&wl_start_lock);
DHD_OS_MUTEX_INIT(&wl_softap_lock);
#if defined(WL_IW_USE_ISCAN)