Search Linux Wireless

[PATCH 4/5] ath9k_htc: Fix target ready race condition

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The ready message from the target could be processed
before the host HW init has completed. In this case,
htc_process_target_rdy() would assume the target has timed
out, when it hasn't. Fix this by checking if the target
has sent the ready message properly.

Signed-off-by: Sujith <Sujith.Manoharan@xxxxxxxxxxx>
---
 drivers/net/wireless/ath/ath9k/htc_drv_init.c |    7 +++++++
 drivers/net/wireless/ath/ath9k/htc_hst.c      |    3 +++
 drivers/net/wireless/ath/ath9k/htc_hst.h      |    1 +
 3 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
index 17111fc..dc01507 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -81,6 +81,11 @@ static int ath9k_htc_wait_for_target(struct ath9k_htc_priv *priv)
 {
 	int time_left;
 
+	if (atomic_read(&priv->htc->tgt_ready) > 0) {
+		atomic_dec(&priv->htc->tgt_ready);
+		return 0;
+	}
+
 	/* Firmware can take up to 50ms to get ready, to be safe use 1 second */
 	time_left = wait_for_completion_timeout(&priv->htc->target_wait, HZ);
 	if (!time_left) {
@@ -88,6 +93,8 @@ static int ath9k_htc_wait_for_target(struct ath9k_htc_priv *priv)
 		return -ETIMEDOUT;
 	}
 
+	atomic_dec(&priv->htc->tgt_ready);
+
 	return 0;
 }
 
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c
index 2c8006a..e86e172 100644
--- a/drivers/net/wireless/ath/ath9k/htc_hst.c
+++ b/drivers/net/wireless/ath/ath9k/htc_hst.c
@@ -95,6 +95,7 @@ static void htc_process_target_rdy(struct htc_target *target,
 	endpoint = &target->endpoint[ENDPOINT0];
 	endpoint->service_id = HTC_CTRL_RSVD_SVC;
 	endpoint->max_msglen = HTC_MAX_CONTROL_MESSAGE_LENGTH;
+	atomic_inc(&target->tgt_ready);
 	complete(&target->target_wait);
 }
 
@@ -451,6 +452,8 @@ struct htc_target *ath9k_htc_hw_alloc(void *hif_handle,
 	endpoint->ul_pipeid = hif->control_ul_pipe;
 	endpoint->dl_pipeid = hif->control_dl_pipe;
 
+	atomic_set(&target->tgt_ready, 0);
+
 	return target;
 }
 
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.h b/drivers/net/wireless/ath/ath9k/htc_hst.h
index d216c0f..4f1cdb0 100644
--- a/drivers/net/wireless/ath/ath9k/htc_hst.h
+++ b/drivers/net/wireless/ath/ath9k/htc_hst.h
@@ -147,6 +147,7 @@ struct htc_target {
 	u16 credits;
 	u16 credit_size;
 	u8 htc_flags;
+	atomic_t tgt_ready;
 };
 
 enum htc_msg_id {
-- 
1.7.1


-- 
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]
  Powered by Linux