Commit d8c49ffb authored by Sujith.Manoharan@atheros.com's avatar Sujith.Manoharan@atheros.com Committed by John W. Linville

ath9k_htc: Fix target ready race condition

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: default avatarSujith <Sujith.Manoharan@atheros.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 47fce026
...@@ -81,6 +81,11 @@ static int ath9k_htc_wait_for_target(struct ath9k_htc_priv *priv) ...@@ -81,6 +81,11 @@ static int ath9k_htc_wait_for_target(struct ath9k_htc_priv *priv)
{ {
int time_left; 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 */ /* 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); time_left = wait_for_completion_timeout(&priv->htc->target_wait, HZ);
if (!time_left) { if (!time_left) {
...@@ -88,6 +93,8 @@ static int ath9k_htc_wait_for_target(struct ath9k_htc_priv *priv) ...@@ -88,6 +93,8 @@ static int ath9k_htc_wait_for_target(struct ath9k_htc_priv *priv)
return -ETIMEDOUT; return -ETIMEDOUT;
} }
atomic_dec(&priv->htc->tgt_ready);
return 0; return 0;
} }
......
...@@ -95,6 +95,7 @@ static void htc_process_target_rdy(struct htc_target *target, ...@@ -95,6 +95,7 @@ static void htc_process_target_rdy(struct htc_target *target,
endpoint = &target->endpoint[ENDPOINT0]; endpoint = &target->endpoint[ENDPOINT0];
endpoint->service_id = HTC_CTRL_RSVD_SVC; endpoint->service_id = HTC_CTRL_RSVD_SVC;
endpoint->max_msglen = HTC_MAX_CONTROL_MESSAGE_LENGTH; endpoint->max_msglen = HTC_MAX_CONTROL_MESSAGE_LENGTH;
atomic_inc(&target->tgt_ready);
complete(&target->target_wait); complete(&target->target_wait);
} }
...@@ -451,6 +452,8 @@ struct htc_target *ath9k_htc_hw_alloc(void *hif_handle, ...@@ -451,6 +452,8 @@ struct htc_target *ath9k_htc_hw_alloc(void *hif_handle,
endpoint->ul_pipeid = hif->control_ul_pipe; endpoint->ul_pipeid = hif->control_ul_pipe;
endpoint->dl_pipeid = hif->control_dl_pipe; endpoint->dl_pipeid = hif->control_dl_pipe;
atomic_set(&target->tgt_ready, 0);
return target; return target;
} }
......
...@@ -147,6 +147,7 @@ struct htc_target { ...@@ -147,6 +147,7 @@ struct htc_target {
u16 credits; u16 credits;
u16 credit_size; u16 credit_size;
u8 htc_flags; u8 htc_flags;
atomic_t tgt_ready;
}; };
enum htc_msg_id { enum htc_msg_id {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment