iwlwifi: handle DMA mapping failures
The RX replenish code doesn't handle DMA mapping failures, which will cause issues if there actually is a failure. This was reported by Shuah Khan who found a DMA mapping framework warning ("device driver failed to check map error"). Cc: stable@vger.kernel.org Reported-by: Shuah Khan <shuah.khan@hp.com> Reviewed-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
8f7b8db6e0
commit
7c34158231
@ -321,6 +321,14 @@ static void iwl_rx_allocate(struct iwl_trans *trans, gfp_t priority)
|
|||||||
dma_map_page(trans->dev, page, 0,
|
dma_map_page(trans->dev, page, 0,
|
||||||
PAGE_SIZE << trans_pcie->rx_page_order,
|
PAGE_SIZE << trans_pcie->rx_page_order,
|
||||||
DMA_FROM_DEVICE);
|
DMA_FROM_DEVICE);
|
||||||
|
if (dma_mapping_error(trans->dev, rxb->page_dma)) {
|
||||||
|
rxb->page = NULL;
|
||||||
|
spin_lock_irqsave(&rxq->lock, flags);
|
||||||
|
list_add(&rxb->list, &rxq->rx_used);
|
||||||
|
spin_unlock_irqrestore(&rxq->lock, flags);
|
||||||
|
__free_pages(page, trans_pcie->rx_page_order);
|
||||||
|
return;
|
||||||
|
}
|
||||||
/* dma address must be no more than 36 bits */
|
/* dma address must be no more than 36 bits */
|
||||||
BUG_ON(rxb->page_dma & ~DMA_BIT_MASK(36));
|
BUG_ON(rxb->page_dma & ~DMA_BIT_MASK(36));
|
||||||
/* and also 256 byte aligned! */
|
/* and also 256 byte aligned! */
|
||||||
@ -488,8 +496,19 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans,
|
|||||||
dma_map_page(trans->dev, rxb->page, 0,
|
dma_map_page(trans->dev, rxb->page, 0,
|
||||||
PAGE_SIZE << trans_pcie->rx_page_order,
|
PAGE_SIZE << trans_pcie->rx_page_order,
|
||||||
DMA_FROM_DEVICE);
|
DMA_FROM_DEVICE);
|
||||||
list_add_tail(&rxb->list, &rxq->rx_free);
|
if (dma_mapping_error(trans->dev, rxb->page_dma)) {
|
||||||
rxq->free_count++;
|
/*
|
||||||
|
* free the page(s) as well to not break
|
||||||
|
* the invariant that the items on the used
|
||||||
|
* list have no page(s)
|
||||||
|
*/
|
||||||
|
__free_pages(rxb->page, trans_pcie->rx_page_order);
|
||||||
|
rxb->page = NULL;
|
||||||
|
list_add_tail(&rxb->list, &rxq->rx_used);
|
||||||
|
} else {
|
||||||
|
list_add_tail(&rxb->list, &rxq->rx_free);
|
||||||
|
rxq->free_count++;
|
||||||
|
}
|
||||||
} else
|
} else
|
||||||
list_add_tail(&rxb->list, &rxq->rx_used);
|
list_add_tail(&rxb->list, &rxq->rx_used);
|
||||||
spin_unlock_irqrestore(&rxq->lock, flags);
|
spin_unlock_irqrestore(&rxq->lock, flags);
|
||||||
|
Loading…
Reference in New Issue
Block a user