diff options
author | Johannes Berg <johannes.berg@intel.com> | 2011-04-28 16:27:10 +0200 |
---|---|---|
committer | Wey-Yi Guy <wey-yi.w.guy@intel.com> | 2011-05-06 19:46:23 +0200 |
commit | 2c46f72e069eef5e98f2b04df08cde6bdc673aa7 (patch) | |
tree | 62243e8844fd39864bffacbd50b393d1470b8000 /drivers/net/wireless/iwlwifi/iwl-tx.c | |
parent | iwlagn: remove bytecount indirection (diff) | |
download | linux-2c46f72e069eef5e98f2b04df08cde6bdc673aa7.tar.xz linux-2c46f72e069eef5e98f2b04df08cde6bdc673aa7.zip |
iwlagn: check DMA mapping errors
DMA mappings can fail, but the current code
doesn't check for that. Add checking, which
requires some restructuring for proper error
paths.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Diffstat (limited to '')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-tx.c | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 5a7cd177fe5e..e69597ea43e2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -500,7 +500,6 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) } memset(out_meta, 0, sizeof(*out_meta)); /* re-initialize to NULL */ - out_meta->flags = cmd->flags | CMD_MAPPED; if (cmd->flags & CMD_WANT_SKB) out_meta->source = cmd; if (cmd->flags & CMD_ASYNC) @@ -538,13 +537,20 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) q->write_ptr, idx, priv->cmd_queue); } #endif - txq->need_update = 1; - phys_addr = pci_map_single(priv->pci_dev, &out_cmd->hdr, fix_size, PCI_DMA_BIDIRECTIONAL); + if (unlikely(pci_dma_mapping_error(priv->pci_dev, phys_addr))) { + idx = -ENOMEM; + goto out; + } + dma_unmap_addr_set(out_meta, mapping, phys_addr); dma_unmap_len_set(out_meta, len, fix_size); + out_meta->flags = cmd->flags | CMD_MAPPED; + + txq->need_update = 1; + trace_iwlwifi_dev_hcmd(priv, &out_cmd->hdr, fix_size, cmd->flags); priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq, @@ -555,6 +561,7 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); iwl_txq_update_write_ptr(priv, txq); + out: spin_unlock_irqrestore(&priv->hcmd_lock, flags); return idx; } |