提交 abae2386 编写于 作者: E Emmanuel Grumbach 提交者: Johannes Berg

iwlwifi: always check that grab_nic_access succeeds

This allows to let sparse check that the NIC access is
always released.
Signed-off-by: NEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: NJohannes Berg <johannes.berg@intel.com>
上级 c8f9b0fe
...@@ -354,7 +354,7 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base, ...@@ -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 */ /* Make sure device is powered up for SRAM reads */
spin_lock_irqsave(&priv->trans->reg_lock, reg_flags); 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); spin_unlock_irqrestore(&priv->trans->reg_lock, reg_flags);
return; return;
} }
...@@ -1718,7 +1718,7 @@ static int iwl_print_event_log(struct iwl_priv *priv, u32 start_idx, ...@@ -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 */ /* Make sure device is powered up for SRAM reads */
spin_lock_irqsave(&trans->reg_lock, reg_flags); 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; goto out_unlock;
/* Set starting address; reads will auto-increment */ /* Set starting address; reads will auto-increment */
......
...@@ -186,7 +186,7 @@ static void iwl_tt_check_exit_ct_kill(unsigned long data) ...@@ -186,7 +186,7 @@ static void iwl_tt_check_exit_ct_kill(unsigned long data)
} }
iwl_read32(priv->trans, CSR_UCODE_DRV_GP1); iwl_read32(priv->trans, CSR_UCODE_DRV_GP1);
spin_lock_irqsave(&priv->trans->reg_lock, flags); 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); iwl_trans_release_nic_access(priv->trans);
spin_unlock_irqrestore(&priv->trans->reg_lock, flags); spin_unlock_irqrestore(&priv->trans->reg_lock, flags);
......
...@@ -101,13 +101,14 @@ EXPORT_SYMBOL_GPL(iwl_poll_bit); ...@@ -101,13 +101,14 @@ EXPORT_SYMBOL_GPL(iwl_poll_bit);
u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg) u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg)
{ {
u32 value; u32 value = 0x5a5a5a5a;
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&trans->reg_lock, flags); spin_lock_irqsave(&trans->reg_lock, flags);
iwl_trans_grab_nic_access(trans, false); if (iwl_trans_grab_nic_access(trans, false)) {
value = iwl_read32(trans, reg); value = iwl_read32(trans, reg);
iwl_trans_release_nic_access(trans); iwl_trans_release_nic_access(trans);
}
spin_unlock_irqrestore(&trans->reg_lock, flags); spin_unlock_irqrestore(&trans->reg_lock, flags);
return value; return value;
...@@ -119,7 +120,7 @@ void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value) ...@@ -119,7 +120,7 @@ void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value)
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&trans->reg_lock, 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_write32(trans, reg, value);
iwl_trans_release_nic_access(trans); iwl_trans_release_nic_access(trans);
} }
...@@ -159,12 +160,13 @@ static inline void __iwl_write_prph(struct iwl_trans *trans, u32 ofs, u32 val) ...@@ -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) u32 iwl_read_prph(struct iwl_trans *trans, u32 ofs)
{ {
unsigned long flags; unsigned long flags;
u32 val; u32 val = 0x5a5a5a5a;
spin_lock_irqsave(&trans->reg_lock, flags); spin_lock_irqsave(&trans->reg_lock, flags);
iwl_trans_grab_nic_access(trans, false); if (iwl_trans_grab_nic_access(trans, false)) {
val = __iwl_read_prph(trans, ofs); val = __iwl_read_prph(trans, ofs);
iwl_trans_release_nic_access(trans); iwl_trans_release_nic_access(trans);
}
spin_unlock_irqrestore(&trans->reg_lock, flags); spin_unlock_irqrestore(&trans->reg_lock, flags);
return val; return val;
} }
...@@ -175,7 +177,7 @@ void iwl_write_prph(struct iwl_trans *trans, u32 ofs, u32 val) ...@@ -175,7 +177,7 @@ void iwl_write_prph(struct iwl_trans *trans, u32 ofs, u32 val)
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&trans->reg_lock, 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_write_prph(trans, ofs, val);
iwl_trans_release_nic_access(trans); iwl_trans_release_nic_access(trans);
} }
...@@ -188,7 +190,7 @@ void iwl_set_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask) ...@@ -188,7 +190,7 @@ void iwl_set_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask)
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&trans->reg_lock, 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_write_prph(trans, ofs,
__iwl_read_prph(trans, ofs) | mask); __iwl_read_prph(trans, ofs) | mask);
iwl_trans_release_nic_access(trans); iwl_trans_release_nic_access(trans);
...@@ -203,7 +205,7 @@ void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 ofs, ...@@ -203,7 +205,7 @@ void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 ofs,
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&trans->reg_lock, 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_write_prph(trans, ofs,
(__iwl_read_prph(trans, ofs) & mask) | bits); (__iwl_read_prph(trans, ofs) & mask) | bits);
iwl_trans_release_nic_access(trans); iwl_trans_release_nic_access(trans);
...@@ -218,7 +220,7 @@ void iwl_clear_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask) ...@@ -218,7 +220,7 @@ void iwl_clear_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask)
u32 val; u32 val;
spin_lock_irqsave(&trans->reg_lock, 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)) {
val = __iwl_read_prph(trans, ofs); val = __iwl_read_prph(trans, ofs);
__iwl_write_prph(trans, ofs, (val & ~mask)); __iwl_write_prph(trans, ofs, (val & ~mask));
iwl_trans_release_nic_access(trans); iwl_trans_release_nic_access(trans);
......
...@@ -467,7 +467,10 @@ static int iwl_test_indirect_read(struct iwl_test *tst, u32 addr, u32 size) ...@@ -467,7 +467,10 @@ static int iwl_test_indirect_read(struct iwl_test *tst, u32 addr, u32 size)
if (IWL_ABS_PRPH_START <= addr && if (IWL_ABS_PRPH_START <= addr &&
addr < IWL_ABS_PRPH_START + PRPH_END) { addr < IWL_ABS_PRPH_START + PRPH_END) {
spin_lock_irqsave(&trans->reg_lock, flags); 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, iwl_write32(trans, HBUS_TARG_PRPH_RADDR,
addr | (3 << 24)); addr | (3 << 24));
for (i = 0; i < size; i += 4) for (i = 0; i < size; i += 4)
...@@ -500,26 +503,29 @@ static int iwl_test_indirect_write(struct iwl_test *tst, u32 addr, ...@@ -500,26 +503,29 @@ static int iwl_test_indirect_write(struct iwl_test *tst, u32 addr,
if (IWL_ABS_PRPH_START <= addr && if (IWL_ABS_PRPH_START <= addr &&
addr < IWL_ABS_PRPH_START + PRPH_END) { addr < IWL_ABS_PRPH_START + PRPH_END) {
/* Periphery writes can be 1-3 bytes long, or DWORDs */ /* Periphery writes can be 1-3 bytes long, or DWORDs */
if (size < 4) { if (size < 4) {
memcpy(&val, buf, size); memcpy(&val, buf, size);
spin_lock_irqsave(&trans->reg_lock, flags); spin_lock_irqsave(&trans->reg_lock, flags);
iwl_trans_grab_nic_access(trans, false); if (!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();
spin_unlock_irqrestore(&trans->reg_lock, flags); spin_unlock_irqrestore(&trans->reg_lock, flags);
} else { return -EIO;
if (size % 4)
return -EINVAL;
for (i = 0; i < size; i += 4)
iwl_write_prph(trans, addr+i,
*(u32 *)(buf+i));
} }
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)) { } else if (iwl_test_valid_hw_addr(tst, addr)) {
iwl_trans_write_mem(trans, addr, buf, size / 4); iwl_trans_write_mem(trans, addr, buf, size / 4);
} else { } else {
......
...@@ -734,15 +734,15 @@ static inline void iwl_trans_set_pmi(struct iwl_trans *trans, bool state) ...@@ -734,15 +734,15 @@ static inline void iwl_trans_set_pmi(struct iwl_trans *trans, bool state)
trans->ops->set_pmi(trans, state); trans->ops->set_pmi(trans, state);
} }
static inline bool iwl_trans_grab_nic_access(struct iwl_trans *trans, #define iwl_trans_grab_nic_access(trans, silent) \
bool silent) __cond_lock(nic_access, \
{ likely((trans)->ops->grab_nic_access(trans, silent)))
return 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); trans->ops->release_nic_access(trans);
__release(nic_access);
} }
/***************************************************** /*****************************************************
......
...@@ -795,7 +795,7 @@ static int iwl_trans_pcie_read_mem(struct iwl_trans *trans, u32 addr, ...@@ -795,7 +795,7 @@ static int iwl_trans_pcie_read_mem(struct iwl_trans *trans, u32 addr,
u32 *vals = buf; u32 *vals = buf;
spin_lock_irqsave(&trans->reg_lock, 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, HBUS_TARG_MEM_RADDR, addr); iwl_write32(trans, HBUS_TARG_MEM_RADDR, addr);
for (offs = 0; offs < dwords; offs++) for (offs = 0; offs < dwords; offs++)
vals[offs] = iwl_read32(trans, HBUS_TARG_MEM_RDAT); 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, ...@@ -815,7 +815,7 @@ static int iwl_trans_pcie_write_mem(struct iwl_trans *trans, u32 addr,
u32 *vals = buf; u32 *vals = buf;
spin_lock_irqsave(&trans->reg_lock, 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, HBUS_TARG_MEM_WADDR, addr); iwl_write32(trans, HBUS_TARG_MEM_WADDR, addr);
for (offs = 0; offs < dwords; offs++) for (offs = 0; offs < dwords; offs++)
iwl_write32(trans, HBUS_TARG_MEM_WDAT, vals[offs]); iwl_write32(trans, HBUS_TARG_MEM_WDAT, vals[offs]);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册