[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <24b2e6936782b494815165de6cc7863cee900a69.1310339688.git.mirq-linux@rere.qmqm.pl>
Date: Mon, 11 Jul 2011 02:52:46 +0200 (CEST)
From: Michał Mirosław <mirq-linux@...e.qmqm.pl>
To: netdev@...r.kernel.org
Subject: [PATCH v2 06/46] net/tokenring: 3c359: fix DMA API usage
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@...e.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
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists