diff options
author | Tejun Heo <tj@kernel.org> | 2012-12-21 20:56:57 -0500 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2012-12-28 16:40:15 -0500 |
commit | 7f5855c979ef0d49a8680b7fbdd3fc8e3093cb73 (patch) | |
tree | 5a4a892ce8819d5ce4313348d1a6b7bd333679f2 /drivers/net/wireless/mwifiex/sdio.c | |
parent | 1cab3f9fcc7ecaf70c77a10032b4757f769e345b (diff) |
mwifiex: don't use [delayed_]work_pending()
Drop work_pending() test from mwifiex_sdio_card_reset(). As
work_pending() becomes %false before sdio_card_reset_worker() starts
executing, it doesn't really protect anything. reset_host may change
between mmc_remove_host() and mmc_add_host(). Make
sdio_card_reset_worker() cache the target mmc_host so that it isn't
affected by mwifiex_sdio_card_reset() racing with it.
Only compile tested.
Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Bing Zhao <bzhao@marvell.com>
Cc: linux-wireless@vger.kernel.org
Diffstat (limited to 'drivers/net/wireless/mwifiex/sdio.c')
-rw-r--r-- | drivers/net/wireless/mwifiex/sdio.c | 9 |
1 files changed, 4 insertions, 5 deletions
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c index 5a1c1d0e5599..f2874c3392b4 100644 --- a/drivers/net/wireless/mwifiex/sdio.c +++ b/drivers/net/wireless/mwifiex/sdio.c | |||
@@ -1752,6 +1752,8 @@ mwifiex_update_mp_end_port(struct mwifiex_adapter *adapter, u16 port) | |||
1752 | static struct mmc_host *reset_host; | 1752 | static struct mmc_host *reset_host; |
1753 | static void sdio_card_reset_worker(struct work_struct *work) | 1753 | static void sdio_card_reset_worker(struct work_struct *work) |
1754 | { | 1754 | { |
1755 | struct mmc_host *target = reset_host; | ||
1756 | |||
1755 | /* The actual reset operation must be run outside of driver thread. | 1757 | /* The actual reset operation must be run outside of driver thread. |
1756 | * This is because mmc_remove_host() will cause the device to be | 1758 | * This is because mmc_remove_host() will cause the device to be |
1757 | * instantly destroyed, and the driver then needs to end its thread, | 1759 | * instantly destroyed, and the driver then needs to end its thread, |
@@ -1761,10 +1763,10 @@ static void sdio_card_reset_worker(struct work_struct *work) | |||
1761 | */ | 1763 | */ |
1762 | 1764 | ||
1763 | pr_err("Resetting card...\n"); | 1765 | pr_err("Resetting card...\n"); |
1764 | mmc_remove_host(reset_host); | 1766 | mmc_remove_host(target); |
1765 | /* 20ms delay is based on experiment with sdhci controller */ | 1767 | /* 20ms delay is based on experiment with sdhci controller */ |
1766 | mdelay(20); | 1768 | mdelay(20); |
1767 | mmc_add_host(reset_host); | 1769 | mmc_add_host(target); |
1768 | } | 1770 | } |
1769 | static DECLARE_WORK(card_reset_work, sdio_card_reset_worker); | 1771 | static DECLARE_WORK(card_reset_work, sdio_card_reset_worker); |
1770 | 1772 | ||
@@ -1773,9 +1775,6 @@ static void mwifiex_sdio_card_reset(struct mwifiex_adapter *adapter) | |||
1773 | { | 1775 | { |
1774 | struct sdio_mmc_card *card = adapter->card; | 1776 | struct sdio_mmc_card *card = adapter->card; |
1775 | 1777 | ||
1776 | if (work_pending(&card_reset_work)) | ||
1777 | return; | ||
1778 | |||
1779 | reset_host = card->func->card->host; | 1778 | reset_host = card->func->card->host; |
1780 | schedule_work(&card_reset_work); | 1779 | schedule_work(&card_reset_work); |
1781 | } | 1780 | } |