Commit 639b421b authored by Andi Kleen's avatar Andi Kleen Committed by Linus Torvalds

[PATCH] x86_64: Check for bad dma address in b44 1GB DMA workaround

Needed for interaction with the nommu code in x86-64 which
will return bad_dma_address if the address exceeds dma_mask.

Cc: netdev@vger.kernel.org
Signed-off-by: default avatarAndi Kleen <ak@suse.de>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent c4694c76
...@@ -650,8 +650,10 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked) ...@@ -650,8 +650,10 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
/* Hardware bug work-around, the chip is unable to do PCI DMA /* Hardware bug work-around, the chip is unable to do PCI DMA
to/from anything above 1GB :-( */ to/from anything above 1GB :-( */
if (mapping + RX_PKT_BUF_SZ > B44_DMA_MASK) { if (dma_mapping_error(mapping) ||
mapping + RX_PKT_BUF_SZ > B44_DMA_MASK) {
/* Sigh... */ /* Sigh... */
if (!dma_mapping_error(mapping))
pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE); pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE);
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
skb = __dev_alloc_skb(RX_PKT_BUF_SZ,GFP_DMA); skb = __dev_alloc_skb(RX_PKT_BUF_SZ,GFP_DMA);
...@@ -660,7 +662,9 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked) ...@@ -660,7 +662,9 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
mapping = pci_map_single(bp->pdev, skb->data, mapping = pci_map_single(bp->pdev, skb->data,
RX_PKT_BUF_SZ, RX_PKT_BUF_SZ,
PCI_DMA_FROMDEVICE); PCI_DMA_FROMDEVICE);
if (mapping + RX_PKT_BUF_SZ > B44_DMA_MASK) { if (dma_mapping_error(mapping) ||
mapping + RX_PKT_BUF_SZ > B44_DMA_MASK) {
if (!dma_mapping_error(mapping))
pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE); pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE);
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
return -ENOMEM; return -ENOMEM;
...@@ -967,8 +971,9 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -967,8 +971,9 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
} }
mapping = pci_map_single(bp->pdev, skb->data, len, PCI_DMA_TODEVICE); mapping = pci_map_single(bp->pdev, skb->data, len, PCI_DMA_TODEVICE);
if (mapping + len > B44_DMA_MASK) { if (dma_mapping_error(mapping) || mapping + len > B44_DMA_MASK) {
/* Chip can't handle DMA to/from >1GB, use bounce buffer */ /* Chip can't handle DMA to/from >1GB, use bounce buffer */
if (!dma_mapping_error(mapping))
pci_unmap_single(bp->pdev, mapping, len, PCI_DMA_TODEVICE); pci_unmap_single(bp->pdev, mapping, len, PCI_DMA_TODEVICE);
bounce_skb = __dev_alloc_skb(TX_PKT_BUF_SZ, bounce_skb = __dev_alloc_skb(TX_PKT_BUF_SZ,
...@@ -978,7 +983,8 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -978,7 +983,8 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
mapping = pci_map_single(bp->pdev, bounce_skb->data, mapping = pci_map_single(bp->pdev, bounce_skb->data,
len, PCI_DMA_TODEVICE); len, PCI_DMA_TODEVICE);
if (mapping + len > B44_DMA_MASK) { if (dma_mapping_error(mapping) || mapping + len > B44_DMA_MASK) {
if (!dma_mapping_error(mapping))
pci_unmap_single(bp->pdev, mapping, pci_unmap_single(bp->pdev, mapping,
len, PCI_DMA_TODEVICE); len, PCI_DMA_TODEVICE);
dev_kfree_skb_any(bounce_skb); dev_kfree_skb_any(bounce_skb);
...@@ -1203,7 +1209,8 @@ static int b44_alloc_consistent(struct b44 *bp) ...@@ -1203,7 +1209,8 @@ static int b44_alloc_consistent(struct b44 *bp)
DMA_TABLE_BYTES, DMA_TABLE_BYTES,
DMA_BIDIRECTIONAL); DMA_BIDIRECTIONAL);
if (rx_ring_dma + size > B44_DMA_MASK) { if (dma_mapping_error(rx_ring_dma) ||
rx_ring_dma + size > B44_DMA_MASK) {
kfree(rx_ring); kfree(rx_ring);
goto out_err; goto out_err;
} }
...@@ -1229,7 +1236,8 @@ static int b44_alloc_consistent(struct b44 *bp) ...@@ -1229,7 +1236,8 @@ static int b44_alloc_consistent(struct b44 *bp)
DMA_TABLE_BYTES, DMA_TABLE_BYTES,
DMA_TO_DEVICE); DMA_TO_DEVICE);
if (tx_ring_dma + size > B44_DMA_MASK) { if (dma_mapping_error(tx_ring_dma) ||
tx_ring_dma + size > B44_DMA_MASK) {
kfree(tx_ring); kfree(tx_ring);
goto out_err; goto out_err;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment