[PATCH v2 06/46] net/tokenring: 3c359: fix DMA API usage
From: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Date: 2011-07-11 00:52:50
Subsystem:
networking drivers, the rest · Maintainers:
Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds
TX/RX rings should be allocated from DMA coherent memory (driver does not sync the descriptors in any way). Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl> --- drivers/net/tokenring/3c359.c | 49 +++++++++++++++++++++++++---------------- drivers/net/tokenring/3c359.h | 4 +- 2 files changed, 32 insertions(+), 21 deletions(-)
diff --git a/drivers/net/tokenring/3c359.c b/drivers/net/tokenring/3c359.c
index b6162fe..d321640 100644
--- a/drivers/net/tokenring/3c359.c
+++ b/drivers/net/tokenring/3c359.c@@ -672,21 +672,25 @@ static int xl_open(struct net_device *dev) * Now to set up the Rx and Tx buffer structures */ /* These MUST be on 8 byte boundaries */ - xl_priv->xl_tx_ring = kzalloc((sizeof(struct xl_tx_desc) * XL_TX_RING_SIZE) + 7, GFP_DMA | GFP_KERNEL); + xl_priv->xl_tx_ring = dma_alloc_coherent(&xl_priv->pdev->dev, + sizeof(struct xl_tx_desc) * XL_TX_RING_SIZE, + &xl_priv->tx_ring_dma_addr, GFP_KERNEL); if (xl_priv->xl_tx_ring == NULL) { printk(KERN_WARNING "%s: Not enough memory to allocate tx buffers.\n", dev->name); - free_irq(dev->irq,dev); - return -ENOMEM; + goto err_free_irq; } - xl_priv->xl_rx_ring = kzalloc((sizeof(struct xl_rx_desc) * XL_RX_RING_SIZE) +7, GFP_DMA | GFP_KERNEL); + xl_priv->xl_rx_ring = dma_alloc_coherent(&xl_priv->pdev->dev, + sizeof(struct xl_rx_desc) * XL_RX_RING_SIZE, + &xl_priv->rx_ring_dma_addr, GFP_KERNEL); if (xl_priv->xl_rx_ring == NULL) { printk(KERN_WARNING "%s: Not enough memory to allocate rx buffers.\n", dev->name); - free_irq(dev->irq,dev); - kfree(xl_priv->xl_tx_ring); - return -ENOMEM; + goto err_free_tx; } + /* dma_alloc_coherent() should provide for the following */ + BUG_ON(!IS_ALIGNED((unsigned long)xl_priv->xl_tx_ring, 8)); + BUG_ON(!IS_ALIGNED((unsigned long)xl_priv->xl_rx_ring, 8)); /* Setup Rx Ring */ for (i=0 ; i < XL_RX_RING_SIZE ; i++) {
@@ -704,10 +708,7 @@ static int xl_open(struct net_device *dev) if (i==0) { printk(KERN_WARNING "%s: Not enough memory to allocate rx buffers. Adapter disabled\n",dev->name); - free_irq(dev->irq,dev) ; - kfree(xl_priv->xl_tx_ring); - kfree(xl_priv->xl_rx_ring); - return -EIO ; + goto err_free_rxtx; } xl_priv->rx_ring_no = i ;
@@ -722,8 +723,6 @@ static int xl_open(struct net_device *dev) /* Setup Tx Ring */ - xl_priv->tx_ring_dma_addr = pci_map_single(xl_priv->pdev,xl_priv->xl_tx_ring, sizeof(struct xl_tx_desc) * XL_TX_RING_SIZE,PCI_DMA_TODEVICE) ; - xl_priv->tx_ring_head = 1 ; xl_priv->tx_ring_tail = 255 ; /* Special marker for first packet */ xl_priv->free_ring_entries = XL_TX_RING_SIZE ;
@@ -752,7 +751,18 @@ static int xl_open(struct net_device *dev) netif_start_queue(dev) ; return 0; - + +err_free_rxtx: + dma_free_coherent(&xl_priv->pdev->dev, + sizeof(struct xl_rx_desc) * XL_RX_RING_SIZE, + xl_priv->xl_rx_ring, xl_priv->rx_ring_dma_addr); +err_free_tx: + dma_free_coherent(&xl_priv->pdev->dev, + sizeof(struct xl_tx_desc) * XL_TX_RING_SIZE, + xl_priv->xl_tx_ring, xl_priv->tx_ring_dma_addr); +err_free_irq: + free_irq(dev->irq,dev); + return -ENOMEM; } static int xl_open_hw(struct net_device *dev)
@@ -1060,12 +1070,13 @@ static void xl_freemem(struct net_device *dev) } /* unmap ring */ - pci_unmap_single(xl_priv->pdev,xl_priv->rx_ring_dma_addr, sizeof(struct xl_rx_desc) * XL_RX_RING_SIZE, PCI_DMA_FROMDEVICE) ; - - pci_unmap_single(xl_priv->pdev,xl_priv->tx_ring_dma_addr, sizeof(struct xl_tx_desc) * XL_TX_RING_SIZE, PCI_DMA_TODEVICE) ; + dma_free_coherent(&xl_priv->pdev->dev, + sizeof(struct xl_rx_desc) * XL_RX_RING_SIZE, + xl_priv->xl_rx_ring, xl_priv->rx_ring_dma_addr); - kfree(xl_priv->xl_rx_ring) ; - kfree(xl_priv->xl_tx_ring) ; + dma_free_coherent(&xl_priv->pdev->dev, + sizeof(struct xl_tx_desc) * XL_TX_RING_SIZE, + xl_priv->xl_tx_ring, xl_priv->tx_ring_dma_addr); return ; }
diff --git a/drivers/net/tokenring/3c359.h b/drivers/net/tokenring/3c359.h
index bcb1a6b..baefdd3 100644
--- a/drivers/net/tokenring/3c359.h
+++ b/drivers/net/tokenring/3c359.h@@ -282,8 +282,8 @@ struct xl_private { unsigned char xl_functional_addr[4] ; u16 xl_addr_table_addr, xl_parms_addr ; u8 xl_laa[6] ; - u32 rx_ring_dma_addr ; - u32 tx_ring_dma_addr ; + dma_addr_t rx_ring_dma_addr; + dma_addr_t tx_ring_dma_addr; /* firmware section */ const struct firmware *fw;
--
1.7.5.4