mirror of https://gitee.com/openkylin/linux.git
atl1e: fix 2.6.31-git4 -- ATL1E 0000:03:00.0: DMA-API: device driver frees DMA
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> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
a19d215843
commit
03f1899161
|
@ -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 */
|
||||
|
|
|
@ -635,6 +635,10 @@ 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) {
|
||||
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,6 +1224,10 @@ 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) {
|
||||
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) &
|
||||
|
|
Loading…
Reference in New Issue