Commit 65c71efe authored by Wei-Ning Huang's avatar Wei-Ning Huang Committed by Kalle Valo

mwifiex: fix racing condition when downloading firmware

The action 'check for winner' and 'download firmware' should be an
atomic action. This is true for btmrvl driver but not mwmfiex, which
cause firmware download to fail when the following senerio happens:

1) mwifiex check winner status: true
2) btmrvl check winner status: true, and start downloading firmware
3) mwfieix tries to download firmware, but failed because btmrvl is
already downloading.

This won't happen if 1) and 3) is an atomic action. This patch adds
sdio_claim/release_host call around those two actions to make sure it's
atomic.
Signed-off-by: default avatarWei-Ning Huang <wnhuang@chromium.org>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent 6b128a01
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "wmm.h" #include "wmm.h"
#include "cfg80211.h" #include "cfg80211.h"
#include "11n.h" #include "11n.h"
#include "sdio.h"
#define VERSION "1.0" #define VERSION "1.0"
...@@ -514,6 +515,7 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context) ...@@ -514,6 +515,7 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
struct semaphore *sem = adapter->card_sem; struct semaphore *sem = adapter->card_sem;
bool init_failed = false; bool init_failed = false;
struct wireless_dev *wdev; struct wireless_dev *wdev;
struct sdio_mmc_card *card = adapter->card;
if (!firmware) { if (!firmware) {
mwifiex_dbg(adapter, ERROR, mwifiex_dbg(adapter, ERROR,
...@@ -526,10 +528,16 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context) ...@@ -526,10 +528,16 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
fw.fw_buf = (u8 *) adapter->firmware->data; fw.fw_buf = (u8 *) adapter->firmware->data;
fw.fw_len = adapter->firmware->size; fw.fw_len = adapter->firmware->size;
if (adapter->if_ops.dnld_fw) if (adapter->if_ops.dnld_fw) {
ret = adapter->if_ops.dnld_fw(adapter, &fw); ret = adapter->if_ops.dnld_fw(adapter, &fw);
else } else {
if (adapter->iface_type == MWIFIEX_SDIO)
sdio_claim_host(card->func);
ret = mwifiex_dnld_fw(adapter, &fw); ret = mwifiex_dnld_fw(adapter, &fw);
if (adapter->iface_type == MWIFIEX_SDIO)
sdio_release_host(card->func);
}
if (ret == -1) if (ret == -1)
goto err_dnld_fw; goto err_dnld_fw;
......
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