From: Dmitry Shmidt Date: Tue, 2 Nov 2010 23:35:22 +0000 (-0700) Subject: net: wireless: bcm4329: Fix race conditions for sysioc_thread X-Git-Tag: firefly_0821_release~9833^2~5^2~95 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=fce23317f22c67bc9feea650af94b030e75244a7;p=firefly-linux-kernel-4.4.55.git net: wireless: bcm4329: Fix race conditions for sysioc_thread Signed-off-by: Dmitry Shmidt --- diff --git a/drivers/net/wireless/bcm4329/dhd.h b/drivers/net/wireless/bcm4329/dhd.h index 4e5ffcbd5237..d136517c51a4 100644 --- a/drivers/net/wireless/bcm4329/dhd.h +++ b/drivers/net/wireless/bcm4329/dhd.h @@ -219,6 +219,9 @@ extern int dhd_os_wake_unlock(dhd_pub_t *pub); extern int dhd_os_wake_lock_timeout(dhd_pub_t *pub); extern int dhd_os_wake_lock_timeout_enable(dhd_pub_t *pub); +extern void dhd_os_start_lock(dhd_pub_t *pub); +extern void dhd_os_start_unlock(dhd_pub_t *pub); + typedef struct dhd_if_event { uint8 ifidx; uint8 action; diff --git a/drivers/net/wireless/bcm4329/dhd_linux.c b/drivers/net/wireless/bcm4329/dhd_linux.c index d7e72c8d12d2..0b52e0373e3e 100644 --- a/drivers/net/wireless/bcm4329/dhd_linux.c +++ b/drivers/net/wireless/bcm4329/dhd_linux.c @@ -282,6 +282,8 @@ typedef struct dhd_info { int hang_was_sent; + struct mutex wl_start_lock; + /* Thread to issue ioctl for multicast */ long sysioc_pid; struct semaphore sysioc_sem; @@ -1065,9 +1067,11 @@ _dhd_sysioc_thread(void *data) DAEMONIZE("dhd_sysioc"); while (down_interruptible(&dhd->sysioc_sem) == 0) { + dhd_os_start_lock(&dhd->pub); dhd_os_wake_lock(&dhd->pub); for (i = 0; i < DHD_MAX_IFS; i++) { if (dhd->iflist[i]) { + DHD_TRACE(("%s: interface %d\n",__FUNCTION__, i)); #ifdef SOFTAP in_ap = (ap_net_dev != NULL); #endif /* SOFTAP */ @@ -1102,6 +1106,7 @@ _dhd_sysioc_thread(void *data) } } dhd_os_wake_unlock(&dhd->pub); + dhd_os_start_unlock(&dhd->pub); } complete_and_exit(&dhd->sysioc_exited, 0); } @@ -1115,6 +1120,7 @@ dhd_set_mac_address(struct net_device *dev, void *addr) struct sockaddr *sa = (struct sockaddr *)addr; int ifidx; + DHD_TRACE(("%s: Enter\n",__FUNCTION__)); ifidx = dhd_net2idx(dhd, dev); if (ifidx == DHD_BAD_IF) return -1; @@ -1133,6 +1139,7 @@ dhd_set_multicast_list(struct net_device *dev) dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev); int ifidx; + DHD_TRACE(("%s: Enter\n",__FUNCTION__)); ifidx = dhd_net2idx(dhd, dev); if (ifidx == DHD_BAD_IF) return; @@ -2119,6 +2126,7 @@ 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 + mutex_init(&dhd->wl_start_lock); /* Link to info module */ dhd->pub.info = dhd; @@ -3289,3 +3297,19 @@ int net_os_send_hang_message(struct net_device *dev) } return ret; } + +void dhd_os_start_lock(dhd_pub_t *pub) +{ + dhd_info_t *dhd = (dhd_info_t *)(pub->info); + + if (dhd) + mutex_lock(&dhd->wl_start_lock); +} + +void dhd_os_start_unlock(dhd_pub_t *pub) +{ + dhd_info_t *dhd = (dhd_info_t *)(pub->info); + + if (dhd) + mutex_unlock(&dhd->wl_start_lock); +} diff --git a/drivers/net/wireless/bcm4329/wl_iw.c b/drivers/net/wireless/bcm4329/wl_iw.c index 82164edc6534..525d3909e7ae 100644 --- a/drivers/net/wireless/bcm4329/wl_iw.c +++ b/drivers/net/wireless/bcm4329/wl_iw.c @@ -110,8 +110,7 @@ static int wl_iw_softap_deassoc_stations(struct net_device *dev); } while (0) static int g_onoff = G_WLAN_SET_ON; -wl_iw_extra_params_t g_wl_iw_params; -static struct mutex wl_start_lock; +wl_iw_extra_params_t g_wl_iw_params; static struct mutex wl_cache_lock; extern bool wl_iw_conn_status_str(uint32 event_type, uint32 status, @@ -1449,6 +1448,7 @@ wl_iw_send_priv_event( int wl_control_wl_start(struct net_device *dev) { + wl_iw_t *iw; int ret = 0; WL_TRACE(("Enter %s \n", __FUNCTION__)); @@ -1458,7 +1458,8 @@ wl_control_wl_start(struct net_device *dev) return -1; } - mutex_lock(&wl_start_lock); + iw = *(wl_iw_t **)netdev_priv(dev); + dhd_os_start_lock(iw->pub); if (g_onoff == G_WLAN_SET_OFF) { dhd_customer_gpio_wlan_ctrl(WLAN_RESET_ON); @@ -1479,7 +1480,7 @@ wl_control_wl_start(struct net_device *dev) } WL_TRACE(("Exited %s \n", __FUNCTION__)); - mutex_unlock(&wl_start_lock); + dhd_os_start_unlock(iw->pub); return ret; } @@ -1490,7 +1491,9 @@ wl_iw_control_wl_off( struct iw_request_info *info ) { + wl_iw_t *iw; int ret = 0; + WL_TRACE(("Enter %s\n", __FUNCTION__)); if (!dev) { @@ -1498,7 +1501,8 @@ wl_iw_control_wl_off( return -1; } - mutex_lock(&wl_start_lock); + iw = *(wl_iw_t **)netdev_priv(dev); + dhd_os_start_lock(iw->pub); #ifdef SOFTAP ap_cfg_running = FALSE; @@ -1537,7 +1541,7 @@ wl_iw_control_wl_off( wl_iw_send_priv_event(dev, "STOP"); } - mutex_unlock(&wl_start_lock); + dhd_os_start_unlock(iw->pub); WL_TRACE(("Exited %s\n", __FUNCTION__)); @@ -7884,7 +7888,7 @@ wl_iw_bt_init(struct net_device *dev) return 0; } -int wl_iw_attach(struct net_device *dev, void * dhdp) +int wl_iw_attach(struct net_device *dev, void *dhdp) { int params_size; wl_iw_t *iw; @@ -7893,7 +7897,6 @@ int wl_iw_attach(struct net_device *dev, void * dhdp) #endif mutex_init(&wl_cache_lock); - mutex_init(&wl_start_lock); #if defined(WL_IW_USE_ISCAN) if (!dev)