From 4720a01ff353c9d71c28fdac106efebf55c88bb9 Mon Sep 17 00:00:00 2001
From: Dmitry Shmidt <dimitrysh@google.com>
Date: Tue, 28 Jun 2011 13:57:55 -0700
Subject: [PATCH 337/696] net: wireless: bcmdhd: Fix wd_timer_valid field protection

Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
---
 drivers/net/wireless/bcmdhd/dhd_linux.c |   16 +++++++++++++++-
 1 files changed, 15 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/bcmdhd/dhd_linux.c b/drivers/net/wireless/bcmdhd/dhd_linux.c
index c4b5539..0908cd0 100644
--- a/drivers/net/wireless/bcmdhd/dhd_linux.c
+++ b/drivers/net/wireless/bcmdhd/dhd_linux.c
@@ -1597,6 +1597,7 @@ dhd_watchdog_thread(void *data)
 
 	while (1)
 		if (down_interruptible (&tsk->sema) == 0) {
+			unsigned long flags;
 
 			SMP_RD_BARRIER_DEPENDS();
 			if (tsk->terminated) {
@@ -1610,12 +1611,14 @@ dhd_watchdog_thread(void *data)
 				/* Call the bus module watchdog */
 				dhd_bus_watchdog(&dhd->pub);
 
+				flags = dhd_os_spin_lock(&dhd->pub);
 				/* Count the tick for reference */
 				dhd->pub.tickcnt++;
 				/* Reschedule the watchdog */
 				if (dhd->wd_timer_valid)
 					mod_timer(&dhd->timer,
 					jiffies + dhd_watchdog_ms * HZ / 1000);
+				dhd_os_spin_unlock(&dhd->pub, flags);
 			}
 			dhd_os_sdunlock(&dhd->pub);
 			DHD_OS_WAKE_UNLOCK(&dhd->pub);
@@ -1630,6 +1633,7 @@ dhd_watchdog_thread(void *data)
 static void dhd_watchdog(ulong data)
 {
 	dhd_info_t *dhd = (dhd_info_t *)data;
+	unsigned long flags;
 
 	DHD_OS_WAKE_LOCK(&dhd->pub);
 	if (dhd->pub.dongle_reset) {
@@ -1648,12 +1652,14 @@ static void dhd_watchdog(ulong data)
 	/* Call the bus module watchdog */
 	dhd_bus_watchdog(&dhd->pub);
 
+	flags = dhd_os_spin_lock(&dhd->pub);
 	/* Count the tick for reference */
 	dhd->pub.tickcnt++;
 
 	/* Reschedule the watchdog */
 	if (dhd->wd_timer_valid)
 		mod_timer(&dhd->timer, jiffies + dhd_watchdog_ms * HZ / 1000);
+	dhd_os_spin_unlock(&dhd->pub, flags);
 	dhd_os_sdunlock(&dhd->pub);
 	DHD_OS_WAKE_UNLOCK(&dhd->pub);
 }
@@ -2561,6 +2567,7 @@ dhd_bus_start(dhd_pub_t *dhdp)
 {
 	int ret = -1;
 	dhd_info_t *dhd = (dhd_info_t*)dhdp->info;
+	unsigned long flags;
 #ifdef EMBEDDED_PLATFORM
 	char iovbuf[WL_EVENTING_MASK_LEN + 12];	/*  Room for "event_msgs" + '\0' + bitvec  */
 #endif /* EMBEDDED_PLATFORM */
@@ -2603,7 +2610,9 @@ dhd_bus_start(dhd_pub_t *dhdp)
 	/* Host registration for OOB interrupt */
 	if (bcmsdh_register_oob_intr(dhdp)) {
 		/* deactivate timer and wait for the handler to finish */
+		flags = dhd_os_spin_lock(&dhd->pub);
 		dhd->wd_timer_valid = FALSE;
+		dhd_os_spin_unlock(&dhd->pub, flags);
 		del_timer_sync(&dhd->timer);
 
 		DHD_ERROR(("%s Host failed to register for OOB\n", __FUNCTION__));
@@ -2617,8 +2626,10 @@ dhd_bus_start(dhd_pub_t *dhdp)
 
 	/* If bus is not ready, can't come up */
 	if (dhd->pub.busstate != DHD_BUS_DATA) {
-		del_timer_sync(&dhd->timer);
+		flags = dhd_os_spin_lock(&dhd->pub);
 		dhd->wd_timer_valid = FALSE;
+		dhd_os_spin_unlock(&dhd->pub, flags);
+		del_timer_sync(&dhd->timer);
 		DHD_ERROR(("%s failed bus is not ready\n", __FUNCTION__));
 		dhd_os_sdunlock(dhdp);
 		return -ENODEV;
@@ -2991,6 +3002,7 @@ dhd_bus_detach(dhd_pub_t *dhdp)
 void dhd_detach(dhd_pub_t *dhdp)
 {
 	dhd_info_t *dhd;
+	unsigned long flags;
 
 	if (!dhdp)
 		return;
@@ -3060,7 +3072,9 @@ void dhd_detach(dhd_pub_t *dhdp)
 	}
 
 	/* Clear the watchdog timer */
+	flags = dhd_os_spin_lock(&dhd->pub);
 	dhd->wd_timer_valid = FALSE;
+	dhd_os_spin_unlock(&dhd->pub, flags);
 	del_timer_sync(&dhd->timer);
 
 	if (dhd->dhd_state & DHD_ATTACH_STATE_THREADS_CREATED) {
-- 
1.7.1

