Patchwork [net-next] atl1e:fix 2.6.31-git4 -- ATL1E 0000:03:00.0: DMA-API: device driver frees DMA

login
register
mail settings
Submitter jie.yang@atheros.com
Date Sept. 16, 2009, 9:28 a.m.
Message ID <12530933101782-git-send-email-jie.yang@atheros.com>
Download mbox | patch
Permalink /patch/33693/
State Accepted
Delegated to: David Miller
Headers show

Comments

jie.yang@atheros.com - Sept. 16, 2009, 9:28 a.m.
use the wrong API when free dma. So when map dma use a flag to demostrate whether it is 'pci_map_single' or 'pci_map_page'. When free the dma, check the flags to select the right APIs('pci_unmap_single' or 'pci_unmap_page').

set the flags type to u16  instead of unsigned long  on David's comments.

Signed-off-by: Jie Yang <jie.yang@atheros.com>
---


--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
David Miller - Sept. 17, 2009, 5:27 p.m.
From: <jie.yang@atheros.com>
Date: Wed, 16 Sep 2009 17:28:30 +0800

> use the wrong API when free dma. So when map dma use a flag to demostrate whether it is 'pci_map_single' or 'pci_map_page'. When free the dma, check the flags to select the right APIs('pci_unmap_single' or 'pci_unmap_page').
> 
> set the flags type to u16  instead of unsigned long  on David's comments.
> 
> Signed-off-by: Jie Yang <jie.yang@atheros.com>

Applied.
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Patch

diff --git a/drivers/net/atl1e/atl1e.h b/drivers/net/atl1e/atl1e.h
index ba48220..490d3b3 100644
--- a/drivers/net/atl1e/atl1e.h
+++ b/drivers/net/atl1e/atl1e.h
@@ -377,10 +377,19 @@  struct atl1e_hw {
  */
 struct atl1e_tx_buffer {
 	struct sk_buff *skb;
+	u16 flags;
+#define ATL1E_TX_PCIMAP_SINGLE		0x0001
+#define ATL1E_TX_PCIMAP_PAGE		0x0002
+#define ATL1E_TX_PCIMAP_TYPE_MASK	0x0003
 	u16 length;
 	dma_addr_t dma;
 };
 
+#define ATL1E_SET_PCIMAP_TYPE(tx_buff, type) do {		\
+	((tx_buff)->flags) &= ~ATL1E_TX_PCIMAP_TYPE_MASK;	\
+	((tx_buff)->flags) |= (type);				\
+	} while (0)
+
 struct atl1e_rx_page {
 	dma_addr_t	dma;    /* receive rage DMA address */
 	u8		*addr;   /* receive rage virtual address */
diff --git a/drivers/net/atl1e/atl1e_main.c b/drivers/net/atl1e/atl1e_main.c
index 69b830f..955da73 100644
--- a/drivers/net/atl1e/atl1e_main.c
+++ b/drivers/net/atl1e/atl1e_main.c
@@ -635,7 +635,11 @@  static void atl1e_clean_tx_ring(struct atl1e_adapter *adapter)
 	for (index = 0; index < ring_count; index++) {
 		tx_buffer = &tx_ring->tx_buffer[index];
 		if (tx_buffer->dma) {
-			pci_unmap_page(pdev, tx_buffer->dma,
+			if (tx_buffer->flags & ATL1E_TX_PCIMAP_SINGLE)
+				pci_unmap_single(pdev, tx_buffer->dma,
+					tx_buffer->length, PCI_DMA_TODEVICE);
+			else if (tx_buffer->flags & ATL1E_TX_PCIMAP_PAGE)
+				pci_unmap_page(pdev, tx_buffer->dma,
 					tx_buffer->length, PCI_DMA_TODEVICE);
 			tx_buffer->dma = 0;
 		}
@@ -1220,7 +1224,11 @@  static bool atl1e_clean_tx_irq(struct atl1e_adapter *adapter)
 	while (next_to_clean != hw_next_to_clean) {
 		tx_buffer = &tx_ring->tx_buffer[next_to_clean];
 		if (tx_buffer->dma) {
-			pci_unmap_page(adapter->pdev, tx_buffer->dma,
+			if (tx_buffer->flags & ATL1E_TX_PCIMAP_SINGLE)
+				pci_unmap_single(adapter->pdev, tx_buffer->dma,
+					tx_buffer->length, PCI_DMA_TODEVICE);
+			else if (tx_buffer->flags & ATL1E_TX_PCIMAP_PAGE)
+				pci_unmap_page(adapter->pdev, tx_buffer->dma,
 					tx_buffer->length, PCI_DMA_TODEVICE);
 			tx_buffer->dma = 0;
 		}
@@ -1741,6 +1749,7 @@  static void atl1e_tx_map(struct atl1e_adapter *adapter,
 		tx_buffer->length = map_len;
 		tx_buffer->dma = pci_map_single(adapter->pdev,
 					skb->data, hdr_len, PCI_DMA_TODEVICE);
+		ATL1E_SET_PCIMAP_TYPE(tx_buffer, ATL1E_TX_PCIMAP_SINGLE);
 		mapped_len += map_len;
 		use_tpd->buffer_addr = cpu_to_le64(tx_buffer->dma);
 		use_tpd->word2 = (use_tpd->word2 & (~TPD_BUFLEN_MASK)) |
@@ -1766,6 +1775,7 @@  static void atl1e_tx_map(struct atl1e_adapter *adapter,
 		tx_buffer->dma =
 			pci_map_single(adapter->pdev, skb->data + mapped_len,
 					map_len, PCI_DMA_TODEVICE);
+		ATL1E_SET_PCIMAP_TYPE(tx_buffer, ATL1E_TX_PCIMAP_SINGLE);
 		mapped_len  += map_len;
 		use_tpd->buffer_addr = cpu_to_le64(tx_buffer->dma);
 		use_tpd->word2 = (use_tpd->word2 & (~TPD_BUFLEN_MASK)) |
@@ -1801,6 +1811,7 @@  static void atl1e_tx_map(struct atl1e_adapter *adapter,
 						(i * MAX_TX_BUF_LEN),
 						tx_buffer->length,
 						PCI_DMA_TODEVICE);
+			ATL1E_SET_PCIMAP_TYPE(tx_buffer, ATL1E_TX_PCIMAP_PAGE);
 			use_tpd->buffer_addr = cpu_to_le64(tx_buffer->dma);
 			use_tpd->word2 = (use_tpd->word2 & (~TPD_BUFLEN_MASK)) |
 					((cpu_to_le32(tx_buffer->length) &