iwlwifi: clear rxq->queue in queue reset
authorZhu Yi <yi.zhu@intel.com>
Tue, 23 Mar 2010 02:33:41 +0000 (19:33 -0700)
committerReinette Chatre <reinette.chatre@intel.com>
Fri, 2 Apr 2010 19:50:37 +0000 (12:50 -0700)
In iwl_rx_queue_reset(), we didn't clear the rxq->queue[]. This might
cause the same rxb appears on multiple places in rxq->queue. Although
this won't cause any problem because of the read and write pointers
protection in rxq, we'd better clear it to avoid misleading.

Signed-off-by: Zhu Yi <yi.zhu@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
drivers/net/wireless/iwlwifi/iwl-agn-lib.c

index 1d2e84c1fad58dcd31a0225380a4d3d714eb8d8a..6fe1d937187ba9e0a7d46bac964af63b3e62983e 100644 (file)
@@ -403,6 +403,9 @@ void iwlagn_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
                list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
        }
 
+       for (i = 0; i < RX_QUEUE_SIZE; i++)
+               rxq->queue[i] = NULL;
+
        /* Set us so that we have processed and used all buffers, but have
         * not restocked the Rx queue with fresh buffers */
        rxq->read = rxq->write = 0;
@@ -538,11 +541,13 @@ void iwlagn_rx_queue_restock(struct iwl_priv *priv)
        struct list_head *element;
        struct iwl_rx_mem_buffer *rxb;
        unsigned long flags;
-       int write;
 
        spin_lock_irqsave(&rxq->lock, flags);
-       write = rxq->write & ~0x7;
        while ((iwl_rx_queue_space(rxq) > 0) && (rxq->free_count)) {
+               /* The overwritten rxb must be a used one */
+               rxb = rxq->queue[rxq->write];
+               BUG_ON(rxb && rxb->page);
+
                /* Get next free Rx buffer, remove from free list */
                element = rxq->rx_free.next;
                rxb = list_entry(element, struct iwl_rx_mem_buffer, list);
@@ -635,6 +640,7 @@ void iwlagn_rx_allocate(struct iwl_priv *priv, gfp_t priority)
 
                spin_unlock_irqrestore(&rxq->lock, flags);
 
+               BUG_ON(rxb->page);
                rxb->page = page;
                /* Get physical address of the RB */
                rxb->page_dma = pci_map_page(priv->pci_dev, page, 0,