lkml.org 
[lkml]   [2012]   [Nov]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[ 50/83] iwlwifi: handle DMA mapping failures
    Date
    3.6-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Johannes Berg <johannes.berg@intel.com>

    commit 7c34158231b2eda8dcbd297be2bb1559e69cb433 upstream.

    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").

    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>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/net/wireless/iwlwifi/pcie/rx.c | 23 +++++++++++++++++++++--
    1 file changed, 21 insertions(+), 2 deletions(-)

    --- a/drivers/net/wireless/iwlwifi/pcie/rx.c
    +++ b/drivers/net/wireless/iwlwifi/pcie/rx.c
    @@ -314,6 +314,14 @@ static void iwlagn_rx_allocate(struct iw
    dma_map_page(trans->dev, page, 0,
    PAGE_SIZE << trans_pcie->rx_page_order,
    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 */
    BUG_ON(rxb->page_dma & ~DMA_BIT_MASK(36));
    /* and also 256 byte aligned! */
    @@ -463,8 +471,19 @@ static void iwl_rx_handle_rxbuf(struct i
    dma_map_page(trans->dev, rxb->page, 0,
    PAGE_SIZE << trans_pcie->rx_page_order,
    DMA_FROM_DEVICE);
    - list_add_tail(&rxb->list, &rxq->rx_free);
    - rxq->free_count++;
    + if (dma_mapping_error(trans->dev, rxb->page_dma)) {
    + /*
    + * 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
    list_add_tail(&rxb->list, &rxq->rx_used);
    spin_unlock_irqrestore(&rxq->lock, flags);



    \
     
     \ /
      Last update: 2012-11-25 23:21    [W:4.034 / U:0.060 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site