From cb415d30048f0c1f80fd2f5340a982e8c9617d0d Mon Sep 17 00:00:00 2001
From: Paolo Galtieri <pgaltieri@mvista.com>
Date: Mon, 16 Jan 2006 16:48:02 -0700
Subject: [PATCH] [PATCH] mv643xx_eth: Fix dma_map/dma_unmap relations

If you do a dma_map_single you must do dma_unmap_single and if you do
a dma_map_page you must do a dma_unmap_page.

Signed-off-by: Paolo Galtieri <pgaltieri@mvista.com>
Signed-off-by: Dale Farnsworth <dale@farnsworth.org>

 mv643xx_eth.c |   51 +++++++++++++++++++++------------------------------
 1 file changed, 21 insertions(+), 30 deletions(-)
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
---
 drivers/net/mv643xx_eth.c | 49 +++++++++++++++------------------------
 1 file changed, 19 insertions(+), 30 deletions(-)

diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index a6152db82e9c..fe53fa0e3aed 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -353,27 +353,19 @@ static int mv643xx_eth_free_tx_queue(struct net_device *dev,
 			stats->tx_errors++;
 		}
 
-		/*
-		 * If return_info is different than 0, release the skb.
-		 * The case where return_info is not 0 is only in case
-		 * when transmitted a scatter/gather packet, where only
-		 * last skb releases the whole chain.
-		 */
-		if (pkt_info.return_info) {
-			if (skb_shinfo(pkt_info.return_info)->nr_frags)
-				dma_unmap_page(NULL, pkt_info.buf_ptr,
-						pkt_info.byte_cnt,
-						DMA_TO_DEVICE);
-			else
-				dma_unmap_single(NULL, pkt_info.buf_ptr,
-						pkt_info.byte_cnt,
-						DMA_TO_DEVICE);
+		if (pkt_info.cmd_sts & ETH_TX_FIRST_DESC)
+			dma_unmap_single(NULL, pkt_info.buf_ptr,
+					pkt_info.byte_cnt,
+					DMA_TO_DEVICE);
+		else
+			dma_unmap_page(NULL, pkt_info.buf_ptr,
+					pkt_info.byte_cnt,
+					DMA_TO_DEVICE);
 
+		if (pkt_info.return_info) {
 			dev_kfree_skb_irq(pkt_info.return_info);
 			released = 0;
-		} else
-			dma_unmap_page(NULL, pkt_info.buf_ptr,
-					pkt_info.byte_cnt, DMA_TO_DEVICE);
+		}
 	}
 
 	spin_unlock(&mp->lock);
@@ -1024,20 +1016,17 @@ static void mv643xx_tx(struct net_device *dev)
 	struct pkt_info pkt_info;
 
 	while (eth_tx_return_desc(mp, &pkt_info) == ETH_OK) {
-		if (pkt_info.return_info) {
-			if (skb_shinfo(pkt_info.return_info)->nr_frags)
-				dma_unmap_page(NULL, pkt_info.buf_ptr,
-						pkt_info.byte_cnt,
-						DMA_TO_DEVICE);
-			else
-				dma_unmap_single(NULL, pkt_info.buf_ptr,
-						pkt_info.byte_cnt,
-						DMA_TO_DEVICE);
+		if (pkt_info.cmd_sts & ETH_TX_FIRST_DESC)
+			dma_unmap_single(NULL, pkt_info.buf_ptr,
+					pkt_info.byte_cnt,
+					DMA_TO_DEVICE);
+		else
+			dma_unmap_page(NULL, pkt_info.buf_ptr,
+					pkt_info.byte_cnt,
+					DMA_TO_DEVICE);
 
+		if (pkt_info.return_info)
 			dev_kfree_skb_irq(pkt_info.return_info);
-		} else
-			dma_unmap_page(NULL, pkt_info.buf_ptr,
-					pkt_info.byte_cnt, DMA_TO_DEVICE);
 	}
 
 	if (netif_queue_stopped(dev) &&
-- 
2.34.1