From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Sven Neumann , Andreas Fenkart , Daniel Mack , Dylan Reid , Amitkumar Karwar , Bing Zhao , Paul Stewart , "John W. Linville" Subject: [PATCH 3.11 23/94] mwifiex: fix SDIO interrupt lost issue Date: Fri, 8 Nov 2013 22:51:29 -0800 Message-Id: <20131109065205.870511190@linuxfoundation.org> In-Reply-To: <20131109065204.252462489@linuxfoundation.org> References: <20131109065204.252462489@linuxfoundation.org> Sender: linux-kernel-owner@vger.kernel.org List-ID: 3.11-stable review patch. If anyone has any objections, please let me know. ------------------ From: Amitkumar Karwar commit 453b0c3f6910672f79da354077af728d92f95c5b upstream. 601216e "mwifiex: process RX packets in SDIO IRQ thread directly" introduced a command timeout issue which can be reproduced easily on an AM33xx platform using a test application written by Daniel Mack: https://gist.github.com/zonque/6579314 mwifiex_main_process() is called from both the SDIO handler and the workqueue. In case an interrupt occurs right after the int_status check, but before updating the mwifiex_processing flag, this interrupt gets lost, resulting in a command timeout and consequently a card reset. Let main_proc_lock protect both int_status and mwifiex_processing flag. This fixes the interrupt lost issue. Reported-by: Sven Neumann Reported-by: Andreas Fenkart Tested-by: Daniel Mack Reviewed-by: Dylan Reid Signed-off-by: Amitkumar Karwar Signed-off-by: Bing Zhao Signed-off-by: Paul Stewart Signed-off-by: John W. Linville Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/mwifiex/main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) --- a/drivers/net/wireless/mwifiex/main.c +++ b/drivers/net/wireless/mwifiex/main.c @@ -354,10 +354,12 @@ process_start: } } while (true); - if ((adapter->int_status) || IS_CARD_RX_RCVD(adapter)) + spin_lock_irqsave(&adapter->main_proc_lock, flags); + if ((adapter->int_status) || IS_CARD_RX_RCVD(adapter)) { + spin_unlock_irqrestore(&adapter->main_proc_lock, flags); goto process_start; + } - spin_lock_irqsave(&adapter->main_proc_lock, flags); adapter->mwifiex_processing = false; spin_unlock_irqrestore(&adapter->main_proc_lock, flags);