Commit 73b7d742 authored by Tomas Winkler's avatar Tomas Winkler Committed by John W. Linville

iwlwifi: fix Tx cmd memory allocation failure handling

This patch "iwlwifi: do not use GFP_DMA in iwl_tx_queue_init" removes
GFP_DMA from allocation tx command buffers. GFP_DMA allows allocation
only for memory under 16M which causes allocation problems
suspend/resume flows.

Using kmalloc is temporal solution and some consistent/coherent
allocation schema will be more correct. Since iwlwifi hardware
supports 64bit address this solution should work on x86 (32 and
64bit) for now.

This patch fixes memory freeing problem in the previous patch.
Signed-off-by: default avatarTomas Winkler <tomas.winkler@intel.com>
Signed-off-by: default avatarIan Schram <ischram@telenet.be>
Signed-off-by: default avatarZhu Yi <yi.zhu@intel.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 28a6b07a
...@@ -402,12 +402,11 @@ static int iwl_hw_tx_queue_init(struct iwl_priv *priv, ...@@ -402,12 +402,11 @@ static int iwl_hw_tx_queue_init(struct iwl_priv *priv,
/** /**
* iwl_tx_queue_init - Allocate and initialize one tx/cmd queue * iwl_tx_queue_init - Allocate and initialize one tx/cmd queue
*/ */
static int iwl_tx_queue_init(struct iwl_priv *priv, static int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
struct iwl_tx_queue *txq,
int slots_num, u32 txq_id) int slots_num, u32 txq_id)
{ {
int i, len; int i, len;
int rc = 0; int ret;
/* /*
* Alloc buffer array for commands (Tx or other types of commands). * Alloc buffer array for commands (Tx or other types of commands).
...@@ -428,17 +427,14 @@ static int iwl_tx_queue_init(struct iwl_priv *priv, ...@@ -428,17 +427,14 @@ static int iwl_tx_queue_init(struct iwl_priv *priv,
txq->cmd[i] = kmalloc(len, GFP_KERNEL); txq->cmd[i] = kmalloc(len, GFP_KERNEL);
if (!txq->cmd[i]) if (!txq->cmd[i])
return -ENOMEM; goto err;
} }
/* Alloc driver data array and TFD circular buffer */ /* Alloc driver data array and TFD circular buffer */
rc = iwl_tx_queue_alloc(priv, txq, txq_id); ret = iwl_tx_queue_alloc(priv, txq, txq_id);
if (rc) { if (ret)
for (i = 0; i < slots_num; i++) goto err;
kfree(txq->cmd[i]);
return -ENOMEM;
}
txq->need_update = 0; txq->need_update = 0;
/* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise
...@@ -452,6 +448,17 @@ static int iwl_tx_queue_init(struct iwl_priv *priv, ...@@ -452,6 +448,17 @@ static int iwl_tx_queue_init(struct iwl_priv *priv,
iwl_hw_tx_queue_init(priv, txq); iwl_hw_tx_queue_init(priv, txq);
return 0; return 0;
err:
for (i = 0; i < slots_num; i++) {
kfree(txq->cmd[i]);
txq->cmd[i] = NULL;
}
if (txq_id == IWL_CMD_QUEUE_NUM) {
kfree(txq->cmd[slots_num]);
txq->cmd[slots_num] = NULL;
}
return -ENOMEM;
} }
/** /**
* iwl_hw_txq_ctx_free - Free TXQ Context * iwl_hw_txq_ctx_free - Free TXQ Context
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment