diff options
Diffstat (limited to 'drivers/net/wireless/b43legacy/dma.c')
-rw-r--r-- | drivers/net/wireless/b43legacy/dma.c | 55 |
1 files changed, 31 insertions, 24 deletions
diff --git a/drivers/net/wireless/b43legacy/dma.c b/drivers/net/wireless/b43legacy/dma.c index e87b427..c990f87 100644 --- a/drivers/net/wireless/b43legacy/dma.c +++ b/drivers/net/wireless/b43legacy/dma.c @@ -393,11 +393,11 @@ dma_addr_t map_descbuffer(struct b43legacy_dmaring *ring, dma_addr_t dmaaddr; if (tx) - dmaaddr = dma_map_single(ring->dev->dev->dev, + dmaaddr = dma_map_single(ring->dev->dev->dma_dev, buf, len, DMA_TO_DEVICE); else - dmaaddr = dma_map_single(ring->dev->dev->dev, + dmaaddr = dma_map_single(ring->dev->dev->dma_dev, buf, len, DMA_FROM_DEVICE); @@ -411,11 +411,11 @@ void unmap_descbuffer(struct b43legacy_dmaring *ring, int tx) { if (tx) - dma_unmap_single(ring->dev->dev->dev, + dma_unmap_single(ring->dev->dev->dma_dev, addr, len, DMA_TO_DEVICE); else - dma_unmap_single(ring->dev->dev->dev, + dma_unmap_single(ring->dev->dev->dma_dev, addr, len, DMA_FROM_DEVICE); } @@ -427,7 +427,7 @@ void sync_descbuffer_for_cpu(struct b43legacy_dmaring *ring, { B43legacy_WARN_ON(ring->tx); - dma_sync_single_for_cpu(ring->dev->dev->dev, + dma_sync_single_for_cpu(ring->dev->dev->dma_dev, addr, len, DMA_FROM_DEVICE); } @@ -438,7 +438,7 @@ void sync_descbuffer_for_device(struct b43legacy_dmaring *ring, { B43legacy_WARN_ON(ring->tx); - dma_sync_single_for_device(ring->dev->dev->dev, + dma_sync_single_for_device(ring->dev->dev->dma_dev, addr, len, DMA_FROM_DEVICE); } @@ -458,9 +458,9 @@ void free_descriptor_buffer(struct b43legacy_dmaring *ring, static int alloc_ringmemory(struct b43legacy_dmaring *ring) { - struct device *dev = ring->dev->dev->dev; + struct device *dma_dev = ring->dev->dev->dma_dev; - ring->descbase = dma_alloc_coherent(dev, B43legacy_DMA_RINGMEMSIZE, + ring->descbase = dma_alloc_coherent(dma_dev, B43legacy_DMA_RINGMEMSIZE, &(ring->dmabase), GFP_KERNEL); if (!ring->descbase) { b43legacyerr(ring->dev->wl, "DMA ringmemory allocation" @@ -474,9 +474,9 @@ static int alloc_ringmemory(struct b43legacy_dmaring *ring) static void free_ringmemory(struct b43legacy_dmaring *ring) { - struct device *dev = ring->dev->dev->dev; + struct device *dma_dev = ring->dev->dev->dma_dev; - dma_free_coherent(dev, B43legacy_DMA_RINGMEMSIZE, + dma_free_coherent(dma_dev, B43legacy_DMA_RINGMEMSIZE, ring->descbase, ring->dmabase); } @@ -585,8 +585,9 @@ static int b43legacy_dmacontroller_tx_reset(struct b43legacy_wldev *dev, /* Check if a DMA mapping address is invalid. */ static bool b43legacy_dma_mapping_error(struct b43legacy_dmaring *ring, - dma_addr_t addr, - size_t buffersize) + dma_addr_t addr, + size_t buffersize, + bool dma_to_device) { if (unlikely(dma_mapping_error(addr))) return 1; @@ -594,11 +595,11 @@ static bool b43legacy_dma_mapping_error(struct b43legacy_dmaring *ring, switch (ring->type) { case B43legacy_DMA_30BIT: if ((u64)addr + buffersize > (1ULL << 30)) - return 1; + goto address_error; break; case B43legacy_DMA_32BIT: if ((u64)addr + buffersize > (1ULL << 32)) - return 1; + goto address_error; break; case B43legacy_DMA_64BIT: /* Currently we can't have addresses beyond 64 bits in the kernel. */ @@ -607,6 +608,12 @@ static bool b43legacy_dma_mapping_error(struct b43legacy_dmaring *ring, /* The address is OK. */ return 0; + +address_error: + /* We can't support this address. Unmap it again. */ + unmap_descbuffer(ring, addr, buffersize, dma_to_device); + + return 1; } static int setup_rx_descbuffer(struct b43legacy_dmaring *ring, @@ -626,7 +633,7 @@ static int setup_rx_descbuffer(struct b43legacy_dmaring *ring, return -ENOMEM; dmaaddr = map_descbuffer(ring, skb->data, ring->rx_buffersize, 0); - if (b43legacy_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize)) { + if (b43legacy_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize, 0)) { /* ugh. try to realloc in zone_dma */ gfp_flags |= GFP_DMA; @@ -639,7 +646,7 @@ static int setup_rx_descbuffer(struct b43legacy_dmaring *ring, ring->rx_buffersize, 0); } - if (b43legacy_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize)) { + if (b43legacy_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize, 0)) { dev_kfree_skb_any(skb); return -EIO; } @@ -886,12 +893,12 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev, goto err_kfree_meta; /* test for ability to dma to txhdr_cache */ - dma_test = dma_map_single(dev->dev->dev, ring->txhdr_cache, + dma_test = dma_map_single(dev->dev->dma_dev, ring->txhdr_cache, sizeof(struct b43legacy_txhdr_fw3), DMA_TO_DEVICE); if (b43legacy_dma_mapping_error(ring, dma_test, - sizeof(struct b43legacy_txhdr_fw3))) { + sizeof(struct b43legacy_txhdr_fw3), 1)) { /* ugh realloc */ kfree(ring->txhdr_cache); ring->txhdr_cache = kcalloc(nr_slots, @@ -900,17 +907,17 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev, if (!ring->txhdr_cache) goto err_kfree_meta; - dma_test = dma_map_single(dev->dev->dev, + dma_test = dma_map_single(dev->dev->dma_dev, ring->txhdr_cache, sizeof(struct b43legacy_txhdr_fw3), DMA_TO_DEVICE); if (b43legacy_dma_mapping_error(ring, dma_test, - sizeof(struct b43legacy_txhdr_fw3))) + sizeof(struct b43legacy_txhdr_fw3), 1)) goto err_kfree_txhdr_cache; } - dma_unmap_single(dev->dev->dev, + dma_unmap_single(dev->dev->dma_dev, dma_test, sizeof(struct b43legacy_txhdr_fw3), DMA_TO_DEVICE); } @@ -1235,7 +1242,7 @@ static int dma_tx_fragment(struct b43legacy_dmaring *ring, meta_hdr->dmaaddr = map_descbuffer(ring, (unsigned char *)header, sizeof(struct b43legacy_txhdr_fw3), 1); if (b43legacy_dma_mapping_error(ring, meta_hdr->dmaaddr, - sizeof(struct b43legacy_txhdr_fw3))) { + sizeof(struct b43legacy_txhdr_fw3), 1)) { ring->current_slot = old_top_slot; ring->used_slots = old_used_slots; return -EIO; @@ -1254,7 +1261,7 @@ static int dma_tx_fragment(struct b43legacy_dmaring *ring, meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1); /* create a bounce buffer in zone_dma on mapping failure. */ - if (b43legacy_dma_mapping_error(ring, meta->dmaaddr, skb->len)) { + if (b43legacy_dma_mapping_error(ring, meta->dmaaddr, skb->len, 1)) { bounce_skb = __dev_alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA); if (!bounce_skb) { ring->current_slot = old_top_slot; @@ -1268,7 +1275,7 @@ static int dma_tx_fragment(struct b43legacy_dmaring *ring, skb = bounce_skb; meta->skb = skb; meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1); - if (b43legacy_dma_mapping_error(ring, meta->dmaaddr, skb->len)) { + if (b43legacy_dma_mapping_error(ring, meta->dmaaddr, skb->len, 1)) { ring->current_slot = old_top_slot; ring->used_slots = old_used_slots; err = -EIO; |