Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9ee09d9c authored by Jon Mason's avatar Jon Mason Committed by Jeff Garzik
Browse files

[PATCH] dl2k: DMA freeing error



This patch fixes an error in the dl2k driver's DMA mapping/unmapping.
The adapter uses the upper 16bits of the DMA address for the buffer
size.  However, this is not masked off when referencing the DMA
address, and can lead to errors by trying to free a DMA address out of
range.

Thanks,
Jon

Signed-off-by: default avatarJon Mason <jdmason@us.ibm.com>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent 9e927fb6
Loading
Loading
Loading
Loading
+15 −10
Original line number Diff line number Diff line
@@ -50,8 +50,8 @@

*/
#define DRV_NAME	"D-Link DL2000-based linux driver"
#define DRV_VERSION	"v1.17a"
#define DRV_RELDATE	"2002/10/04"
#define DRV_VERSION	"v1.17b"
#define DRV_RELDATE	"2006/03/10"
#include "dl2k.h"

static char version[] __devinitdata =
@@ -765,7 +765,7 @@ rio_free_tx (struct net_device *dev, int irq)
			break;
		skb = np->tx_skbuff[entry];
		pci_unmap_single (np->pdev,
				  np->tx_ring[entry].fraginfo,
				  np->tx_ring[entry].fraginfo & 0xffffffffffff,
				  skb->len, PCI_DMA_TODEVICE);
		if (irq)
			dev_kfree_skb_irq (skb);
@@ -892,14 +892,16 @@ receive_packet (struct net_device *dev)

			/* Small skbuffs for short packets */
			if (pkt_len > copy_thresh) {
				pci_unmap_single (np->pdev, desc->fraginfo,
				pci_unmap_single (np->pdev,
						  desc->fraginfo & 0xffffffffffff,
						  np->rx_buf_sz,
						  PCI_DMA_FROMDEVICE);
				skb_put (skb = np->rx_skbuff[entry], pkt_len);
				np->rx_skbuff[entry] = NULL;
			} else if ((skb = dev_alloc_skb (pkt_len + 2)) != NULL) {
				pci_dma_sync_single_for_cpu(np->pdev,
							    desc->fraginfo,
				  			    desc->fraginfo & 
							    	0xffffffffffff,
							    np->rx_buf_sz,
							    PCI_DMA_FROMDEVICE);
				skb->dev = dev;
@@ -910,7 +912,8 @@ receive_packet (struct net_device *dev)
						  pkt_len, 0);
				skb_put (skb, pkt_len);
				pci_dma_sync_single_for_device(np->pdev,
							       desc->fraginfo,
				  			       desc->fraginfo &
							       	 0xffffffffffff,
							       np->rx_buf_sz,
							       PCI_DMA_FROMDEVICE);
			}
@@ -1796,7 +1799,8 @@ rio_close (struct net_device *dev)
		np->rx_ring[i].fraginfo = 0;
		skb = np->rx_skbuff[i];
		if (skb) {
			pci_unmap_single (np->pdev, np->rx_ring[i].fraginfo,
			pci_unmap_single(np->pdev, 
					 np->rx_ring[i].fraginfo & 0xffffffffffff,
					 skb->len, PCI_DMA_FROMDEVICE);
			dev_kfree_skb (skb);
			np->rx_skbuff[i] = NULL;
@@ -1805,7 +1809,8 @@ rio_close (struct net_device *dev)
	for (i = 0; i < TX_RING_SIZE; i++) {
		skb = np->tx_skbuff[i];
		if (skb) {
			pci_unmap_single (np->pdev, np->tx_ring[i].fraginfo,
			pci_unmap_single(np->pdev, 
					 np->tx_ring[i].fraginfo & 0xffffffffffff,
					 skb->len, PCI_DMA_TODEVICE);
			dev_kfree_skb (skb);
			np->tx_skbuff[i] = NULL;