diff options
author | Russell King <rmk@dyn-67.arm.linux.org.uk> | 2008-04-19 12:17:29 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2008-04-19 12:17:29 -0400 |
commit | adf6d34e460387ee3e8f1e1875d52bff51212c7d (patch) | |
tree | 88ef100143e6184103a608f82dfd232bf6376eaf /drivers/net/wireless/b43/dma.c | |
parent | d1964dab60ce7c104dd21590e987a8787db18051 (diff) | |
parent | 3760d31f11bfbd0ead9eaeb8573e0602437a9d7c (diff) |
Merge branch 'omap2-upstream' into devel
Diffstat (limited to 'drivers/net/wireless/b43/dma.c')
-rw-r--r-- | drivers/net/wireless/b43/dma.c | 37 |
1 files changed, 25 insertions, 12 deletions
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c index 3dfb28a34be9..948eb1fe916b 100644 --- a/drivers/net/wireless/b43/dma.c +++ b/drivers/net/wireless/b43/dma.c | |||
@@ -560,7 +560,7 @@ static int b43_dmacontroller_tx_reset(struct b43_wldev *dev, u16 mmio_base, | |||
560 | /* Check if a DMA mapping address is invalid. */ | 560 | /* Check if a DMA mapping address is invalid. */ |
561 | static bool b43_dma_mapping_error(struct b43_dmaring *ring, | 561 | static bool b43_dma_mapping_error(struct b43_dmaring *ring, |
562 | dma_addr_t addr, | 562 | dma_addr_t addr, |
563 | size_t buffersize) | 563 | size_t buffersize, bool dma_to_device) |
564 | { | 564 | { |
565 | if (unlikely(dma_mapping_error(addr))) | 565 | if (unlikely(dma_mapping_error(addr))) |
566 | return 1; | 566 | return 1; |
@@ -568,11 +568,11 @@ static bool b43_dma_mapping_error(struct b43_dmaring *ring, | |||
568 | switch (ring->type) { | 568 | switch (ring->type) { |
569 | case B43_DMA_30BIT: | 569 | case B43_DMA_30BIT: |
570 | if ((u64)addr + buffersize > (1ULL << 30)) | 570 | if ((u64)addr + buffersize > (1ULL << 30)) |
571 | return 1; | 571 | goto address_error; |
572 | break; | 572 | break; |
573 | case B43_DMA_32BIT: | 573 | case B43_DMA_32BIT: |
574 | if ((u64)addr + buffersize > (1ULL << 32)) | 574 | if ((u64)addr + buffersize > (1ULL << 32)) |
575 | return 1; | 575 | goto address_error; |
576 | break; | 576 | break; |
577 | case B43_DMA_64BIT: | 577 | case B43_DMA_64BIT: |
578 | /* Currently we can't have addresses beyond | 578 | /* Currently we can't have addresses beyond |
@@ -582,6 +582,12 @@ static bool b43_dma_mapping_error(struct b43_dmaring *ring, | |||
582 | 582 | ||
583 | /* The address is OK. */ | 583 | /* The address is OK. */ |
584 | return 0; | 584 | return 0; |
585 | |||
586 | address_error: | ||
587 | /* We can't support this address. Unmap it again. */ | ||
588 | unmap_descbuffer(ring, addr, buffersize, dma_to_device); | ||
589 | |||
590 | return 1; | ||
585 | } | 591 | } |
586 | 592 | ||
587 | static int setup_rx_descbuffer(struct b43_dmaring *ring, | 593 | static int setup_rx_descbuffer(struct b43_dmaring *ring, |
@@ -599,7 +605,7 @@ static int setup_rx_descbuffer(struct b43_dmaring *ring, | |||
599 | if (unlikely(!skb)) | 605 | if (unlikely(!skb)) |
600 | return -ENOMEM; | 606 | return -ENOMEM; |
601 | dmaaddr = map_descbuffer(ring, skb->data, ring->rx_buffersize, 0); | 607 | dmaaddr = map_descbuffer(ring, skb->data, ring->rx_buffersize, 0); |
602 | if (b43_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize)) { | 608 | if (b43_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize, 0)) { |
603 | /* ugh. try to realloc in zone_dma */ | 609 | /* ugh. try to realloc in zone_dma */ |
604 | gfp_flags |= GFP_DMA; | 610 | gfp_flags |= GFP_DMA; |
605 | 611 | ||
@@ -612,7 +618,8 @@ static int setup_rx_descbuffer(struct b43_dmaring *ring, | |||
612 | ring->rx_buffersize, 0); | 618 | ring->rx_buffersize, 0); |
613 | } | 619 | } |
614 | 620 | ||
615 | if (b43_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize)) { | 621 | if (b43_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize, 0)) { |
622 | b43err(ring->dev->wl, "RX DMA buffer allocation failed\n"); | ||
616 | dev_kfree_skb_any(skb); | 623 | dev_kfree_skb_any(skb); |
617 | return -EIO; | 624 | return -EIO; |
618 | } | 625 | } |
@@ -852,7 +859,8 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev, | |||
852 | b43_txhdr_size(dev), | 859 | b43_txhdr_size(dev), |
853 | DMA_TO_DEVICE); | 860 | DMA_TO_DEVICE); |
854 | 861 | ||
855 | if (b43_dma_mapping_error(ring, dma_test, b43_txhdr_size(dev))) { | 862 | if (b43_dma_mapping_error(ring, dma_test, |
863 | b43_txhdr_size(dev), 1)) { | ||
856 | /* ugh realloc */ | 864 | /* ugh realloc */ |
857 | kfree(ring->txhdr_cache); | 865 | kfree(ring->txhdr_cache); |
858 | ring->txhdr_cache = kcalloc(nr_slots, | 866 | ring->txhdr_cache = kcalloc(nr_slots, |
@@ -867,8 +875,12 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev, | |||
867 | DMA_TO_DEVICE); | 875 | DMA_TO_DEVICE); |
868 | 876 | ||
869 | if (b43_dma_mapping_error(ring, dma_test, | 877 | if (b43_dma_mapping_error(ring, dma_test, |
870 | b43_txhdr_size(dev))) | 878 | b43_txhdr_size(dev), 1)) { |
879 | |||
880 | b43err(dev->wl, | ||
881 | "TXHDR DMA allocation failed\n"); | ||
871 | goto err_kfree_txhdr_cache; | 882 | goto err_kfree_txhdr_cache; |
883 | } | ||
872 | } | 884 | } |
873 | 885 | ||
874 | dma_unmap_single(dev->dev->dev, | 886 | dma_unmap_single(dev->dev->dev, |
@@ -1189,7 +1201,7 @@ static int dma_tx_fragment(struct b43_dmaring *ring, | |||
1189 | 1201 | ||
1190 | meta_hdr->dmaaddr = map_descbuffer(ring, (unsigned char *)header, | 1202 | meta_hdr->dmaaddr = map_descbuffer(ring, (unsigned char *)header, |
1191 | hdrsize, 1); | 1203 | hdrsize, 1); |
1192 | if (b43_dma_mapping_error(ring, meta_hdr->dmaaddr, hdrsize)) { | 1204 | if (b43_dma_mapping_error(ring, meta_hdr->dmaaddr, hdrsize, 1)) { |
1193 | ring->current_slot = old_top_slot; | 1205 | ring->current_slot = old_top_slot; |
1194 | ring->used_slots = old_used_slots; | 1206 | ring->used_slots = old_used_slots; |
1195 | return -EIO; | 1207 | return -EIO; |
@@ -1208,7 +1220,7 @@ static int dma_tx_fragment(struct b43_dmaring *ring, | |||
1208 | 1220 | ||
1209 | meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1); | 1221 | meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1); |
1210 | /* create a bounce buffer in zone_dma on mapping failure. */ | 1222 | /* create a bounce buffer in zone_dma on mapping failure. */ |
1211 | if (b43_dma_mapping_error(ring, meta->dmaaddr, skb->len)) { | 1223 | if (b43_dma_mapping_error(ring, meta->dmaaddr, skb->len, 1)) { |
1212 | bounce_skb = __dev_alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA); | 1224 | bounce_skb = __dev_alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA); |
1213 | if (!bounce_skb) { | 1225 | if (!bounce_skb) { |
1214 | ring->current_slot = old_top_slot; | 1226 | ring->current_slot = old_top_slot; |
@@ -1222,7 +1234,7 @@ static int dma_tx_fragment(struct b43_dmaring *ring, | |||
1222 | skb = bounce_skb; | 1234 | skb = bounce_skb; |
1223 | meta->skb = skb; | 1235 | meta->skb = skb; |
1224 | meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1); | 1236 | meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1); |
1225 | if (b43_dma_mapping_error(ring, meta->dmaaddr, skb->len)) { | 1237 | if (b43_dma_mapping_error(ring, meta->dmaaddr, skb->len, 1)) { |
1226 | ring->current_slot = old_top_slot; | 1238 | ring->current_slot = old_top_slot; |
1227 | ring->used_slots = old_used_slots; | 1239 | ring->used_slots = old_used_slots; |
1228 | err = -EIO; | 1240 | err = -EIO; |
@@ -1337,6 +1349,7 @@ out_unlock: | |||
1337 | return err; | 1349 | return err; |
1338 | } | 1350 | } |
1339 | 1351 | ||
1352 | /* Called with IRQs disabled. */ | ||
1340 | void b43_dma_handle_txstatus(struct b43_wldev *dev, | 1353 | void b43_dma_handle_txstatus(struct b43_wldev *dev, |
1341 | const struct b43_txstatus *status) | 1354 | const struct b43_txstatus *status) |
1342 | { | 1355 | { |
@@ -1349,8 +1362,8 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev, | |||
1349 | ring = parse_cookie(dev, status->cookie, &slot); | 1362 | ring = parse_cookie(dev, status->cookie, &slot); |
1350 | if (unlikely(!ring)) | 1363 | if (unlikely(!ring)) |
1351 | return; | 1364 | return; |
1352 | B43_WARN_ON(!irqs_disabled()); | 1365 | |
1353 | spin_lock(&ring->lock); | 1366 | spin_lock(&ring->lock); /* IRQs are already disabled. */ |
1354 | 1367 | ||
1355 | B43_WARN_ON(!ring->tx); | 1368 | B43_WARN_ON(!ring->tx); |
1356 | ops = ring->ops; | 1369 | ops = ring->ops; |