iwlwifi: always check that grab_nic_access succeeds
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Mon, 31 Dec 2012 11:46:42 +0000 (13:46 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Thu, 3 Jan 2013 14:34:11 +0000 (15:34 +0100)
This allows to let sparse check that the NIC access is
always released.

Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
drivers/net/wireless/iwlwifi/dvm/main.c
drivers/net/wireless/iwlwifi/dvm/tt.c
drivers/net/wireless/iwlwifi/iwl-io.c
drivers/net/wireless/iwlwifi/iwl-test.c
drivers/net/wireless/iwlwifi/iwl-trans.h
drivers/net/wireless/iwlwifi/pcie/trans.c

index 517d7ae..a64f361 100644 (file)
@@ -354,7 +354,7 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base,
 
        /* Make sure device is powered up for SRAM reads */
        spin_lock_irqsave(&priv->trans->reg_lock, reg_flags);
-       if (unlikely(!iwl_trans_grab_nic_access(priv->trans, false))) {
+       if (!iwl_trans_grab_nic_access(priv->trans, false)) {
                spin_unlock_irqrestore(&priv->trans->reg_lock, reg_flags);
                return;
        }
@@ -1718,7 +1718,7 @@ static int iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
 
        /* Make sure device is powered up for SRAM reads */
        spin_lock_irqsave(&trans->reg_lock, reg_flags);
-       if (unlikely(!iwl_trans_grab_nic_access(trans, false)))
+       if (!iwl_trans_grab_nic_access(trans, false))
                goto out_unlock;
 
        /* Set starting address; reads will auto-increment */
index a8ae513..b28cfc8 100644 (file)
@@ -186,7 +186,7 @@ static void iwl_tt_check_exit_ct_kill(unsigned long data)
                }
                iwl_read32(priv->trans, CSR_UCODE_DRV_GP1);
                spin_lock_irqsave(&priv->trans->reg_lock, flags);
-               if (likely(iwl_trans_grab_nic_access(priv->trans, false)))
+               if (iwl_trans_grab_nic_access(priv->trans, false))
                        iwl_trans_release_nic_access(priv->trans);
                spin_unlock_irqrestore(&priv->trans->reg_lock, flags);
 
index 2bd84ad..bff3ac9 100644 (file)
@@ -101,13 +101,14 @@ EXPORT_SYMBOL_GPL(iwl_poll_bit);
 
 u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg)
 {
-       u32 value;
+       u32 value = 0x5a5a5a5a;
        unsigned long flags;
 
        spin_lock_irqsave(&trans->reg_lock, flags);
-       iwl_trans_grab_nic_access(trans, false);
-       value = iwl_read32(trans, reg);
-       iwl_trans_release_nic_access(trans);
+       if (iwl_trans_grab_nic_access(trans, false)) {
+               value = iwl_read32(trans, reg);
+               iwl_trans_release_nic_access(trans);
+       }
        spin_unlock_irqrestore(&trans->reg_lock, flags);
 
        return value;
@@ -119,7 +120,7 @@ void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value)
        unsigned long flags;
 
        spin_lock_irqsave(&trans->reg_lock, flags);
-       if (likely(iwl_trans_grab_nic_access(trans, false))) {
+       if (iwl_trans_grab_nic_access(trans, false)) {
                iwl_write32(trans, reg, value);
                iwl_trans_release_nic_access(trans);
        }
@@ -159,12 +160,13 @@ static inline void __iwl_write_prph(struct iwl_trans *trans, u32 ofs, u32 val)
 u32 iwl_read_prph(struct iwl_trans *trans, u32 ofs)
 {
        unsigned long flags;
-       u32 val;
+       u32 val = 0x5a5a5a5a;
 
        spin_lock_irqsave(&trans->reg_lock, flags);
-       iwl_trans_grab_nic_access(trans, false);
-       val = __iwl_read_prph(trans, ofs);
-       iwl_trans_release_nic_access(trans);
+       if (iwl_trans_grab_nic_access(trans, false)) {
+               val = __iwl_read_prph(trans, ofs);
+               iwl_trans_release_nic_access(trans);
+       }
        spin_unlock_irqrestore(&trans->reg_lock, flags);
        return val;
 }
@@ -175,7 +177,7 @@ void iwl_write_prph(struct iwl_trans *trans, u32 ofs, u32 val)
        unsigned long flags;
 
        spin_lock_irqsave(&trans->reg_lock, flags);
-       if (likely(iwl_trans_grab_nic_access(trans, false))) {
+       if (iwl_trans_grab_nic_access(trans, false)) {
                __iwl_write_prph(trans, ofs, val);
                iwl_trans_release_nic_access(trans);
        }
@@ -188,7 +190,7 @@ void iwl_set_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask)
        unsigned long flags;
 
        spin_lock_irqsave(&trans->reg_lock, flags);
-       if (likely(iwl_trans_grab_nic_access(trans, false))) {
+       if (iwl_trans_grab_nic_access(trans, false)) {
                __iwl_write_prph(trans, ofs,
                                 __iwl_read_prph(trans, ofs) | mask);
                iwl_trans_release_nic_access(trans);
@@ -203,7 +205,7 @@ void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 ofs,
        unsigned long flags;
 
        spin_lock_irqsave(&trans->reg_lock, flags);
-       if (likely(iwl_trans_grab_nic_access(trans, false))) {
+       if (iwl_trans_grab_nic_access(trans, false)) {
                __iwl_write_prph(trans, ofs,
                                 (__iwl_read_prph(trans, ofs) & mask) | bits);
                iwl_trans_release_nic_access(trans);
@@ -218,7 +220,7 @@ void iwl_clear_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask)
        u32 val;
 
        spin_lock_irqsave(&trans->reg_lock, flags);
-       if (likely(iwl_trans_grab_nic_access(trans, false))) {
+       if (iwl_trans_grab_nic_access(trans, false)) {
                val = __iwl_read_prph(trans, ofs);
                __iwl_write_prph(trans, ofs, (val & ~mask));
                iwl_trans_release_nic_access(trans);
index f8d8df8..1a22611 100644 (file)
@@ -467,7 +467,10 @@ static int iwl_test_indirect_read(struct iwl_test *tst, u32 addr, u32 size)
        if (IWL_ABS_PRPH_START <= addr &&
            addr < IWL_ABS_PRPH_START + PRPH_END) {
                        spin_lock_irqsave(&trans->reg_lock, flags);
-                       iwl_trans_grab_nic_access(trans, false);
+                       if (!iwl_trans_grab_nic_access(trans, false)) {
+                               spin_unlock_irqrestore(&trans->reg_lock, flags);
+                               return -EIO;
+                       }
                        iwl_write32(trans, HBUS_TARG_PRPH_RADDR,
                                    addr | (3 << 24));
                        for (i = 0; i < size; i += 4)
@@ -500,26 +503,29 @@ static int iwl_test_indirect_write(struct iwl_test *tst, u32 addr,
 
        if (IWL_ABS_PRPH_START <= addr &&
            addr < IWL_ABS_PRPH_START + PRPH_END) {
-                       /* Periphery writes can be 1-3 bytes long, or DWORDs */
-                       if (size < 4) {
-                               memcpy(&val, buf, size);
-                               spin_lock_irqsave(&trans->reg_lock, flags);
-                               iwl_trans_grab_nic_access(trans, false);
-                               iwl_write32(trans, HBUS_TARG_PRPH_WADDR,
-                                           (addr & 0x0000FFFF) |
-                                           ((size - 1) << 24));
-                               iwl_write32(trans, HBUS_TARG_PRPH_WDAT, val);
-                               iwl_trans_release_nic_access(trans);
-                               /* needed after consecutive writes w/o read */
-                               mmiowb();
+               /* Periphery writes can be 1-3 bytes long, or DWORDs */
+               if (size < 4) {
+                       memcpy(&val, buf, size);
+                       spin_lock_irqsave(&trans->reg_lock, flags);
+                       if (!iwl_trans_grab_nic_access(trans, false)) {
                                spin_unlock_irqrestore(&trans->reg_lock, flags);
-                       } else {
-                               if (size % 4)
-                                       return -EINVAL;
-                               for (i = 0; i < size; i += 4)
-                                       iwl_write_prph(trans, addr+i,
-                                                      *(u32 *)(buf+i));
+                                       return -EIO;
                        }
+                       iwl_write32(trans, HBUS_TARG_PRPH_WADDR,
+                                   (addr & 0x0000FFFF) |
+                                   ((size - 1) << 24));
+                       iwl_write32(trans, HBUS_TARG_PRPH_WDAT, val);
+                       iwl_trans_release_nic_access(trans);
+                       /* needed after consecutive writes w/o read */
+                       mmiowb();
+                       spin_unlock_irqrestore(&trans->reg_lock, flags);
+               } else {
+                       if (size % 4)
+                               return -EINVAL;
+                       for (i = 0; i < size; i += 4)
+                               iwl_write_prph(trans, addr+i,
+                                              *(u32 *)(buf+i));
+               }
        } else if (iwl_test_valid_hw_addr(tst, addr)) {
                iwl_trans_write_mem(trans, addr, buf, size / 4);
        } else {
index 7584d55..b0d5c71 100644 (file)
@@ -734,15 +734,15 @@ static inline void iwl_trans_set_pmi(struct iwl_trans *trans, bool state)
        trans->ops->set_pmi(trans, state);
 }
 
-static inline bool iwl_trans_grab_nic_access(struct iwl_trans *trans,
-                                            bool silent)
-{
-       return trans->ops->grab_nic_access(trans, silent);
-}
+#define iwl_trans_grab_nic_access(trans, silent)       \
+       __cond_lock(nic_access,                         \
+                   likely((trans)->ops->grab_nic_access(trans, silent)))
 
-static inline void iwl_trans_release_nic_access(struct iwl_trans *trans)
+static inline void __releases(nic_access)
+iwl_trans_release_nic_access(struct iwl_trans *trans)
 {
        trans->ops->release_nic_access(trans);
+       __release(nic_access);
 }
 
 /*****************************************************
index bca6203..db3b055 100644 (file)
@@ -795,7 +795,7 @@ static int iwl_trans_pcie_read_mem(struct iwl_trans *trans, u32 addr,
        u32 *vals = buf;
 
        spin_lock_irqsave(&trans->reg_lock, flags);
-       if (likely(iwl_trans_grab_nic_access(trans, false))) {
+       if (iwl_trans_grab_nic_access(trans, false)) {
                iwl_write32(trans, HBUS_TARG_MEM_RADDR, addr);
                for (offs = 0; offs < dwords; offs++)
                        vals[offs] = iwl_read32(trans, HBUS_TARG_MEM_RDAT);
@@ -815,7 +815,7 @@ static int iwl_trans_pcie_write_mem(struct iwl_trans *trans, u32 addr,
        u32 *vals = buf;
 
        spin_lock_irqsave(&trans->reg_lock, flags);
-       if (likely(iwl_trans_grab_nic_access(trans, false))) {
+       if (iwl_trans_grab_nic_access(trans, false)) {
                iwl_write32(trans, HBUS_TARG_MEM_WADDR, addr);
                for (offs = 0; offs < dwords; offs++)
                        iwl_write32(trans, HBUS_TARG_MEM_WDAT, vals[offs]);