aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/pcie/rx.c
diff options
context:
space:
mode:
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>2012-06-14 07:23:02 -0400
committerJohannes Berg <johannes.berg@intel.com>2012-06-18 07:46:49 -0400
commiteb6476441bc2fecf6232a87d0313a85f8e3da7f4 (patch)
tree336fa8676b46bbf1a7b2ad90978bdfa12dfdb71d /drivers/net/wireless/iwlwifi/pcie/rx.c
parentae8baec22878be1f8d14b5bb00ac83f7954a9832 (diff)
iwlwifi: protect use_ict with irq_lock
This variable was accessed without taking the lock. Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/pcie/rx.c')
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/rx.c30
1 files changed, 14 insertions, 16 deletions
diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c
index d6860c070c16..be143eb4aa4f 100644
--- a/drivers/net/wireless/iwlwifi/pcie/rx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/rx.c
@@ -867,24 +867,23 @@ void iwl_disable_ict(struct iwl_trans *trans)
867 spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); 867 spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
868} 868}
869 869
870/* legacy (non-ICT) ISR. Assumes that trans_pcie->irq_lock is held */
870static irqreturn_t iwl_isr(int irq, void *data) 871static irqreturn_t iwl_isr(int irq, void *data)
871{ 872{
872 struct iwl_trans *trans = data; 873 struct iwl_trans *trans = data;
873 struct iwl_trans_pcie *trans_pcie; 874 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
874 u32 inta, inta_mask; 875 u32 inta, inta_mask;
875 unsigned long flags;
876#ifdef CONFIG_IWLWIFI_DEBUG 876#ifdef CONFIG_IWLWIFI_DEBUG
877 u32 inta_fh; 877 u32 inta_fh;
878#endif 878#endif
879
880 lockdep_assert_held(&trans_pcie->irq_lock);
881
879 if (!trans) 882 if (!trans)
880 return IRQ_NONE; 883 return IRQ_NONE;
881 884
882 trace_iwlwifi_dev_irq(trans->dev); 885 trace_iwlwifi_dev_irq(trans->dev);
883 886
884 trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
885
886 spin_lock_irqsave(&trans_pcie->irq_lock, flags);
887
888 /* Disable (but don't clear!) interrupts here to avoid 887 /* Disable (but don't clear!) interrupts here to avoid
889 * back-to-back ISRs and sporadic interrupts from our NIC. 888 * back-to-back ISRs and sporadic interrupts from our NIC.
890 * If we have something to service, the tasklet will re-enable ints. 889 * If we have something to service, the tasklet will re-enable ints.
@@ -907,7 +906,7 @@ static irqreturn_t iwl_isr(int irq, void *data)
907 /* Hardware disappeared. It might have already raised 906 /* Hardware disappeared. It might have already raised
908 * an interrupt */ 907 * an interrupt */
909 IWL_WARN(trans, "HARDWARE GONE?? INTA == 0x%08x\n", inta); 908 IWL_WARN(trans, "HARDWARE GONE?? INTA == 0x%08x\n", inta);
910 goto unplugged; 909 return IRQ_HANDLED;
911 } 910 }
912 911
913#ifdef CONFIG_IWLWIFI_DEBUG 912#ifdef CONFIG_IWLWIFI_DEBUG
@@ -926,18 +925,13 @@ static irqreturn_t iwl_isr(int irq, void *data)
926 !trans_pcie->inta) 925 !trans_pcie->inta)
927 iwl_enable_interrupts(trans); 926 iwl_enable_interrupts(trans);
928 927
929 unplugged: 928none:
930 spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
931 return IRQ_HANDLED;
932
933 none:
934 /* re-enable interrupts here since we don't have anything to service. */ 929 /* re-enable interrupts here since we don't have anything to service. */
935 /* only Re-enable if disabled by irq and no schedules tasklet. */ 930 /* only Re-enable if disabled by irq and no schedules tasklet. */
936 if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) && 931 if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) &&
937 !trans_pcie->inta) 932 !trans_pcie->inta)
938 iwl_enable_interrupts(trans); 933 iwl_enable_interrupts(trans);
939 934
940 spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
941 return IRQ_NONE; 935 return IRQ_NONE;
942} 936}
943 937
@@ -963,15 +957,19 @@ irqreturn_t iwl_isr_ict(int irq, void *data)
963 957
964 trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 958 trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
965 959
960 spin_lock_irqsave(&trans_pcie->irq_lock, flags);
961
966 /* dram interrupt table not set yet, 962 /* dram interrupt table not set yet,
967 * use legacy interrupt. 963 * use legacy interrupt.
968 */ 964 */
969 if (!trans_pcie->use_ict) 965 if (unlikely(!trans_pcie->use_ict)) {
970 return iwl_isr(irq, data); 966 irqreturn_t ret = iwl_isr(irq, data);
967 spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
968 return ret;
969 }
971 970
972 trace_iwlwifi_dev_irq(trans->dev); 971 trace_iwlwifi_dev_irq(trans->dev);
973 972
974 spin_lock_irqsave(&trans_pcie->irq_lock, flags);
975 973
976 /* Disable (but don't clear!) interrupts here to avoid 974 /* Disable (but don't clear!) interrupts here to avoid
977 * back-to-back ISRs and sporadic interrupts from our NIC. 975 * back-to-back ISRs and sporadic interrupts from our NIC.