aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-tx.c
diff options
context:
space:
mode:
authorTomas Winkler <tomas.winkler@intel.com>2008-09-02 23:18:48 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-09-03 15:10:37 -0400
commit73b7d742519ab4cc1b7a12c7af15187fc0ede8e7 (patch)
tree784bc7704d117a1df95181188fb57ba5b68479a6 /drivers/net/wireless/iwlwifi/iwl-tx.c
parent28a6b07a14bd5e63af2c0304306f35c5b963910b (diff)
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: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: Ian Schram <ischram@telenet.be> Signed-off-by: Zhu Yi <yi.zhu@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-tx.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c27
1 files changed, 17 insertions, 10 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index ff879d46624..78b1a7a4ca4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -402,12 +402,11 @@ static int iwl_hw_tx_queue_init(struct iwl_priv *priv,
402/** 402/**
403 * iwl_tx_queue_init - Allocate and initialize one tx/cmd queue 403 * iwl_tx_queue_init - Allocate and initialize one tx/cmd queue
404 */ 404 */
405static int iwl_tx_queue_init(struct iwl_priv *priv, 405static int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
406 struct iwl_tx_queue *txq,
407 int slots_num, u32 txq_id) 406 int slots_num, u32 txq_id)
408{ 407{
409 int i, len; 408 int i, len;
410 int rc = 0; 409 int ret;
411 410
412 /* 411 /*
413 * Alloc buffer array for commands (Tx or other types of commands). 412 * 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 427
429 txq->cmd[i] = kmalloc(len, GFP_KERNEL); 428 txq->cmd[i] = kmalloc(len, GFP_KERNEL);
430 if (!txq->cmd[i]) 429 if (!txq->cmd[i])
431 return -ENOMEM; 430 goto err;
432 } 431 }
433 432
434 /* Alloc driver data array and TFD circular buffer */ 433 /* Alloc driver data array and TFD circular buffer */
435 rc = iwl_tx_queue_alloc(priv, txq, txq_id); 434 ret = iwl_tx_queue_alloc(priv, txq, txq_id);
436 if (rc) { 435 if (ret)
437 for (i = 0; i < slots_num; i++) 436 goto err;
438 kfree(txq->cmd[i]);
439 437
440 return -ENOMEM;
441 }
442 txq->need_update = 0; 438 txq->need_update = 0;
443 439
444 /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise 440 /* 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 iwl_hw_tx_queue_init(priv, txq); 448 iwl_hw_tx_queue_init(priv, txq);
453 449
454 return 0; 450 return 0;
451err:
452 for (i = 0; i < slots_num; i++) {
453 kfree(txq->cmd[i]);
454 txq->cmd[i] = NULL;
455 }
456
457 if (txq_id == IWL_CMD_QUEUE_NUM) {
458 kfree(txq->cmd[slots_num]);
459 txq->cmd[slots_num] = NULL;
460 }
461 return -ENOMEM;
455} 462}
456/** 463/**
457 * iwl_hw_txq_ctx_free - Free TXQ Context 464 * iwl_hw_txq_ctx_free - Free TXQ Context